@rendra-ui/web 2.5.0 → 2.7.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.
- package/README.md +13 -3
- package/dist/base.css +1 -1
- package/dist/{empty-state-Cdb1vkMT.js → brand-feedback-icon-BYNcqBel.js} +4 -64
- package/dist/brand-feedback-icon-BYNcqBel.js.map +1 -0
- package/dist/{button-BzJgR2gH.js → button-DlzWwpZk.js} +7 -7
- package/dist/button-DlzWwpZk.js.map +1 -0
- package/dist/chart.js +15 -13
- package/dist/chart.js.map +1 -1
- package/dist/cli/auditar.js +1 -1
- package/dist/cli/codigos.js +2 -2
- package/dist/cli/executar-auditar.js +1 -1
- package/dist/cli/help.js +1 -1
- package/dist/cli/trocar.js +2 -2
- package/dist/cli/typescript-loader.js +1 -1
- package/dist/{cn-Cw7M5kEP.js → cn-B0N3Pek0.js} +2 -2
- package/dist/{cn-Cw7M5kEP.js.map → cn-B0N3Pek0.js.map} +1 -1
- package/dist/{components-DkpspH9h.js → components-CpQPMGfT.js} +18 -2
- package/dist/{components-DkpspH9h.js.map → components-CpQPMGfT.js.map} +1 -1
- package/dist/components.css +90 -1
- package/dist/document-viewer.js +4 -4
- package/dist/{tooltip-BAMSaGbS.js → dropdown-menu-M8vs0byD.js} +15 -81
- package/dist/dropdown-menu-M8vs0byD.js.map +1 -0
- package/dist/empty-state-a47Kd_Ci.js +67 -0
- package/dist/empty-state-a47Kd_Ci.js.map +1 -0
- package/dist/{features-max--5VEt6M7.js → features-max-ScxV8gb3.js} +1 -1
- package/dist/flow.js +1485 -0
- package/dist/flow.js.map +1 -0
- package/dist/index.js +130 -1899
- package/dist/index.js.map +1 -1
- package/dist/motion-context-BUMPf0e9.js +222 -0
- package/dist/motion-context-BUMPf0e9.js.map +1 -0
- package/dist/motion-on-CNN6y8g-.js +29 -0
- package/dist/motion-on-CNN6y8g-.js.map +1 -0
- package/dist/motion.js +3 -0
- package/dist/{rendra-provider-CRe0XdOU.js → rendra-provider-DEURIIL3.js} +3 -3
- package/dist/rendra-provider-DEURIIL3.js.map +1 -0
- package/dist/rich-text-editor.js +4 -3
- package/dist/rich-text-editor.js.map +1 -1
- package/dist/router-bridge.js +2 -2
- package/dist/router-bridge.js.map +1 -1
- package/dist/timeline-BOh7gUdA.js +1803 -0
- package/dist/timeline-BOh7gUdA.js.map +1 -0
- package/dist/tokens.css +1 -1
- package/dist/tooltip-Ym9S4h9_.js +76 -0
- package/dist/tooltip-Ym9S4h9_.js.map +1 -0
- package/dist/types/components/rendra-provider.d.ts +7 -2
- package/dist/types/components/rendra-router-bridge.d.ts +2 -1
- package/dist/types/components/ui/flow-editor.d.ts +11 -0
- package/dist/types/components/ui/flow-viewer.d.ts +58 -0
- package/dist/types/flow.d.ts +3 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/lib/flow.d.ts +121 -0
- package/dist/types/lib/motion/index.d.ts +1 -1
- package/dist/types/lib/motion/motion-context.d.ts +21 -6
- package/dist/types/lib/motion/motion-on.d.ts +12 -0
- package/dist/types/motion.d.ts +1 -0
- package/dist/{use-breakpoint-O9eqFmsF.js → use-breakpoint-En17oXKY.js} +2 -2
- package/dist/{use-breakpoint-O9eqFmsF.js.map → use-breakpoint-En17oXKY.js.map} +1 -1
- package/dist/{use-motion-presets-BrkgL8lG.js → use-motion-presets-D3ww1oJX.js} +3 -3
- package/dist/{use-motion-presets-BrkgL8lG.js.map → use-motion-presets-D3ww1oJX.js.map} +1 -1
- package/dist/widget-grid.js +2 -2
- package/package.json +14 -1
- package/dist/button-BzJgR2gH.js.map +0 -1
- package/dist/empty-state-Cdb1vkMT.js.map +0 -1
- package/dist/motion-context-5BRIQAJm.js +0 -107
- package/dist/motion-context-5BRIQAJm.js.map +0 -1
- package/dist/rendra-provider-CRe0XdOU.js.map +0 -1
- package/dist/tooltip-BAMSaGbS.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
2
|
-
import { t as cn } from "./cn-
|
|
3
|
-
import { a as getReducedMotion, n as useLayoutReady, o as
|
|
4
|
-
import { t as useMotionPresets } from "./use-motion-presets-
|
|
5
|
-
import { a as
|
|
6
|
-
import { n as
|
|
7
|
-
import {
|
|
8
|
-
import { a as
|
|
9
|
-
import {
|
|
10
|
-
import { n as
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
1
|
+
/*! Rendra Design System v2.7.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
|
+
import { t as cn } from "./cn-B0N3Pek0.js";
|
|
3
|
+
import { a as useMotionMode, c as getReducedMotion, i as useMotionLib, l as subscribeReducedMotion, n as useLayoutReady, o as useMotionOn, r as useMotionAdopted, u as usePrefersReducedMotion } from "./motion-context-BUMPf0e9.js";
|
|
4
|
+
import { t as useMotionPresets } from "./use-motion-presets-D3ww1oJX.js";
|
|
5
|
+
import { A as lookupCnpj, B as ActionBar, C as toE164, D as controlInput, E as controlFrame, F as CardHeader, H as useShell, I as CardTitle, L as InfoHint, M as CardContent, N as CardDescription, O as useLookup, P as CardFooter, R as Modal, S as toCents, T as controlAdornmentSpace, V as ShellContext, _ as internationalPhoneMask, a as Label, b as percentMask, c as fieldGridClass, d as Drawer, f as PickerPanel, g as formatCurrency, h as formatCents, i as Field, j as Card, k as lookupCep, l as gapClass, m as DEFAULT_DDI, n as useFillHeight, o as useFieldControl, p as Input, r as Select, s as alignClass, t as Timeline, u as justifyClass, v as masks, w as controlAdornmentButton, x as phoneCountries, y as parseLocaleNumber, z as Alert } from "./timeline-BOh7gUdA.js";
|
|
6
|
+
import { a as catalogByComponent, c as findComponentsWithoutDefault, d as findPresetCollisions, f as getCatalogEntry, i as assertCatalogIntegrity, l as findDuplicateCodes, n as CATALOG_EXCLUDED_FILES, o as filesMissingCatalogEntry, p as resolveCatalogCode, r as COMPONENT_CODE_PATTERN, s as findComponentsWithMultipleDefaults, t as CATALOG, u as findInvalidFormatCodes } from "./components-CpQPMGfT.js";
|
|
7
|
+
import { n as buttonVariants, r as Spinner, t as Button } from "./button-DlzWwpZk.js";
|
|
8
|
+
import { a as DropdownMenuItem, c as DropdownMenuRadioItem, d as DropdownMenuSubContent, f as DropdownMenuSubTrigger, i as DropdownMenuGroup, l as DropdownMenuSeparator, n as DropdownMenuCheckboxItem, o as DropdownMenuLabel, p as DropdownMenuTrigger, r as DropdownMenuContent, s as DropdownMenuRadioGroup, t as DropdownMenu, u as DropdownMenuSub } from "./dropdown-menu-M8vs0byD.js";
|
|
9
|
+
import { i as BrandContext, n as feedbackLabels, r as useBrand, t as BrandFeedbackIcon } from "./brand-feedback-icon-BYNcqBel.js";
|
|
10
|
+
import { a as useRendraNavigate, i as useRendraLink, n as useCurrentPath, r as useRendraBreadcrumbs, t as RendraProvider } from "./rendra-provider-DEURIIL3.js";
|
|
11
|
+
import { n as useBreakpoint, t as breakpoints } from "./use-breakpoint-En17oXKY.js";
|
|
12
|
+
import { t as EmptyState } from "./empty-state-a47Kd_Ci.js";
|
|
13
|
+
import { n as TooltipProvider, t as Tooltip } from "./tooltip-Ym9S4h9_.js";
|
|
14
|
+
import { ArrowDown, ArrowDownRight, ArrowLeft, ArrowRight, ArrowRightLeft, ArrowUp, ArrowUpRight, Bell, Bot, CalendarDays, Check, CheckCheck, ChevronDown, ChevronLeft, ChevronRight, ChevronsUpDown, Clock, Columns3, Download, EllipsisVertical, FileText, Film, Filter, Globe, GripVertical, Home, ImageIcon, ImagePlus, LayoutTemplate, LogOut, Mail, MapPin, Menu, MessageCircle, MessagesSquare, Mic, Minus, Monitor, Moon, MoreHorizontal, Palette, PanelLeft, Paperclip, Pause, Pencil, Phone, Play, Plus, Reply, RotateCw, Search, Send, Smartphone, Smile, Star, Sun, Trash2, TriangleAlert, UploadCloud, User, VideoIcon, X, Zap } from "lucide-react";
|
|
15
|
+
import { Accordion as Accordion$1, Avatar as Avatar$1, Checkbox as Checkbox$1, Collapsible, ContextMenu, Dialog, NavigationMenu, Popover as Popover$1, Progress as Progress$1, RadioGroup as RadioGroup$1, Slider as Slider$1, Slot, Switch as Switch$1, Tabs as Tabs$1, VisuallyHidden } from "radix-ui";
|
|
16
|
+
import { Fragment, createContext, forwardRef, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
15
17
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
-
import { createPortal } from "react-dom";
|
|
17
18
|
import { cva } from "class-variance-authority";
|
|
18
19
|
import { addDays, addMonths, addWeeks, differenceInMinutes, endOfMonth, endOfWeek, format, isSameDay, isSameMonth, isToday, isYesterday, startOfDay, startOfMonth, startOfWeek } from "date-fns";
|
|
19
20
|
import { ptBR } from "date-fns/locale";
|
|
20
|
-
import IMask from "imask";
|
|
21
21
|
import { DayPicker } from "react-day-picker";
|
|
22
22
|
import { ptBR as ptBR$1 } from "react-day-picker/locale";
|
|
23
23
|
import { FormProvider, useController, useFormContext } from "react-hook-form";
|
|
@@ -74,10 +74,10 @@ function formatLike(parsed, n) {
|
|
|
74
74
|
//#region src/components/ui/accordion.tsx
|
|
75
75
|
/** Accordion único, com animação de altura e área de toque de 44px no mobile. */
|
|
76
76
|
function Accordion({ items, multiple, defaultValue, className }) {
|
|
77
|
-
const
|
|
77
|
+
const lib = useMotionLib();
|
|
78
78
|
const presets = useMotionPresets();
|
|
79
79
|
const [open, setOpen] = useState(multiple ? defaultValue ?? [] : defaultValue?.[0] ? [defaultValue[0]] : []);
|
|
80
|
-
if (
|
|
80
|
+
if (lib) {
|
|
81
81
|
const rootProps = multiple ? {
|
|
82
82
|
type: "multiple",
|
|
83
83
|
value: open,
|
|
@@ -100,19 +100,19 @@ function Accordion({ items, multiple, defaultValue, className }) {
|
|
|
100
100
|
className: "border-b last:border-b-0",
|
|
101
101
|
children: [/* @__PURE__ */ jsx(Accordion$1.Header, { children: /* @__PURE__ */ jsxs(Accordion$1.Trigger, {
|
|
102
102
|
className: "group flex min-h-touch w-full cursor-pointer items-center justify-between gap-4 py-4 text-left text-sm font-medium transition-colors hover:text-primary-text disabled:cursor-not-allowed disabled:opacity-50 md:min-h-0",
|
|
103
|
-
children: [it.title, /* @__PURE__ */ jsx(m.span, {
|
|
103
|
+
children: [it.title, /* @__PURE__ */ jsx(lib.m.span, {
|
|
104
104
|
"aria-hidden": true,
|
|
105
105
|
className: "flex shrink-0",
|
|
106
106
|
animate: { rotate: isOpen ? 180 : 0 },
|
|
107
107
|
transition: presets.fade.transition,
|
|
108
108
|
children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-icon-sm text-muted-foreground" })
|
|
109
109
|
})]
|
|
110
|
-
}) }), /* @__PURE__ */ jsx(AnimatePresence, {
|
|
110
|
+
}) }), /* @__PURE__ */ jsx(lib.AnimatePresence, {
|
|
111
111
|
initial: false,
|
|
112
112
|
children: isOpen && /* @__PURE__ */ jsx(Accordion$1.Content, {
|
|
113
113
|
forceMount: true,
|
|
114
114
|
asChild: true,
|
|
115
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
115
|
+
children: /* @__PURE__ */ jsx(lib.m.div, {
|
|
116
116
|
className: "overflow-hidden text-sm wrap-break-word text-muted-foreground",
|
|
117
117
|
initial: {
|
|
118
118
|
height: 0,
|
|
@@ -172,129 +172,6 @@ function Accordion({ items, multiple, defaultValue, className }) {
|
|
|
172
172
|
});
|
|
173
173
|
}
|
|
174
174
|
//#endregion
|
|
175
|
-
//#region src/components/app-shell/shell-context.ts
|
|
176
|
-
var ShellContext = createContext(null);
|
|
177
|
-
function useShell() {
|
|
178
|
-
const ctx = useContext(ShellContext);
|
|
179
|
-
if (!ctx) throw new Error("useShell precisa estar dentro de <AppShell>.");
|
|
180
|
-
return ctx;
|
|
181
|
-
}
|
|
182
|
-
//#endregion
|
|
183
|
-
//#region src/components/ui/action-bar.tsx
|
|
184
|
-
/**
|
|
185
|
-
* Barra de ações única, com a regra de botões do sistema:
|
|
186
|
-
* 1 botão = 100%; 2 botões = cancelar 30% + principal 70%; 3 ou mais = extras no menu.
|
|
187
|
-
* Vale para drawer, modal e formulário em página, em qualquer tamanho de tela.
|
|
188
|
-
*/
|
|
189
|
-
function ActionBar({ primary, cancel, secondary, sticky, className }) {
|
|
190
|
-
const slot = useContext(ShellContext)?.footerSlot;
|
|
191
|
-
const hasMenu = Boolean(secondary?.length);
|
|
192
|
-
const layout = cancel ? hasMenu ? "grid-actions-3" : "grid-actions-2" : hasMenu ? "grid-actions-3" : "";
|
|
193
|
-
const bar = /* @__PURE__ */ jsx("div", {
|
|
194
|
-
"data-rendra": "ACB-001",
|
|
195
|
-
className: cn(sticky && "border-t bg-card px-4 pt-4 pb-safe md:px-6", sticky && !slot && "sticky bottom-0 z-20", className),
|
|
196
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
197
|
-
className: cn("grid gap-3", layout || "grid-cols-1", sticky && "w-full"),
|
|
198
|
-
children: [
|
|
199
|
-
hasMenu && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
200
|
-
asChild: true,
|
|
201
|
-
children: /* @__PURE__ */ jsx(Button, {
|
|
202
|
-
variant: "outline",
|
|
203
|
-
iconOnly: true,
|
|
204
|
-
"aria-label": "Mais ações",
|
|
205
|
-
children: /* @__PURE__ */ jsx(MoreHorizontal, {})
|
|
206
|
-
})
|
|
207
|
-
}), /* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
208
|
-
align: "start",
|
|
209
|
-
side: "top",
|
|
210
|
-
children: secondary.map((a) => /* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
211
|
-
onSelect: a.onClick,
|
|
212
|
-
disabled: a.disabled,
|
|
213
|
-
destructive: a.destructive,
|
|
214
|
-
children: [a.icon, a.label]
|
|
215
|
-
}, a.label))
|
|
216
|
-
})] }),
|
|
217
|
-
cancel ? /* @__PURE__ */ jsx(Button, {
|
|
218
|
-
variant: "outline",
|
|
219
|
-
icon: cancel.icon,
|
|
220
|
-
onClick: cancel.onClick,
|
|
221
|
-
disabled: cancel.disabled || primary.loading,
|
|
222
|
-
fullWidth: true,
|
|
223
|
-
children: cancel.label
|
|
224
|
-
}) : hasMenu ? /* @__PURE__ */ jsx("span", { "aria-hidden": true }) : null,
|
|
225
|
-
/* @__PURE__ */ jsx(Button, {
|
|
226
|
-
type: primary.type ?? "button",
|
|
227
|
-
form: primary.form,
|
|
228
|
-
variant: primary.destructive ? "destructive" : "primary",
|
|
229
|
-
icon: primary.icon,
|
|
230
|
-
onClick: primary.onClick,
|
|
231
|
-
disabled: primary.disabled,
|
|
232
|
-
loading: primary.loading,
|
|
233
|
-
fullWidth: true,
|
|
234
|
-
children: primary.loading ? primary.loadingLabel ?? "Salvando..." : primary.label
|
|
235
|
-
})
|
|
236
|
-
]
|
|
237
|
-
})
|
|
238
|
-
});
|
|
239
|
-
return sticky && slot ? createPortal(bar, slot) : bar;
|
|
240
|
-
}
|
|
241
|
-
//#endregion
|
|
242
|
-
//#region src/components/ui/alert.tsx
|
|
243
|
-
/**
|
|
244
|
-
* Alert único do sistema: ícone da marca à esquerda, título em destaque e descrição.
|
|
245
|
-
* O tipo é prop; o formato vem do template ativo (quadrado, meio-termo ou arredondado).
|
|
246
|
-
*/
|
|
247
|
-
var alertVariants = cva("flex w-full min-w-0 items-start gap-3 rounded-control border", {
|
|
248
|
-
variants: { type: {
|
|
249
|
-
success: "border-success/25 bg-success-soft text-success-soft-foreground",
|
|
250
|
-
error: "border-destructive/25 bg-destructive-soft text-destructive-soft-foreground",
|
|
251
|
-
warning: "border-warning/25 bg-warning-soft text-warning-soft-foreground",
|
|
252
|
-
info: "border-info/25 bg-info-soft text-info-soft-foreground"
|
|
253
|
-
} },
|
|
254
|
-
defaultVariants: { type: "info" }
|
|
255
|
-
});
|
|
256
|
-
function Alert({ type, title, description, action, onDismiss, animated = false, className }) {
|
|
257
|
-
const { shape } = useBrand();
|
|
258
|
-
const pill = shape === "pill";
|
|
259
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
260
|
-
role: type === "error" || type === "warning" ? "alert" : "status",
|
|
261
|
-
"data-rendra": "ALRT-001",
|
|
262
|
-
className: cn(alertVariants({ type }), pill ? "items-center py-3 pr-4 pl-4 md:pr-6" : "p-4", className),
|
|
263
|
-
children: [
|
|
264
|
-
/* @__PURE__ */ jsx(BrandFeedbackIcon, {
|
|
265
|
-
type,
|
|
266
|
-
size: "lg",
|
|
267
|
-
animated,
|
|
268
|
-
className: cn(!pill && "mt-px")
|
|
269
|
-
}),
|
|
270
|
-
/* @__PURE__ */ jsxs("div", {
|
|
271
|
-
className: cn("flex min-w-0 flex-1 flex-col", !pill && "gap-1"),
|
|
272
|
-
children: [/* @__PURE__ */ jsx("p", {
|
|
273
|
-
className: "text-sm font-semibold",
|
|
274
|
-
children: title
|
|
275
|
-
}), description && /* @__PURE__ */ jsx("p", {
|
|
276
|
-
className: "text-sm opacity-90",
|
|
277
|
-
children: description
|
|
278
|
-
})]
|
|
279
|
-
}),
|
|
280
|
-
action && /* @__PURE__ */ jsx("div", {
|
|
281
|
-
className: "shrink-0 self-center",
|
|
282
|
-
children: action
|
|
283
|
-
}),
|
|
284
|
-
onDismiss && /* @__PURE__ */ jsx("button", {
|
|
285
|
-
type: "button",
|
|
286
|
-
onClick: onDismiss,
|
|
287
|
-
"aria-label": "Fechar aviso",
|
|
288
|
-
className: cn("flex size-touch shrink-0 items-center justify-center rounded-full transition-colors hover:bg-card/60 md:size-8", pill ? "-my-2" : "-mt-2 -mr-2"),
|
|
289
|
-
children: /* @__PURE__ */ jsx(X, {
|
|
290
|
-
className: "size-icon-sm",
|
|
291
|
-
"aria-hidden": true
|
|
292
|
-
})
|
|
293
|
-
})
|
|
294
|
-
]
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
//#endregion
|
|
298
175
|
//#region src/lib/initials.ts
|
|
299
176
|
/** Iniciais de um nome: primeira letra do primeiro e do último nome, em maiúsculas. */
|
|
300
177
|
function initials(name) {
|
|
@@ -618,264 +495,6 @@ function ButtonGroup({ children, options, value, onChange, size = "md", fullWidt
|
|
|
618
495
|
});
|
|
619
496
|
}
|
|
620
497
|
//#endregion
|
|
621
|
-
//#region src/components/ui/overlay-shell.tsx
|
|
622
|
-
function OverlayShell({ title, description, icon, children, footer, hideHeader, onRequestClose, bodyClassName }) {
|
|
623
|
-
const closeButton = /* @__PURE__ */ jsx("button", {
|
|
624
|
-
type: "button",
|
|
625
|
-
onClick: onRequestClose,
|
|
626
|
-
"aria-label": "Fechar",
|
|
627
|
-
className: cn("-mt-1 -mr-2 flex size-touch shrink-0 cursor-pointer items-center justify-center rounded-item text-muted-foreground transition-colors hover:bg-accent hover:text-foreground md:size-control-md", hideHeader && "pointer-events-auto m-0 cursor-default opacity-0 focus-visible:cursor-pointer focus-visible:opacity-100"),
|
|
628
|
-
children: /* @__PURE__ */ jsx(X, {
|
|
629
|
-
className: "size-icon-md",
|
|
630
|
-
"aria-hidden": true
|
|
631
|
-
})
|
|
632
|
-
});
|
|
633
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
634
|
-
hideHeader && /* @__PURE__ */ jsx("div", {
|
|
635
|
-
className: "pointer-events-none absolute inset-x-0 top-0 z-10 flex justify-end px-2 pt-safe md:px-4 md:pt-4",
|
|
636
|
-
children: closeButton
|
|
637
|
-
}),
|
|
638
|
-
/* @__PURE__ */ jsxs("header", {
|
|
639
|
-
className: cn("flex shrink-0 items-start gap-3 border-b px-4 pt-safe pb-4 md:px-6 md:pt-6", hideHeader && "sr-only"),
|
|
640
|
-
children: [
|
|
641
|
-
icon && /* @__PURE__ */ jsx("span", {
|
|
642
|
-
"aria-hidden": true,
|
|
643
|
-
className: "flex size-control-md shrink-0 items-center justify-center rounded-control bg-primary-soft text-primary-soft-foreground [&_svg]:size-icon-md",
|
|
644
|
-
children: icon
|
|
645
|
-
}),
|
|
646
|
-
/* @__PURE__ */ jsxs("div", {
|
|
647
|
-
className: "flex min-w-0 flex-1 flex-col gap-1 pt-1",
|
|
648
|
-
children: [/* @__PURE__ */ jsx(Dialog.Title, {
|
|
649
|
-
className: "text-lg font-semibold wrap-break-word",
|
|
650
|
-
children: title
|
|
651
|
-
}), description ? /* @__PURE__ */ jsx(Dialog.Description, {
|
|
652
|
-
className: "text-sm wrap-break-word text-muted-foreground",
|
|
653
|
-
children: description
|
|
654
|
-
}) : /* @__PURE__ */ jsx(Dialog.Description, {
|
|
655
|
-
className: "sr-only",
|
|
656
|
-
children: title
|
|
657
|
-
})]
|
|
658
|
-
}),
|
|
659
|
-
!hideHeader && closeButton
|
|
660
|
-
]
|
|
661
|
-
}),
|
|
662
|
-
/* @__PURE__ */ jsx("div", {
|
|
663
|
-
className: cn("min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-6 md:px-6", bodyClassName),
|
|
664
|
-
children
|
|
665
|
-
}),
|
|
666
|
-
footer && /* @__PURE__ */ jsx("footer", {
|
|
667
|
-
className: "shrink-0 border-t bg-card px-4 pt-4 pb-safe md:px-6 md:pb-6",
|
|
668
|
-
children: footer
|
|
669
|
-
})
|
|
670
|
-
] });
|
|
671
|
-
}
|
|
672
|
-
//#endregion
|
|
673
|
-
//#region src/components/ui/modal.tsx
|
|
674
|
-
var sizes$1 = {
|
|
675
|
-
sm: "md:max-w-sm",
|
|
676
|
-
md: "md:max-w-lg",
|
|
677
|
-
lg: "md:max-w-2xl"
|
|
678
|
-
};
|
|
679
|
-
var overlayCls$1 = "fixed inset-0 z-50 bg-overlay";
|
|
680
|
-
var overlayOffCls = cn(overlayCls$1, "data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0");
|
|
681
|
-
var contentCls = cn("fixed inset-0 z-50 flex h-dvh flex-col bg-card text-card-foreground outline-none", "md:inset-auto md:top-1/2 md:left-1/2 md:h-auto md:max-h-sheet md:w-full md:-translate-x-1/2 md:-translate-y-1/2 md:rounded-surface md:border md:shadow-lg");
|
|
682
|
-
var feedback = {
|
|
683
|
-
confirm: "info",
|
|
684
|
-
destructive: "error",
|
|
685
|
-
info: "info"
|
|
686
|
-
};
|
|
687
|
-
function Modal({ open, onOpenChange, title, description, type = "confirm", size = "sm", children, confirmLabel = type === "destructive" ? "Excluir" : type === "info" ? "Entendi" : "Confirmar", cancelLabel, onConfirm, formId, loading }) {
|
|
688
|
-
const [busy, setBusy] = useState(false);
|
|
689
|
-
const close = () => onOpenChange(false);
|
|
690
|
-
const confirm = async () => {
|
|
691
|
-
if (!onConfirm) return close();
|
|
692
|
-
try {
|
|
693
|
-
setBusy(true);
|
|
694
|
-
await onConfirm();
|
|
695
|
-
close();
|
|
696
|
-
} finally {
|
|
697
|
-
setBusy(false);
|
|
698
|
-
}
|
|
699
|
-
};
|
|
700
|
-
const isForm = type === "form";
|
|
701
|
-
const motion = useMotionMode();
|
|
702
|
-
const presets = useMotionPresets();
|
|
703
|
-
const { isMobile } = useBreakpoint();
|
|
704
|
-
const code = resolveCatalogCode("Modal", { type: type === "destructive" ? "confirm" : type });
|
|
705
|
-
const sizeCls = sizes$1[size];
|
|
706
|
-
const shell = /* @__PURE__ */ jsxs(OverlayShell, {
|
|
707
|
-
title,
|
|
708
|
-
description: isForm ? description : void 0,
|
|
709
|
-
hideHeader: !isForm,
|
|
710
|
-
onRequestClose: close,
|
|
711
|
-
bodyClassName: cn(!isForm && "flex flex-col items-center justify-center gap-4 text-center"),
|
|
712
|
-
footer: /* @__PURE__ */ jsx(ActionBar, {
|
|
713
|
-
primary: {
|
|
714
|
-
label: confirmLabel,
|
|
715
|
-
destructive: type === "destructive",
|
|
716
|
-
loading: busy || loading,
|
|
717
|
-
loadingLabel: `${confirmLabel}...`,
|
|
718
|
-
type: isForm && formId ? "submit" : "button",
|
|
719
|
-
form: isForm ? formId : void 0,
|
|
720
|
-
onClick: isForm && formId ? void 0 : confirm
|
|
721
|
-
},
|
|
722
|
-
cancel: type === "info" && cancelLabel === void 0 ? void 0 : {
|
|
723
|
-
label: cancelLabel ?? "Cancelar",
|
|
724
|
-
onClick: close
|
|
725
|
-
}
|
|
726
|
-
}),
|
|
727
|
-
children: [!isForm && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
728
|
-
/* @__PURE__ */ jsx(BrandFeedbackIcon, {
|
|
729
|
-
type: feedback[type],
|
|
730
|
-
size: "2xl",
|
|
731
|
-
animated: true
|
|
732
|
-
}),
|
|
733
|
-
/* @__PURE__ */ jsxs("div", {
|
|
734
|
-
className: "flex flex-col gap-2",
|
|
735
|
-
children: [/* @__PURE__ */ jsx("p", {
|
|
736
|
-
className: "text-lg font-semibold wrap-anywhere",
|
|
737
|
-
children: title
|
|
738
|
-
}), description && /* @__PURE__ */ jsx("p", {
|
|
739
|
-
className: "text-sm wrap-anywhere text-muted-foreground",
|
|
740
|
-
children: description
|
|
741
|
-
})]
|
|
742
|
-
}),
|
|
743
|
-
children
|
|
744
|
-
] }), isForm && /* @__PURE__ */ jsx("div", {
|
|
745
|
-
className: "flex flex-col gap-2",
|
|
746
|
-
children
|
|
747
|
-
})]
|
|
748
|
-
});
|
|
749
|
-
if (motion === "on") return /* @__PURE__ */ jsx(Dialog.Root, {
|
|
750
|
-
open,
|
|
751
|
-
onOpenChange,
|
|
752
|
-
children: /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsxs(Dialog.Portal, {
|
|
753
|
-
forceMount: true,
|
|
754
|
-
children: [/* @__PURE__ */ jsx(Dialog.Overlay, {
|
|
755
|
-
forceMount: true,
|
|
756
|
-
asChild: true,
|
|
757
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
758
|
-
className: overlayCls$1,
|
|
759
|
-
...presets.fade
|
|
760
|
-
})
|
|
761
|
-
}), /* @__PURE__ */ jsx(Dialog.Content, {
|
|
762
|
-
forceMount: true,
|
|
763
|
-
asChild: true,
|
|
764
|
-
"data-rendra": code,
|
|
765
|
-
className: cn(contentCls, sizeCls),
|
|
766
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
767
|
-
...presets.open(isMobile ? { y: 8 } : void 0),
|
|
768
|
-
children: shell
|
|
769
|
-
})
|
|
770
|
-
})]
|
|
771
|
-
}, "modal") })
|
|
772
|
-
});
|
|
773
|
-
return /* @__PURE__ */ jsx(Dialog.Root, {
|
|
774
|
-
open,
|
|
775
|
-
onOpenChange,
|
|
776
|
-
children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: overlayOffCls }), /* @__PURE__ */ jsx(Dialog.Content, {
|
|
777
|
-
"data-rendra": code,
|
|
778
|
-
className: cn(contentCls, "data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 md:data-[state=open]:zoom-in-95", sizeCls),
|
|
779
|
-
children: shell
|
|
780
|
-
})] })
|
|
781
|
-
});
|
|
782
|
-
}
|
|
783
|
-
//#endregion
|
|
784
|
-
//#region src/components/ui/info-hint.tsx
|
|
785
|
-
function InfoHint({ title, children, className }) {
|
|
786
|
-
const [open, setOpen] = useState(false);
|
|
787
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
788
|
-
className: "contents",
|
|
789
|
-
"data-rendra": "INFO-001",
|
|
790
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
791
|
-
variant: "ghost",
|
|
792
|
-
size: "sm",
|
|
793
|
-
iconOnly: true,
|
|
794
|
-
"aria-label": `Sobre: ${title}`,
|
|
795
|
-
onClick: () => setOpen(true),
|
|
796
|
-
className: cn("shrink-0 text-muted-foreground hover:text-primary-text max-md:size-touch", className),
|
|
797
|
-
children: /* @__PURE__ */ jsx(Info, { "aria-hidden": true })
|
|
798
|
-
}), /* @__PURE__ */ jsx(Modal, {
|
|
799
|
-
open,
|
|
800
|
-
onOpenChange: setOpen,
|
|
801
|
-
type: "info",
|
|
802
|
-
title,
|
|
803
|
-
size: "md",
|
|
804
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
805
|
-
className: "flex flex-col gap-3 text-sm text-muted-foreground",
|
|
806
|
-
children
|
|
807
|
-
})
|
|
808
|
-
})]
|
|
809
|
-
});
|
|
810
|
-
}
|
|
811
|
-
//#endregion
|
|
812
|
-
//#region src/components/ui/card.tsx
|
|
813
|
-
function Card({ className, "data-rendra": dataRendra, ...props }) {
|
|
814
|
-
return /* @__PURE__ */ jsx("div", {
|
|
815
|
-
"data-slot": "card",
|
|
816
|
-
"data-rendra": dataRendra ?? "CARD-001",
|
|
817
|
-
className: cn("flex min-w-0 flex-col rounded-surface border bg-card text-card-foreground", className),
|
|
818
|
-
...props
|
|
819
|
-
});
|
|
820
|
-
}
|
|
821
|
-
function CardHeader({ className, actions, children, ...props }) {
|
|
822
|
-
if (!actions) return /* @__PURE__ */ jsx("div", {
|
|
823
|
-
"data-slot": "card-header",
|
|
824
|
-
className: cn("flex flex-col gap-1 p-4 md:p-6", className),
|
|
825
|
-
...props,
|
|
826
|
-
children
|
|
827
|
-
});
|
|
828
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
829
|
-
"data-slot": "card-header",
|
|
830
|
-
className: cn("flex flex-wrap items-start justify-between gap-x-4 gap-y-3 p-4 md:p-6", className),
|
|
831
|
-
...props,
|
|
832
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
833
|
-
className: "flex min-w-0 flex-1 flex-col gap-1",
|
|
834
|
-
children
|
|
835
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
836
|
-
className: "flex shrink-0 items-center gap-2",
|
|
837
|
-
children: actions
|
|
838
|
-
})]
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
function CardTitle({ className, children, help, ...props }) {
|
|
842
|
-
const heading = /* @__PURE__ */ jsx("h3", {
|
|
843
|
-
"data-slot": "card-title",
|
|
844
|
-
className: cn("text-lg font-semibold", className),
|
|
845
|
-
...props,
|
|
846
|
-
children
|
|
847
|
-
});
|
|
848
|
-
if (!help) return heading;
|
|
849
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
850
|
-
className: "flex min-w-0 items-center gap-1",
|
|
851
|
-
children: [heading, /* @__PURE__ */ jsx(InfoHint, {
|
|
852
|
-
title: typeof children === "string" ? children : "Sobre esta seção",
|
|
853
|
-
children: help
|
|
854
|
-
})]
|
|
855
|
-
});
|
|
856
|
-
}
|
|
857
|
-
function CardDescription({ className, ...props }) {
|
|
858
|
-
return /* @__PURE__ */ jsx("p", {
|
|
859
|
-
"data-slot": "card-description",
|
|
860
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
861
|
-
...props
|
|
862
|
-
});
|
|
863
|
-
}
|
|
864
|
-
function CardContent({ className, ...props }) {
|
|
865
|
-
return /* @__PURE__ */ jsx("div", {
|
|
866
|
-
"data-slot": "card-content",
|
|
867
|
-
className: cn("p-4 md:p-6 [[data-slot=card-header]+&]:pt-0", className),
|
|
868
|
-
...props
|
|
869
|
-
});
|
|
870
|
-
}
|
|
871
|
-
function CardFooter({ className, ...props }) {
|
|
872
|
-
return /* @__PURE__ */ jsx("div", {
|
|
873
|
-
"data-slot": "card-footer",
|
|
874
|
-
className: cn("flex items-center gap-3 border-t px-4 py-3 md:px-6", className),
|
|
875
|
-
...props
|
|
876
|
-
});
|
|
877
|
-
}
|
|
878
|
-
//#endregion
|
|
879
498
|
//#region src/components/ui/calendar.tsx
|
|
880
499
|
var viewLabels = {
|
|
881
500
|
month: "Mês",
|
|
@@ -1314,575 +933,6 @@ function Calendar({ events, view: viewProp, defaultView = "month", onViewChange,
|
|
|
1314
933
|
});
|
|
1315
934
|
}
|
|
1316
935
|
//#endregion
|
|
1317
|
-
//#region src/lib/lookup.ts
|
|
1318
|
-
var digits$1 = (v) => v.replace(/\D/g, "");
|
|
1319
|
-
/** Endereço do CEP (8 dígitos). null se não existir; lança erro se a busca falhar. */
|
|
1320
|
-
async function lookupCep(cep, signal) {
|
|
1321
|
-
const d = digits$1(cep);
|
|
1322
|
-
if (d.length !== 8) return null;
|
|
1323
|
-
const res = await fetch(`https://viacep.com.br/ws/${d}/json/`, { signal });
|
|
1324
|
-
if (!res.ok) throw new Error("Não foi possível buscar o CEP agora.");
|
|
1325
|
-
const data = await res.json();
|
|
1326
|
-
if (data.erro) return null;
|
|
1327
|
-
return {
|
|
1328
|
-
cep: String(data.cep ?? ""),
|
|
1329
|
-
logradouro: String(data.logradouro ?? ""),
|
|
1330
|
-
complemento: String(data.complemento ?? ""),
|
|
1331
|
-
bairro: String(data.bairro ?? ""),
|
|
1332
|
-
cidade: String(data.localidade ?? ""),
|
|
1333
|
-
uf: String(data.uf ?? "")
|
|
1334
|
-
};
|
|
1335
|
-
}
|
|
1336
|
-
/** Dados públicos do CNPJ (14 dígitos). null se não existir; lança erro se a busca falhar. */
|
|
1337
|
-
async function lookupCnpj(cnpj, signal) {
|
|
1338
|
-
const d = digits$1(cnpj);
|
|
1339
|
-
if (d.length !== 14) return null;
|
|
1340
|
-
const res = await fetch(`https://brasilapi.com.br/api/cnpj/v1/${d}`, { signal });
|
|
1341
|
-
if (res.status === 404) return null;
|
|
1342
|
-
if (!res.ok) throw new Error("Não foi possível buscar o CNPJ agora.");
|
|
1343
|
-
const data = await res.json();
|
|
1344
|
-
const s = (k) => data[k] == null ? "" : String(data[k]);
|
|
1345
|
-
const fone = digits$1(s("ddd_telefone_1"));
|
|
1346
|
-
return {
|
|
1347
|
-
razaoSocial: s("razao_social"),
|
|
1348
|
-
nomeFantasia: s("nome_fantasia"),
|
|
1349
|
-
email: s("email").toLowerCase(),
|
|
1350
|
-
telefone: fone.length >= 10 ? `(${fone.slice(0, 2)}) ${fone.slice(2, -4)}-${fone.slice(-4)}` : "",
|
|
1351
|
-
situacao: s("descricao_situacao_cadastral"),
|
|
1352
|
-
endereco: {
|
|
1353
|
-
cep: s("cep"),
|
|
1354
|
-
logradouro: [s("descricao_tipo_de_logradouro"), s("logradouro")].filter(Boolean).join(" "),
|
|
1355
|
-
numero: s("numero"),
|
|
1356
|
-
complemento: s("complemento"),
|
|
1357
|
-
bairro: s("bairro"),
|
|
1358
|
-
cidade: s("municipio"),
|
|
1359
|
-
uf: s("uf")
|
|
1360
|
-
}
|
|
1361
|
-
};
|
|
1362
|
-
}
|
|
1363
|
-
//#endregion
|
|
1364
|
-
//#region src/hooks/use-lookup.ts
|
|
1365
|
-
/**
|
|
1366
|
-
* Busca CEP (8 dígitos) ou CNPJ (14 dígitos) assim que o valor fica completo. Cancela a
|
|
1367
|
-
* busca anterior quando o valor muda. `kind` 'auto' decide pelo tamanho (CPF ou CNPJ: só
|
|
1368
|
-
* o CNPJ busca). Sem `onResult`, não faz nada.
|
|
1369
|
-
*/
|
|
1370
|
-
function useLookup(kind, value, onResult) {
|
|
1371
|
-
const [loading, setLoading] = useState(false);
|
|
1372
|
-
const cb = useRef(onResult);
|
|
1373
|
-
cb.current = onResult;
|
|
1374
|
-
const digits = value.replace(/\D/g, "");
|
|
1375
|
-
const target = kind === "cep" && digits.length === 8 ? "cep" : (kind === "cnpj" || kind === "auto") && digits.length === 14 ? "cnpj" : null;
|
|
1376
|
-
const enabled = Boolean(onResult) && target !== null;
|
|
1377
|
-
useEffect(() => {
|
|
1378
|
-
if (!enabled || !target) return;
|
|
1379
|
-
const ctrl = new AbortController();
|
|
1380
|
-
const send = (r) => {
|
|
1381
|
-
if (!ctrl.signal.aborted) cb.current?.(r);
|
|
1382
|
-
};
|
|
1383
|
-
setLoading(true);
|
|
1384
|
-
send({
|
|
1385
|
-
status: "loading",
|
|
1386
|
-
kind: target
|
|
1387
|
-
});
|
|
1388
|
-
(target === "cep" ? lookupCep(digits, ctrl.signal).then((data) => data ? send({
|
|
1389
|
-
status: "found",
|
|
1390
|
-
kind: "cep",
|
|
1391
|
-
data,
|
|
1392
|
-
message: "Endereço preenchido pelo CEP."
|
|
1393
|
-
}) : send({
|
|
1394
|
-
status: "not-found",
|
|
1395
|
-
kind: "cep",
|
|
1396
|
-
message: "CEP não encontrado. Preencha o endereço."
|
|
1397
|
-
})) : lookupCnpj(digits, ctrl.signal).then((data) => data ? send({
|
|
1398
|
-
status: "found",
|
|
1399
|
-
kind: "cnpj",
|
|
1400
|
-
data,
|
|
1401
|
-
message: `${data.situacao ? `Situação: ${data.situacao}. ` : ""}Dados preenchidos pelo CNPJ.`
|
|
1402
|
-
}) : send({
|
|
1403
|
-
status: "not-found",
|
|
1404
|
-
kind: "cnpj",
|
|
1405
|
-
message: "CNPJ não encontrado. Preencha os dados abaixo."
|
|
1406
|
-
}))).catch((e) => send({
|
|
1407
|
-
status: "error",
|
|
1408
|
-
kind: target,
|
|
1409
|
-
message: e instanceof Error ? e.message : "Não foi possível buscar agora."
|
|
1410
|
-
})).finally(() => {
|
|
1411
|
-
if (!ctrl.signal.aborted) setLoading(false);
|
|
1412
|
-
});
|
|
1413
|
-
return () => {
|
|
1414
|
-
ctrl.abort();
|
|
1415
|
-
setLoading(false);
|
|
1416
|
-
};
|
|
1417
|
-
}, [
|
|
1418
|
-
enabled,
|
|
1419
|
-
target,
|
|
1420
|
-
digits
|
|
1421
|
-
]);
|
|
1422
|
-
return loading;
|
|
1423
|
-
}
|
|
1424
|
-
//#endregion
|
|
1425
|
-
//#region src/lib/control.ts
|
|
1426
|
-
/**
|
|
1427
|
-
* Moldura única dos campos (Input, Select, DatePicker, Textarea). Mesma altura dos botões
|
|
1428
|
-
* em cada tamanho; fonte de 16px no mobile para o iOS não dar zoom ao focar.
|
|
1429
|
-
*/
|
|
1430
|
-
/** Marque o elemento com data-slot="control": o teste de toque mede a moldura, não o input. */
|
|
1431
|
-
var controlFrame = cva("group/control flex w-full min-w-0 items-center gap-2 rounded-control border border-input bg-field text-base text-foreground transition-[border-color,box-shadow] duration-150 focus-within:border-ring focus-within:bg-card focus-within:ring-2 focus-within:ring-ring/25 hover:border-foreground/40 has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-60 has-[:disabled]:hover:border-input md:text-sm", {
|
|
1432
|
-
variants: {
|
|
1433
|
-
size: {
|
|
1434
|
-
sm: "h-control-sm px-3",
|
|
1435
|
-
md: "h-control-md px-3",
|
|
1436
|
-
lg: "h-control-lg px-4"
|
|
1437
|
-
},
|
|
1438
|
-
invalid: {
|
|
1439
|
-
true: "border-destructive focus-within:border-destructive focus-within:ring-destructive/25 hover:border-destructive",
|
|
1440
|
-
false: ""
|
|
1441
|
-
}
|
|
1442
|
-
},
|
|
1443
|
-
defaultVariants: {
|
|
1444
|
-
size: "md",
|
|
1445
|
-
invalid: false
|
|
1446
|
-
}
|
|
1447
|
-
});
|
|
1448
|
-
/** Classe do <input> nativo dentro da moldura. */
|
|
1449
|
-
var controlInput = "h-full min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed";
|
|
1450
|
-
/** Botão pequeno dentro da moldura (limpar, mostrar senha). */
|
|
1451
|
-
var controlAdornmentButton = "-mr-2 flex size-control-sm shrink-0 cursor-pointer items-center justify-center rounded-item text-muted-foreground transition-colors outline-none hover:bg-accent hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring md:-mr-1 md:size-8 [&_svg]:size-icon-sm";
|
|
1452
|
-
/**
|
|
1453
|
-
* Reserva, dentro de um gatilho, o espaço do botão sobreposto (limpar do Select e do
|
|
1454
|
-
* DatePicker), para o texto não passar por baixo dele.
|
|
1455
|
-
*/
|
|
1456
|
-
var controlAdornmentSpace = "size-control-sm shrink-0 md:size-8";
|
|
1457
|
-
//#endregion
|
|
1458
|
-
//#region src/lib/masks.ts
|
|
1459
|
-
var numberBlock = (scale, max) => ({
|
|
1460
|
-
mask: Number,
|
|
1461
|
-
scale,
|
|
1462
|
-
thousandsSeparator: ".",
|
|
1463
|
-
radix: ",",
|
|
1464
|
-
mapToRadix: ["."],
|
|
1465
|
-
padFractionalZeros: true,
|
|
1466
|
-
normalizeZeros: true,
|
|
1467
|
-
min: 0,
|
|
1468
|
-
...max !== void 0 ? { max } : {}
|
|
1469
|
-
});
|
|
1470
|
-
var masks = {
|
|
1471
|
-
cpf: {
|
|
1472
|
-
options: { mask: "000.000.000-00" },
|
|
1473
|
-
inputMode: "numeric",
|
|
1474
|
-
placeholder: "000.000.000-00"
|
|
1475
|
-
},
|
|
1476
|
-
cnpj: {
|
|
1477
|
-
options: { mask: "00.000.000/0000-00" },
|
|
1478
|
-
inputMode: "numeric",
|
|
1479
|
-
placeholder: "00.000.000/0000-00"
|
|
1480
|
-
},
|
|
1481
|
-
cpfCnpj: {
|
|
1482
|
-
options: { mask: [{ mask: "000.000.000-00" }, { mask: "00.000.000/0000-00" }] },
|
|
1483
|
-
inputMode: "numeric",
|
|
1484
|
-
placeholder: "CPF ou CNPJ"
|
|
1485
|
-
},
|
|
1486
|
-
phone: {
|
|
1487
|
-
options: { mask: [{ mask: "(00) 0000-0000" }, { mask: "(00) 00000-0000" }] },
|
|
1488
|
-
inputMode: "tel",
|
|
1489
|
-
placeholder: "(00) 00000-0000"
|
|
1490
|
-
},
|
|
1491
|
-
cep: {
|
|
1492
|
-
options: { mask: "00000-000" },
|
|
1493
|
-
inputMode: "numeric",
|
|
1494
|
-
placeholder: "00000-000"
|
|
1495
|
-
},
|
|
1496
|
-
date: {
|
|
1497
|
-
options: { mask: "00/00/0000" },
|
|
1498
|
-
inputMode: "numeric",
|
|
1499
|
-
placeholder: "DD/MM/AAAA"
|
|
1500
|
-
},
|
|
1501
|
-
time: {
|
|
1502
|
-
options: { mask: "00:00" },
|
|
1503
|
-
inputMode: "numeric",
|
|
1504
|
-
placeholder: "00:00"
|
|
1505
|
-
},
|
|
1506
|
-
currency: {
|
|
1507
|
-
options: {
|
|
1508
|
-
mask: "R$ num",
|
|
1509
|
-
lazy: false,
|
|
1510
|
-
blocks: { num: numberBlock(2) }
|
|
1511
|
-
},
|
|
1512
|
-
inputMode: "decimal",
|
|
1513
|
-
placeholder: "R$ 0,00"
|
|
1514
|
-
},
|
|
1515
|
-
percent: {
|
|
1516
|
-
options: {
|
|
1517
|
-
mask: "num %",
|
|
1518
|
-
lazy: false,
|
|
1519
|
-
blocks: { num: numberBlock(2, 100) }
|
|
1520
|
-
},
|
|
1521
|
-
inputMode: "decimal",
|
|
1522
|
-
placeholder: "0,00 %"
|
|
1523
|
-
}
|
|
1524
|
-
};
|
|
1525
|
-
/** Máscara de percentual com teto configurável (padrão 100), para o Input com unidades (A9). */
|
|
1526
|
-
function percentMask(max = 100) {
|
|
1527
|
-
return {
|
|
1528
|
-
options: {
|
|
1529
|
-
mask: "num %",
|
|
1530
|
-
lazy: false,
|
|
1531
|
-
blocks: { num: numberBlock(2, max) }
|
|
1532
|
-
},
|
|
1533
|
-
inputMode: "decimal",
|
|
1534
|
-
placeholder: "0,00 %"
|
|
1535
|
-
};
|
|
1536
|
-
}
|
|
1537
|
-
/** DDI padrão do campo de telefone. */
|
|
1538
|
-
var DEFAULT_DDI = "55";
|
|
1539
|
-
/** Lista padrão do seletor de DDI (Brasil primeiro). Troque com a prop ddiOptions do Input. */
|
|
1540
|
-
var phoneCountries = [
|
|
1541
|
-
{
|
|
1542
|
-
ddi: "55",
|
|
1543
|
-
name: "Brasil"
|
|
1544
|
-
},
|
|
1545
|
-
{
|
|
1546
|
-
ddi: "54",
|
|
1547
|
-
name: "Argentina"
|
|
1548
|
-
},
|
|
1549
|
-
{
|
|
1550
|
-
ddi: "56",
|
|
1551
|
-
name: "Chile"
|
|
1552
|
-
},
|
|
1553
|
-
{
|
|
1554
|
-
ddi: "57",
|
|
1555
|
-
name: "Colômbia"
|
|
1556
|
-
},
|
|
1557
|
-
{
|
|
1558
|
-
ddi: "595",
|
|
1559
|
-
name: "Paraguai"
|
|
1560
|
-
},
|
|
1561
|
-
{
|
|
1562
|
-
ddi: "598",
|
|
1563
|
-
name: "Uruguai"
|
|
1564
|
-
},
|
|
1565
|
-
{
|
|
1566
|
-
ddi: "52",
|
|
1567
|
-
name: "México"
|
|
1568
|
-
},
|
|
1569
|
-
{
|
|
1570
|
-
ddi: "1",
|
|
1571
|
-
name: "Estados Unidos e Canadá"
|
|
1572
|
-
},
|
|
1573
|
-
{
|
|
1574
|
-
ddi: "351",
|
|
1575
|
-
name: "Portugal"
|
|
1576
|
-
},
|
|
1577
|
-
{
|
|
1578
|
-
ddi: "34",
|
|
1579
|
-
name: "Espanha"
|
|
1580
|
-
},
|
|
1581
|
-
{
|
|
1582
|
-
ddi: "33",
|
|
1583
|
-
name: "França"
|
|
1584
|
-
},
|
|
1585
|
-
{
|
|
1586
|
-
ddi: "39",
|
|
1587
|
-
name: "Itália"
|
|
1588
|
-
},
|
|
1589
|
-
{
|
|
1590
|
-
ddi: "49",
|
|
1591
|
-
name: "Alemanha"
|
|
1592
|
-
},
|
|
1593
|
-
{
|
|
1594
|
-
ddi: "44",
|
|
1595
|
-
name: "Reino Unido"
|
|
1596
|
-
}
|
|
1597
|
-
];
|
|
1598
|
-
/** Máscara do número fora do Brasil: só dígitos, em grupos, até 15 (limite do padrão E.164). */
|
|
1599
|
-
var internationalPhoneMask = {
|
|
1600
|
-
options: { mask: "000 000 000 000 000" },
|
|
1601
|
-
inputMode: "tel",
|
|
1602
|
-
placeholder: "Número com DDD"
|
|
1603
|
-
};
|
|
1604
|
-
/** Número completo no padrão internacional: toE164("55", "(11) 91234-5678") = "+5511912345678". */
|
|
1605
|
-
function toE164(ddi, national) {
|
|
1606
|
-
const digits = national.replace(/\D/g, "");
|
|
1607
|
-
return digits ? `+${ddi}${digits}` : "";
|
|
1608
|
-
}
|
|
1609
|
-
/** Converte "R$ 1.250,00" ou "12,5 %" em número. */
|
|
1610
|
-
function parseLocaleNumber(masked) {
|
|
1611
|
-
const clean = masked.replace(/[^\d,-]/g, "").replace(",", ".");
|
|
1612
|
-
if (!clean) return null;
|
|
1613
|
-
const n = Number(clean);
|
|
1614
|
-
return Number.isFinite(n) ? n : null;
|
|
1615
|
-
}
|
|
1616
|
-
/**
|
|
1617
|
-
* Moeda em centavos inteiros, sem erro de arredondamento de ponto flutuante:
|
|
1618
|
-
* "R$ 1.250,50" -> 125050. Vazio -> null. Use centavos para guardar e somar dinheiro.
|
|
1619
|
-
*/
|
|
1620
|
-
function toCents(masked) {
|
|
1621
|
-
const d = masked.replace(/\D/g, "");
|
|
1622
|
-
if (!d) return null;
|
|
1623
|
-
if (!/,\d{1,2}\s*$/.test(masked.replace(/\s*%$/, ""))) return Number(d) * 100;
|
|
1624
|
-
const [int = "", dec = ""] = masked.replace(/[^\d,]/g, "").split(",");
|
|
1625
|
-
return Number(int || "0") * 100 + Number(dec.padEnd(2, "0").slice(0, 2));
|
|
1626
|
-
}
|
|
1627
|
-
/** Centavos para o texto do campo de moeda: 125050 -> "R$ 1.250,50". */
|
|
1628
|
-
function formatCents(cents) {
|
|
1629
|
-
return formatCurrency(cents / 100);
|
|
1630
|
-
}
|
|
1631
|
-
/** Formata número como moeda brasileira: 1250 -> "R$ 1.250,00". */
|
|
1632
|
-
function formatCurrency(value) {
|
|
1633
|
-
return value.toLocaleString("pt-BR", {
|
|
1634
|
-
style: "currency",
|
|
1635
|
-
currency: "BRL"
|
|
1636
|
-
});
|
|
1637
|
-
}
|
|
1638
|
-
//#endregion
|
|
1639
|
-
//#region src/components/ui/input.tsx
|
|
1640
|
-
/**
|
|
1641
|
-
* Input único. Tipos, máscaras, ícone, limpar, senha, unidades e valor guardado são props:
|
|
1642
|
-
* nunca crie InputCPF, InputTelefone, InputSenha ou InputSegredo.
|
|
1643
|
-
*/
|
|
1644
|
-
var Input = forwardRef(function Input({ size, mask, icon, suffix, clearable, invalid, type = "text", value, defaultValue, onChange, onValueChange, disabled, className, inputClassName, inputMode, placeholder, ddi: ddiProp, onDdiChange, ddiOptions = phoneCountries, hideDdi, onCentsChange, onLookup, units, unit: unitProp, onUnitChange, percentMax, variant, hasValue, maskedHint, isEditing, onStartEdit, onCancelEdit, onRemove, removing, ...props }, ref) {
|
|
1645
|
-
const inputRef = useRef(null);
|
|
1646
|
-
useImperativeHandle(ref, () => inputRef.current);
|
|
1647
|
-
const maskRef = useRef(null);
|
|
1648
|
-
const [showPassword, setShowPassword] = useState(false);
|
|
1649
|
-
const [inner, setInner] = useState(String(value ?? defaultValue ?? ""));
|
|
1650
|
-
const current = value ?? inner;
|
|
1651
|
-
const [secretDraft, setSecretDraft] = useState("");
|
|
1652
|
-
const [lastIsEditing, setLastIsEditing] = useState(isEditing);
|
|
1653
|
-
if (isEditing !== lastIsEditing) {
|
|
1654
|
-
setLastIsEditing(isEditing);
|
|
1655
|
-
if (isEditing) setSecretDraft("");
|
|
1656
|
-
}
|
|
1657
|
-
const cb = useRef({
|
|
1658
|
-
onChange,
|
|
1659
|
-
onValueChange,
|
|
1660
|
-
onCentsChange
|
|
1661
|
-
});
|
|
1662
|
-
cb.current = {
|
|
1663
|
-
onChange,
|
|
1664
|
-
onValueChange,
|
|
1665
|
-
onCentsChange
|
|
1666
|
-
};
|
|
1667
|
-
const searching = useLookup(mask === "cep" ? "cep" : mask === "cnpj" ? "cnpj" : mask === "cpfCnpj" ? "auto" : void 0, current, onLookup);
|
|
1668
|
-
const isPhone = mask === "phone";
|
|
1669
|
-
const [innerDdi, setInnerDdi] = useState(ddiProp ?? "55");
|
|
1670
|
-
const ddi = ddiProp ?? innerDdi;
|
|
1671
|
-
const showDdi = isPhone && !hideDdi;
|
|
1672
|
-
const intl = isPhone && ddi !== "55";
|
|
1673
|
-
const hasUnits = Boolean(units && units.length > 0);
|
|
1674
|
-
const [innerUnit, setInnerUnit] = useState(unitProp ?? units?.[0]?.id ?? "");
|
|
1675
|
-
const unit = hasUnits ? unitProp ?? innerUnit : void 0;
|
|
1676
|
-
const unitMaskName = unit === "percent" ? "percent" : unit === "currency" ? "currency" : void 0;
|
|
1677
|
-
const def = intl ? internationalPhoneMask : hasUnits ? unitMaskName === "percent" ? percentMask(percentMax) : unitMaskName === "currency" ? masks.currency : void 0 : mask ? masks[mask] : void 0;
|
|
1678
|
-
const maskKey = !def ? void 0 : intl ? "phone-intl" : hasUnits ? `unit-${unitMaskName}-${percentMax ?? ""}` : mask;
|
|
1679
|
-
useEffect(() => {
|
|
1680
|
-
if (!maskKey || !def || !inputRef.current) return;
|
|
1681
|
-
const m = IMask(inputRef.current, def.options);
|
|
1682
|
-
maskRef.current = m;
|
|
1683
|
-
m.on("accept", () => {
|
|
1684
|
-
setInner(m.value);
|
|
1685
|
-
cb.current.onChange?.(m.value);
|
|
1686
|
-
cb.current.onValueChange?.(m.unmaskedValue, m.value);
|
|
1687
|
-
if (mask === "currency" || unitMaskName === "currency") cb.current.onCentsChange?.(toCents(m.value));
|
|
1688
|
-
});
|
|
1689
|
-
return () => {
|
|
1690
|
-
m.destroy();
|
|
1691
|
-
maskRef.current = null;
|
|
1692
|
-
};
|
|
1693
|
-
}, [maskKey]);
|
|
1694
|
-
useEffect(() => {
|
|
1695
|
-
const m = maskRef.current;
|
|
1696
|
-
if (m && value !== void 0 && value !== m.value) m.value = value;
|
|
1697
|
-
}, [value]);
|
|
1698
|
-
const isPassword = type === "password";
|
|
1699
|
-
const country = ddiOptions.find((c) => c.ddi === ddi);
|
|
1700
|
-
const isSecret = variant === "secret";
|
|
1701
|
-
const { id: fieldId, "aria-describedby": fieldDescribedBy, "aria-required": fieldRequired } = props;
|
|
1702
|
-
const resetValue = () => {
|
|
1703
|
-
if (maskRef.current) maskRef.current.value = "";
|
|
1704
|
-
setInner("");
|
|
1705
|
-
setSecretDraft("");
|
|
1706
|
-
onChange?.("");
|
|
1707
|
-
onValueChange?.("", "");
|
|
1708
|
-
onCentsChange?.(null);
|
|
1709
|
-
};
|
|
1710
|
-
const clear = () => {
|
|
1711
|
-
resetValue();
|
|
1712
|
-
inputRef.current?.focus();
|
|
1713
|
-
};
|
|
1714
|
-
const changeUnit = (id) => {
|
|
1715
|
-
setInnerUnit(id);
|
|
1716
|
-
onUnitChange?.(id);
|
|
1717
|
-
resetValue();
|
|
1718
|
-
};
|
|
1719
|
-
if (isSecret && !isEditing) return /* @__PURE__ */ jsxs("div", {
|
|
1720
|
-
"data-slot": "control",
|
|
1721
|
-
"data-rendra": "CAMP-001",
|
|
1722
|
-
className: cn(controlFrame({
|
|
1723
|
-
size,
|
|
1724
|
-
invalid
|
|
1725
|
-
}), className),
|
|
1726
|
-
children: [
|
|
1727
|
-
/* @__PURE__ */ jsx("span", {
|
|
1728
|
-
className: "min-w-0 flex-1 truncate font-mono text-sm text-muted-foreground",
|
|
1729
|
-
children: hasValue ? maskedHint ?? "••••••••" : "Nenhum valor salvo"
|
|
1730
|
-
}),
|
|
1731
|
-
/* @__PURE__ */ jsx(Button, {
|
|
1732
|
-
type: "button",
|
|
1733
|
-
variant: "ghost",
|
|
1734
|
-
size: "sm",
|
|
1735
|
-
onClick: onStartEdit,
|
|
1736
|
-
disabled,
|
|
1737
|
-
id: fieldId,
|
|
1738
|
-
"aria-describedby": fieldDescribedBy,
|
|
1739
|
-
"aria-required": fieldRequired,
|
|
1740
|
-
children: "Trocar"
|
|
1741
|
-
}),
|
|
1742
|
-
hasValue && onRemove && /* @__PURE__ */ jsx(Button, {
|
|
1743
|
-
type: "button",
|
|
1744
|
-
variant: "ghost",
|
|
1745
|
-
size: "sm",
|
|
1746
|
-
onClick: onRemove,
|
|
1747
|
-
disabled: disabled || removing,
|
|
1748
|
-
loading: removing,
|
|
1749
|
-
children: "Remover"
|
|
1750
|
-
})
|
|
1751
|
-
]
|
|
1752
|
-
});
|
|
1753
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
1754
|
-
"data-slot": "control",
|
|
1755
|
-
"data-rendra": "CAMP-001",
|
|
1756
|
-
className: cn(controlFrame({
|
|
1757
|
-
size,
|
|
1758
|
-
invalid
|
|
1759
|
-
}), className),
|
|
1760
|
-
children: [
|
|
1761
|
-
showDdi && /* @__PURE__ */ jsxs("span", {
|
|
1762
|
-
className: "relative -ml-1 flex h-full min-w-touch shrink-0 items-center gap-1 border-r pr-2 text-sm font-medium",
|
|
1763
|
-
children: [
|
|
1764
|
-
/* @__PURE__ */ jsxs("span", {
|
|
1765
|
-
"aria-hidden": true,
|
|
1766
|
-
children: ["+", ddi]
|
|
1767
|
-
}),
|
|
1768
|
-
/* @__PURE__ */ jsx(ChevronDown, {
|
|
1769
|
-
className: "size-icon-sm text-muted-foreground",
|
|
1770
|
-
"aria-hidden": true
|
|
1771
|
-
}),
|
|
1772
|
-
/* @__PURE__ */ jsx("select", {
|
|
1773
|
-
"aria-label": `Código do país (DDI): ${country?.name ?? ""} +${ddi}`,
|
|
1774
|
-
value: ddi,
|
|
1775
|
-
disabled,
|
|
1776
|
-
onChange: (e) => {
|
|
1777
|
-
setInnerDdi(e.target.value);
|
|
1778
|
-
onDdiChange?.(e.target.value);
|
|
1779
|
-
},
|
|
1780
|
-
className: "absolute inset-0 cursor-pointer bg-popover text-popover-foreground opacity-0 disabled:cursor-not-allowed",
|
|
1781
|
-
children: ddiOptions.map((c) => /* @__PURE__ */ jsxs("option", {
|
|
1782
|
-
value: c.ddi,
|
|
1783
|
-
className: "bg-popover text-popover-foreground",
|
|
1784
|
-
children: [
|
|
1785
|
-
c.name,
|
|
1786
|
-
" (+",
|
|
1787
|
-
c.ddi,
|
|
1788
|
-
")"
|
|
1789
|
-
]
|
|
1790
|
-
}, c.ddi))
|
|
1791
|
-
})
|
|
1792
|
-
]
|
|
1793
|
-
}),
|
|
1794
|
-
icon && /* @__PURE__ */ jsx("span", {
|
|
1795
|
-
className: "flex shrink-0 text-muted-foreground [&_svg]:size-icon-sm",
|
|
1796
|
-
"aria-hidden": true,
|
|
1797
|
-
children: icon
|
|
1798
|
-
}),
|
|
1799
|
-
/* @__PURE__ */ jsx("input", {
|
|
1800
|
-
ref: inputRef,
|
|
1801
|
-
type: isSecret ? showPassword ? "text" : "password" : isPassword && showPassword ? "text" : type,
|
|
1802
|
-
inputMode: inputMode ?? def?.inputMode,
|
|
1803
|
-
placeholder: placeholder ?? def?.placeholder,
|
|
1804
|
-
disabled,
|
|
1805
|
-
"aria-invalid": invalid || void 0,
|
|
1806
|
-
"aria-busy": searching || void 0,
|
|
1807
|
-
className: cn(controlInput, inputClassName),
|
|
1808
|
-
...isSecret ? {
|
|
1809
|
-
value: secretDraft,
|
|
1810
|
-
onChange: (e) => {
|
|
1811
|
-
setSecretDraft(e.target.value);
|
|
1812
|
-
onChange?.(e.target.value);
|
|
1813
|
-
onValueChange?.(e.target.value, e.target.value);
|
|
1814
|
-
}
|
|
1815
|
-
} : maskKey ? { defaultValue: current } : {
|
|
1816
|
-
value: current,
|
|
1817
|
-
onChange: (e) => {
|
|
1818
|
-
setInner(e.target.value);
|
|
1819
|
-
onChange?.(e.target.value);
|
|
1820
|
-
onValueChange?.(e.target.value, e.target.value);
|
|
1821
|
-
}
|
|
1822
|
-
},
|
|
1823
|
-
...props
|
|
1824
|
-
}, hasUnits ? `unit-${unit}` : void 0),
|
|
1825
|
-
searching && /* @__PURE__ */ jsx(Spinner, {
|
|
1826
|
-
size: "sm",
|
|
1827
|
-
label: "Buscando…",
|
|
1828
|
-
className: "shrink-0 text-muted-foreground"
|
|
1829
|
-
}),
|
|
1830
|
-
hasUnits && /* @__PURE__ */ jsxs("span", {
|
|
1831
|
-
className: "relative -mr-1 flex h-full min-w-touch shrink-0 items-center gap-1 border-l pl-2 text-sm font-medium",
|
|
1832
|
-
children: [
|
|
1833
|
-
/* @__PURE__ */ jsx("span", {
|
|
1834
|
-
"aria-hidden": true,
|
|
1835
|
-
children: units?.find((u) => u.id === unit)?.label ?? unit
|
|
1836
|
-
}),
|
|
1837
|
-
/* @__PURE__ */ jsx(ChevronDown, {
|
|
1838
|
-
className: "size-icon-sm text-muted-foreground",
|
|
1839
|
-
"aria-hidden": true
|
|
1840
|
-
}),
|
|
1841
|
-
/* @__PURE__ */ jsx("select", {
|
|
1842
|
-
"aria-label": `Unidade: ${units?.find((u) => u.id === unit)?.label ?? unit}`,
|
|
1843
|
-
value: unit,
|
|
1844
|
-
disabled,
|
|
1845
|
-
onChange: (e) => changeUnit(e.target.value),
|
|
1846
|
-
className: "absolute inset-0 cursor-pointer bg-popover text-popover-foreground opacity-0 disabled:cursor-not-allowed",
|
|
1847
|
-
children: units?.map((u) => /* @__PURE__ */ jsx("option", {
|
|
1848
|
-
value: u.id,
|
|
1849
|
-
className: "bg-popover text-popover-foreground",
|
|
1850
|
-
children: u.label
|
|
1851
|
-
}, u.id))
|
|
1852
|
-
})
|
|
1853
|
-
]
|
|
1854
|
-
}),
|
|
1855
|
-
!hasUnits && suffix && /* @__PURE__ */ jsx("span", {
|
|
1856
|
-
className: "shrink-0 text-sm text-muted-foreground",
|
|
1857
|
-
children: suffix
|
|
1858
|
-
}),
|
|
1859
|
-
clearable && (isSecret ? secretDraft : current) && !disabled && /* @__PURE__ */ jsx("button", {
|
|
1860
|
-
type: "button",
|
|
1861
|
-
onClick: clear,
|
|
1862
|
-
"aria-label": "Limpar campo",
|
|
1863
|
-
className: "-mr-2 flex size-control-sm shrink-0 cursor-pointer items-center justify-center rounded-item text-muted-foreground transition-colors outline-none hover:bg-accent hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring md:-mr-1 md:size-8 [&_svg]:size-icon-sm",
|
|
1864
|
-
children: /* @__PURE__ */ jsx(X, { "aria-hidden": true })
|
|
1865
|
-
}),
|
|
1866
|
-
(isPassword || isSecret) && /* @__PURE__ */ jsx("button", {
|
|
1867
|
-
type: "button",
|
|
1868
|
-
onClick: () => setShowPassword((s) => !s),
|
|
1869
|
-
"aria-label": showPassword ? "Ocultar senha" : "Mostrar senha",
|
|
1870
|
-
"aria-pressed": showPassword,
|
|
1871
|
-
className: "-mr-2 flex size-control-sm shrink-0 cursor-pointer items-center justify-center rounded-item text-muted-foreground transition-colors outline-none hover:bg-accent hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring md:-mr-1 md:size-8 [&_svg]:size-icon-sm",
|
|
1872
|
-
children: showPassword ? /* @__PURE__ */ jsx(EyeOff, { "aria-hidden": true }) : /* @__PURE__ */ jsx(Eye, { "aria-hidden": true })
|
|
1873
|
-
}),
|
|
1874
|
-
isSecret && /* @__PURE__ */ jsx(Button, {
|
|
1875
|
-
type: "button",
|
|
1876
|
-
variant: "ghost",
|
|
1877
|
-
size: "sm",
|
|
1878
|
-
onClick: onCancelEdit,
|
|
1879
|
-
disabled,
|
|
1880
|
-
children: "Cancelar"
|
|
1881
|
-
})
|
|
1882
|
-
]
|
|
1883
|
-
});
|
|
1884
|
-
});
|
|
1885
|
-
//#endregion
|
|
1886
936
|
//#region src/components/ui/popover.tsx
|
|
1887
937
|
var PopoverOpenContext = createContext(null);
|
|
1888
938
|
function AnimatedRoot({ open, defaultOpen, onOpenChange, ...rest }) {
|
|
@@ -1908,10 +958,10 @@ var PopoverClose = Popover$1.Close;
|
|
|
1908
958
|
var PopoverAnchor = Popover$1.Anchor;
|
|
1909
959
|
function PopoverContent({ className, align = "center", sideOffset = 8, width = "md", children, asChild, ...props }) {
|
|
1910
960
|
const open = useContext(PopoverOpenContext);
|
|
1911
|
-
const
|
|
961
|
+
const lib = useMotionLib();
|
|
1912
962
|
const presets = useMotionPresets();
|
|
1913
963
|
const base = cn("z-50 origin-(--radix-popover-content-transform-origin) rounded-surface border bg-popover text-popover-foreground shadow-md outline-none", width === "sm" ? "w-popover-sm" : "w-popover");
|
|
1914
|
-
if (
|
|
964
|
+
if (lib && open !== null && !asChild) return /* @__PURE__ */ jsx(lib.AnimatePresence, { children: open && /* @__PURE__ */ jsx(Popover$1.Portal, {
|
|
1915
965
|
forceMount: true,
|
|
1916
966
|
children: /* @__PURE__ */ jsx(Popover$1.Content, {
|
|
1917
967
|
forceMount: true,
|
|
@@ -1922,7 +972,7 @@ function PopoverContent({ className, align = "center", sideOffset = 8, width = "
|
|
|
1922
972
|
"data-rendra": "POP-001",
|
|
1923
973
|
className: cn(base, className),
|
|
1924
974
|
...props,
|
|
1925
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
975
|
+
children: /* @__PURE__ */ jsx(lib.m.div, {
|
|
1926
976
|
...presets.open(),
|
|
1927
977
|
children
|
|
1928
978
|
})
|
|
@@ -3029,7 +2079,8 @@ function QuickReplyList({ items, onPick }) {
|
|
|
3029
2079
|
function Checkbox({ checked, defaultChecked, onCheckedChange, label, description, disabled, invalid, id, name, className, ...aria }) {
|
|
3030
2080
|
const auto = useId();
|
|
3031
2081
|
const cid = id ?? `cb${auto}`;
|
|
3032
|
-
const
|
|
2082
|
+
const lib = useMotionLib();
|
|
2083
|
+
const on = lib !== null;
|
|
3033
2084
|
const presets = useMotionPresets();
|
|
3034
2085
|
const [inner, setInner] = useState(defaultChecked ?? false);
|
|
3035
2086
|
const state = checked ?? inner;
|
|
@@ -3060,16 +2111,16 @@ function Checkbox({ checked, defaultChecked, onCheckedChange, label, description
|
|
|
3060
2111
|
const box = on ? /* @__PURE__ */ jsx(Checkbox$1.Root, {
|
|
3061
2112
|
asChild: true,
|
|
3062
2113
|
...rootProps,
|
|
3063
|
-
children: /* @__PURE__ */ jsx(m.button, {
|
|
2114
|
+
children: /* @__PURE__ */ jsx(lib.m.button, {
|
|
3064
2115
|
type: "button",
|
|
3065
2116
|
whileTap: presets.press.whileTap,
|
|
3066
2117
|
transition: presets.press.transition,
|
|
3067
|
-
children: /* @__PURE__ */ jsx(AnimatePresence, {
|
|
2118
|
+
children: /* @__PURE__ */ jsx(lib.AnimatePresence, {
|
|
3068
2119
|
initial: false,
|
|
3069
2120
|
children: state !== false && /* @__PURE__ */ jsx(Checkbox$1.Indicator, {
|
|
3070
2121
|
forceMount: true,
|
|
3071
2122
|
asChild: true,
|
|
3072
|
-
children: /* @__PURE__ */ jsx(m.span, {
|
|
2123
|
+
children: /* @__PURE__ */ jsx(lib.m.span, {
|
|
3073
2124
|
className: "flex items-center justify-center",
|
|
3074
2125
|
...presets.indicator,
|
|
3075
2126
|
children: mark
|
|
@@ -3429,270 +2480,57 @@ function createPalette(seeds) {
|
|
|
3429
2480
|
"--rendra-muted-foreground": reach(mix(fgD, mutedD, .35), mutedD, 4.5, "light"),
|
|
3430
2481
|
"--rendra-border": mix(cardD, WHITE$1, .12),
|
|
3431
2482
|
"--rendra-input": reach(mix(cardD, WHITE$1, .32), cardD, 3, "light"),
|
|
3432
|
-
"--rendra-field": mix(g2, BLACK$1, .1),
|
|
3433
|
-
"--rendra-overlay": alpha(mix(g2, BLACK$1, .6), .7),
|
|
3434
|
-
...brandDark,
|
|
3435
|
-
"--rendra-primary-soft": softD,
|
|
3436
|
-
"--rendra-primary-soft-foreground": reach(mix(P, WHITE$1, .45), softD, 4.5, "light"),
|
|
3437
|
-
"--rendra-primary-text": textD,
|
|
3438
|
-
"--rendra-ring": textD,
|
|
3439
|
-
"--rendra-accent": mix(cardD, WHITE$1, .06),
|
|
3440
|
-
"--rendra-accent-foreground": fgD,
|
|
3441
|
-
...sidebar,
|
|
3442
|
-
"--rendra-sidebar": mix(g2, BLACK$1, .1),
|
|
3443
|
-
"--rendra-gradient-soft": `linear-gradient(135deg, ${softD} 0%, ${cardD} 65%)`,
|
|
3444
|
-
"--rendra-chart-1": reach(P, cardD, 3, "light"),
|
|
3445
|
-
"--rendra-chart-2": reach(S, cardD, 3, "light"),
|
|
3446
|
-
"--rendra-chart-3": mix(P, WHITE$1, .45),
|
|
3447
|
-
"--rendra-chart-4": mix(P, WHITE$1, .72),
|
|
3448
|
-
"--rendra-chart-5": reach(mix(S, WHITE$1, .3), cardD, 3, "light"),
|
|
3449
|
-
"--rendra-shadow-color": "0 0 0"
|
|
3450
|
-
},
|
|
3451
|
-
sidebarLogo: sidebarDark ? "dark" : "light",
|
|
3452
|
-
adjustments: notes
|
|
3453
|
-
};
|
|
3454
|
-
}
|
|
3455
|
-
var block$1 = (selector, vars) => `${selector} {\n${Object.entries(vars).map(([k, v]) => ` ${k}: ${v};`).join("\n")}\n}\n`;
|
|
3456
|
-
/**
|
|
3457
|
-
* CSS da paleta. `isDefault` também aplica a paleta quando o <html> ainda não tem
|
|
3458
|
-
* data-palette (primeira pintura).
|
|
3459
|
-
*/
|
|
3460
|
-
function paletteCss(palette, isDefault = false) {
|
|
3461
|
-
const id = palette.seeds.id;
|
|
3462
|
-
const light = isDefault ? `:root:not([data-palette]),\n:root[data-palette='${id}']` : `:root[data-palette='${id}']`;
|
|
3463
|
-
const dark = isDefault ? `:root:not([data-palette]).dark,\n:root[data-palette='${id}'].dark` : `:root[data-palette='${id}'].dark`;
|
|
3464
|
-
const notes = palette.adjustments.length ? `/* Ajustes de contraste: ${palette.adjustments.join("; ")}. */\n` : "";
|
|
3465
|
-
return `/* ${palette.seeds.name} */\n${notes}${block$1(light, palette.light)}\n${block$1(dark, palette.dark)}`;
|
|
3466
|
-
}
|
|
3467
|
-
/**
|
|
3468
|
-
* White label em tempo de execução: gera a paleta de um cliente e a injeta na página
|
|
3469
|
-
* (um <style> por paleta), sem build. Depois é só usar data-palette com o id dela.
|
|
3470
|
-
* Devolve a paleta gerada, com os ajustes de contraste feitos.
|
|
3471
|
-
*/
|
|
3472
|
-
function applyPalette(seeds, doc = document) {
|
|
3473
|
-
const palette = createPalette(seeds);
|
|
3474
|
-
const attr = "data-palette-runtime";
|
|
3475
|
-
let style = doc.head.querySelector(`style[${attr}="${seeds.id}"]`);
|
|
3476
|
-
if (!style) {
|
|
3477
|
-
style = doc.createElement("style");
|
|
3478
|
-
style.setAttribute(attr, seeds.id);
|
|
3479
|
-
doc.head.appendChild(style);
|
|
3480
|
-
}
|
|
3481
|
-
style.textContent = paletteCss(palette);
|
|
3482
|
-
return palette;
|
|
3483
|
-
}
|
|
3484
|
-
//#endregion
|
|
3485
|
-
//#region src/components/ui/picker-panel.tsx
|
|
3486
|
-
/** A folha fecha se o arraste passou de 40% da altura ou se foi um arremesso (> 0,11 px/ms). */
|
|
3487
|
-
var DISMISS_FRACTION = .4;
|
|
3488
|
-
var DISMISS_VELOCITY = 110;
|
|
3489
|
-
/**
|
|
3490
|
-
* A folha do celular em `on`: entra de baixo, acompanha o dedo (arraste vertical pela alça, com
|
|
3491
|
-
* fricção ao puxar para cima), fecha por distância ou por arremesso e, se o dedo solta antes
|
|
3492
|
-
* disso, volta à origem com a mola da folha (a velocidade do dedo entra na mola, sem costura). O
|
|
3493
|
-
* fundo escurecido acompanha a distância. Só a alça arrasta: o corpo rola sem disputar o gesto.
|
|
3494
|
-
* Nenhum valor passa por `style`: o Motion guarda a posição do arraste, e o escurecimento do
|
|
3495
|
-
* fundo é gravado direto no elemento (sem render por quadro).
|
|
3496
|
-
*/
|
|
3497
|
-
function MobileSheet({ open, onOpenChange, trigger, adornment, head, rest }) {
|
|
3498
|
-
const presets = useMotionPresets();
|
|
3499
|
-
const ready = useLayoutReady();
|
|
3500
|
-
const controls = useDragControls();
|
|
3501
|
-
const sheetRef = useRef(null);
|
|
3502
|
-
const dimRef = useRef(null);
|
|
3503
|
-
const height = useRef(1);
|
|
3504
|
-
return /* @__PURE__ */ jsxs(Dialog.Root, {
|
|
3505
|
-
open,
|
|
3506
|
-
onOpenChange,
|
|
3507
|
-
children: [/* @__PURE__ */ jsx(Anchor, {
|
|
3508
|
-
adornment,
|
|
3509
|
-
children: /* @__PURE__ */ jsx(Dialog.Trigger, {
|
|
3510
|
-
asChild: true,
|
|
3511
|
-
children: trigger
|
|
3512
|
-
})
|
|
3513
|
-
}), /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsxs(Dialog.Portal, {
|
|
3514
|
-
forceMount: true,
|
|
3515
|
-
children: [/* @__PURE__ */ jsx(Dialog.Overlay, {
|
|
3516
|
-
forceMount: true,
|
|
3517
|
-
asChild: true,
|
|
3518
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
3519
|
-
className: "fixed inset-0 z-40",
|
|
3520
|
-
...presets.fade,
|
|
3521
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
3522
|
-
ref: dimRef,
|
|
3523
|
-
className: "absolute inset-0 bg-overlay"
|
|
3524
|
-
})
|
|
3525
|
-
})
|
|
3526
|
-
}), /* @__PURE__ */ jsx(Dialog.Content, {
|
|
3527
|
-
forceMount: true,
|
|
3528
|
-
asChild: true,
|
|
3529
|
-
"aria-describedby": void 0,
|
|
3530
|
-
className: "fixed inset-x-0 bottom-0 z-50 flex max-h-sheet flex-col rounded-t-surface border-t bg-popover text-popover-foreground shadow-lg outline-none",
|
|
3531
|
-
children: /* @__PURE__ */ jsxs(m.div, {
|
|
3532
|
-
ref: sheetRef,
|
|
3533
|
-
...presets.sheet("bottom"),
|
|
3534
|
-
drag: ready ? "y" : false,
|
|
3535
|
-
dragControls: controls,
|
|
3536
|
-
dragListener: false,
|
|
3537
|
-
dragConstraints: { top: 0 },
|
|
3538
|
-
dragElastic: {
|
|
3539
|
-
top: .2,
|
|
3540
|
-
bottom: 0
|
|
3541
|
-
},
|
|
3542
|
-
dragSnapToOrigin: true,
|
|
3543
|
-
dragTransition: presets.sheetBounce,
|
|
3544
|
-
onDragStart: () => {
|
|
3545
|
-
height.current = sheetRef.current?.offsetHeight || 1;
|
|
3546
|
-
},
|
|
3547
|
-
onDrag: (_, info) => {
|
|
3548
|
-
const dim = dimRef.current;
|
|
3549
|
-
if (dim) dim.style.opacity = String(1 - Math.min(1, Math.max(0, info.offset.y / height.current)));
|
|
3550
|
-
},
|
|
3551
|
-
onDragEnd: (_, info) => {
|
|
3552
|
-
if (info.offset.y > height.current * DISMISS_FRACTION || info.velocity.y > DISMISS_VELOCITY) {
|
|
3553
|
-
onOpenChange(false);
|
|
3554
|
-
return;
|
|
3555
|
-
}
|
|
3556
|
-
if (dimRef.current) animate(dimRef.current, { opacity: 1 }, presets.springSheet);
|
|
3557
|
-
},
|
|
3558
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
3559
|
-
"data-sheet-handle": true,
|
|
3560
|
-
onPointerDown: (e) => controls.start(e),
|
|
3561
|
-
className: "touch-none",
|
|
3562
|
-
children: head
|
|
3563
|
-
}), rest]
|
|
3564
|
-
})
|
|
3565
|
-
})]
|
|
3566
|
-
}, "sheet") })]
|
|
3567
|
-
});
|
|
3568
|
-
}
|
|
3569
|
-
function Anchor({ adornment, children }) {
|
|
3570
|
-
if (!adornment) return children;
|
|
3571
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
3572
|
-
className: "relative w-full min-w-0",
|
|
3573
|
-
children: [children, adornment]
|
|
3574
|
-
});
|
|
3575
|
-
}
|
|
3576
|
-
function PickerPanel({ open, onOpenChange, trigger, title, header, children, footer, width = "trigger", adornment, align = "start" }) {
|
|
3577
|
-
const { isMobile } = useBreakpoint();
|
|
3578
|
-
const motion = useMotionMode();
|
|
3579
|
-
const presets = useMotionPresets();
|
|
3580
|
-
const on = motion === "on";
|
|
3581
|
-
const sheetHead = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
3582
|
-
className: "flex shrink-0 flex-col items-center pt-2",
|
|
3583
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
3584
|
-
"aria-hidden": true,
|
|
3585
|
-
className: "h-1 w-12 rounded-full bg-border"
|
|
3586
|
-
})
|
|
3587
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
3588
|
-
className: "flex shrink-0 items-center justify-between gap-2 pr-2 pl-4",
|
|
3589
|
-
children: [/* @__PURE__ */ jsx(Dialog.Title, {
|
|
3590
|
-
className: "truncate text-base font-semibold",
|
|
3591
|
-
children: title
|
|
3592
|
-
}), /* @__PURE__ */ jsx(Dialog.Close, {
|
|
3593
|
-
"aria-label": "Fechar",
|
|
3594
|
-
className: "flex size-touch items-center justify-center rounded-item text-muted-foreground hover:bg-accent",
|
|
3595
|
-
children: /* @__PURE__ */ jsx(X, {
|
|
3596
|
-
className: "size-icon-md",
|
|
3597
|
-
"aria-hidden": true
|
|
3598
|
-
})
|
|
3599
|
-
})]
|
|
3600
|
-
})] });
|
|
3601
|
-
const sheetRest = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3602
|
-
header && /* @__PURE__ */ jsx("div", {
|
|
3603
|
-
className: "shrink-0 border-b px-4 pb-3",
|
|
3604
|
-
children: header
|
|
3605
|
-
}),
|
|
3606
|
-
/* @__PURE__ */ jsx("div", {
|
|
3607
|
-
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-2",
|
|
3608
|
-
children
|
|
3609
|
-
}),
|
|
3610
|
-
footer && /* @__PURE__ */ jsx("div", {
|
|
3611
|
-
className: "shrink-0 border-t px-4 pt-3 pb-safe",
|
|
3612
|
-
children: footer
|
|
3613
|
-
})
|
|
3614
|
-
] });
|
|
3615
|
-
const sheetBody = /* @__PURE__ */ jsxs(Fragment$1, { children: [sheetHead, sheetRest] });
|
|
3616
|
-
const panelCls = cn("z-50 flex max-h-command origin-(--radix-popover-content-transform-origin) flex-col overflow-hidden rounded-surface border bg-popover text-popover-foreground shadow-md outline-none", width === "trigger" ? "w-trigger max-w-popover" : "w-auto max-w-popover md:max-w-none");
|
|
3617
|
-
const panelBody = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3618
|
-
header && /* @__PURE__ */ jsx("div", {
|
|
3619
|
-
className: "shrink-0 border-b p-2",
|
|
3620
|
-
children: header
|
|
3621
|
-
}),
|
|
3622
|
-
/* @__PURE__ */ jsx("div", {
|
|
3623
|
-
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-1",
|
|
3624
|
-
children
|
|
3625
|
-
}),
|
|
3626
|
-
footer && /* @__PURE__ */ jsx("div", {
|
|
3627
|
-
className: "shrink-0 border-t p-2",
|
|
3628
|
-
children: footer
|
|
3629
|
-
})
|
|
3630
|
-
] });
|
|
3631
|
-
if (on && isMobile) return /* @__PURE__ */ jsx(MobileSheet, {
|
|
3632
|
-
open,
|
|
3633
|
-
onOpenChange,
|
|
3634
|
-
trigger,
|
|
3635
|
-
adornment,
|
|
3636
|
-
head: sheetHead,
|
|
3637
|
-
rest: sheetRest
|
|
3638
|
-
});
|
|
3639
|
-
if (on) return /* @__PURE__ */ jsxs(Popover$1.Root, {
|
|
3640
|
-
open,
|
|
3641
|
-
onOpenChange,
|
|
3642
|
-
children: [/* @__PURE__ */ jsx(Anchor, {
|
|
3643
|
-
adornment,
|
|
3644
|
-
children: /* @__PURE__ */ jsx(Popover$1.Trigger, {
|
|
3645
|
-
asChild: true,
|
|
3646
|
-
children: trigger
|
|
3647
|
-
})
|
|
3648
|
-
}), /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsx(Popover$1.Portal, {
|
|
3649
|
-
forceMount: true,
|
|
3650
|
-
children: /* @__PURE__ */ jsx(Popover$1.Content, {
|
|
3651
|
-
forceMount: true,
|
|
3652
|
-
asChild: true,
|
|
3653
|
-
align,
|
|
3654
|
-
sideOffset: 6,
|
|
3655
|
-
collisionPadding: 16,
|
|
3656
|
-
className: panelCls,
|
|
3657
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
3658
|
-
...presets.open(),
|
|
3659
|
-
children: panelBody
|
|
3660
|
-
})
|
|
3661
|
-
})
|
|
3662
|
-
}, "panel") })]
|
|
3663
|
-
});
|
|
3664
|
-
if (isMobile) return /* @__PURE__ */ jsxs(Dialog.Root, {
|
|
3665
|
-
open,
|
|
3666
|
-
onOpenChange,
|
|
3667
|
-
children: [/* @__PURE__ */ jsx(Anchor, {
|
|
3668
|
-
adornment,
|
|
3669
|
-
children: /* @__PURE__ */ jsx(Dialog.Trigger, {
|
|
3670
|
-
asChild: true,
|
|
3671
|
-
children: trigger
|
|
3672
|
-
})
|
|
3673
|
-
}), /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: "fixed inset-0 z-40 bg-overlay data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0" }), /* @__PURE__ */ jsx(Dialog.Content, {
|
|
3674
|
-
"aria-describedby": void 0,
|
|
3675
|
-
className: "fixed inset-x-0 bottom-0 z-50 flex max-h-sheet flex-col rounded-t-surface border-t bg-popover text-popover-foreground shadow-lg outline-none data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:slide-out-to-bottom data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom",
|
|
3676
|
-
children: sheetBody
|
|
3677
|
-
})] })]
|
|
3678
|
-
});
|
|
3679
|
-
return /* @__PURE__ */ jsxs(Popover$1.Root, {
|
|
3680
|
-
open,
|
|
3681
|
-
onOpenChange,
|
|
3682
|
-
children: [/* @__PURE__ */ jsx(Anchor, {
|
|
3683
|
-
adornment,
|
|
3684
|
-
children: /* @__PURE__ */ jsx(Popover$1.Trigger, {
|
|
3685
|
-
asChild: true,
|
|
3686
|
-
children: trigger
|
|
3687
|
-
})
|
|
3688
|
-
}), /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(Popover$1.Content, {
|
|
3689
|
-
align,
|
|
3690
|
-
sideOffset: 6,
|
|
3691
|
-
collisionPadding: 16,
|
|
3692
|
-
className: cn("z-50 flex max-h-command origin-(--radix-popover-content-transform-origin) flex-col overflow-hidden rounded-surface border bg-popover text-popover-foreground shadow-md outline-none", "data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", width === "trigger" ? "w-trigger max-w-popover" : "w-auto max-w-popover md:max-w-none"),
|
|
3693
|
-
children: panelBody
|
|
3694
|
-
}) })]
|
|
3695
|
-
});
|
|
2483
|
+
"--rendra-field": mix(g2, BLACK$1, .1),
|
|
2484
|
+
"--rendra-overlay": alpha(mix(g2, BLACK$1, .6), .7),
|
|
2485
|
+
...brandDark,
|
|
2486
|
+
"--rendra-primary-soft": softD,
|
|
2487
|
+
"--rendra-primary-soft-foreground": reach(mix(P, WHITE$1, .45), softD, 4.5, "light"),
|
|
2488
|
+
"--rendra-primary-text": textD,
|
|
2489
|
+
"--rendra-ring": textD,
|
|
2490
|
+
"--rendra-accent": mix(cardD, WHITE$1, .06),
|
|
2491
|
+
"--rendra-accent-foreground": fgD,
|
|
2492
|
+
...sidebar,
|
|
2493
|
+
"--rendra-sidebar": mix(g2, BLACK$1, .1),
|
|
2494
|
+
"--rendra-gradient-soft": `linear-gradient(135deg, ${softD} 0%, ${cardD} 65%)`,
|
|
2495
|
+
"--rendra-chart-1": reach(P, cardD, 3, "light"),
|
|
2496
|
+
"--rendra-chart-2": reach(S, cardD, 3, "light"),
|
|
2497
|
+
"--rendra-chart-3": mix(P, WHITE$1, .45),
|
|
2498
|
+
"--rendra-chart-4": mix(P, WHITE$1, .72),
|
|
2499
|
+
"--rendra-chart-5": reach(mix(S, WHITE$1, .3), cardD, 3, "light"),
|
|
2500
|
+
"--rendra-shadow-color": "0 0 0"
|
|
2501
|
+
},
|
|
2502
|
+
sidebarLogo: sidebarDark ? "dark" : "light",
|
|
2503
|
+
adjustments: notes
|
|
2504
|
+
};
|
|
2505
|
+
}
|
|
2506
|
+
var block$1 = (selector, vars) => `${selector} {\n${Object.entries(vars).map(([k, v]) => ` ${k}: ${v};`).join("\n")}\n}\n`;
|
|
2507
|
+
/**
|
|
2508
|
+
* CSS da paleta. `isDefault` também aplica a paleta quando o <html> ainda não tem
|
|
2509
|
+
* data-palette (primeira pintura).
|
|
2510
|
+
*/
|
|
2511
|
+
function paletteCss(palette, isDefault = false) {
|
|
2512
|
+
const id = palette.seeds.id;
|
|
2513
|
+
const light = isDefault ? `:root:not([data-palette]),\n:root[data-palette='${id}']` : `:root[data-palette='${id}']`;
|
|
2514
|
+
const dark = isDefault ? `:root:not([data-palette]).dark,\n:root[data-palette='${id}'].dark` : `:root[data-palette='${id}'].dark`;
|
|
2515
|
+
const notes = palette.adjustments.length ? `/* Ajustes de contraste: ${palette.adjustments.join("; ")}. */\n` : "";
|
|
2516
|
+
return `/* ${palette.seeds.name} */\n${notes}${block$1(light, palette.light)}\n${block$1(dark, palette.dark)}`;
|
|
2517
|
+
}
|
|
2518
|
+
/**
|
|
2519
|
+
* White label em tempo de execução: gera a paleta de um cliente e a injeta na página
|
|
2520
|
+
* (um <style> por paleta), sem build. Depois é só usar data-palette com o id dela.
|
|
2521
|
+
* Devolve a paleta gerada, com os ajustes de contraste feitos.
|
|
2522
|
+
*/
|
|
2523
|
+
function applyPalette(seeds, doc = document) {
|
|
2524
|
+
const palette = createPalette(seeds);
|
|
2525
|
+
const attr = "data-palette-runtime";
|
|
2526
|
+
let style = doc.head.querySelector(`style[${attr}="${seeds.id}"]`);
|
|
2527
|
+
if (!style) {
|
|
2528
|
+
style = doc.createElement("style");
|
|
2529
|
+
style.setAttribute(attr, seeds.id);
|
|
2530
|
+
doc.head.appendChild(style);
|
|
2531
|
+
}
|
|
2532
|
+
style.textContent = paletteCss(palette);
|
|
2533
|
+
return palette;
|
|
3696
2534
|
}
|
|
3697
2535
|
//#endregion
|
|
3698
2536
|
//#region src/components/ui/color-picker.tsx
|
|
@@ -3789,93 +2627,17 @@ var ColorPicker = forwardRef(function ColorPicker({ value, onChange, swatches =
|
|
|
3789
2627
|
});
|
|
3790
2628
|
});
|
|
3791
2629
|
//#endregion
|
|
3792
|
-
//#region src/components/ui/drawer.tsx
|
|
3793
|
-
var sizes = {
|
|
3794
|
-
"30": "md:w-sheet-30",
|
|
3795
|
-
"40": "md:w-sheet-40",
|
|
3796
|
-
"50": "md:w-sheet-50",
|
|
3797
|
-
"75": "md:w-sheet-75",
|
|
3798
|
-
full: "md:w-full",
|
|
3799
|
-
sm: "md:w-sheet-30",
|
|
3800
|
-
md: "md:w-sheet-30",
|
|
3801
|
-
lg: "md:w-sheet-50",
|
|
3802
|
-
xl: "md:w-sheet-75"
|
|
3803
|
-
};
|
|
3804
|
-
var overlayCls = "fixed inset-0 z-50 bg-overlay";
|
|
3805
|
-
var panelCls = "fixed inset-y-0 right-0 z-50 flex h-dvh w-full flex-col bg-card text-card-foreground shadow-lg outline-none md:border-l";
|
|
3806
|
-
function Drawer({ open, onOpenChange, title, description, icon, size = "30", children, footer, dirty, discardTitle = "Descartar alterações?", discardDescription = "As informações preenchidas neste painel serão perdidas." }) {
|
|
3807
|
-
const [confirming, setConfirming] = useState(false);
|
|
3808
|
-
const requestClose = () => dirty ? setConfirming(true) : onOpenChange(false);
|
|
3809
|
-
const motion = useMotionMode();
|
|
3810
|
-
const presets = useMotionPresets();
|
|
3811
|
-
const keepOpenIfDirty = (e) => {
|
|
3812
|
-
if (dirty) {
|
|
3813
|
-
e.preventDefault();
|
|
3814
|
-
setConfirming(true);
|
|
3815
|
-
}
|
|
3816
|
-
};
|
|
3817
|
-
const shell = /* @__PURE__ */ jsx(OverlayShell, {
|
|
3818
|
-
title,
|
|
3819
|
-
description,
|
|
3820
|
-
icon,
|
|
3821
|
-
footer,
|
|
3822
|
-
onRequestClose: requestClose,
|
|
3823
|
-
children
|
|
3824
|
-
});
|
|
3825
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Dialog.Root, {
|
|
3826
|
-
open,
|
|
3827
|
-
onOpenChange: (o) => o ? onOpenChange(true) : requestClose(),
|
|
3828
|
-
children: motion === "on" ? /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsxs(Dialog.Portal, {
|
|
3829
|
-
forceMount: true,
|
|
3830
|
-
children: [/* @__PURE__ */ jsx(Dialog.Overlay, {
|
|
3831
|
-
forceMount: true,
|
|
3832
|
-
asChild: true,
|
|
3833
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
3834
|
-
className: overlayCls,
|
|
3835
|
-
...presets.fade
|
|
3836
|
-
})
|
|
3837
|
-
}), /* @__PURE__ */ jsx(Dialog.Content, {
|
|
3838
|
-
forceMount: true,
|
|
3839
|
-
asChild: true,
|
|
3840
|
-
onEscapeKeyDown: keepOpenIfDirty,
|
|
3841
|
-
onPointerDownOutside: keepOpenIfDirty,
|
|
3842
|
-
"data-rendra": "GAV-001",
|
|
3843
|
-
className: cn(panelCls, sizes[size]),
|
|
3844
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
3845
|
-
...presets.sheet("right"),
|
|
3846
|
-
children: shell
|
|
3847
|
-
})
|
|
3848
|
-
})]
|
|
3849
|
-
}, "drawer") }) : /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: cn(overlayCls, "data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0") }), /* @__PURE__ */ jsx(Dialog.Content, {
|
|
3850
|
-
onEscapeKeyDown: keepOpenIfDirty,
|
|
3851
|
-
onPointerDownOutside: keepOpenIfDirty,
|
|
3852
|
-
"data-rendra": "GAV-001",
|
|
3853
|
-
className: cn(panelCls, "data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:slide-out-to-right data-[state=open]:animate-in data-[state=open]:slide-in-from-right", sizes[size]),
|
|
3854
|
-
children: shell
|
|
3855
|
-
})] })
|
|
3856
|
-
}), /* @__PURE__ */ jsx(Modal, {
|
|
3857
|
-
open: confirming,
|
|
3858
|
-
onOpenChange: setConfirming,
|
|
3859
|
-
type: "destructive",
|
|
3860
|
-
title: discardTitle,
|
|
3861
|
-
description: discardDescription,
|
|
3862
|
-
confirmLabel: "Descartar",
|
|
3863
|
-
cancelLabel: "Continuar editando",
|
|
3864
|
-
onConfirm: () => onOpenChange(false)
|
|
3865
|
-
})] });
|
|
3866
|
-
}
|
|
3867
|
-
//#endregion
|
|
3868
2630
|
//#region src/components/ui/switch.tsx
|
|
3869
2631
|
/** Switch único, com rótulo e descrição à esquerda e a chave à direita. */
|
|
3870
2632
|
function Switch({ checked, defaultChecked, onCheckedChange, label, description, disabled, id, name, className, ...aria }) {
|
|
3871
2633
|
const auto = useId();
|
|
3872
2634
|
const sid = id ?? `sw${auto}`;
|
|
3873
|
-
const
|
|
2635
|
+
const lib = useMotionLib();
|
|
3874
2636
|
const presets = useMotionPresets();
|
|
3875
2637
|
const rootCls = "relative inline-flex h-6 w-12 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-input transition-colors disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary max-md:before:absolute max-md:before:-inset-3";
|
|
3876
|
-
const thumbCls = cn("pointer-events-none block size-icon-md rounded-full bg-card shadow-sm duration-(--rendra-duration-base) ease-move data-[state=checked]:translate-x-6",
|
|
2638
|
+
const thumbCls = cn("pointer-events-none block size-icon-md rounded-full bg-card shadow-sm duration-(--rendra-duration-base) ease-move data-[state=checked]:translate-x-6", lib ? "transition-[translate]" : "transition-transform");
|
|
3877
2639
|
const tap = presets.tap;
|
|
3878
|
-
const control =
|
|
2640
|
+
const control = lib ? /* @__PURE__ */ jsx(Switch$1.Root, {
|
|
3879
2641
|
asChild: true,
|
|
3880
2642
|
id: sid,
|
|
3881
2643
|
name,
|
|
@@ -3886,7 +2648,7 @@ function Switch({ checked, defaultChecked, onCheckedChange, label, description,
|
|
|
3886
2648
|
"aria-label": aria["aria-label"],
|
|
3887
2649
|
"data-touch": "expanded",
|
|
3888
2650
|
"data-rendra": "SWT-001",
|
|
3889
|
-
children: /* @__PURE__ */ jsx(m.button, {
|
|
2651
|
+
children: /* @__PURE__ */ jsx(lib.m.button, {
|
|
3890
2652
|
type: "button",
|
|
3891
2653
|
className: rootCls,
|
|
3892
2654
|
initial: "rest",
|
|
@@ -3894,7 +2656,7 @@ function Switch({ checked, defaultChecked, onCheckedChange, label, description,
|
|
|
3894
2656
|
whileTap: tap ? "tap" : void 0,
|
|
3895
2657
|
children: /* @__PURE__ */ jsx(Switch$1.Thumb, {
|
|
3896
2658
|
asChild: true,
|
|
3897
|
-
children: /* @__PURE__ */ jsx(m.span, {
|
|
2659
|
+
children: /* @__PURE__ */ jsx(lib.m.span, {
|
|
3898
2660
|
className: thumbCls,
|
|
3899
2661
|
variants: {
|
|
3900
2662
|
rest: { scale: 1 },
|
|
@@ -4086,121 +2848,6 @@ function DataToolbar({ search, filters, filterCount = 0, onClearFilters, chips =
|
|
|
4086
2848
|
});
|
|
4087
2849
|
}
|
|
4088
2850
|
//#endregion
|
|
4089
|
-
//#region src/components/layout/tokens.ts
|
|
4090
|
-
var gapClass = {
|
|
4091
|
-
"0": "gap-0",
|
|
4092
|
-
"1": "gap-1",
|
|
4093
|
-
"2": "gap-2",
|
|
4094
|
-
"3": "gap-3",
|
|
4095
|
-
"4": "gap-4",
|
|
4096
|
-
"6": "gap-6",
|
|
4097
|
-
"8": "gap-8",
|
|
4098
|
-
"12": "gap-12",
|
|
4099
|
-
"16": "gap-16",
|
|
4100
|
-
"24": "gap-24",
|
|
4101
|
-
section: "gap-8 md:gap-12",
|
|
4102
|
-
fields: "gap-x-4 gap-y-4 md:gap-x-6"
|
|
4103
|
-
};
|
|
4104
|
-
/**
|
|
4105
|
-
* Grade de formulário, pela largura do próprio bloco (container query), não da tela:
|
|
4106
|
-
* 1 coluna estreito, 6 colunas a partir de 28rem, 12 colunas a partir de 48rem.
|
|
4107
|
-
* No largo, o padrão é 3 campos por linha (md = 4/12). Nunca 2 por linha por padrão.
|
|
4108
|
-
*/
|
|
4109
|
-
var fieldGridClass = "grid grid-cols-1 @md:grid-cols-6 @3xl:grid-cols-12";
|
|
4110
|
-
/** Largura do Field na grade de formulário (no largo, em 12 colunas). */
|
|
4111
|
-
var fieldSpanClass = {
|
|
4112
|
-
/** 2/12, cerca de 17%: UF, número, DDD. */
|
|
4113
|
-
xs: "@md:col-span-2 @3xl:col-span-2",
|
|
4114
|
-
/** 3/12 = 25%: CEP, CNPJ, CPF, datas curtas. */
|
|
4115
|
-
sm: "@md:col-span-2 @3xl:col-span-3",
|
|
4116
|
-
/** 4/12 = 33%: o padrão, 3 campos por linha. */
|
|
4117
|
-
md: "@md:col-span-3 @3xl:col-span-4",
|
|
4118
|
-
/** 6/12 = 50%. */
|
|
4119
|
-
lg: "@md:col-span-3 @3xl:col-span-6",
|
|
4120
|
-
/** 8/12 = 67%: nome, logradouro longo. */
|
|
4121
|
-
xl: "@md:col-span-6 @3xl:col-span-8",
|
|
4122
|
-
/** Linha inteira. */
|
|
4123
|
-
full: "@md:col-span-6 @3xl:col-span-12"
|
|
4124
|
-
};
|
|
4125
|
-
var alignClass = {
|
|
4126
|
-
start: "items-start",
|
|
4127
|
-
center: "items-center",
|
|
4128
|
-
end: "items-end",
|
|
4129
|
-
stretch: "items-stretch",
|
|
4130
|
-
baseline: "items-baseline"
|
|
4131
|
-
};
|
|
4132
|
-
var justifyClass = {
|
|
4133
|
-
start: "justify-start",
|
|
4134
|
-
center: "justify-center",
|
|
4135
|
-
end: "justify-end",
|
|
4136
|
-
between: "justify-between"
|
|
4137
|
-
};
|
|
4138
|
-
//#endregion
|
|
4139
|
-
//#region src/components/ui/field.tsx
|
|
4140
|
-
function Label({ className, required, children, ...props }) {
|
|
4141
|
-
return /* @__PURE__ */ jsxs(Label$1.Root, {
|
|
4142
|
-
"data-rendra": "FLD-002",
|
|
4143
|
-
className: cn("text-label text-label-foreground label-case", className),
|
|
4144
|
-
...props,
|
|
4145
|
-
children: [
|
|
4146
|
-
children,
|
|
4147
|
-
required && /* @__PURE__ */ jsxs("span", {
|
|
4148
|
-
className: "text-destructive",
|
|
4149
|
-
"aria-hidden": true,
|
|
4150
|
-
children: [" ", "*"]
|
|
4151
|
-
}),
|
|
4152
|
-
required && /* @__PURE__ */ jsx("span", {
|
|
4153
|
-
className: "sr-only",
|
|
4154
|
-
children: " (obrigatório)"
|
|
4155
|
-
})
|
|
4156
|
-
]
|
|
4157
|
-
});
|
|
4158
|
-
}
|
|
4159
|
-
var FieldContext = createContext(null);
|
|
4160
|
-
/** Liga um controle ao Field mais próximo (id, aria-describedby, aria-invalid). */
|
|
4161
|
-
function useFieldControl() {
|
|
4162
|
-
return useContext(FieldContext);
|
|
4163
|
-
}
|
|
4164
|
-
function Field({ label, required, help, error, span = "md", newRow, reserveMessage = false, id, className, children }) {
|
|
4165
|
-
const auto = useId();
|
|
4166
|
-
const controlId = id ?? `campo${auto}`;
|
|
4167
|
-
const messageId = `${controlId}-mensagem`;
|
|
4168
|
-
const invalid = Boolean(error);
|
|
4169
|
-
const message = error ?? help;
|
|
4170
|
-
const child = isValidElement(children) && typeof children.type !== "string" ? cloneElement(children, {
|
|
4171
|
-
id: children.props.id ?? controlId,
|
|
4172
|
-
...invalid ? { invalid: children.props.invalid ?? true } : {},
|
|
4173
|
-
"aria-describedby": message ? messageId : void 0,
|
|
4174
|
-
"aria-required": required || void 0
|
|
4175
|
-
}) : children;
|
|
4176
|
-
return /* @__PURE__ */ jsx(FieldContext.Provider, {
|
|
4177
|
-
value: {
|
|
4178
|
-
id: controlId,
|
|
4179
|
-
describedBy: message ? messageId : "",
|
|
4180
|
-
invalid
|
|
4181
|
-
},
|
|
4182
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
4183
|
-
"data-slot": "field",
|
|
4184
|
-
"data-rendra": "FLD-001",
|
|
4185
|
-
className: cn("flex min-w-0 flex-col gap-2", fieldSpanClass[span === "half" ? "md" : span], newRow && "@md:col-start-1 @3xl:col-start-1", className),
|
|
4186
|
-
children: [
|
|
4187
|
-
label && /* @__PURE__ */ jsx(Label, {
|
|
4188
|
-
htmlFor: controlId,
|
|
4189
|
-
required,
|
|
4190
|
-
children: label
|
|
4191
|
-
}),
|
|
4192
|
-
child,
|
|
4193
|
-
(reserveMessage || message) && /* @__PURE__ */ jsx("p", {
|
|
4194
|
-
id: messageId,
|
|
4195
|
-
role: invalid ? "alert" : void 0,
|
|
4196
|
-
className: cn("-mt-1 min-h-4 text-help", invalid ? "font-medium text-destructive" : "text-help-foreground"),
|
|
4197
|
-
children: message
|
|
4198
|
-
})
|
|
4199
|
-
]
|
|
4200
|
-
})
|
|
4201
|
-
});
|
|
4202
|
-
}
|
|
4203
|
-
//#endregion
|
|
4204
2851
|
//#region src/components/ui/date-picker.tsx
|
|
4205
2852
|
var fmtDate = (d) => format(d, "dd/MM/yyyy");
|
|
4206
2853
|
var fmtTime = (d) => format(d, "HH:mm");
|
|
@@ -4583,318 +3230,6 @@ function Slider({ value, defaultValue = [50], onChange, min = 0, max = 100, step
|
|
|
4583
3230
|
});
|
|
4584
3231
|
}
|
|
4585
3232
|
//#endregion
|
|
4586
|
-
//#region src/components/ui/select.tsx
|
|
4587
|
-
/** Acima deste número de opções, o "Selecionar todos" aparece sem a prop `selectAll`. */
|
|
4588
|
-
var SELECT_ALL_AUTO_MIN = 5;
|
|
4589
|
-
/**
|
|
4590
|
-
* Select único do sistema. Busca, múltiplo, selecionar todos, contador, criar opção,
|
|
4591
|
-
* busca remota e carregamento são props. No mobile abre como bottom sheet.
|
|
4592
|
-
*/
|
|
4593
|
-
var Select = forwardRef(function Select(props, ref) {
|
|
4594
|
-
const { options: staticOptions = [], placeholder = "Selecione", label, size, invalid, disabled, searchable, creatable, onCreate, loadOptions, loading, clearable, emptyText = "Nenhuma opção encontrada.", id, className } = props;
|
|
4595
|
-
const multiple = props.multiple === true;
|
|
4596
|
-
const { isMobile } = useBreakpoint();
|
|
4597
|
-
const [open, setOpen] = useState(false);
|
|
4598
|
-
const listId = `${useId()}-lista`;
|
|
4599
|
-
const [query, setQuery] = useState("");
|
|
4600
|
-
const [remote, setRemote] = useState(null);
|
|
4601
|
-
const [remoteLoading, setRemoteLoading] = useState(false);
|
|
4602
|
-
const [created, setCreated] = useState([]);
|
|
4603
|
-
const [innerSingle, setInnerSingle] = useState(null);
|
|
4604
|
-
const [innerMulti, setInnerMulti] = useState([]);
|
|
4605
|
-
const [draft, setDraft] = useState([]);
|
|
4606
|
-
const selectedSingle = multiple ? null : props.value ?? innerSingle;
|
|
4607
|
-
const selectedMulti = multiple ? props.value ?? innerMulti : [];
|
|
4608
|
-
const seq = useRef(0);
|
|
4609
|
-
useEffect(() => {
|
|
4610
|
-
if (!loadOptions || !open) return;
|
|
4611
|
-
const n = ++seq.current;
|
|
4612
|
-
setRemoteLoading(true);
|
|
4613
|
-
const t = window.setTimeout(async () => {
|
|
4614
|
-
const res = await loadOptions(query);
|
|
4615
|
-
if (n === seq.current) {
|
|
4616
|
-
setRemote(res);
|
|
4617
|
-
setRemoteLoading(false);
|
|
4618
|
-
}
|
|
4619
|
-
}, 250);
|
|
4620
|
-
return () => window.clearTimeout(t);
|
|
4621
|
-
}, [
|
|
4622
|
-
loadOptions,
|
|
4623
|
-
query,
|
|
4624
|
-
open
|
|
4625
|
-
]);
|
|
4626
|
-
const all = useMemo(() => {
|
|
4627
|
-
const base = remote ?? staticOptions;
|
|
4628
|
-
const map = /* @__PURE__ */ new Map();
|
|
4629
|
-
[...base, ...created].forEach((o) => map.set(o.value, o));
|
|
4630
|
-
return [...map.values()];
|
|
4631
|
-
}, [
|
|
4632
|
-
remote,
|
|
4633
|
-
staticOptions,
|
|
4634
|
-
created
|
|
4635
|
-
]);
|
|
4636
|
-
const byValue = (v) => all.find((o) => o.value === v);
|
|
4637
|
-
const isSearchable = searchable || creatable || Boolean(loadOptions);
|
|
4638
|
-
const busy = loading || remoteLoading;
|
|
4639
|
-
const multiValue = isMobile && multiple ? draft : selectedMulti;
|
|
4640
|
-
const commitSingle = (v) => {
|
|
4641
|
-
setInnerSingle(v);
|
|
4642
|
-
props.onChange?.(v);
|
|
4643
|
-
};
|
|
4644
|
-
const commitMulti = (v) => {
|
|
4645
|
-
setInnerMulti(v);
|
|
4646
|
-
props.onChange?.(v);
|
|
4647
|
-
};
|
|
4648
|
-
const toggle = (v) => {
|
|
4649
|
-
if (!multiple) {
|
|
4650
|
-
commitSingle(v);
|
|
4651
|
-
setOpen(false);
|
|
4652
|
-
return;
|
|
4653
|
-
}
|
|
4654
|
-
const next = multiValue.includes(v) ? multiValue.filter((x) => x !== v) : [...multiValue, v];
|
|
4655
|
-
if (isMobile) setDraft(next);
|
|
4656
|
-
else commitMulti(next);
|
|
4657
|
-
};
|
|
4658
|
-
const enabled = all.filter((o) => !o.disabled);
|
|
4659
|
-
const allSelected = enabled.length > 0 && enabled.every((o) => multiValue.includes(o.value));
|
|
4660
|
-
const showSelectAll = multiple && (props.selectAll ?? all.length > SELECT_ALL_AUTO_MIN);
|
|
4661
|
-
const toggleAll = () => {
|
|
4662
|
-
const next = allSelected ? [] : enabled.map((o) => o.value);
|
|
4663
|
-
if (isMobile) setDraft(next);
|
|
4664
|
-
else commitMulti(next);
|
|
4665
|
-
};
|
|
4666
|
-
const create = async () => {
|
|
4667
|
-
const text = query.trim();
|
|
4668
|
-
if (!text) return;
|
|
4669
|
-
const opt = onCreate ? await onCreate(text) : {
|
|
4670
|
-
value: text,
|
|
4671
|
-
label: text
|
|
4672
|
-
};
|
|
4673
|
-
setCreated((c) => [...c, opt]);
|
|
4674
|
-
setQuery("");
|
|
4675
|
-
toggle(opt.value);
|
|
4676
|
-
};
|
|
4677
|
-
const onOpenChange = (o) => {
|
|
4678
|
-
setOpen(o);
|
|
4679
|
-
if (o) setDraft(selectedMulti);
|
|
4680
|
-
else setQuery("");
|
|
4681
|
-
};
|
|
4682
|
-
const hasValue = multiple ? selectedMulti.length > 0 : selectedSingle != null;
|
|
4683
|
-
const maxChips = props.maxChips ?? 2;
|
|
4684
|
-
let display = /* @__PURE__ */ jsx("span", {
|
|
4685
|
-
className: "truncate text-muted-foreground",
|
|
4686
|
-
children: placeholder
|
|
4687
|
-
});
|
|
4688
|
-
if (!multiple && selectedSingle != null) {
|
|
4689
|
-
const o = byValue(selectedSingle);
|
|
4690
|
-
display = /* @__PURE__ */ jsxs("span", {
|
|
4691
|
-
className: "flex min-w-0 items-center gap-2",
|
|
4692
|
-
children: [o?.icon, /* @__PURE__ */ jsx("span", {
|
|
4693
|
-
className: "truncate",
|
|
4694
|
-
children: o?.label ?? selectedSingle
|
|
4695
|
-
})]
|
|
4696
|
-
});
|
|
4697
|
-
} else if (multiple && selectedMulti.length > 0) display = props.showCount ? /* @__PURE__ */ jsxs("span", {
|
|
4698
|
-
className: "truncate",
|
|
4699
|
-
children: [
|
|
4700
|
-
selectedMulti.length,
|
|
4701
|
-
" ",
|
|
4702
|
-
selectedMulti.length === 1 ? "selecionado" : "selecionados"
|
|
4703
|
-
]
|
|
4704
|
-
}) : /* @__PURE__ */ jsxs("span", {
|
|
4705
|
-
className: "flex min-w-0 items-center gap-1 overflow-hidden",
|
|
4706
|
-
children: [selectedMulti.slice(0, maxChips).map((v) => /* @__PURE__ */ jsx("span", {
|
|
4707
|
-
className: "max-w-3xs shrink-0 truncate rounded-item bg-primary-soft px-2 py-1 text-xs leading-none font-medium text-primary-soft-foreground",
|
|
4708
|
-
children: byValue(v)?.label ?? v
|
|
4709
|
-
}, v)), selectedMulti.length > maxChips && /* @__PURE__ */ jsxs("span", {
|
|
4710
|
-
className: "shrink-0 rounded-item bg-muted px-2 py-1 text-xs leading-none font-medium",
|
|
4711
|
-
children: ["+", selectedMulti.length - maxChips]
|
|
4712
|
-
})]
|
|
4713
|
-
});
|
|
4714
|
-
const showClear = clearable && hasValue && !disabled;
|
|
4715
|
-
const clear = showClear ? /* @__PURE__ */ jsx("button", {
|
|
4716
|
-
type: "button",
|
|
4717
|
-
"aria-label": "Limpar seleção",
|
|
4718
|
-
className: cn(controlAdornmentButton, "absolute top-1/2 right-8 mr-0 -translate-y-1/2 md:mr-0"),
|
|
4719
|
-
onClick: () => multiple ? commitMulti([]) : commitSingle(null),
|
|
4720
|
-
children: /* @__PURE__ */ jsx(X, { "aria-hidden": true })
|
|
4721
|
-
}) : void 0;
|
|
4722
|
-
const trigger = /* @__PURE__ */ jsxs("button", {
|
|
4723
|
-
ref,
|
|
4724
|
-
id,
|
|
4725
|
-
type: "button",
|
|
4726
|
-
role: "combobox",
|
|
4727
|
-
"aria-expanded": open,
|
|
4728
|
-
"aria-controls": listId,
|
|
4729
|
-
"aria-haspopup": "listbox",
|
|
4730
|
-
"aria-invalid": invalid || void 0,
|
|
4731
|
-
"aria-describedby": props["aria-describedby"],
|
|
4732
|
-
"aria-label": id ? void 0 : label,
|
|
4733
|
-
disabled,
|
|
4734
|
-
"data-rendra": "SEL-001",
|
|
4735
|
-
onKeyDown: (e) => e.stopPropagation(),
|
|
4736
|
-
className: cn(controlFrame({
|
|
4737
|
-
size,
|
|
4738
|
-
invalid
|
|
4739
|
-
}), "cursor-pointer text-left disabled:cursor-not-allowed disabled:opacity-60", className),
|
|
4740
|
-
children: [
|
|
4741
|
-
/* @__PURE__ */ jsx("span", {
|
|
4742
|
-
className: "flex min-w-0 flex-1 items-center",
|
|
4743
|
-
children: display
|
|
4744
|
-
}),
|
|
4745
|
-
showClear && /* @__PURE__ */ jsx("span", {
|
|
4746
|
-
"aria-hidden": true,
|
|
4747
|
-
className: cn("size-control-sm shrink-0 md:size-8", "-mr-1")
|
|
4748
|
-
}),
|
|
4749
|
-
/* @__PURE__ */ jsx(ChevronDown, {
|
|
4750
|
-
"aria-hidden": true,
|
|
4751
|
-
className: cn("size-icon-sm shrink-0 text-muted-foreground transition-transform duration-(--rendra-duration-base) ease-move", open && "rotate-180")
|
|
4752
|
-
})
|
|
4753
|
-
]
|
|
4754
|
-
});
|
|
4755
|
-
const groups = all.reduce((acc, o) => {
|
|
4756
|
-
(acc[o.group ?? ""] ??= []).push(o);
|
|
4757
|
-
return acc;
|
|
4758
|
-
}, {});
|
|
4759
|
-
const q = query.trim().toLowerCase();
|
|
4760
|
-
const showCreate = creatable && q && !all.some((o) => o.label.toLowerCase() === q);
|
|
4761
|
-
const itemClass = "relative flex min-h-touch cursor-pointer items-center gap-3 rounded-item px-3 text-sm outline-none select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent md:min-h-0 md:py-2";
|
|
4762
|
-
const checkbox = (checked) => /* @__PURE__ */ jsx("span", {
|
|
4763
|
-
"aria-hidden": true,
|
|
4764
|
-
className: cn("flex size-icon-sm shrink-0 items-center justify-center rounded-item border transition-colors", checked ? "border-primary bg-primary text-primary-foreground" : "border-input bg-card"),
|
|
4765
|
-
children: checked && /* @__PURE__ */ jsx(Check, {
|
|
4766
|
-
className: "size-3",
|
|
4767
|
-
strokeWidth: 3
|
|
4768
|
-
})
|
|
4769
|
-
});
|
|
4770
|
-
const list = /* @__PURE__ */ jsxs(Command.List, {
|
|
4771
|
-
id: listId,
|
|
4772
|
-
"aria-label": label ?? placeholder,
|
|
4773
|
-
children: [
|
|
4774
|
-
busy && /* @__PURE__ */ jsx(Command.Loading, { children: /* @__PURE__ */ jsxs("div", {
|
|
4775
|
-
className: "flex items-center gap-2 px-3 py-4 text-sm text-muted-foreground",
|
|
4776
|
-
children: [/* @__PURE__ */ jsx(Spinner, { size: "sm" }), "Carregando opções..."]
|
|
4777
|
-
}) }),
|
|
4778
|
-
!busy && /* @__PURE__ */ jsx(Command.Empty, {
|
|
4779
|
-
className: "px-3 py-6 text-center text-sm text-muted-foreground",
|
|
4780
|
-
children: emptyText
|
|
4781
|
-
}),
|
|
4782
|
-
showCreate && /* @__PURE__ */ jsxs(Command.Item, {
|
|
4783
|
-
value: `__criar__${query}`,
|
|
4784
|
-
onSelect: create,
|
|
4785
|
-
className: itemClass,
|
|
4786
|
-
children: [/* @__PURE__ */ jsx(Plus, {
|
|
4787
|
-
className: "size-icon-sm shrink-0 text-primary-text",
|
|
4788
|
-
"aria-hidden": true
|
|
4789
|
-
}), /* @__PURE__ */ jsxs("span", {
|
|
4790
|
-
className: "truncate",
|
|
4791
|
-
children: ["Criar ", /* @__PURE__ */ jsxs("strong", {
|
|
4792
|
-
className: "font-semibold",
|
|
4793
|
-
children: [
|
|
4794
|
-
"“",
|
|
4795
|
-
query.trim(),
|
|
4796
|
-
"”"
|
|
4797
|
-
]
|
|
4798
|
-
})]
|
|
4799
|
-
})]
|
|
4800
|
-
}),
|
|
4801
|
-
showSelectAll && !q && enabled.length > 0 && /* @__PURE__ */ jsxs(Command.Item, {
|
|
4802
|
-
value: "__todos__",
|
|
4803
|
-
onSelect: toggleAll,
|
|
4804
|
-
className: cn(itemClass, "font-medium"),
|
|
4805
|
-
children: [checkbox(allSelected), allSelected ? "Desmarcar todos" : "Selecionar todos"]
|
|
4806
|
-
}),
|
|
4807
|
-
Object.entries(groups).map(([group, opts]) => /* @__PURE__ */ jsx(Command.Group, {
|
|
4808
|
-
heading: group || void 0,
|
|
4809
|
-
className: "[&_[cmdk-group-heading]]:px-3 [&_[cmdk-group-heading]]:py-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
|
|
4810
|
-
children: opts.map((o) => {
|
|
4811
|
-
const checked = multiple ? multiValue.includes(o.value) : selectedSingle === o.value;
|
|
4812
|
-
return /* @__PURE__ */ jsxs(Command.Item, {
|
|
4813
|
-
value: `${o.label} ${o.description ?? ""} ${o.value}`,
|
|
4814
|
-
disabled: o.disabled,
|
|
4815
|
-
onSelect: () => toggle(o.value),
|
|
4816
|
-
"aria-selected": checked,
|
|
4817
|
-
className: itemClass,
|
|
4818
|
-
children: [
|
|
4819
|
-
multiple && checkbox(checked),
|
|
4820
|
-
o.icon && /* @__PURE__ */ jsx("span", {
|
|
4821
|
-
className: "flex shrink-0 [&_svg]:size-icon-sm",
|
|
4822
|
-
children: o.icon
|
|
4823
|
-
}),
|
|
4824
|
-
/* @__PURE__ */ jsxs("span", {
|
|
4825
|
-
className: "flex min-w-0 flex-1 flex-col",
|
|
4826
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
4827
|
-
className: cn("truncate", checked && !multiple && "font-medium"),
|
|
4828
|
-
children: o.label
|
|
4829
|
-
}), o.description && /* @__PURE__ */ jsx("span", {
|
|
4830
|
-
className: "truncate text-xs text-muted-foreground",
|
|
4831
|
-
children: o.description
|
|
4832
|
-
})]
|
|
4833
|
-
}),
|
|
4834
|
-
!multiple && checked && /* @__PURE__ */ jsx(Check, {
|
|
4835
|
-
className: "size-icon-sm shrink-0 text-primary-text",
|
|
4836
|
-
"aria-hidden": true
|
|
4837
|
-
})
|
|
4838
|
-
]
|
|
4839
|
-
}, o.value);
|
|
4840
|
-
})
|
|
4841
|
-
}, group || "sem-grupo"))
|
|
4842
|
-
]
|
|
4843
|
-
});
|
|
4844
|
-
const search = isSearchable ? /* @__PURE__ */ jsxs("div", {
|
|
4845
|
-
className: cn(controlFrame({ size: "md" }), "bg-background"),
|
|
4846
|
-
children: [/* @__PURE__ */ jsx(Search, {
|
|
4847
|
-
className: "size-icon-sm shrink-0 text-muted-foreground",
|
|
4848
|
-
"aria-hidden": true
|
|
4849
|
-
}), /* @__PURE__ */ jsx(Command.Input, {
|
|
4850
|
-
value: query,
|
|
4851
|
-
onValueChange: setQuery,
|
|
4852
|
-
placeholder: creatable ? "Buscar ou criar..." : "Buscar...",
|
|
4853
|
-
className: "h-full min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground"
|
|
4854
|
-
})]
|
|
4855
|
-
}) : null;
|
|
4856
|
-
const count = multiValue.length;
|
|
4857
|
-
const footer = multiple && (isMobile || count > 0) ? /* @__PURE__ */ jsxs("div", {
|
|
4858
|
-
className: "grid grid-actions-2 gap-3",
|
|
4859
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
4860
|
-
variant: "outline",
|
|
4861
|
-
onClick: () => isMobile ? setDraft([]) : commitMulti([]),
|
|
4862
|
-
disabled: count === 0,
|
|
4863
|
-
children: "Limpar"
|
|
4864
|
-
}), isMobile ? /* @__PURE__ */ jsxs(Button, {
|
|
4865
|
-
onClick: () => {
|
|
4866
|
-
commitMulti(draft);
|
|
4867
|
-
setOpen(false);
|
|
4868
|
-
},
|
|
4869
|
-
children: ["Aplicar", count ? ` (${count})` : ""]
|
|
4870
|
-
}) : /* @__PURE__ */ jsxs(Button, {
|
|
4871
|
-
variant: "secondary",
|
|
4872
|
-
onClick: () => setOpen(false),
|
|
4873
|
-
children: [
|
|
4874
|
-
"Pronto (",
|
|
4875
|
-
count,
|
|
4876
|
-
")"
|
|
4877
|
-
]
|
|
4878
|
-
})]
|
|
4879
|
-
}) : void 0;
|
|
4880
|
-
return /* @__PURE__ */ jsx(Command, {
|
|
4881
|
-
shouldFilter: !loadOptions,
|
|
4882
|
-
loop: true,
|
|
4883
|
-
className: "contents",
|
|
4884
|
-
label: label ?? placeholder,
|
|
4885
|
-
children: /* @__PURE__ */ jsx(PickerPanel, {
|
|
4886
|
-
open,
|
|
4887
|
-
onOpenChange,
|
|
4888
|
-
trigger,
|
|
4889
|
-
adornment: clear,
|
|
4890
|
-
title: label ?? placeholder,
|
|
4891
|
-
header: search,
|
|
4892
|
-
footer,
|
|
4893
|
-
children: list
|
|
4894
|
-
})
|
|
4895
|
-
});
|
|
4896
|
-
});
|
|
4897
|
-
//#endregion
|
|
4898
3233
|
//#region src/components/ui/tabs.tsx
|
|
4899
3234
|
/** Contador de instâncias, só para o `layoutId` do indicador (ver `indicatorId`). */
|
|
4900
3235
|
var tabsCreated = 0;
|
|
@@ -4924,6 +3259,7 @@ function Tabs({ items, value, defaultValue, onChange, variant = "line", classNam
|
|
|
4924
3259
|
}, [items, variant]);
|
|
4925
3260
|
const presets = useMotionPresets();
|
|
4926
3261
|
const on = useLayoutReady();
|
|
3262
|
+
const lib = useMotionLib();
|
|
4927
3263
|
const listRef = useRef(null);
|
|
4928
3264
|
const [clip, setClip] = useState({
|
|
4929
3265
|
l: 0,
|
|
@@ -4955,7 +3291,7 @@ function Tabs({ items, value, defaultValue, onChange, variant = "line", classNam
|
|
|
4955
3291
|
]);
|
|
4956
3292
|
const [indicatorId] = useState(() => `rendra-tabs-${++tabsCreated}`);
|
|
4957
3293
|
const trigger = cn("inline-flex min-h-touch shrink-0 cursor-pointer items-center justify-center gap-2 px-3 text-sm font-medium whitespace-nowrap transition-colors outline-none disabled:cursor-not-allowed disabled:opacity-50 md:min-h-0 [&_svg]:size-icon-sm", variant === "line" ? on ? "relative -mb-px border-b-2 border-transparent py-3 text-muted-foreground hover:text-foreground" : "-mb-px border-b-2 border-transparent py-3 text-muted-foreground hover:text-foreground data-[state=active]:border-primary data-[state=active]:text-foreground" : on ? "relative isolate rounded-item py-2 text-muted-foreground hover:bg-card/60 hover:text-foreground" : "rounded-item py-2 text-muted-foreground hover:bg-card/60 hover:text-foreground data-[state=active]:bg-card data-[state=active]:text-foreground data-[state=active]:shadow-sm");
|
|
4958
|
-
const indicator = /* @__PURE__ */ jsx(m.span, {
|
|
3294
|
+
const indicator = lib && /* @__PURE__ */ jsx(lib.m.span, {
|
|
4959
3295
|
layoutId: indicatorId,
|
|
4960
3296
|
"data-indicator": "tabs",
|
|
4961
3297
|
"aria-hidden": true,
|
|
@@ -5456,33 +3792,6 @@ function ImageViewer({ images, index, onIndexChange }) {
|
|
|
5456
3792
|
});
|
|
5457
3793
|
}
|
|
5458
3794
|
//#endregion
|
|
5459
|
-
//#region src/hooks/use-fill-height.ts
|
|
5460
|
-
/**
|
|
5461
|
-
* Mede o espaço que sobra na área de conteúdo (o <main>) abaixo do elemento e grava em
|
|
5462
|
-
* --board-h. Com a classe h-board, o elemento ocupa exatamente essa altura: a página não
|
|
5463
|
-
* rola e a rolagem acontece dentro dele (kanban, chat).
|
|
5464
|
-
*/
|
|
5465
|
-
function useFillHeight() {
|
|
5466
|
-
const ref = useRef(null);
|
|
5467
|
-
useLayoutEffect(() => {
|
|
5468
|
-
const el = ref.current;
|
|
5469
|
-
if (!el) return;
|
|
5470
|
-
const main = el.closest("main");
|
|
5471
|
-
const measure = () => {
|
|
5472
|
-
const h = el.getBoundingClientRect().height;
|
|
5473
|
-
const page = main?.firstElementChild;
|
|
5474
|
-
const room = main && page ? main.clientHeight - (page.getBoundingClientRect().height - h) : window.innerHeight - el.getBoundingClientRect().top;
|
|
5475
|
-
el.style.setProperty("--board-h", `${Math.max(320, Math.floor(room))}px`);
|
|
5476
|
-
};
|
|
5477
|
-
measure();
|
|
5478
|
-
const ro = new ResizeObserver(measure);
|
|
5479
|
-
ro.observe(document.documentElement);
|
|
5480
|
-
if (main) ro.observe(main);
|
|
5481
|
-
return () => ro.disconnect();
|
|
5482
|
-
}, []);
|
|
5483
|
-
return ref;
|
|
5484
|
-
}
|
|
5485
|
-
//#endregion
|
|
5486
3795
|
//#region src/components/ui/kanban.tsx
|
|
5487
3796
|
/** Marca o fim da lista: ao aparecer na rolagem da etapa, pede mais cards. */
|
|
5488
3797
|
function LoadMore({ onVisible }) {
|
|
@@ -5630,6 +3939,7 @@ function Kanban({ columns, cards, onCardMove, onCardClick, onAddCard, renderCard
|
|
|
5630
3939
|
const code = resolveCatalogCode("Kanban", { hasDropTargets: Boolean(dropTargets?.length) });
|
|
5631
3940
|
const { isMobile } = useBreakpoint();
|
|
5632
3941
|
const motion = useMotionMode();
|
|
3942
|
+
const lib = useMotionLib();
|
|
5633
3943
|
const ready = useLayoutReady();
|
|
5634
3944
|
const presets = useMotionPresets();
|
|
5635
3945
|
const [boardId] = useState(() => `rendra-kanban-${++boardsCreated}`);
|
|
@@ -5846,13 +4156,13 @@ function Kanban({ columns, cards, onCardMove, onCardClick, onAddCard, renderCard
|
|
|
5846
4156
|
children: moveMenu(card)
|
|
5847
4157
|
})
|
|
5848
4158
|
] });
|
|
5849
|
-
if (
|
|
4159
|
+
if (lib) {
|
|
5850
4160
|
const layout = layoutEnabled({
|
|
5851
4161
|
mode: motion,
|
|
5852
4162
|
ready,
|
|
5853
4163
|
dragging: touchDrag !== null
|
|
5854
4164
|
});
|
|
5855
|
-
return /* @__PURE__ */ jsx(m.li, {
|
|
4165
|
+
return /* @__PURE__ */ jsx(lib.m.li, {
|
|
5856
4166
|
ref: (el) => {
|
|
5857
4167
|
if (!el) return;
|
|
5858
4168
|
const onStart = (e) => dragStart(e.dataTransfer);
|
|
@@ -6080,9 +4390,10 @@ function List({ items, divided = true, empty, className, onReorder, itemLabel =
|
|
|
6080
4390
|
});
|
|
6081
4391
|
const sortableEnabled = Boolean(onReorder);
|
|
6082
4392
|
const motion = useMotionMode();
|
|
4393
|
+
const lib = useMotionLib();
|
|
6083
4394
|
const ready = useLayoutReady();
|
|
6084
4395
|
const presets = useMotionPresets();
|
|
6085
|
-
const Item =
|
|
4396
|
+
const Item = lib ? lib.m.li : "li";
|
|
6086
4397
|
const itemMotion = motion === "on" ? {
|
|
6087
4398
|
layout: layoutEnabled({
|
|
6088
4399
|
mode: motion,
|
|
@@ -6163,9 +4474,10 @@ function List({ items, divided = true, empty, className, onReorder, itemLabel =
|
|
|
6163
4474
|
*/
|
|
6164
4475
|
function OtpInput({ length = 6, value, onChange, onComplete, invalid, disabled, id, ...aria }) {
|
|
6165
4476
|
const refs = useRef([]);
|
|
6166
|
-
const
|
|
4477
|
+
const lib = useMotionLib();
|
|
4478
|
+
const on = lib !== null;
|
|
6167
4479
|
const presets = useMotionPresets();
|
|
6168
|
-
const Cell = on ? m.input : "input";
|
|
4480
|
+
const Cell = on ? lib.m.input : "input";
|
|
6169
4481
|
const digits = Array.from({ length }, (_, i) => value[i] ?? "");
|
|
6170
4482
|
const set = (next) => {
|
|
6171
4483
|
const clean = next.replace(/\D/g, "").slice(0, length);
|
|
@@ -7220,16 +5532,17 @@ var cols = {
|
|
|
7220
5532
|
* O item do Radix. Em `on` ele é um `m.button` (asChild) que responde ao toque (whileTap 0,97,
|
|
7221
5533
|
* em `press`); em `off` é o `R.Item` de sempre, sem nó novo.
|
|
7222
5534
|
*/
|
|
7223
|
-
function Item({
|
|
5535
|
+
function Item({ children, ...props }) {
|
|
7224
5536
|
const presets = useMotionPresets();
|
|
7225
|
-
|
|
5537
|
+
const lib = useMotionLib();
|
|
5538
|
+
if (!lib) return /* @__PURE__ */ jsx(RadioGroup$1.Item, {
|
|
7226
5539
|
...props,
|
|
7227
5540
|
children
|
|
7228
5541
|
});
|
|
7229
5542
|
return /* @__PURE__ */ jsx(RadioGroup$1.Item, {
|
|
7230
5543
|
asChild: true,
|
|
7231
5544
|
...props,
|
|
7232
|
-
children: /* @__PURE__ */ jsx(m.button, {
|
|
5545
|
+
children: /* @__PURE__ */ jsx(lib.m.button, {
|
|
7233
5546
|
type: "button",
|
|
7234
5547
|
whileTap: presets.press.whileTap,
|
|
7235
5548
|
transition: presets.press.transition,
|
|
@@ -7239,14 +5552,15 @@ function Item({ on, children, ...props }) {
|
|
|
7239
5552
|
}
|
|
7240
5553
|
/** Radio único: em lista ou em cards, por prop. */
|
|
7241
5554
|
function RadioGroup({ options, value, defaultValue, onChange, variant = "list", columns = 2, orientation = "vertical", invalid, disabled, id, name, ...aria }) {
|
|
7242
|
-
const
|
|
5555
|
+
const lib = useMotionLib();
|
|
5556
|
+
const on = lib !== null;
|
|
7243
5557
|
const presets = useMotionPresets();
|
|
7244
5558
|
const [inner, setInner] = useState(defaultValue);
|
|
7245
5559
|
const current = value ?? inner;
|
|
7246
5560
|
const dotFor = (optionValue) => /* @__PURE__ */ jsx("span", {
|
|
7247
5561
|
"aria-hidden": true,
|
|
7248
5562
|
className: cn("flex size-icon-md shrink-0 items-center justify-center rounded-full border border-input bg-card transition-colors group-data-[state=checked]:border-primary", invalid && "border-destructive"),
|
|
7249
|
-
children: on ? /* @__PURE__ */ jsx(m.span, {
|
|
5563
|
+
children: on ? /* @__PURE__ */ jsx(lib.m.span, {
|
|
7250
5564
|
className: "size-2 rounded-full bg-primary",
|
|
7251
5565
|
initial: false,
|
|
7252
5566
|
animate: current === optionValue ? presets.indicator.animate : presets.indicator.initial,
|
|
@@ -7269,7 +5583,6 @@ function RadioGroup({ options, value, defaultValue, onChange, variant = "list",
|
|
|
7269
5583
|
"data-rendra": resolveCatalogCode("RadioGroup", { variant }),
|
|
7270
5584
|
className: cn(variant === "cards" ? cn("grid grid-cols-1 gap-3", cols[columns]) : orientation === "horizontal" ? "flex flex-col sm:flex-row sm:flex-wrap sm:gap-x-6" : "flex flex-col"),
|
|
7271
5585
|
children: options.map((o) => variant === "cards" ? /* @__PURE__ */ jsxs(Item, {
|
|
7272
|
-
on,
|
|
7273
5586
|
value: o.value,
|
|
7274
5587
|
disabled: o.disabled,
|
|
7275
5588
|
className: cn("group relative flex cursor-pointer items-start gap-3 rounded-control border bg-card p-4 text-left transition-[border-color,box-shadow,background-color]", "hover:border-primary data-[state=checked]:border-primary data-[state=checked]:bg-primary-soft data-[state=checked]:ring-1 data-[state=checked]:ring-primary", "disabled:cursor-not-allowed disabled:opacity-50", invalid && "border-destructive"),
|
|
@@ -7293,7 +5606,6 @@ function RadioGroup({ options, value, defaultValue, onChange, variant = "list",
|
|
|
7293
5606
|
}, o.value) : /* @__PURE__ */ jsxs("label", {
|
|
7294
5607
|
className: cn("flex min-h-touch cursor-pointer items-start gap-3 py-3 md:min-h-0 md:py-1", o.disabled && "cursor-not-allowed opacity-60"),
|
|
7295
5608
|
children: [/* @__PURE__ */ jsx(Item, {
|
|
7296
|
-
on,
|
|
7297
5609
|
value: o.value,
|
|
7298
5610
|
disabled: o.disabled,
|
|
7299
5611
|
className: "group flex pt-px outline-none focus-visible:[&>span]:focus-ring",
|
|
@@ -7551,11 +5863,14 @@ function Skeleton({ className, ...props }) {
|
|
|
7551
5863
|
//#region src/components/ui/stat-card.tsx
|
|
7552
5864
|
/** Contagem de 0 até o valor, com o formato do texto original; no fim mostra o `value` exato. */
|
|
7553
5865
|
function Counter({ parsed, value }) {
|
|
5866
|
+
const { animate, m, useMotionValue, useTransform } = useMotionOn();
|
|
7554
5867
|
const presets = useMotionPresets();
|
|
7555
|
-
const
|
|
5868
|
+
const [skip] = useState(useMotionAdopted());
|
|
5869
|
+
const progress = useMotionValue(skip ? parsed.value : 0);
|
|
7556
5870
|
const text = useTransform(progress, (n) => formatLike(parsed, n));
|
|
7557
|
-
const [done, setDone] = useState(
|
|
5871
|
+
const [done, setDone] = useState(skip);
|
|
7558
5872
|
useEffect(() => {
|
|
5873
|
+
if (skip) return;
|
|
7559
5874
|
const controls = animate(progress, parsed.value, {
|
|
7560
5875
|
duration: presets.tokens.reveal.count,
|
|
7561
5876
|
ease: presets.tokens.ease.out,
|
|
@@ -7563,9 +5878,11 @@ function Counter({ parsed, value }) {
|
|
|
7563
5878
|
});
|
|
7564
5879
|
return () => controls.stop();
|
|
7565
5880
|
}, [
|
|
5881
|
+
animate,
|
|
7566
5882
|
progress,
|
|
7567
5883
|
parsed.value,
|
|
7568
|
-
presets.tokens
|
|
5884
|
+
presets.tokens,
|
|
5885
|
+
skip
|
|
7569
5886
|
]);
|
|
7570
5887
|
return /* @__PURE__ */ jsx(m.span, {
|
|
7571
5888
|
...presets.fade,
|
|
@@ -7578,11 +5895,11 @@ function Counter({ parsed, value }) {
|
|
|
7578
5895
|
* o valor final aparece direto.
|
|
7579
5896
|
*/
|
|
7580
5897
|
function StatValue({ value }) {
|
|
7581
|
-
const
|
|
5898
|
+
const lib = useMotionLib();
|
|
7582
5899
|
const presets = useMotionPresets();
|
|
7583
5900
|
const parsed = useMemo(() => parseLocaleNumber$1(value), [value]);
|
|
7584
|
-
if (
|
|
7585
|
-
if (!parsed || presets.reduced) return /* @__PURE__ */ jsx(m.span, {
|
|
5901
|
+
if (!lib) return /* @__PURE__ */ jsx(Fragment$1, { children: value });
|
|
5902
|
+
if (!parsed || presets.reduced) return /* @__PURE__ */ jsx(lib.m.span, {
|
|
7586
5903
|
...presets.fade,
|
|
7587
5904
|
children: value
|
|
7588
5905
|
});
|
|
@@ -7783,7 +6100,7 @@ var tableFeatureSet = tableFeatures({
|
|
|
7783
6100
|
* conteúdo fechado sai do DOM; em `off` é o Collapsible de sempre, com as animações em CSS.
|
|
7784
6101
|
*/
|
|
7785
6102
|
function MobileDetails({ children }) {
|
|
7786
|
-
const
|
|
6103
|
+
const lib = useMotionLib();
|
|
7787
6104
|
const presets = useMotionPresets();
|
|
7788
6105
|
const [open, setOpen] = useState(false);
|
|
7789
6106
|
const trigger = /* @__PURE__ */ jsxs(Collapsible.Trigger, {
|
|
@@ -7803,15 +6120,15 @@ function MobileDetails({ children }) {
|
|
|
7803
6120
|
})
|
|
7804
6121
|
]
|
|
7805
6122
|
});
|
|
7806
|
-
if (
|
|
6123
|
+
if (lib) return /* @__PURE__ */ jsxs(Collapsible.Root, {
|
|
7807
6124
|
open,
|
|
7808
6125
|
onOpenChange: setOpen,
|
|
7809
|
-
children: [trigger, /* @__PURE__ */ jsx(AnimatePresence, {
|
|
6126
|
+
children: [trigger, /* @__PURE__ */ jsx(lib.AnimatePresence, {
|
|
7810
6127
|
initial: false,
|
|
7811
6128
|
children: open && /* @__PURE__ */ jsx(Collapsible.Content, {
|
|
7812
6129
|
forceMount: true,
|
|
7813
6130
|
asChild: true,
|
|
7814
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
6131
|
+
children: /* @__PURE__ */ jsx(lib.m.div, {
|
|
7815
6132
|
className: "overflow-hidden",
|
|
7816
6133
|
initial: {
|
|
7817
6134
|
height: 0,
|
|
@@ -7838,7 +6155,8 @@ function MobileDetails({ children }) {
|
|
|
7838
6155
|
}
|
|
7839
6156
|
function Table({ data: dataProp, source, queryKey = "", columns: columnsProp, statusLast = true, getRowId, selectable, expandable, sortable = true, globalFilter, columnVisibility, bulkActions, bulkMenu, rowActions, density = "default", loading, error, onRetry, empty, pageSize: pageSizeProp = 15, mobilePagination = "pages", toolbar, ...aria }) {
|
|
7840
6157
|
const { isMobile } = useBreakpoint();
|
|
7841
|
-
const
|
|
6158
|
+
const lib = useMotionLib();
|
|
6159
|
+
const on = lib !== null;
|
|
7842
6160
|
const presets = useMotionPresets();
|
|
7843
6161
|
const columns = useMemo(() => statusLast ? [...columnsProp.filter((c) => c.kind !== "badge"), ...columnsProp.filter((c) => c.kind === "badge")] : columnsProp, [columnsProp, statusLast]);
|
|
7844
6162
|
const [sorting, setSorting] = useState([]);
|
|
@@ -8259,14 +6577,14 @@ function Table({ data: dataProp, source, queryKey = "", columns: columnsProp, st
|
|
|
8259
6577
|
children: expandable(row)
|
|
8260
6578
|
})
|
|
8261
6579
|
}),
|
|
8262
|
-
expandable && on && /* @__PURE__ */ jsx(AnimatePresence, {
|
|
6580
|
+
expandable && on && /* @__PURE__ */ jsx(lib.AnimatePresence, {
|
|
8263
6581
|
initial: false,
|
|
8264
6582
|
children: r.getIsExpanded() && /* @__PURE__ */ jsx("tr", {
|
|
8265
6583
|
className: "bg-muted/30",
|
|
8266
6584
|
children: /* @__PURE__ */ jsx("td", {
|
|
8267
6585
|
colSpan: visibleCols.length + (selectable ? 1 : 0) + 1 + (rowActions ? 1 : 0),
|
|
8268
6586
|
className: "px-4",
|
|
8269
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
6587
|
+
children: /* @__PURE__ */ jsx(lib.m.div, {
|
|
8270
6588
|
className: "overflow-hidden",
|
|
8271
6589
|
initial: {
|
|
8272
6590
|
height: 0,
|
|
@@ -8386,94 +6704,6 @@ var Textarea = forwardRef(function Textarea({ invalid, counter, value, defaultVa
|
|
|
8386
6704
|
});
|
|
8387
6705
|
});
|
|
8388
6706
|
//#endregion
|
|
8389
|
-
//#region src/components/ui/timeline.tsx
|
|
8390
|
-
var dot = {
|
|
8391
|
-
neutral: "bg-muted text-muted-foreground",
|
|
8392
|
-
info: "bg-info-soft text-info-soft-foreground",
|
|
8393
|
-
success: "bg-success-soft text-success-soft-foreground",
|
|
8394
|
-
warning: "bg-warning-soft text-warning-soft-foreground",
|
|
8395
|
-
error: "bg-destructive-soft text-destructive-soft-foreground"
|
|
8396
|
-
};
|
|
8397
|
-
var statusTone = {
|
|
8398
|
-
succeeded: "success",
|
|
8399
|
-
failed: "error",
|
|
8400
|
-
skipped: "neutral"
|
|
8401
|
-
};
|
|
8402
|
-
var statusIcon = {
|
|
8403
|
-
succeeded: CheckCircle2,
|
|
8404
|
-
failed: XCircle,
|
|
8405
|
-
skipped: SkipForward
|
|
8406
|
-
};
|
|
8407
|
-
var statusLabel$1 = {
|
|
8408
|
-
succeeded: "Concluído",
|
|
8409
|
-
failed: "Falhou",
|
|
8410
|
-
skipped: "Ignorado"
|
|
8411
|
-
};
|
|
8412
|
-
var statusTextTone = {
|
|
8413
|
-
succeeded: "text-success-soft-foreground",
|
|
8414
|
-
failed: "text-destructive-soft-foreground",
|
|
8415
|
-
skipped: "text-muted-foreground"
|
|
8416
|
-
};
|
|
8417
|
-
/** Linha do tempo única, com eventos em ordem e tom semântico por evento. */
|
|
8418
|
-
function Timeline({ events, className }) {
|
|
8419
|
-
const on = useMotionMode() === "on";
|
|
8420
|
-
const presets = useMotionPresets();
|
|
8421
|
-
const Item = on ? m.li : "li";
|
|
8422
|
-
const enter = presets.slide("bottom", "short");
|
|
8423
|
-
return /* @__PURE__ */ jsx("ol", {
|
|
8424
|
-
"data-rendra": "TLN-001",
|
|
8425
|
-
className: cn("@container flex flex-col", className),
|
|
8426
|
-
children: events.map((e, i) => {
|
|
8427
|
-
const StatusIcon = e.status ? statusIcon[e.status] : null;
|
|
8428
|
-
const tone = e.tone ?? (e.status ? statusTone[e.status] : "neutral");
|
|
8429
|
-
return /* @__PURE__ */ jsxs(Item, {
|
|
8430
|
-
className: "relative flex gap-3 pb-6 last:pb-0",
|
|
8431
|
-
...on ? {
|
|
8432
|
-
...enter,
|
|
8433
|
-
transition: {
|
|
8434
|
-
...enter.transition,
|
|
8435
|
-
...presets.stagger(i)
|
|
8436
|
-
}
|
|
8437
|
-
} : {},
|
|
8438
|
-
children: [
|
|
8439
|
-
i < events.length - 1 && /* @__PURE__ */ jsx("span", {
|
|
8440
|
-
"aria-hidden": true,
|
|
8441
|
-
className: "absolute top-8 bottom-0 left-4 w-px -translate-x-1/2 bg-border"
|
|
8442
|
-
}),
|
|
8443
|
-
/* @__PURE__ */ jsx("span", {
|
|
8444
|
-
"aria-hidden": true,
|
|
8445
|
-
className: cn("relative flex size-8 shrink-0 items-center justify-center rounded-full [&_svg]:size-icon-sm", dot[tone]),
|
|
8446
|
-
children: e.icon ?? (StatusIcon && /* @__PURE__ */ jsx(StatusIcon, {})) ?? /* @__PURE__ */ jsx("span", { className: "size-2 rounded-full bg-current" })
|
|
8447
|
-
}),
|
|
8448
|
-
/* @__PURE__ */ jsxs("div", {
|
|
8449
|
-
className: "flex min-w-0 flex-1 flex-col gap-1 pt-1",
|
|
8450
|
-
children: [
|
|
8451
|
-
/* @__PURE__ */ jsxs("div", {
|
|
8452
|
-
className: "flex min-w-0 flex-col gap-1 @sm:flex-row @sm:items-baseline @sm:justify-between @sm:gap-3",
|
|
8453
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
8454
|
-
className: "text-sm font-medium wrap-break-word",
|
|
8455
|
-
children: e.title
|
|
8456
|
-
}), /* @__PURE__ */ jsx("time", {
|
|
8457
|
-
className: "shrink-0 text-xs text-muted-foreground tabular-nums",
|
|
8458
|
-
children: e.date
|
|
8459
|
-
})]
|
|
8460
|
-
}),
|
|
8461
|
-
e.description && /* @__PURE__ */ jsx("p", {
|
|
8462
|
-
className: "text-sm wrap-break-word text-muted-foreground",
|
|
8463
|
-
children: e.description
|
|
8464
|
-
}),
|
|
8465
|
-
e.status && StatusIcon && /* @__PURE__ */ jsxs("span", {
|
|
8466
|
-
className: cn("inline-flex w-fit items-center gap-1 text-xs font-medium [&_svg]:size-icon-sm", statusTextTone[e.status]),
|
|
8467
|
-
children: [/* @__PURE__ */ jsx(StatusIcon, {}), statusLabel$1[e.status]]
|
|
8468
|
-
})
|
|
8469
|
-
]
|
|
8470
|
-
})
|
|
8471
|
-
]
|
|
8472
|
-
}, e.id);
|
|
8473
|
-
})
|
|
8474
|
-
});
|
|
8475
|
-
}
|
|
8476
|
-
//#endregion
|
|
8477
6707
|
//#region src/components/ui/toast.tsx
|
|
8478
6708
|
var tone = {
|
|
8479
6709
|
success: "border-success/25",
|
|
@@ -8680,9 +6910,10 @@ function Upload({ accept, multiple = true, maxSizeMb = 10, onUpload, onChange, h
|
|
|
8680
6910
|
}
|
|
8681
6911
|
});
|
|
8682
6912
|
const motion = useMotionMode();
|
|
6913
|
+
const lib = useMotionLib();
|
|
8683
6914
|
const ready = useLayoutReady();
|
|
8684
6915
|
const presets = useMotionPresets();
|
|
8685
|
-
const Item =
|
|
6916
|
+
const Item = lib ? lib.m.li : "li";
|
|
8686
6917
|
const itemMotion = motion === "on" ? {
|
|
8687
6918
|
...presets.fade,
|
|
8688
6919
|
layout: layoutEnabled({
|
|
@@ -8695,7 +6926,7 @@ function Upload({ accept, multiple = true, maxSizeMb = 10, onUpload, onChange, h
|
|
|
8695
6926
|
layout: presets.move
|
|
8696
6927
|
}
|
|
8697
6928
|
} : {};
|
|
8698
|
-
const animated = (nodes) =>
|
|
6929
|
+
const animated = (nodes) => lib ? /* @__PURE__ */ jsx(lib.AnimatePresence, {
|
|
8699
6930
|
mode: "popLayout",
|
|
8700
6931
|
initial: false,
|
|
8701
6932
|
children: nodes
|
|
@@ -8944,7 +7175,7 @@ var statusLabel = {
|
|
|
8944
7175
|
*/
|
|
8945
7176
|
function Stepper({ steps, current, errors = [], orientation = "horizontal", onStepClick, className }) {
|
|
8946
7177
|
const step = steps[current];
|
|
8947
|
-
const
|
|
7178
|
+
const lib = useMotionLib();
|
|
8948
7179
|
const presets = useMotionPresets();
|
|
8949
7180
|
return /* @__PURE__ */ jsxs("div", {
|
|
8950
7181
|
"data-rendra": "WIZ-002",
|
|
@@ -8985,7 +7216,7 @@ function Stepper({ steps, current, errors = [], orientation = "horizontal", onSt
|
|
|
8985
7216
|
const clickable = onStepClick && st === "complete";
|
|
8986
7217
|
const circle = /* @__PURE__ */ jsx("span", {
|
|
8987
7218
|
className: cn("flex size-8 shrink-0 items-center justify-center rounded-full border-2 text-sm font-semibold tabular-nums transition-colors", st === "complete" && "border-primary bg-primary text-primary-foreground", st === "current" && "border-primary bg-card text-primary-text", st === "pending" && "border-border bg-card text-muted-foreground", st === "error" && "border-destructive bg-destructive text-destructive-foreground"),
|
|
8988
|
-
children: st === "complete" ?
|
|
7219
|
+
children: st === "complete" ? lib ? /* @__PURE__ */ jsx(lib.m.span, {
|
|
8989
7220
|
className: "flex",
|
|
8990
7221
|
...presets.pop,
|
|
8991
7222
|
children: /* @__PURE__ */ jsx(Check, {
|
|
@@ -9075,17 +7306,17 @@ function Wizard({ steps, children, onValidateStep, onFinish, onCancel, cancelLab
|
|
|
9075
7306
|
setCurrent((c) => c + 1);
|
|
9076
7307
|
onSkip?.();
|
|
9077
7308
|
};
|
|
9078
|
-
const
|
|
7309
|
+
const lib = useMotionLib();
|
|
9079
7310
|
const presets = useMotionPresets();
|
|
9080
7311
|
const previous = useRef(current);
|
|
9081
7312
|
const direction = current >= previous.current ? 1 : -1;
|
|
9082
7313
|
previous.current = current;
|
|
9083
|
-
const body =
|
|
7314
|
+
const body = lib ? /* @__PURE__ */ jsx("div", {
|
|
9084
7315
|
className: "relative flex min-w-0 flex-col gap-6",
|
|
9085
|
-
children: /* @__PURE__ */ jsx(AnimatePresence, {
|
|
7316
|
+
children: /* @__PURE__ */ jsx(lib.AnimatePresence, {
|
|
9086
7317
|
mode: "popLayout",
|
|
9087
7318
|
initial: false,
|
|
9088
|
-
children: /* @__PURE__ */ jsx(m.div, {
|
|
7319
|
+
children: /* @__PURE__ */ jsx(lib.m.div, {
|
|
9089
7320
|
...presets.swap(direction),
|
|
9090
7321
|
className: "flex min-w-0 flex-col gap-6",
|
|
9091
7322
|
children: children[current]
|