@freitas-ds/react 0.1.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/LICENSE +21 -0
- package/README.md +32 -0
- package/dist/index.d.mts +1195 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2728 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +99 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2728 @@
|
|
|
1
|
+
import { AlertTriangle, ArrowUpDown, CalendarIcon, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, ChevronsUpDown, Circle, CircleAlert, CircleCheck, CircleX, Inbox, Info, LoaderCircle, LogOut, MoreHorizontal, Search, Settings, User, X } from "lucide-react";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { twMerge } from "tailwind-merge";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
8
|
+
import { cva } from "class-variance-authority";
|
|
9
|
+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
10
|
+
import { DayPicker } from "react-day-picker";
|
|
11
|
+
import { ptBR } from "react-day-picker/locale";
|
|
12
|
+
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
13
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
14
|
+
import { Command } from "cmdk";
|
|
15
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
16
|
+
import { format } from "date-fns";
|
|
17
|
+
import { ptBR as ptBR$1 } from "date-fns/locale";
|
|
18
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
19
|
+
import { useForm } from "@tanstack/react-form";
|
|
20
|
+
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
|
21
|
+
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
22
|
+
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
|
23
|
+
import * as SwitchPrimitive from "@radix-ui/react-switch";
|
|
24
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
25
|
+
import * as ToastPrimitive from "@radix-ui/react-toast";
|
|
26
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
27
|
+
import { applyTheme, resolveTheme } from "@freitas-ds/theme";
|
|
28
|
+
//#region src/utils/cn.ts
|
|
29
|
+
function cn(...inputs) {
|
|
30
|
+
return twMerge(clsx(inputs));
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/components/action-bar.tsx
|
|
34
|
+
function ActionBar({ selectedCount, label, onClearSelection, className, children, ...props }) {
|
|
35
|
+
if (selectedCount <= 0) return null;
|
|
36
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
37
|
+
className: cn("flex flex-col gap-3 rounded-fds-lg border border-primary/30 bg-primary-container p-3 text-on-primary-container", "sm:flex-row sm:items-center sm:justify-between", className),
|
|
38
|
+
...props,
|
|
39
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
40
|
+
className: "flex min-w-0 items-center gap-3",
|
|
41
|
+
children: [onClearSelection ? /* @__PURE__ */ jsx("button", {
|
|
42
|
+
type: "button",
|
|
43
|
+
onClick: onClearSelection,
|
|
44
|
+
className: cn("flex size-7 shrink-0 items-center justify-center rounded-fds-md", "text-on-primary-container/80 transition-colors", "hover:bg-primary/10 hover:text-on-primary-container", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/35"),
|
|
45
|
+
"aria-label": "Limpar seleção",
|
|
46
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4" })
|
|
47
|
+
}) : null, /* @__PURE__ */ jsx("p", {
|
|
48
|
+
className: "body-sm font-medium",
|
|
49
|
+
children: label ?? `${selectedCount} item(ns) selecionado(s)`
|
|
50
|
+
})]
|
|
51
|
+
}), children ? /* @__PURE__ */ jsx("div", {
|
|
52
|
+
className: "flex flex-wrap items-center gap-2",
|
|
53
|
+
children
|
|
54
|
+
}) : null]
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/components/alert.tsx
|
|
59
|
+
const alertToneClasses = {
|
|
60
|
+
neutral: "border-border bg-muted text-on-surface",
|
|
61
|
+
info: "border-info/30 bg-info-container text-on-info-container",
|
|
62
|
+
success: "border-success/30 bg-success-container text-on-success-container",
|
|
63
|
+
warning: "border-warning/30 bg-warning-container text-on-warning-container",
|
|
64
|
+
danger: "border-error/30 bg-error-container text-on-error-container"
|
|
65
|
+
};
|
|
66
|
+
const iconToneClasses = {
|
|
67
|
+
neutral: "text-muted-foreground",
|
|
68
|
+
info: "text-info",
|
|
69
|
+
success: "text-success",
|
|
70
|
+
warning: "text-warning",
|
|
71
|
+
danger: "text-error"
|
|
72
|
+
};
|
|
73
|
+
const defaultIcons = {
|
|
74
|
+
neutral: /* @__PURE__ */ jsx(Info, { className: "size-4" }),
|
|
75
|
+
info: /* @__PURE__ */ jsx(Info, { className: "size-4" }),
|
|
76
|
+
success: /* @__PURE__ */ jsx(CircleCheck, { className: "size-4" }),
|
|
77
|
+
warning: /* @__PURE__ */ jsx(CircleAlert, { className: "size-4" }),
|
|
78
|
+
danger: /* @__PURE__ */ jsx(CircleX, { className: "size-4" })
|
|
79
|
+
};
|
|
80
|
+
function Alert({ className, tone = "info", title, description, icon, children, ...props }) {
|
|
81
|
+
const currentIcon = icon === false ? null : icon ?? defaultIcons[tone];
|
|
82
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
83
|
+
role: "status",
|
|
84
|
+
className: cn("relative flex gap-3 rounded-fds-lg border p-4", alertToneClasses[tone], className),
|
|
85
|
+
...props,
|
|
86
|
+
children: [currentIcon ? /* @__PURE__ */ jsx("div", {
|
|
87
|
+
className: cn("mt-0.5 shrink-0", iconToneClasses[tone]),
|
|
88
|
+
children: currentIcon
|
|
89
|
+
}) : null, /* @__PURE__ */ jsxs("div", {
|
|
90
|
+
className: "min-w-0 flex-1",
|
|
91
|
+
children: [
|
|
92
|
+
title ? /* @__PURE__ */ jsx("h3", {
|
|
93
|
+
className: "body-sm font-semibold leading-5",
|
|
94
|
+
children: title
|
|
95
|
+
}) : null,
|
|
96
|
+
description ? /* @__PURE__ */ jsx("p", {
|
|
97
|
+
className: cn("body-sm", title && "mt-1"),
|
|
98
|
+
children: description
|
|
99
|
+
}) : null,
|
|
100
|
+
children ? /* @__PURE__ */ jsx("div", {
|
|
101
|
+
className: title || description ? "mt-2" : "",
|
|
102
|
+
children
|
|
103
|
+
}) : null
|
|
104
|
+
]
|
|
105
|
+
})]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/components/button.tsx
|
|
110
|
+
const buttonVariants = cva([
|
|
111
|
+
"inline-flex items-center justify-center gap-2",
|
|
112
|
+
"rounded-fds-md",
|
|
113
|
+
"font-medium",
|
|
114
|
+
"transition-colors duration-150",
|
|
115
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface",
|
|
116
|
+
"disabled:pointer-events-none disabled:opacity-50"
|
|
117
|
+
], {
|
|
118
|
+
variants: {
|
|
119
|
+
variant: {
|
|
120
|
+
primary: "bg-primary text-on-primary hover:brightness-95",
|
|
121
|
+
secondary: "bg-secondary text-on-secondary hover:brightness-95",
|
|
122
|
+
tertiary: "bg-tertiary text-on-tertiary hover:brightness-95",
|
|
123
|
+
danger: "bg-error text-on-error hover:brightness-95",
|
|
124
|
+
outline: "border border-outline bg-transparent text-on-surface hover:bg-surface-container",
|
|
125
|
+
ghost: "bg-transparent text-on-surface hover:bg-surface-container"
|
|
126
|
+
},
|
|
127
|
+
size: {
|
|
128
|
+
sm: "h-8 px-3 text-sm",
|
|
129
|
+
md: "h-10 px-4 text-sm",
|
|
130
|
+
lg: "h-12 px-6 text-base"
|
|
131
|
+
},
|
|
132
|
+
fullWidth: {
|
|
133
|
+
true: "w-full",
|
|
134
|
+
false: ""
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
defaultVariants: {
|
|
138
|
+
variant: "primary",
|
|
139
|
+
size: "md",
|
|
140
|
+
fullWidth: false
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
const Button = React.forwardRef(({ className, variant, size, fullWidth, loading = false, disabled, asChild = false, children, ...props }, ref) => {
|
|
144
|
+
return /* @__PURE__ */ jsx(asChild ? Slot : "button", {
|
|
145
|
+
ref,
|
|
146
|
+
className: cn(buttonVariants({
|
|
147
|
+
variant,
|
|
148
|
+
size,
|
|
149
|
+
fullWidth
|
|
150
|
+
}), className),
|
|
151
|
+
disabled: disabled || loading,
|
|
152
|
+
"aria-busy": loading,
|
|
153
|
+
...props,
|
|
154
|
+
children: loading ? "Carregando..." : children
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
Button.displayName = "Button";
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/components/alert-dialog.tsx
|
|
160
|
+
const AlertDialog = AlertDialogPrimitive.Root;
|
|
161
|
+
const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
|
|
162
|
+
const AlertDialogPortal = AlertDialogPrimitive.Portal;
|
|
163
|
+
const AlertDialogCancel = AlertDialogPrimitive.Cancel;
|
|
164
|
+
const AlertDialogAction = AlertDialogPrimitive.Action;
|
|
165
|
+
const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => {
|
|
166
|
+
return /* @__PURE__ */ jsx(AlertDialogPrimitive.Overlay, {
|
|
167
|
+
ref,
|
|
168
|
+
className: cn("fixed inset-0 z-50 bg-black/45", "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0", className),
|
|
169
|
+
...props
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
|
173
|
+
const AlertDialogContent = React.forwardRef(({ className, ...props }, ref) => {
|
|
174
|
+
return /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [/* @__PURE__ */ jsx(AlertDialogOverlay, {}), /* @__PURE__ */ jsx(AlertDialogPrimitive.Content, {
|
|
175
|
+
ref,
|
|
176
|
+
className: cn("fixed left-1/2 top-1/2 z-50 grid w-[calc(100%-2rem)] max-w-md", "-translate-x-1/2 -translate-y-1/2 gap-4", "rounded-fds-lg border border-border bg-popover p-6 text-popover-foreground shadow-lg", "duration-200", "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0", "data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95", className),
|
|
177
|
+
...props
|
|
178
|
+
})] });
|
|
179
|
+
});
|
|
180
|
+
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
|
|
181
|
+
function AlertDialogHeader({ className, ...props }) {
|
|
182
|
+
return /* @__PURE__ */ jsx("div", {
|
|
183
|
+
className: cn("flex flex-col gap-1.5 text-left", className),
|
|
184
|
+
...props
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
function AlertDialogFooter({ className, ...props }) {
|
|
188
|
+
return /* @__PURE__ */ jsx("div", {
|
|
189
|
+
className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
|
|
190
|
+
...props
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => {
|
|
194
|
+
return /* @__PURE__ */ jsx(AlertDialogPrimitive.Title, {
|
|
195
|
+
ref,
|
|
196
|
+
className: cn("h3 text-on-surface", className),
|
|
197
|
+
...props
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
|
201
|
+
const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => {
|
|
202
|
+
return /* @__PURE__ */ jsx(AlertDialogPrimitive.Description, {
|
|
203
|
+
ref,
|
|
204
|
+
className: cn("body-sm text-muted", className),
|
|
205
|
+
...props
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
|
|
209
|
+
function AlertDialogCancelButton({ className, ...props }) {
|
|
210
|
+
return /* @__PURE__ */ jsx(AlertDialogPrimitive.Cancel, {
|
|
211
|
+
className: cn(buttonVariants({
|
|
212
|
+
variant: "outline",
|
|
213
|
+
size: "md"
|
|
214
|
+
}), className),
|
|
215
|
+
...props
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
function AlertDialogActionButton({ className, variant = "danger", ...props }) {
|
|
219
|
+
return /* @__PURE__ */ jsx(AlertDialogPrimitive.Action, {
|
|
220
|
+
className: cn(buttonVariants({
|
|
221
|
+
variant,
|
|
222
|
+
size: "md"
|
|
223
|
+
}), className),
|
|
224
|
+
...props
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/components/app-shell.tsx
|
|
229
|
+
function AppShell({ sidebar, topbar, children, className, ...props }) {
|
|
230
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
231
|
+
className: cn("h-dvh overflow-hidden bg-surface text-on-surface", "grid grid-cols-1 md:grid-cols-[16rem_minmax(0,1fr)]", className),
|
|
232
|
+
...props,
|
|
233
|
+
children: [sidebar ? /* @__PURE__ */ jsx("aside", {
|
|
234
|
+
className: "hidden h-dvh min-h-0 overflow-hidden border-r border-border bg-card md:block",
|
|
235
|
+
children: sidebar
|
|
236
|
+
}) : null, /* @__PURE__ */ jsxs("div", {
|
|
237
|
+
className: "flex min-h-0 min-w-0 flex-col",
|
|
238
|
+
children: [topbar ? /* @__PURE__ */ jsx("header", {
|
|
239
|
+
className: "shrink-0 border-b border-border bg-surface/90 backdrop-blur",
|
|
240
|
+
children: topbar
|
|
241
|
+
}) : null, /* @__PURE__ */ jsx("main", {
|
|
242
|
+
className: "min-h-0 min-w-0 flex-1 overflow-y-auto",
|
|
243
|
+
children
|
|
244
|
+
})]
|
|
245
|
+
})]
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
function AppShellContent({ className, ...props }) {
|
|
249
|
+
return /* @__PURE__ */ jsx("div", {
|
|
250
|
+
className: cn("mx-auto flex w-full max-w-6xl flex-col gap-8 px-6 py-8", className),
|
|
251
|
+
...props
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/components/avatar.tsx
|
|
256
|
+
const Avatar = React.forwardRef(({ className, ...props }, ref) => {
|
|
257
|
+
return /* @__PURE__ */ jsx(AvatarPrimitive.Root, {
|
|
258
|
+
ref,
|
|
259
|
+
className: cn("relative flex size-10 shrink-0 overflow-hidden rounded-fds-full", className),
|
|
260
|
+
...props
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
264
|
+
const AvatarImage = React.forwardRef(({ className, ...props }, ref) => {
|
|
265
|
+
return /* @__PURE__ */ jsx(AvatarPrimitive.Image, {
|
|
266
|
+
ref,
|
|
267
|
+
className: cn("aspect-square size-full object-cover", className),
|
|
268
|
+
...props
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
272
|
+
const AvatarFallback = React.forwardRef(({ className, ...props }, ref) => {
|
|
273
|
+
return /* @__PURE__ */ jsx(AvatarPrimitive.Fallback, {
|
|
274
|
+
ref,
|
|
275
|
+
className: cn("flex size-full items-center justify-center rounded-fds-full", "bg-primary-container text-sm font-semibold text-on-primary-container", className),
|
|
276
|
+
...props
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
280
|
+
function getInitials(name) {
|
|
281
|
+
return name.trim().split(/\s+/).slice(0, 2).map((part) => part[0]?.toUpperCase()).join("");
|
|
282
|
+
}
|
|
283
|
+
//#endregion
|
|
284
|
+
//#region src/components/badge.tsx
|
|
285
|
+
const badgeVariants = cva([
|
|
286
|
+
"inline-flex w-fit shrink-0 items-center gap-1",
|
|
287
|
+
"rounded-fds-full border px-2 py-0.5",
|
|
288
|
+
"text-xs font-medium leading-5",
|
|
289
|
+
"transition-colors duration-150"
|
|
290
|
+
], {
|
|
291
|
+
variants: {
|
|
292
|
+
tone: {
|
|
293
|
+
neutral: "border-border bg-muted text-muted-foreground",
|
|
294
|
+
primary: "border-transparent bg-primary-container text-on-primary-container",
|
|
295
|
+
secondary: "border-transparent bg-secondary-container text-on-secondary-container",
|
|
296
|
+
success: "border-transparent bg-success-container text-on-success-container",
|
|
297
|
+
warning: "border-transparent bg-warning-container text-on-warning-container",
|
|
298
|
+
info: "border-transparent bg-info-container text-on-info-container",
|
|
299
|
+
danger: "border-transparent bg-error-container text-on-error-container"
|
|
300
|
+
},
|
|
301
|
+
variant: {
|
|
302
|
+
soft: "",
|
|
303
|
+
outline: "bg-transparent",
|
|
304
|
+
solid: ""
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
compoundVariants: [
|
|
308
|
+
{
|
|
309
|
+
tone: "primary",
|
|
310
|
+
variant: "solid",
|
|
311
|
+
className: "border-transparent bg-primary text-on-primary"
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
tone: "secondary",
|
|
315
|
+
variant: "solid",
|
|
316
|
+
className: "border-transparent bg-secondary text-on-secondary"
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
tone: "success",
|
|
320
|
+
variant: "solid",
|
|
321
|
+
className: "border-transparent bg-success text-on-success"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
tone: "warning",
|
|
325
|
+
variant: "solid",
|
|
326
|
+
className: "border-transparent bg-warning text-on-warning"
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
tone: "info",
|
|
330
|
+
variant: "solid",
|
|
331
|
+
className: "border-transparent bg-info text-on-info"
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
tone: "danger",
|
|
335
|
+
variant: "solid",
|
|
336
|
+
className: "border-transparent bg-error text-on-error"
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
tone: "neutral",
|
|
340
|
+
variant: "outline",
|
|
341
|
+
className: "border-border text-on-surface"
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
tone: "primary",
|
|
345
|
+
variant: "outline",
|
|
346
|
+
className: "border-primary text-primary"
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
tone: "secondary",
|
|
350
|
+
variant: "outline",
|
|
351
|
+
className: "border-secondary text-secondary"
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
tone: "success",
|
|
355
|
+
variant: "outline",
|
|
356
|
+
className: "border-success text-success"
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
tone: "warning",
|
|
360
|
+
variant: "outline",
|
|
361
|
+
className: "border-warning text-warning"
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
tone: "info",
|
|
365
|
+
variant: "outline",
|
|
366
|
+
className: "border-info text-info"
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
tone: "danger",
|
|
370
|
+
variant: "outline",
|
|
371
|
+
className: "border-error text-error"
|
|
372
|
+
}
|
|
373
|
+
],
|
|
374
|
+
defaultVariants: {
|
|
375
|
+
tone: "neutral",
|
|
376
|
+
variant: "soft"
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
function Badge({ className, tone, variant, ...props }) {
|
|
380
|
+
return /* @__PURE__ */ jsx("span", {
|
|
381
|
+
className: cn(badgeVariants({
|
|
382
|
+
tone,
|
|
383
|
+
variant
|
|
384
|
+
}), className),
|
|
385
|
+
...props
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/components/breadcrumb.tsx
|
|
390
|
+
function Breadcrumb({ className, ...props }) {
|
|
391
|
+
return /* @__PURE__ */ jsx("nav", {
|
|
392
|
+
"aria-label": "Breadcrumb",
|
|
393
|
+
className: cn("flex", className),
|
|
394
|
+
...props
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
function BreadcrumbList({ className, ...props }) {
|
|
398
|
+
return /* @__PURE__ */ jsx("ol", {
|
|
399
|
+
className: cn("flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground", className),
|
|
400
|
+
...props
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
function BreadcrumbItem({ className, ...props }) {
|
|
404
|
+
return /* @__PURE__ */ jsx("li", {
|
|
405
|
+
className: cn("inline-flex items-center gap-1.5", className),
|
|
406
|
+
...props
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
function BreadcrumbLink({ className, ...props }) {
|
|
410
|
+
return /* @__PURE__ */ jsx("a", {
|
|
411
|
+
className: cn("transition-colors hover:text-on-surface", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35", className),
|
|
412
|
+
...props
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
function BreadcrumbPage({ className, ...props }) {
|
|
416
|
+
return /* @__PURE__ */ jsx("span", {
|
|
417
|
+
"aria-current": "page",
|
|
418
|
+
className: cn("font-medium text-on-surface", className),
|
|
419
|
+
...props
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
function BreadcrumbSeparator({ children, className, ...props }) {
|
|
423
|
+
return /* @__PURE__ */ jsx("li", {
|
|
424
|
+
role: "presentation",
|
|
425
|
+
"aria-hidden": "true",
|
|
426
|
+
className: cn("text-muted-foreground", className),
|
|
427
|
+
...props,
|
|
428
|
+
children: children ?? /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" })
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
function BreadcrumbEllipsis({ className, ...props }) {
|
|
432
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
433
|
+
role: "presentation",
|
|
434
|
+
"aria-hidden": "true",
|
|
435
|
+
className: cn("flex size-9 items-center justify-center", className),
|
|
436
|
+
...props,
|
|
437
|
+
children: [/* @__PURE__ */ jsx(MoreHorizontal, { className: "size-4" }), /* @__PURE__ */ jsx("span", {
|
|
438
|
+
className: "sr-only",
|
|
439
|
+
children: "Mais"
|
|
440
|
+
})]
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
//#endregion
|
|
444
|
+
//#region src/components/calendar.tsx
|
|
445
|
+
function Calendar({ className, classNames, locale = ptBR, showOutsideDays = true, navLayout = "after", components, ...props }) {
|
|
446
|
+
return /* @__PURE__ */ jsx(DayPicker, {
|
|
447
|
+
locale,
|
|
448
|
+
showOutsideDays,
|
|
449
|
+
navLayout,
|
|
450
|
+
className: cn("p-3", className),
|
|
451
|
+
classNames: {
|
|
452
|
+
root: "w-fit",
|
|
453
|
+
months: "flex flex-col gap-4",
|
|
454
|
+
month: "space-y-4",
|
|
455
|
+
month_caption: "flex h-8 items-center justify-center px-8",
|
|
456
|
+
caption_label: "body-sm font-semibold text-on-surface",
|
|
457
|
+
nav: "absolute right-3 top-3 flex items-center gap-1",
|
|
458
|
+
button_previous: cn(buttonVariants({
|
|
459
|
+
variant: "ghost",
|
|
460
|
+
size: "sm"
|
|
461
|
+
}), "size-8 p-0"),
|
|
462
|
+
button_next: cn(buttonVariants({
|
|
463
|
+
variant: "ghost",
|
|
464
|
+
size: "sm"
|
|
465
|
+
}), "size-8 p-0"),
|
|
466
|
+
month_grid: "w-full border-collapse space-y-1",
|
|
467
|
+
weekdays: "flex",
|
|
468
|
+
weekday: "flex size-9 items-center justify-center rounded-fds-sm caption font-medium text-muted",
|
|
469
|
+
week: "mt-1 flex w-full",
|
|
470
|
+
day: "size-9 p-0 text-center body-sm",
|
|
471
|
+
day_button: cn("flex size-9 items-center justify-center rounded-fds-md body-sm outline-none", "transition-colors duration-150", "hover:bg-accent hover:text-accent-foreground", "focus-visible:ring-2 focus-visible:ring-ring/35"),
|
|
472
|
+
selected: "[&>button]:bg-primary [&>button]:text-on-primary",
|
|
473
|
+
today: "[&>button]:border [&>button]:border-primary",
|
|
474
|
+
outside: "text-muted opacity-45",
|
|
475
|
+
disabled: "pointer-events-none text-muted opacity-35",
|
|
476
|
+
range_start: "[&>button]:rounded-r-none [&>button]:bg-primary [&>button]:text-on-primary",
|
|
477
|
+
range_middle: "[&>button]:rounded-none [&>button]:bg-primary-container [&>button]:text-on-primary-container",
|
|
478
|
+
range_end: "[&>button]:rounded-l-none [&>button]:bg-primary [&>button]:text-on-primary",
|
|
479
|
+
hidden: "invisible",
|
|
480
|
+
...classNames
|
|
481
|
+
},
|
|
482
|
+
components: {
|
|
483
|
+
Chevron: ({ orientation, className, ...iconProps }) => orientation === "left" ? /* @__PURE__ */ jsx(ChevronLeft, {
|
|
484
|
+
className: cn("size-4", className),
|
|
485
|
+
...iconProps
|
|
486
|
+
}) : /* @__PURE__ */ jsx(ChevronRight, {
|
|
487
|
+
className: cn("size-4", className),
|
|
488
|
+
...iconProps
|
|
489
|
+
}),
|
|
490
|
+
...components
|
|
491
|
+
},
|
|
492
|
+
...props
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
//#endregion
|
|
496
|
+
//#region src/components/card.tsx
|
|
497
|
+
function Card({ className, ...props }) {
|
|
498
|
+
return /* @__PURE__ */ jsx("div", {
|
|
499
|
+
className: cn("rounded-fds-lg border border-border bg-card text-card-foreground shadow-sm", "p-6", className),
|
|
500
|
+
...props
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
function CardHeader({ className, ...props }) {
|
|
504
|
+
return /* @__PURE__ */ jsx("div", {
|
|
505
|
+
className: cn("mb-5 flex flex-col gap-1.5", className),
|
|
506
|
+
...props
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
function CardContent({ className, ...props }) {
|
|
510
|
+
return /* @__PURE__ */ jsx("div", {
|
|
511
|
+
className: cn("body", className),
|
|
512
|
+
...props
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
function CardFooter({ className, ...props }) {
|
|
516
|
+
return /* @__PURE__ */ jsx("div", {
|
|
517
|
+
className: cn("mt-6 flex flex-wrap items-center gap-3", className),
|
|
518
|
+
...props
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
//#endregion
|
|
522
|
+
//#region src/components/label.tsx
|
|
523
|
+
function Label({ className, children, required = false, requiredIndicator = "*", showRequiredIndicator = true, ...props }) {
|
|
524
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
525
|
+
className: cn("body-sm font-medium text-on-surface", "disabled:pointer-events-none disabled:opacity-50", className),
|
|
526
|
+
...props,
|
|
527
|
+
children: [children, required ? /* @__PURE__ */ jsxs(Fragment, { children: [showRequiredIndicator ? /* @__PURE__ */ jsxs(Fragment, { children: [" ", /* @__PURE__ */ jsx("span", {
|
|
528
|
+
className: "ml-1 text-error",
|
|
529
|
+
"aria-hidden": "true",
|
|
530
|
+
children: requiredIndicator
|
|
531
|
+
})] }) : null, /* @__PURE__ */ jsx("span", {
|
|
532
|
+
className: "sr-only",
|
|
533
|
+
children: " obrigatório"
|
|
534
|
+
})] }) : null]
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
//#endregion
|
|
538
|
+
//#region src/components/checkbox.tsx
|
|
539
|
+
const Checkbox = React.forwardRef(({ className, error = false, ...props }, ref) => {
|
|
540
|
+
return /* @__PURE__ */ jsx(CheckboxPrimitive.Root, {
|
|
541
|
+
ref,
|
|
542
|
+
className: cn("peer size-4 shrink-0 rounded-sm border border-input bg-transparent shadow-sm", "transition-[color,box-shadow,border-color,background-color] duration-150", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35", "disabled:cursor-not-allowed disabled:opacity-50", "data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-on-primary", error && "border-destructive focus-visible:ring-destructive/25 data-[state=checked]:border-destructive data-[state=checked]:bg-destructive data-[state=checked]:text-destructive-foreground", className),
|
|
543
|
+
...props,
|
|
544
|
+
children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, {
|
|
545
|
+
className: "flex items-center justify-center text-current",
|
|
546
|
+
children: /* @__PURE__ */ jsx(Check, { className: "size-3.5" })
|
|
547
|
+
})
|
|
548
|
+
});
|
|
549
|
+
});
|
|
550
|
+
Checkbox.displayName = "Checkbox";
|
|
551
|
+
function CheckboxField({ id, label, description, errorMessage, required, className, ...props }) {
|
|
552
|
+
const generatedId = React.useId();
|
|
553
|
+
const fieldId = id ?? generatedId;
|
|
554
|
+
const descriptionId = description ? `${fieldId}-description` : void 0;
|
|
555
|
+
const errorId = errorMessage ? `${fieldId}-error` : void 0;
|
|
556
|
+
const describedBy = [descriptionId, errorId].filter(Boolean).join(" ") || void 0;
|
|
557
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
558
|
+
className: cn("flex flex-col gap-1.5", className),
|
|
559
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
560
|
+
className: "flex items-start gap-3",
|
|
561
|
+
children: [/* @__PURE__ */ jsx(Checkbox, {
|
|
562
|
+
id: fieldId,
|
|
563
|
+
required,
|
|
564
|
+
"aria-describedby": describedBy,
|
|
565
|
+
"aria-invalid": errorMessage ? true : void 0,
|
|
566
|
+
error: Boolean(errorMessage),
|
|
567
|
+
...props
|
|
568
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
569
|
+
className: "grid gap-1 leading-none",
|
|
570
|
+
children: [/* @__PURE__ */ jsx(Label, {
|
|
571
|
+
htmlFor: fieldId,
|
|
572
|
+
required,
|
|
573
|
+
className: cn(props.disabled && "cursor-not-allowed opacity-60"),
|
|
574
|
+
children: label
|
|
575
|
+
}), description ? /* @__PURE__ */ jsx("p", {
|
|
576
|
+
id: descriptionId,
|
|
577
|
+
className: "caption text-muted",
|
|
578
|
+
children: description
|
|
579
|
+
}) : null]
|
|
580
|
+
})]
|
|
581
|
+
}), errorMessage ? /* @__PURE__ */ jsx("p", {
|
|
582
|
+
id: errorId,
|
|
583
|
+
className: "caption text-destructive",
|
|
584
|
+
role: "alert",
|
|
585
|
+
children: errorMessage
|
|
586
|
+
}) : null]
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
//#endregion
|
|
590
|
+
//#region src/components/combobox.tsx
|
|
591
|
+
function isGroupedOptions$1(options) {
|
|
592
|
+
return options.length > 0 && "options" in options[0];
|
|
593
|
+
}
|
|
594
|
+
function flattenOptions(options) {
|
|
595
|
+
if (isGroupedOptions$1(options)) return options.flatMap((group) => group.options);
|
|
596
|
+
return options;
|
|
597
|
+
}
|
|
598
|
+
const Combobox = React.forwardRef(({ id, name, value, defaultValue, onValueChange, placeholder = "Selecione uma opção", searchPlaceholder = "Buscar...", emptyMessage = "Nenhum resultado encontrado.", options, actions, disabled = false, required = false, className, contentClassName, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-label": ariaLabel }, ref) => {
|
|
599
|
+
const [open, setOpen] = React.useState(false);
|
|
600
|
+
const [internalValue, setInternalValue] = React.useState(defaultValue ?? "");
|
|
601
|
+
const selectedValue = value ?? internalValue;
|
|
602
|
+
const isInvalid = ariaInvalid === true || ariaInvalid === "true";
|
|
603
|
+
const selectedOption = React.useMemo(() => flattenOptions(options), [options]).find((option) => option.value === selectedValue);
|
|
604
|
+
function handleSelect(nextValue) {
|
|
605
|
+
if (value === void 0) setInternalValue(nextValue);
|
|
606
|
+
onValueChange?.(nextValue);
|
|
607
|
+
setOpen(false);
|
|
608
|
+
}
|
|
609
|
+
return /* @__PURE__ */ jsxs(PopoverPrimitive.Root, {
|
|
610
|
+
open,
|
|
611
|
+
onOpenChange: setOpen,
|
|
612
|
+
children: [
|
|
613
|
+
name ? /* @__PURE__ */ jsx("input", {
|
|
614
|
+
type: "hidden",
|
|
615
|
+
name,
|
|
616
|
+
value: selectedValue,
|
|
617
|
+
required
|
|
618
|
+
}) : null,
|
|
619
|
+
/* @__PURE__ */ jsx(PopoverPrimitive.Trigger, {
|
|
620
|
+
asChild: true,
|
|
621
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
622
|
+
ref,
|
|
623
|
+
id,
|
|
624
|
+
type: "button",
|
|
625
|
+
role: "combobox",
|
|
626
|
+
disabled,
|
|
627
|
+
"aria-label": ariaLabel ?? selectedOption?.label ?? placeholder,
|
|
628
|
+
"aria-haspopup": "listbox",
|
|
629
|
+
"aria-expanded": open,
|
|
630
|
+
"aria-describedby": ariaDescribedBy,
|
|
631
|
+
"aria-invalid": ariaInvalid,
|
|
632
|
+
"aria-required": required ? true : void 0,
|
|
633
|
+
className: cn("flex h-9 w-full items-center justify-between gap-2 whitespace-nowrap", "rounded-fds-md border border-input bg-transparent px-3 py-2", "body-sm text-on-surface shadow-sm outline-none", "transition-[color,box-shadow,border-color,background-color] duration-150", "hover:bg-accent", "focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/35", "disabled:cursor-not-allowed disabled:opacity-50", !selectedOption && "text-muted-foreground", isInvalid && "border-destructive focus-visible:border-destructive focus-visible:ring-destructive/25", className),
|
|
634
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
635
|
+
className: "min-w-0 truncate text-left",
|
|
636
|
+
children: selectedOption ? selectedOption.label : placeholder
|
|
637
|
+
}), /* @__PURE__ */ jsx(ChevronsUpDown, {
|
|
638
|
+
"aria-hidden": "true",
|
|
639
|
+
className: "size-4 shrink-0 text-muted-foreground opacity-70"
|
|
640
|
+
})]
|
|
641
|
+
})
|
|
642
|
+
}),
|
|
643
|
+
/* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(PopoverPrimitive.Content, {
|
|
644
|
+
align: "start",
|
|
645
|
+
sideOffset: 4,
|
|
646
|
+
className: cn("z-50 w-(--radix-popover-trigger-width) overflow-hidden", "rounded-fds-md border border-border bg-popover text-popover-foreground shadow-md", contentClassName),
|
|
647
|
+
children: /* @__PURE__ */ jsxs(Command, {
|
|
648
|
+
loop: true,
|
|
649
|
+
filter: (itemValue, search, keywords) => {
|
|
650
|
+
const normalizedSearch = search.toLowerCase().trim();
|
|
651
|
+
return [itemValue, ...keywords ?? []].join(" ").toLowerCase().includes(normalizedSearch) ? 1 : 0;
|
|
652
|
+
},
|
|
653
|
+
className: "flex max-h-80 w-full flex-col overflow-hidden",
|
|
654
|
+
children: [
|
|
655
|
+
/* @__PURE__ */ jsxs("div", {
|
|
656
|
+
className: "flex items-center border-b border-border px-3",
|
|
657
|
+
children: [/* @__PURE__ */ jsx(Search, {
|
|
658
|
+
"aria-hidden": "true",
|
|
659
|
+
className: "mr-2 size-4 shrink-0 text-muted-foreground"
|
|
660
|
+
}), /* @__PURE__ */ jsx(Command.Input, {
|
|
661
|
+
placeholder: searchPlaceholder,
|
|
662
|
+
className: cn("h-10 w-full bg-transparent py-3 text-sm outline-none", "placeholder:text-muted-foreground", "disabled:cursor-not-allowed disabled:opacity-50")
|
|
663
|
+
})]
|
|
664
|
+
}),
|
|
665
|
+
/* @__PURE__ */ jsxs(Command.List, {
|
|
666
|
+
className: "max-h-60 overflow-y-auto overflow-x-hidden p-1",
|
|
667
|
+
children: [/* @__PURE__ */ jsx(Command.Empty, {
|
|
668
|
+
className: "px-3 py-6 text-center text-sm text-muted-foreground",
|
|
669
|
+
children: emptyMessage
|
|
670
|
+
}), isGroupedOptions$1(options) ? options.map((group, groupIndex) => /* @__PURE__ */ jsxs(Command.Group, {
|
|
671
|
+
heading: group.label,
|
|
672
|
+
className: cn("[&_[cmdk-group-heading]]:px-2", "[&_[cmdk-group-heading]]:py-1.5", "[&_[cmdk-group-heading]]:caption", "[&_[cmdk-group-heading]]:mono", "[&_[cmdk-group-heading]]:uppercase", "[&_[cmdk-group-heading]]:tracking-[0.12em]", "[&_[cmdk-group-heading]]:text-muted-foreground"),
|
|
673
|
+
children: [groupIndex > 0 ? /* @__PURE__ */ jsx("div", { className: "my-1 h-px bg-border" }) : null, group.options.map((option) => /* @__PURE__ */ jsx(ComboboxItem, {
|
|
674
|
+
option,
|
|
675
|
+
selected: option.value === selectedValue,
|
|
676
|
+
onSelect: handleSelect
|
|
677
|
+
}, option.value))]
|
|
678
|
+
}, group.label)) : options.map((option) => /* @__PURE__ */ jsx(ComboboxItem, {
|
|
679
|
+
option,
|
|
680
|
+
selected: option.value === selectedValue,
|
|
681
|
+
onSelect: handleSelect
|
|
682
|
+
}, option.value))]
|
|
683
|
+
}),
|
|
684
|
+
actions ? /* @__PURE__ */ jsx("div", {
|
|
685
|
+
className: "border-t border-border p-1.5",
|
|
686
|
+
children: actions
|
|
687
|
+
}) : null
|
|
688
|
+
]
|
|
689
|
+
})
|
|
690
|
+
}) })
|
|
691
|
+
]
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
Combobox.displayName = "Combobox";
|
|
695
|
+
function ComboboxItem({ option, selected, onSelect }) {
|
|
696
|
+
return /* @__PURE__ */ jsxs(Command.Item, {
|
|
697
|
+
value: option.value,
|
|
698
|
+
keywords: [option.label, option.description ?? ""],
|
|
699
|
+
disabled: option.disabled,
|
|
700
|
+
onSelect: () => onSelect(option.value),
|
|
701
|
+
className: cn("relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 pr-8", "text-sm outline-none", "data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground", "data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50"),
|
|
702
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
703
|
+
className: "flex min-w-0 flex-col",
|
|
704
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
705
|
+
className: "truncate font-medium leading-5",
|
|
706
|
+
children: option.label
|
|
707
|
+
}), option.description ? /* @__PURE__ */ jsx("span", {
|
|
708
|
+
className: "truncate text-xs leading-4 text-muted-foreground",
|
|
709
|
+
children: option.description
|
|
710
|
+
}) : null]
|
|
711
|
+
}), selected ? /* @__PURE__ */ jsx(Check, { className: "absolute right-2 size-4 text-primary" }) : null]
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
//#endregion
|
|
715
|
+
//#region src/components/dialog.tsx
|
|
716
|
+
const Dialog = DialogPrimitive.Root;
|
|
717
|
+
const DialogTrigger = DialogPrimitive.Trigger;
|
|
718
|
+
const DialogPortal = DialogPrimitive.Portal;
|
|
719
|
+
const DialogClose = DialogPrimitive.Close;
|
|
720
|
+
const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => {
|
|
721
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Overlay, {
|
|
722
|
+
ref,
|
|
723
|
+
className: cn("fixed inset-0 z-50 bg-black/45", "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0", className),
|
|
724
|
+
...props
|
|
725
|
+
});
|
|
726
|
+
});
|
|
727
|
+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
728
|
+
const DialogContent = React.forwardRef(({ className, children, showCloseButton = true, ...props }, ref) => {
|
|
729
|
+
return /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
|
|
730
|
+
ref,
|
|
731
|
+
className: cn("fixed left-1/2 top-1/2 z-50 grid w-[calc(100%-2rem)] max-w-lg", "-translate-x-1/2 -translate-y-1/2 gap-4", "rounded-fds-lg border border-border bg-popover p-6 text-popover-foreground shadow-lg", "duration-200", "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0", "data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95", className),
|
|
732
|
+
...props,
|
|
733
|
+
children: [children, showCloseButton ? /* @__PURE__ */ jsxs(DialogPrimitive.Close, {
|
|
734
|
+
className: cn("absolute right-4 top-4 rounded-sm opacity-70", "transition-opacity hover:opacity-100", "focus:outline-none focus:ring-2 focus:ring-ring/35", "disabled:pointer-events-none"),
|
|
735
|
+
children: [/* @__PURE__ */ jsx(X, { className: "size-4" }), /* @__PURE__ */ jsx("span", {
|
|
736
|
+
className: "sr-only",
|
|
737
|
+
children: "Fechar"
|
|
738
|
+
})]
|
|
739
|
+
}) : null]
|
|
740
|
+
})] });
|
|
741
|
+
});
|
|
742
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
743
|
+
function DialogHeader({ className, ...props }) {
|
|
744
|
+
return /* @__PURE__ */ jsx("div", {
|
|
745
|
+
className: cn("flex flex-col gap-1.5 text-left", className),
|
|
746
|
+
...props
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
function DialogFooter({ className, ...props }) {
|
|
750
|
+
return /* @__PURE__ */ jsx("div", {
|
|
751
|
+
className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
|
|
752
|
+
...props
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
const DialogTitle = React.forwardRef(({ className, ...props }, ref) => {
|
|
756
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Title, {
|
|
757
|
+
ref,
|
|
758
|
+
className: cn("h3 text-on-surface", className),
|
|
759
|
+
...props
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
763
|
+
const DialogDescription = React.forwardRef(({ className, ...props }, ref) => {
|
|
764
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Description, {
|
|
765
|
+
ref,
|
|
766
|
+
className: cn("body-sm text-muted", className),
|
|
767
|
+
...props
|
|
768
|
+
});
|
|
769
|
+
});
|
|
770
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
771
|
+
//#endregion
|
|
772
|
+
//#region src/components/kbd.tsx
|
|
773
|
+
const kbdVariants = cva([
|
|
774
|
+
"inline-flex items-center justify-center",
|
|
775
|
+
"rounded-sm border border-border bg-muted",
|
|
776
|
+
"font-mono font-medium text-muted-foreground shadow-sm",
|
|
777
|
+
"select-none"
|
|
778
|
+
], {
|
|
779
|
+
variants: { size: {
|
|
780
|
+
sm: "h-5 min-w-5 px-1 text-[0.6875rem]",
|
|
781
|
+
md: "h-6 min-w-6 px-1.5 text-xs"
|
|
782
|
+
} },
|
|
783
|
+
defaultVariants: { size: "sm" }
|
|
784
|
+
});
|
|
785
|
+
function Kbd({ className, size, ...props }) {
|
|
786
|
+
return /* @__PURE__ */ jsx("kbd", {
|
|
787
|
+
className: cn(kbdVariants({ size }), className),
|
|
788
|
+
...props
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
//#endregion
|
|
792
|
+
//#region src/components/command-menu.tsx
|
|
793
|
+
function CommandMenu({ open, defaultOpen = false, onOpenChange, title = "Menu de comandos", description = "Busque telas e execute ações rápidas.", placeholder = "Buscar comando, tela ou ação...", emptyMessage = "Nenhum comando encontrado.", groups, closeOnSelect = true }) {
|
|
794
|
+
const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
|
|
795
|
+
const currentOpen = open ?? internalOpen;
|
|
796
|
+
function handleOpenChange(nextOpen) {
|
|
797
|
+
if (open === void 0) setInternalOpen(nextOpen);
|
|
798
|
+
onOpenChange?.(nextOpen);
|
|
799
|
+
}
|
|
800
|
+
function handleSelect(item) {
|
|
801
|
+
item.onSelect?.();
|
|
802
|
+
if (closeOnSelect) handleOpenChange(false);
|
|
803
|
+
}
|
|
804
|
+
return /* @__PURE__ */ jsx(Dialog, {
|
|
805
|
+
open: currentOpen,
|
|
806
|
+
onOpenChange: handleOpenChange,
|
|
807
|
+
children: /* @__PURE__ */ jsxs(DialogContent, {
|
|
808
|
+
showCloseButton: false,
|
|
809
|
+
className: "max-w-2xl overflow-hidden p-0",
|
|
810
|
+
children: [
|
|
811
|
+
/* @__PURE__ */ jsx(DialogTitle, {
|
|
812
|
+
className: "sr-only",
|
|
813
|
+
children: title
|
|
814
|
+
}),
|
|
815
|
+
/* @__PURE__ */ jsx(DialogDescription, {
|
|
816
|
+
className: "sr-only",
|
|
817
|
+
children: description
|
|
818
|
+
}),
|
|
819
|
+
/* @__PURE__ */ jsxs(Command, {
|
|
820
|
+
loop: true,
|
|
821
|
+
className: "flex max-h-[70dvh] flex-col overflow-hidden bg-popover text-popover-foreground",
|
|
822
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
823
|
+
className: "flex items-center border-b border-border px-4",
|
|
824
|
+
children: [/* @__PURE__ */ jsx(Search, {
|
|
825
|
+
"aria-hidden": "true",
|
|
826
|
+
className: "mr-3 size-4 shrink-0 text-muted-foreground"
|
|
827
|
+
}), /* @__PURE__ */ jsx(Command.Input, {
|
|
828
|
+
placeholder,
|
|
829
|
+
className: cn("h-12 w-full bg-transparent py-3 body-sm outline-none", "placeholder:text-muted-foreground", "disabled:cursor-not-allowed disabled:opacity-50")
|
|
830
|
+
})]
|
|
831
|
+
}), /* @__PURE__ */ jsxs(Command.List, {
|
|
832
|
+
className: "max-h-[26rem] overflow-y-auto overflow-x-hidden p-2",
|
|
833
|
+
children: [/* @__PURE__ */ jsx(Command.Empty, {
|
|
834
|
+
className: "px-4 py-10 text-center body-sm text-muted",
|
|
835
|
+
children: emptyMessage
|
|
836
|
+
}), groups.map((group) => /* @__PURE__ */ jsx(Command.Group, {
|
|
837
|
+
heading: group.label,
|
|
838
|
+
className: cn("overflow-hidden", "[&_[cmdk-group-heading]]:px-2", "[&_[cmdk-group-heading]]:py-2", "[&_[cmdk-group-heading]]:caption", "[&_[cmdk-group-heading]]:mono", "[&_[cmdk-group-heading]]:uppercase", "[&_[cmdk-group-heading]]:tracking-[0.12em]", "[&_[cmdk-group-heading]]:text-muted"),
|
|
839
|
+
children: group.items.map((item) => /* @__PURE__ */ jsxs(Command.Item, {
|
|
840
|
+
value: item.value,
|
|
841
|
+
keywords: [
|
|
842
|
+
item.label,
|
|
843
|
+
item.description ?? "",
|
|
844
|
+
...item.keywords ?? []
|
|
845
|
+
],
|
|
846
|
+
disabled: item.disabled,
|
|
847
|
+
onSelect: () => handleSelect(item),
|
|
848
|
+
className: cn("relative flex cursor-default select-none items-center gap-3 rounded-fds-md px-3 py-2.5", "body-sm outline-none transition-colors duration-100", "data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground", "data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50"),
|
|
849
|
+
children: [
|
|
850
|
+
item.icon ? /* @__PURE__ */ jsx("span", {
|
|
851
|
+
className: "flex size-4 shrink-0 items-center justify-center text-muted-foreground",
|
|
852
|
+
children: item.icon
|
|
853
|
+
}) : null,
|
|
854
|
+
/* @__PURE__ */ jsxs("span", {
|
|
855
|
+
className: "flex min-w-0 flex-1 flex-col",
|
|
856
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
857
|
+
className: "truncate font-medium",
|
|
858
|
+
children: item.label
|
|
859
|
+
}), item.description ? /* @__PURE__ */ jsx("span", {
|
|
860
|
+
className: "truncate caption text-muted",
|
|
861
|
+
children: item.description
|
|
862
|
+
}) : null]
|
|
863
|
+
}),
|
|
864
|
+
item.shortcut ? /* @__PURE__ */ jsx("span", {
|
|
865
|
+
className: "ml-auto flex shrink-0 items-center gap-1",
|
|
866
|
+
children: Array.isArray(item.shortcut) ? item.shortcut.map((key) => /* @__PURE__ */ jsx(Kbd, { children: key }, key)) : /* @__PURE__ */ jsx(Kbd, { children: item.shortcut })
|
|
867
|
+
}) : null
|
|
868
|
+
]
|
|
869
|
+
}, item.value))
|
|
870
|
+
}, group.label))]
|
|
871
|
+
})]
|
|
872
|
+
})
|
|
873
|
+
]
|
|
874
|
+
})
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
//#endregion
|
|
878
|
+
//#region src/components/empty-state.tsx
|
|
879
|
+
function EmptyState({ className, icon, title, description, action, ...props }) {
|
|
880
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
881
|
+
className: cn("flex min-h-56 flex-col items-center justify-center rounded-fds-lg border border-dashed border-border bg-muted/40 p-8 text-center", className),
|
|
882
|
+
...props,
|
|
883
|
+
children: [
|
|
884
|
+
/* @__PURE__ */ jsx("div", {
|
|
885
|
+
className: "mb-4 flex size-12 items-center justify-center rounded-fds-full bg-surface text-muted-foreground",
|
|
886
|
+
children: icon ?? /* @__PURE__ */ jsx(Inbox, { className: "size-6" })
|
|
887
|
+
}),
|
|
888
|
+
/* @__PURE__ */ jsx("h3", {
|
|
889
|
+
className: "body font-semibold text-on-surface",
|
|
890
|
+
children: title
|
|
891
|
+
}),
|
|
892
|
+
description ? /* @__PURE__ */ jsx("p", {
|
|
893
|
+
className: "mt-1 max-w-md body-sm text-muted",
|
|
894
|
+
children: description
|
|
895
|
+
}) : null,
|
|
896
|
+
action ? /* @__PURE__ */ jsx("div", {
|
|
897
|
+
className: "mt-5",
|
|
898
|
+
children: action
|
|
899
|
+
}) : null
|
|
900
|
+
]
|
|
901
|
+
});
|
|
902
|
+
}
|
|
903
|
+
//#endregion
|
|
904
|
+
//#region src/components/skeleton.tsx
|
|
905
|
+
function Skeleton({ className, ...props }) {
|
|
906
|
+
return /* @__PURE__ */ jsx("div", {
|
|
907
|
+
"aria-hidden": "true",
|
|
908
|
+
className: cn("animate-pulse rounded-fds-md bg-muted", className),
|
|
909
|
+
...props
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
//#endregion
|
|
913
|
+
//#region src/components/table.tsx
|
|
914
|
+
function TableContainer({ className, ...props }) {
|
|
915
|
+
return /* @__PURE__ */ jsx("div", {
|
|
916
|
+
className: cn("w-full overflow-hidden rounded-fds-lg border border-border bg-card", className),
|
|
917
|
+
...props
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
function TableScrollArea({ className, ...props }) {
|
|
921
|
+
return /* @__PURE__ */ jsx("div", {
|
|
922
|
+
className: cn("w-full overflow-auto", className),
|
|
923
|
+
...props
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
const Table = React.forwardRef(({ className, ...props }, ref) => {
|
|
927
|
+
return /* @__PURE__ */ jsx("table", {
|
|
928
|
+
ref,
|
|
929
|
+
className: cn("w-full caption-bottom border-collapse text-sm", className),
|
|
930
|
+
...props
|
|
931
|
+
});
|
|
932
|
+
});
|
|
933
|
+
Table.displayName = "Table";
|
|
934
|
+
const TableHeader = React.forwardRef(({ className, ...props }, ref) => {
|
|
935
|
+
return /* @__PURE__ */ jsx("thead", {
|
|
936
|
+
ref,
|
|
937
|
+
className: cn("border-b border-border bg-muted/60", className),
|
|
938
|
+
...props
|
|
939
|
+
});
|
|
940
|
+
});
|
|
941
|
+
TableHeader.displayName = "TableHeader";
|
|
942
|
+
const TableBody = React.forwardRef(({ className, ...props }, ref) => {
|
|
943
|
+
return /* @__PURE__ */ jsx("tbody", {
|
|
944
|
+
ref,
|
|
945
|
+
className: cn("[&_tr:last-child]:border-0", className),
|
|
946
|
+
...props
|
|
947
|
+
});
|
|
948
|
+
});
|
|
949
|
+
TableBody.displayName = "TableBody";
|
|
950
|
+
const TableFooter = React.forwardRef(({ className, ...props }, ref) => {
|
|
951
|
+
return /* @__PURE__ */ jsx("tfoot", {
|
|
952
|
+
ref,
|
|
953
|
+
className: cn("border-t border-border bg-muted/60 font-medium", className),
|
|
954
|
+
...props
|
|
955
|
+
});
|
|
956
|
+
});
|
|
957
|
+
TableFooter.displayName = "TableFooter";
|
|
958
|
+
const TableRow = React.forwardRef(({ className, ...props }, ref) => {
|
|
959
|
+
return /* @__PURE__ */ jsx("tr", {
|
|
960
|
+
ref,
|
|
961
|
+
className: cn("border-b border-border transition-colors", "hover:bg-muted/60", "data-[state=selected]:bg-muted", className),
|
|
962
|
+
...props
|
|
963
|
+
});
|
|
964
|
+
});
|
|
965
|
+
TableRow.displayName = "TableRow";
|
|
966
|
+
const TableHead = React.forwardRef(({ className, ...props }, ref) => {
|
|
967
|
+
return /* @__PURE__ */ jsx("th", {
|
|
968
|
+
ref,
|
|
969
|
+
className: cn("h-10 px-4 text-left align-middle", "caption font-semibold uppercase tracking-[0.08em] text-muted-foreground", "[&:has([role=checkbox])]:pr-0", className),
|
|
970
|
+
...props
|
|
971
|
+
});
|
|
972
|
+
});
|
|
973
|
+
TableHead.displayName = "TableHead";
|
|
974
|
+
const TableCell = React.forwardRef(({ className, ...props }, ref) => {
|
|
975
|
+
return /* @__PURE__ */ jsx("td", {
|
|
976
|
+
ref,
|
|
977
|
+
className: cn("px-4 py-3 align-middle body-sm", "[&:has([role=checkbox])]:pr-0", className),
|
|
978
|
+
...props
|
|
979
|
+
});
|
|
980
|
+
});
|
|
981
|
+
TableCell.displayName = "TableCell";
|
|
982
|
+
const TableCaption = React.forwardRef(({ className, ...props }, ref) => {
|
|
983
|
+
return /* @__PURE__ */ jsx("caption", {
|
|
984
|
+
ref,
|
|
985
|
+
className: cn("mt-4 caption text-muted", className),
|
|
986
|
+
...props
|
|
987
|
+
});
|
|
988
|
+
});
|
|
989
|
+
TableCaption.displayName = "TableCaption";
|
|
990
|
+
//#endregion
|
|
991
|
+
//#region src/components/data-table.tsx
|
|
992
|
+
function getCellValue(row, column) {
|
|
993
|
+
if (column.cell) return column.cell(row);
|
|
994
|
+
if (typeof column.accessor === "function") return column.accessor(row);
|
|
995
|
+
if (column.accessor) return row[column.accessor];
|
|
996
|
+
return null;
|
|
997
|
+
}
|
|
998
|
+
function renderCellValue(value) {
|
|
999
|
+
if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || React.isValidElement(value)) return value;
|
|
1000
|
+
return String(value);
|
|
1001
|
+
}
|
|
1002
|
+
function compareSortValues(first, second) {
|
|
1003
|
+
if (first === second) return 0;
|
|
1004
|
+
if (first === null || first === void 0) return 1;
|
|
1005
|
+
if (second === null || second === void 0) return -1;
|
|
1006
|
+
const normalizedFirst = first instanceof Date ? first.getTime() : first;
|
|
1007
|
+
const normalizedSecond = second instanceof Date ? second.getTime() : second;
|
|
1008
|
+
if (typeof normalizedFirst === "number" && typeof normalizedSecond === "number") return normalizedFirst - normalizedSecond;
|
|
1009
|
+
return String(normalizedFirst).localeCompare(String(normalizedSecond), "pt-BR", {
|
|
1010
|
+
numeric: true,
|
|
1011
|
+
sensitivity: "base"
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
function getNextSortState(currentSort, columnId) {
|
|
1015
|
+
if (currentSort?.id !== columnId) return {
|
|
1016
|
+
id: columnId,
|
|
1017
|
+
direction: "asc"
|
|
1018
|
+
};
|
|
1019
|
+
if (currentSort.direction === "asc") return {
|
|
1020
|
+
id: columnId,
|
|
1021
|
+
direction: "desc"
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
1024
|
+
function DataTable({ columns, data, getRowId = (_row, index) => String(index), selectedRowIds, defaultSelectedRowIds = [], onSelectedRowIdsChange, sort, defaultSort, onSortChange, onRowClick, emptyState, loading = false, loadingRows = 5, "aria-label": ariaLabel = "Tabela de dados", className }) {
|
|
1025
|
+
const [internalSelectedRowIds, setInternalSelectedRowIds] = React.useState(defaultSelectedRowIds);
|
|
1026
|
+
const [internalSort, setInternalSort] = React.useState(defaultSort);
|
|
1027
|
+
const currentSelectedRowIds = selectedRowIds ?? internalSelectedRowIds;
|
|
1028
|
+
const currentSort = sort ?? internalSort;
|
|
1029
|
+
const selectable = Boolean(selectedRowIds || onSelectedRowIdsChange);
|
|
1030
|
+
const rowIds = React.useMemo(() => data.map((row, index) => getRowId(row, index)), [data, getRowId]);
|
|
1031
|
+
const selectedRows = new Set(currentSelectedRowIds);
|
|
1032
|
+
const selectedVisibleRows = rowIds.filter((rowId) => selectedRows.has(rowId));
|
|
1033
|
+
const allVisibleSelected = rowIds.length > 0 && selectedVisibleRows.length === rowIds.length;
|
|
1034
|
+
const someVisibleSelected = selectedVisibleRows.length > 0 && selectedVisibleRows.length < rowIds.length;
|
|
1035
|
+
const sortedData = React.useMemo(() => {
|
|
1036
|
+
if (!currentSort) return data;
|
|
1037
|
+
const sortedColumn = columns.find((column) => column.id === currentSort.id);
|
|
1038
|
+
if (!sortedColumn?.sortable) return data;
|
|
1039
|
+
return [...data].sort((first, second) => {
|
|
1040
|
+
const result = compareSortValues(sortedColumn.sortValue ? sortedColumn.sortValue(first) : getCellValue(first, sortedColumn)?.toString(), sortedColumn.sortValue ? sortedColumn.sortValue(second) : getCellValue(second, sortedColumn)?.toString());
|
|
1041
|
+
return currentSort.direction === "asc" ? result : result * -1;
|
|
1042
|
+
});
|
|
1043
|
+
}, [
|
|
1044
|
+
columns,
|
|
1045
|
+
currentSort,
|
|
1046
|
+
data
|
|
1047
|
+
]);
|
|
1048
|
+
function updateSelectedRowIds(nextSelectedRowIds) {
|
|
1049
|
+
if (selectedRowIds === void 0) setInternalSelectedRowIds(nextSelectedRowIds);
|
|
1050
|
+
onSelectedRowIdsChange?.(nextSelectedRowIds);
|
|
1051
|
+
}
|
|
1052
|
+
function updateSort(nextSort) {
|
|
1053
|
+
if (sort === void 0) setInternalSort(nextSort);
|
|
1054
|
+
onSortChange?.(nextSort);
|
|
1055
|
+
}
|
|
1056
|
+
function toggleRow(rowId) {
|
|
1057
|
+
const nextSelectedRows = new Set(currentSelectedRowIds);
|
|
1058
|
+
if (nextSelectedRows.has(rowId)) nextSelectedRows.delete(rowId);
|
|
1059
|
+
else nextSelectedRows.add(rowId);
|
|
1060
|
+
updateSelectedRowIds(Array.from(nextSelectedRows));
|
|
1061
|
+
}
|
|
1062
|
+
function toggleAllVisibleRows() {
|
|
1063
|
+
if (allVisibleSelected) {
|
|
1064
|
+
updateSelectedRowIds(currentSelectedRowIds.filter((rowId) => !rowIds.includes(rowId)));
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
updateSelectedRowIds(Array.from(new Set([...currentSelectedRowIds, ...rowIds])));
|
|
1068
|
+
}
|
|
1069
|
+
const columnCount = columns.length + (selectable ? 1 : 0);
|
|
1070
|
+
return /* @__PURE__ */ jsx(TableContainer, {
|
|
1071
|
+
className,
|
|
1072
|
+
children: /* @__PURE__ */ jsx(TableScrollArea, { children: /* @__PURE__ */ jsxs(Table, {
|
|
1073
|
+
"aria-label": ariaLabel,
|
|
1074
|
+
children: [/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [selectable ? /* @__PURE__ */ jsx(TableHead, {
|
|
1075
|
+
className: "w-12",
|
|
1076
|
+
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
1077
|
+
"aria-label": "Selecionar todas as linhas",
|
|
1078
|
+
checked: someVisibleSelected ? "indeterminate" : allVisibleSelected,
|
|
1079
|
+
disabled: loading || rowIds.length === 0,
|
|
1080
|
+
onCheckedChange: toggleAllVisibleRows
|
|
1081
|
+
})
|
|
1082
|
+
}) : null, columns.map((column) => {
|
|
1083
|
+
const isSorted = currentSort?.id === column.id;
|
|
1084
|
+
const SortIcon = isSorted ? currentSort.direction === "asc" ? ChevronUp : ChevronDown : ArrowUpDown;
|
|
1085
|
+
return /* @__PURE__ */ jsx(TableHead, {
|
|
1086
|
+
className: cn(column.align === "center" && "text-center", column.align === "right" && "text-right", column.headerClassName),
|
|
1087
|
+
"aria-sort": isSorted ? currentSort.direction === "asc" ? "ascending" : "descending" : void 0,
|
|
1088
|
+
children: column.sortable ? /* @__PURE__ */ jsxs("button", {
|
|
1089
|
+
type: "button",
|
|
1090
|
+
className: cn("inline-flex items-center gap-1 rounded-fds-sm", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35", column.align === "right" && "ml-auto", column.align === "center" && "mx-auto"),
|
|
1091
|
+
onClick: () => updateSort(getNextSortState(currentSort, column.id)),
|
|
1092
|
+
children: [column.header, /* @__PURE__ */ jsx(SortIcon, {
|
|
1093
|
+
className: "size-3.5",
|
|
1094
|
+
"aria-hidden": "true"
|
|
1095
|
+
})]
|
|
1096
|
+
}) : column.header
|
|
1097
|
+
}, column.id);
|
|
1098
|
+
})] }) }), /* @__PURE__ */ jsxs(TableBody, { children: [
|
|
1099
|
+
loading ? Array.from({ length: loadingRows }, (_, rowIndex) => /* @__PURE__ */ jsx(TableRow, { children: Array.from({ length: columnCount }, (_, cellIndex) => /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-full" }) }, `loading-${rowIndex}-${cellIndex}`)) }, `loading-${rowIndex}`)) : null,
|
|
1100
|
+
!loading && sortedData.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, {
|
|
1101
|
+
colSpan: columnCount,
|
|
1102
|
+
children: emptyState ?? /* @__PURE__ */ jsx(EmptyState, {
|
|
1103
|
+
className: "border-0 bg-transparent",
|
|
1104
|
+
title: "Nenhum registro encontrado",
|
|
1105
|
+
description: "Ajuste os filtros ou cadastre um novo item."
|
|
1106
|
+
})
|
|
1107
|
+
}) }) : null,
|
|
1108
|
+
!loading ? sortedData.map((row, index) => {
|
|
1109
|
+
const rowId = getRowId(row, index);
|
|
1110
|
+
const isSelected = selectedRows.has(rowId);
|
|
1111
|
+
return /* @__PURE__ */ jsxs(TableRow, {
|
|
1112
|
+
"data-state": isSelected ? "selected" : void 0,
|
|
1113
|
+
className: cn(onRowClick && "cursor-pointer"),
|
|
1114
|
+
onClick: () => onRowClick?.(row, rowId),
|
|
1115
|
+
children: [selectable ? /* @__PURE__ */ jsx(TableCell, {
|
|
1116
|
+
onClick: (event) => event.stopPropagation(),
|
|
1117
|
+
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
1118
|
+
"aria-label": `Selecionar linha ${index + 1}`,
|
|
1119
|
+
checked: isSelected,
|
|
1120
|
+
onCheckedChange: () => toggleRow(rowId)
|
|
1121
|
+
})
|
|
1122
|
+
}) : null, columns.map((column) => /* @__PURE__ */ jsx(TableCell, {
|
|
1123
|
+
className: cn(column.align === "center" && "text-center", column.align === "right" && "text-right", column.className),
|
|
1124
|
+
children: renderCellValue(getCellValue(row, column))
|
|
1125
|
+
}, column.id))]
|
|
1126
|
+
}, rowId);
|
|
1127
|
+
}) : null
|
|
1128
|
+
] })]
|
|
1129
|
+
}) })
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
//#endregion
|
|
1133
|
+
//#region src/components/filter-bar.tsx
|
|
1134
|
+
function FilterBar({ label = "Filtros", className, children, ...props }) {
|
|
1135
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1136
|
+
className: cn("flex flex-col gap-3 rounded-fds-lg border border-border bg-muted/40 p-3", className),
|
|
1137
|
+
...props,
|
|
1138
|
+
children: [label ? /* @__PURE__ */ jsx("p", {
|
|
1139
|
+
className: "caption mono uppercase tracking-[0.12em] text-muted",
|
|
1140
|
+
children: label
|
|
1141
|
+
}) : null, /* @__PURE__ */ jsx("div", {
|
|
1142
|
+
className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-4",
|
|
1143
|
+
children
|
|
1144
|
+
})]
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
function FilterBarItem({ label, className, children, ...props }) {
|
|
1148
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1149
|
+
className: cn("grid gap-1.5", className),
|
|
1150
|
+
...props,
|
|
1151
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1152
|
+
className: "caption font-medium text-muted",
|
|
1153
|
+
children: label
|
|
1154
|
+
}), children]
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
//#endregion
|
|
1158
|
+
//#region src/components/pagination.tsx
|
|
1159
|
+
function range(start, end) {
|
|
1160
|
+
const length = end - start + 1;
|
|
1161
|
+
return Array.from({ length }, (_, index) => index + start);
|
|
1162
|
+
}
|
|
1163
|
+
function getPaginationItems(page, totalPages, siblingCount) {
|
|
1164
|
+
if (siblingCount + 5 >= totalPages) return range(1, totalPages);
|
|
1165
|
+
const leftSiblingIndex = Math.max(page - siblingCount, 1);
|
|
1166
|
+
const rightSiblingIndex = Math.min(page + siblingCount, totalPages);
|
|
1167
|
+
const shouldShowLeftEllipsis = leftSiblingIndex > 2;
|
|
1168
|
+
const shouldShowRightEllipsis = rightSiblingIndex < totalPages - 1;
|
|
1169
|
+
const firstPageIndex = 1;
|
|
1170
|
+
const lastPageIndex = totalPages;
|
|
1171
|
+
if (!shouldShowLeftEllipsis && shouldShowRightEllipsis) return [
|
|
1172
|
+
...range(1, 3 + 2 * siblingCount),
|
|
1173
|
+
"ellipsis",
|
|
1174
|
+
totalPages
|
|
1175
|
+
];
|
|
1176
|
+
if (shouldShowLeftEllipsis && !shouldShowRightEllipsis) return [
|
|
1177
|
+
firstPageIndex,
|
|
1178
|
+
"ellipsis",
|
|
1179
|
+
...range(totalPages - (3 + 2 * siblingCount) + 1, totalPages)
|
|
1180
|
+
];
|
|
1181
|
+
return [
|
|
1182
|
+
firstPageIndex,
|
|
1183
|
+
"ellipsis",
|
|
1184
|
+
...range(leftSiblingIndex, rightSiblingIndex),
|
|
1185
|
+
"ellipsis",
|
|
1186
|
+
lastPageIndex
|
|
1187
|
+
];
|
|
1188
|
+
}
|
|
1189
|
+
function Pagination({ page, totalPages, onPageChange, siblingCount = 1, className }) {
|
|
1190
|
+
const items = getPaginationItems(page, totalPages, siblingCount);
|
|
1191
|
+
function goToPage(nextPage) {
|
|
1192
|
+
if (nextPage < 1 || nextPage > totalPages || nextPage === page) return;
|
|
1193
|
+
onPageChange?.(nextPage);
|
|
1194
|
+
}
|
|
1195
|
+
return /* @__PURE__ */ jsxs("nav", {
|
|
1196
|
+
"aria-label": "Paginação",
|
|
1197
|
+
className: cn("flex flex-wrap items-center justify-between gap-3", className),
|
|
1198
|
+
children: [/* @__PURE__ */ jsxs("p", {
|
|
1199
|
+
className: "caption text-muted",
|
|
1200
|
+
children: [
|
|
1201
|
+
"Página ",
|
|
1202
|
+
page,
|
|
1203
|
+
" de ",
|
|
1204
|
+
totalPages
|
|
1205
|
+
]
|
|
1206
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
1207
|
+
className: "flex items-center gap-1",
|
|
1208
|
+
children: [
|
|
1209
|
+
/* @__PURE__ */ jsx(Button, {
|
|
1210
|
+
type: "button",
|
|
1211
|
+
variant: "outline",
|
|
1212
|
+
size: "sm",
|
|
1213
|
+
disabled: page <= 1,
|
|
1214
|
+
onClick: () => goToPage(page - 1),
|
|
1215
|
+
"aria-label": "Página anterior",
|
|
1216
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" })
|
|
1217
|
+
}),
|
|
1218
|
+
items.map((item, index) => {
|
|
1219
|
+
if (item === "ellipsis") {
|
|
1220
|
+
const previousItem = items[index - 1];
|
|
1221
|
+
const nextItem = items[index + 1];
|
|
1222
|
+
return /* @__PURE__ */ jsx("span", {
|
|
1223
|
+
className: "flex size-8 items-center justify-center text-muted-foreground",
|
|
1224
|
+
"aria-hidden": "true",
|
|
1225
|
+
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "size-4" })
|
|
1226
|
+
}, `ellipsis-${previousItem}-${nextItem}`);
|
|
1227
|
+
}
|
|
1228
|
+
const isCurrent = item === page;
|
|
1229
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
1230
|
+
type: "button",
|
|
1231
|
+
variant: isCurrent ? "primary" : "ghost",
|
|
1232
|
+
size: "sm",
|
|
1233
|
+
onClick: () => goToPage(item),
|
|
1234
|
+
"aria-current": isCurrent ? "page" : void 0,
|
|
1235
|
+
className: "size-8 px-0",
|
|
1236
|
+
children: item
|
|
1237
|
+
}, item);
|
|
1238
|
+
}),
|
|
1239
|
+
/* @__PURE__ */ jsx(Button, {
|
|
1240
|
+
type: "button",
|
|
1241
|
+
variant: "outline",
|
|
1242
|
+
size: "sm",
|
|
1243
|
+
disabled: page >= totalPages,
|
|
1244
|
+
onClick: () => goToPage(page + 1),
|
|
1245
|
+
"aria-label": "Próxima página",
|
|
1246
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" })
|
|
1247
|
+
})
|
|
1248
|
+
]
|
|
1249
|
+
})]
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
//#endregion
|
|
1253
|
+
//#region src/components/search-input.tsx
|
|
1254
|
+
const SearchInput = React.forwardRef(({ className, containerClassName, value, defaultValue = "", onValueChange, onChange, onClear, clearable = true, placeholder = "Buscar...", disabled, ...props }, ref) => {
|
|
1255
|
+
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
1256
|
+
const currentValue = value ?? internalValue;
|
|
1257
|
+
const hasValue = currentValue.length > 0;
|
|
1258
|
+
function handleChange(event) {
|
|
1259
|
+
const nextValue = event.target.value;
|
|
1260
|
+
if (value === void 0) setInternalValue(nextValue);
|
|
1261
|
+
onValueChange?.(nextValue);
|
|
1262
|
+
onChange?.(event);
|
|
1263
|
+
}
|
|
1264
|
+
function handleClear() {
|
|
1265
|
+
if (value === void 0) setInternalValue("");
|
|
1266
|
+
onValueChange?.("");
|
|
1267
|
+
onClear?.();
|
|
1268
|
+
}
|
|
1269
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1270
|
+
className: cn("relative w-full", containerClassName),
|
|
1271
|
+
children: [
|
|
1272
|
+
/* @__PURE__ */ jsx(Search, {
|
|
1273
|
+
"aria-hidden": "true",
|
|
1274
|
+
className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground"
|
|
1275
|
+
}),
|
|
1276
|
+
/* @__PURE__ */ jsx("input", {
|
|
1277
|
+
ref,
|
|
1278
|
+
type: "search",
|
|
1279
|
+
value: currentValue,
|
|
1280
|
+
onChange: handleChange,
|
|
1281
|
+
placeholder,
|
|
1282
|
+
disabled,
|
|
1283
|
+
className: cn("h-9 w-full rounded-fds-md border border-input bg-transparent", "pl-9 pr-9 body-sm text-on-surface shadow-sm outline-none", "transition-[color,box-shadow,border-color,background-color] duration-150", "placeholder:text-muted-foreground", "hover:bg-accent", "focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/35", "disabled:cursor-not-allowed disabled:opacity-50", className),
|
|
1284
|
+
...props
|
|
1285
|
+
}),
|
|
1286
|
+
clearable && hasValue && !disabled ? /* @__PURE__ */ jsx("button", {
|
|
1287
|
+
type: "button",
|
|
1288
|
+
onClick: handleClear,
|
|
1289
|
+
className: cn("absolute right-2 top-1/2 flex size-6 -translate-y-1/2 items-center justify-center", "rounded-sm text-muted-foreground transition-colors", "hover:bg-accent hover:text-accent-foreground", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35"),
|
|
1290
|
+
"aria-label": "Limpar busca",
|
|
1291
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4" })
|
|
1292
|
+
}) : null
|
|
1293
|
+
]
|
|
1294
|
+
});
|
|
1295
|
+
});
|
|
1296
|
+
SearchInput.displayName = "SearchInput";
|
|
1297
|
+
//#endregion
|
|
1298
|
+
//#region src/components/toolbar.tsx
|
|
1299
|
+
function Toolbar({ className, ...props }) {
|
|
1300
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1301
|
+
className: cn("flex flex-col gap-4 rounded-fds-lg border border-border bg-card p-4", "lg:flex-row lg:items-center lg:justify-between", className),
|
|
1302
|
+
...props
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
function ToolbarSection({ className, ...props }) {
|
|
1306
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1307
|
+
className: cn("flex min-w-0 flex-1 flex-col gap-3 sm:flex-row sm:items-center", className),
|
|
1308
|
+
...props
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
function ToolbarActions({ className, ...props }) {
|
|
1312
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1313
|
+
className: cn("flex shrink-0 flex-wrap items-center gap-2", className),
|
|
1314
|
+
...props
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
function ToolbarTitle({ title, description, className, ...props }) {
|
|
1318
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1319
|
+
className: cn("min-w-0", className),
|
|
1320
|
+
...props,
|
|
1321
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
1322
|
+
className: "body-sm font-semibold text-on-surface",
|
|
1323
|
+
children: title
|
|
1324
|
+
}), description ? /* @__PURE__ */ jsx("p", {
|
|
1325
|
+
className: "caption text-muted",
|
|
1326
|
+
children: description
|
|
1327
|
+
}) : null]
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
//#endregion
|
|
1331
|
+
//#region src/components/data-view.tsx
|
|
1332
|
+
function isPlainStateContent(content) {
|
|
1333
|
+
return Boolean(content && typeof content === "object" && !Array.isArray(content) && !("type" in content) && "title" in content);
|
|
1334
|
+
}
|
|
1335
|
+
function renderStateContent(content, fallbackIcon) {
|
|
1336
|
+
if (isPlainStateContent(content)) {
|
|
1337
|
+
const { retryLabel = "Tentar novamente", onRetry, action, icon, ...emptyStateProps } = content;
|
|
1338
|
+
return /* @__PURE__ */ jsx(EmptyState, {
|
|
1339
|
+
icon: icon ?? fallbackIcon,
|
|
1340
|
+
action: action ?? (onRetry ? /* @__PURE__ */ jsx(Button, {
|
|
1341
|
+
type: "button",
|
|
1342
|
+
variant: "outline",
|
|
1343
|
+
onClick: onRetry,
|
|
1344
|
+
children: retryLabel
|
|
1345
|
+
}) : void 0),
|
|
1346
|
+
...emptyStateProps
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
return content;
|
|
1350
|
+
}
|
|
1351
|
+
function renderSearch(search) {
|
|
1352
|
+
if (typeof search === "object" && search && !Array.isArray(search) && !("type" in search)) return /* @__PURE__ */ jsx(SearchInput, {
|
|
1353
|
+
placeholder: "Buscar...",
|
|
1354
|
+
...search
|
|
1355
|
+
});
|
|
1356
|
+
return search;
|
|
1357
|
+
}
|
|
1358
|
+
function isPaginationProps(pagination) {
|
|
1359
|
+
return Boolean(pagination && typeof pagination === "object" && !Array.isArray(pagination) && !("type" in pagination) && "page" in pagination && "totalPages" in pagination);
|
|
1360
|
+
}
|
|
1361
|
+
function renderPagination(pagination) {
|
|
1362
|
+
if (isPaginationProps(pagination)) return /* @__PURE__ */ jsx(Pagination, { ...pagination });
|
|
1363
|
+
return pagination;
|
|
1364
|
+
}
|
|
1365
|
+
function DataViewRoot({ title, description, search, filters, actions, selectedCount = 0, selectedActions, selectedLabel, onClearSelection, empty, loading = false, loadingLabel = "Carregando dados", error, pagination, className, children, ...props }) {
|
|
1366
|
+
const hasHeader = title || description || actions;
|
|
1367
|
+
const hasToolbar = search || filters;
|
|
1368
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
1369
|
+
className: cn("flex w-full flex-col gap-4", className),
|
|
1370
|
+
...props,
|
|
1371
|
+
children: [
|
|
1372
|
+
hasHeader ? /* @__PURE__ */ jsx(DataViewHeader, {
|
|
1373
|
+
title,
|
|
1374
|
+
description,
|
|
1375
|
+
actions
|
|
1376
|
+
}) : null,
|
|
1377
|
+
hasToolbar ? /* @__PURE__ */ jsx(DataViewToolbar, {
|
|
1378
|
+
search,
|
|
1379
|
+
filters
|
|
1380
|
+
}) : null,
|
|
1381
|
+
/* @__PURE__ */ jsx(ActionBar, {
|
|
1382
|
+
selectedCount,
|
|
1383
|
+
label: selectedLabel,
|
|
1384
|
+
onClearSelection,
|
|
1385
|
+
children: selectedActions
|
|
1386
|
+
}),
|
|
1387
|
+
/* @__PURE__ */ jsx(DataViewContent, { children: loading ? /* @__PURE__ */ jsxs("div", {
|
|
1388
|
+
className: "grid gap-3 rounded-fds-lg border border-border bg-card p-4",
|
|
1389
|
+
role: "status",
|
|
1390
|
+
"aria-label": loadingLabel,
|
|
1391
|
+
children: [
|
|
1392
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-44" }),
|
|
1393
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" }),
|
|
1394
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" }),
|
|
1395
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-3/4" })
|
|
1396
|
+
]
|
|
1397
|
+
}) : error ? renderStateContent(error, /* @__PURE__ */ jsx(AlertTriangle, { className: "size-6" })) : children ? children : empty ? renderStateContent(empty) : null }),
|
|
1398
|
+
pagination ? /* @__PURE__ */ jsx(DataViewPagination, { children: renderPagination(pagination) }) : null
|
|
1399
|
+
]
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1402
|
+
function DataViewHeader({ title, description, actions, className, ...props }) {
|
|
1403
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1404
|
+
className: cn("flex flex-col gap-3 border-b border-border pb-4", "md:flex-row md:items-end md:justify-between", className),
|
|
1405
|
+
...props,
|
|
1406
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1407
|
+
className: "min-w-0",
|
|
1408
|
+
children: [title ? /* @__PURE__ */ jsx("h2", {
|
|
1409
|
+
className: "h2 truncate",
|
|
1410
|
+
children: title
|
|
1411
|
+
}) : null, description ? /* @__PURE__ */ jsx("p", {
|
|
1412
|
+
className: "mt-1 body-sm text-muted",
|
|
1413
|
+
children: description
|
|
1414
|
+
}) : null]
|
|
1415
|
+
}), actions ? /* @__PURE__ */ jsx("div", {
|
|
1416
|
+
className: "flex shrink-0 flex-wrap items-center gap-2",
|
|
1417
|
+
children: actions
|
|
1418
|
+
}) : null]
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
function DataViewToolbar({ title, description, search, filters, actions, className, ...props }) {
|
|
1422
|
+
return /* @__PURE__ */ jsxs(Toolbar, {
|
|
1423
|
+
className,
|
|
1424
|
+
...props,
|
|
1425
|
+
children: [
|
|
1426
|
+
/* @__PURE__ */ jsxs(ToolbarSection, { children: [title ? /* @__PURE__ */ jsx(ToolbarTitle, {
|
|
1427
|
+
title,
|
|
1428
|
+
description
|
|
1429
|
+
}) : null, search ? /* @__PURE__ */ jsx("div", {
|
|
1430
|
+
className: "min-w-64 flex-1",
|
|
1431
|
+
children: renderSearch(search)
|
|
1432
|
+
}) : null] }),
|
|
1433
|
+
actions ? /* @__PURE__ */ jsx(ToolbarActions, { children: actions }) : null,
|
|
1434
|
+
filters ? /* @__PURE__ */ jsx("div", {
|
|
1435
|
+
className: "basis-full",
|
|
1436
|
+
children: /* @__PURE__ */ jsx(FilterBar, { children: filters })
|
|
1437
|
+
}) : null
|
|
1438
|
+
]
|
|
1439
|
+
});
|
|
1440
|
+
}
|
|
1441
|
+
function DataViewContent({ className, ...props }) {
|
|
1442
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1443
|
+
className: cn("min-w-0", className),
|
|
1444
|
+
...props
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
function DataViewEmpty(props) {
|
|
1448
|
+
return /* @__PURE__ */ jsx(EmptyState, { ...props });
|
|
1449
|
+
}
|
|
1450
|
+
function DataViewPagination({ className, ...props }) {
|
|
1451
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1452
|
+
className: cn("rounded-fds-lg border border-border bg-card p-3", className),
|
|
1453
|
+
...props
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
//#endregion
|
|
1457
|
+
//#region src/components/popover.tsx
|
|
1458
|
+
const Popover = PopoverPrimitive.Root;
|
|
1459
|
+
const PopoverTrigger = PopoverPrimitive.Trigger;
|
|
1460
|
+
const PopoverAnchor = PopoverPrimitive.Anchor;
|
|
1461
|
+
const PopoverContent = React.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => {
|
|
1462
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(PopoverPrimitive.Content, {
|
|
1463
|
+
ref,
|
|
1464
|
+
align,
|
|
1465
|
+
sideOffset,
|
|
1466
|
+
className: cn("z-50 w-72 rounded-fds-md border border-border bg-popover p-4 text-popover-foreground shadow-md", "outline-none", "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0", "data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95", "data-[side=bottom]:slide-in-from-top-1", "data-[side=top]:slide-in-from-bottom-1", className),
|
|
1467
|
+
...props
|
|
1468
|
+
}) });
|
|
1469
|
+
});
|
|
1470
|
+
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
1471
|
+
//#endregion
|
|
1472
|
+
//#region src/components/date-picker.tsx
|
|
1473
|
+
function formatDate(date) {
|
|
1474
|
+
return format(date, "dd/MM/yyyy", { locale: ptBR$1 });
|
|
1475
|
+
}
|
|
1476
|
+
function DatePicker({ value, defaultValue, onValueChange, placeholder = "Selecionar data", disabled = false, required = false, clearable = true, className, calendarClassName, "aria-label": ariaLabel = "Selecionar data", "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }) {
|
|
1477
|
+
const [open, setOpen] = React.useState(false);
|
|
1478
|
+
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
1479
|
+
const selectedDate = value ?? internalValue;
|
|
1480
|
+
const isInvalid = ariaInvalid === true || ariaInvalid === "true";
|
|
1481
|
+
function updateDate(date) {
|
|
1482
|
+
if (value === void 0) setInternalValue(date);
|
|
1483
|
+
onValueChange?.(date);
|
|
1484
|
+
}
|
|
1485
|
+
function handleSelect(date) {
|
|
1486
|
+
updateDate(date);
|
|
1487
|
+
if (date) setOpen(false);
|
|
1488
|
+
}
|
|
1489
|
+
function handleClear(event) {
|
|
1490
|
+
event.stopPropagation();
|
|
1491
|
+
updateDate(void 0);
|
|
1492
|
+
}
|
|
1493
|
+
return /* @__PURE__ */ jsxs(Popover, {
|
|
1494
|
+
open,
|
|
1495
|
+
onOpenChange: setOpen,
|
|
1496
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1497
|
+
className: "relative w-full",
|
|
1498
|
+
children: [/* @__PURE__ */ jsx(PopoverTrigger, {
|
|
1499
|
+
asChild: true,
|
|
1500
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
1501
|
+
type: "button",
|
|
1502
|
+
variant: "outline",
|
|
1503
|
+
disabled,
|
|
1504
|
+
"aria-label": ariaLabel,
|
|
1505
|
+
"aria-describedby": ariaDescribedBy,
|
|
1506
|
+
"aria-invalid": ariaInvalid,
|
|
1507
|
+
"data-required": required ? "" : void 0,
|
|
1508
|
+
className: cn("h-10 w-full justify-start px-3 text-left font-normal", !selectedDate && "text-muted", isInvalid && "border-error focus-visible:ring-error", clearable && selectedDate && "pr-10", className),
|
|
1509
|
+
children: [/* @__PURE__ */ jsx(CalendarIcon, {
|
|
1510
|
+
"aria-hidden": "true",
|
|
1511
|
+
className: "size-4"
|
|
1512
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1513
|
+
className: "min-w-0 truncate",
|
|
1514
|
+
children: selectedDate ? formatDate(selectedDate) : placeholder
|
|
1515
|
+
})]
|
|
1516
|
+
})
|
|
1517
|
+
}), clearable && selectedDate && !disabled ? /* @__PURE__ */ jsx("button", {
|
|
1518
|
+
type: "button",
|
|
1519
|
+
"aria-label": "Limpar data",
|
|
1520
|
+
className: cn("absolute right-2 top-1/2 flex size-7 -translate-y-1/2 items-center justify-center rounded-sm", "text-muted transition-colors hover:bg-accent hover:text-on-surface", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35"),
|
|
1521
|
+
onClick: handleClear,
|
|
1522
|
+
children: /* @__PURE__ */ jsx(X, {
|
|
1523
|
+
"aria-hidden": "true",
|
|
1524
|
+
className: "size-4"
|
|
1525
|
+
})
|
|
1526
|
+
}) : null]
|
|
1527
|
+
}), /* @__PURE__ */ jsx(PopoverContent, {
|
|
1528
|
+
align: "start",
|
|
1529
|
+
className: "w-auto p-0",
|
|
1530
|
+
children: /* @__PURE__ */ jsx(Calendar, {
|
|
1531
|
+
mode: "single",
|
|
1532
|
+
selected: selectedDate,
|
|
1533
|
+
onSelect: handleSelect,
|
|
1534
|
+
disabled,
|
|
1535
|
+
className: calendarClassName,
|
|
1536
|
+
autoFocus: true
|
|
1537
|
+
})
|
|
1538
|
+
})]
|
|
1539
|
+
});
|
|
1540
|
+
}
|
|
1541
|
+
//#endregion
|
|
1542
|
+
//#region src/components/date-range-picker.tsx
|
|
1543
|
+
function formatRange(range) {
|
|
1544
|
+
if (!range?.from) return;
|
|
1545
|
+
if (!range.to) return formatDate(range.from);
|
|
1546
|
+
return `${formatDate(range.from)} - ${formatDate(range.to)}`;
|
|
1547
|
+
}
|
|
1548
|
+
function DateRangePicker({ value, defaultValue, onValueChange, placeholder = "Selecionar período", disabled = false, clearable = true, className, calendarClassName, "aria-label": ariaLabel = "Selecionar período", "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }) {
|
|
1549
|
+
const [open, setOpen] = React.useState(false);
|
|
1550
|
+
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
1551
|
+
const selectedRange = value ?? internalValue;
|
|
1552
|
+
const label = formatRange(selectedRange);
|
|
1553
|
+
const isInvalid = ariaInvalid === true || ariaInvalid === "true";
|
|
1554
|
+
function updateRange(range) {
|
|
1555
|
+
if (value === void 0) setInternalValue(range);
|
|
1556
|
+
onValueChange?.(range);
|
|
1557
|
+
}
|
|
1558
|
+
function handleClear(event) {
|
|
1559
|
+
event.stopPropagation();
|
|
1560
|
+
updateRange(void 0);
|
|
1561
|
+
}
|
|
1562
|
+
return /* @__PURE__ */ jsxs(Popover, {
|
|
1563
|
+
open,
|
|
1564
|
+
onOpenChange: setOpen,
|
|
1565
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1566
|
+
className: "relative w-full",
|
|
1567
|
+
children: [/* @__PURE__ */ jsx(PopoverTrigger, {
|
|
1568
|
+
asChild: true,
|
|
1569
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
1570
|
+
type: "button",
|
|
1571
|
+
variant: "outline",
|
|
1572
|
+
disabled,
|
|
1573
|
+
"aria-label": ariaLabel,
|
|
1574
|
+
"aria-describedby": ariaDescribedBy,
|
|
1575
|
+
"aria-invalid": ariaInvalid,
|
|
1576
|
+
className: cn("h-10 w-full justify-start px-3 text-left font-normal", !label && "text-muted", isInvalid && "border-error focus-visible:ring-error", clearable && label && "pr-10", className),
|
|
1577
|
+
children: [/* @__PURE__ */ jsx(CalendarIcon, {
|
|
1578
|
+
"aria-hidden": "true",
|
|
1579
|
+
className: "size-4"
|
|
1580
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1581
|
+
className: "min-w-0 truncate",
|
|
1582
|
+
children: label ?? placeholder
|
|
1583
|
+
})]
|
|
1584
|
+
})
|
|
1585
|
+
}), clearable && label && !disabled ? /* @__PURE__ */ jsx("button", {
|
|
1586
|
+
type: "button",
|
|
1587
|
+
"aria-label": "Limpar período",
|
|
1588
|
+
className: cn("absolute right-2 top-1/2 flex size-7 -translate-y-1/2 items-center justify-center rounded-sm", "text-muted transition-colors hover:bg-accent hover:text-on-surface", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35"),
|
|
1589
|
+
onClick: handleClear,
|
|
1590
|
+
children: /* @__PURE__ */ jsx(X, {
|
|
1591
|
+
"aria-hidden": "true",
|
|
1592
|
+
className: "size-4"
|
|
1593
|
+
})
|
|
1594
|
+
}) : null]
|
|
1595
|
+
}), /* @__PURE__ */ jsx(PopoverContent, {
|
|
1596
|
+
align: "start",
|
|
1597
|
+
className: "w-auto p-0",
|
|
1598
|
+
children: /* @__PURE__ */ jsx(Calendar, {
|
|
1599
|
+
mode: "range",
|
|
1600
|
+
selected: selectedRange,
|
|
1601
|
+
onSelect: updateRange,
|
|
1602
|
+
disabled,
|
|
1603
|
+
className: calendarClassName,
|
|
1604
|
+
autoFocus: true
|
|
1605
|
+
})
|
|
1606
|
+
})]
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
//#endregion
|
|
1610
|
+
//#region src/components/dropdown-menu.tsx
|
|
1611
|
+
const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
1612
|
+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
1613
|
+
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
1614
|
+
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
1615
|
+
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
1616
|
+
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
1617
|
+
const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => {
|
|
1618
|
+
return /* @__PURE__ */ jsxs(DropdownMenuPrimitive.SubTrigger, {
|
|
1619
|
+
ref,
|
|
1620
|
+
className: cn("flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none", "focus:bg-accent focus:text-accent-foreground", "data-[state=open]:bg-accent data-[state=open]:text-accent-foreground", inset && "pl-8", className),
|
|
1621
|
+
...props,
|
|
1622
|
+
children: [children, /* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto size-4" })]
|
|
1623
|
+
});
|
|
1624
|
+
});
|
|
1625
|
+
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
1626
|
+
const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => {
|
|
1627
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.SubContent, {
|
|
1628
|
+
ref,
|
|
1629
|
+
className: cn("z-50 min-w-40 overflow-hidden rounded-fds-md border border-border bg-popover p-1 text-popover-foreground shadow-md", className),
|
|
1630
|
+
...props
|
|
1631
|
+
});
|
|
1632
|
+
});
|
|
1633
|
+
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
1634
|
+
const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
|
|
1635
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.Content, {
|
|
1636
|
+
ref,
|
|
1637
|
+
sideOffset,
|
|
1638
|
+
className: cn("z-50 min-w-44 overflow-hidden rounded-fds-md border border-border bg-popover p-1 text-popover-foreground shadow-md", className),
|
|
1639
|
+
...props
|
|
1640
|
+
}) });
|
|
1641
|
+
});
|
|
1642
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
1643
|
+
const DropdownMenuItem = React.forwardRef(({ className, inset, tone = "default", ...props }, ref) => {
|
|
1644
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Item, {
|
|
1645
|
+
ref,
|
|
1646
|
+
className: cn("relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none", "transition-colors duration-100", "focus:bg-accent focus:text-accent-foreground", "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", inset && "pl-8", tone === "danger" && "text-error focus:bg-error-container focus:text-on-error-container", className),
|
|
1647
|
+
...props
|
|
1648
|
+
});
|
|
1649
|
+
});
|
|
1650
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
1651
|
+
const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => {
|
|
1652
|
+
return /* @__PURE__ */ jsxs(DropdownMenuPrimitive.CheckboxItem, {
|
|
1653
|
+
ref,
|
|
1654
|
+
className: cn("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none", "transition-colors duration-100", "focus:bg-accent focus:text-accent-foreground", "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
|
|
1655
|
+
checked,
|
|
1656
|
+
...props,
|
|
1657
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1658
|
+
className: "absolute left-2 flex size-4 items-center justify-center",
|
|
1659
|
+
children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "size-4" }) })
|
|
1660
|
+
}), children]
|
|
1661
|
+
});
|
|
1662
|
+
});
|
|
1663
|
+
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
1664
|
+
const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
1665
|
+
return /* @__PURE__ */ jsxs(DropdownMenuPrimitive.RadioItem, {
|
|
1666
|
+
ref,
|
|
1667
|
+
className: cn("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none", "transition-colors duration-100", "focus:bg-accent focus:text-accent-foreground", "data-disabled:pointer-events-none data-[disabled]:opacity-50", className),
|
|
1668
|
+
...props,
|
|
1669
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1670
|
+
className: "absolute left-2 flex size-4 items-center justify-center",
|
|
1671
|
+
children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Circle, { className: "size-2 fill-current" }) })
|
|
1672
|
+
}), children]
|
|
1673
|
+
});
|
|
1674
|
+
});
|
|
1675
|
+
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
1676
|
+
const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => {
|
|
1677
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Label, {
|
|
1678
|
+
ref,
|
|
1679
|
+
className: cn("px-2 py-1.5 caption mono uppercase tracking-[0.12em] text-muted-foreground", inset && "pl-8", className),
|
|
1680
|
+
...props
|
|
1681
|
+
});
|
|
1682
|
+
});
|
|
1683
|
+
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
1684
|
+
const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => {
|
|
1685
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Separator, {
|
|
1686
|
+
ref,
|
|
1687
|
+
className: cn("-mx-1 my-1 h-px bg-border", className),
|
|
1688
|
+
...props
|
|
1689
|
+
});
|
|
1690
|
+
});
|
|
1691
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
1692
|
+
function DropdownMenuShortcut({ className, ...props }) {
|
|
1693
|
+
return /* @__PURE__ */ jsx("span", {
|
|
1694
|
+
className: cn("ml-auto text-xs tracking-widest text-muted", className),
|
|
1695
|
+
...props
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
//#endregion
|
|
1699
|
+
//#region src/components/form.tsx
|
|
1700
|
+
const FormContext = React.createContext(null);
|
|
1701
|
+
const FormFieldContext = React.createContext(null);
|
|
1702
|
+
const FormItemContext = React.createContext(null);
|
|
1703
|
+
function useFormFieldContext() {
|
|
1704
|
+
const fieldContext = React.useContext(FormFieldContext);
|
|
1705
|
+
const itemContext = React.useContext(FormItemContext);
|
|
1706
|
+
if (!fieldContext) throw new Error("Form field components must be used inside <FormFieldController>.");
|
|
1707
|
+
const fieldId = itemContext?.id ?? fieldContext.name;
|
|
1708
|
+
const descriptionId = `${fieldId}-description`;
|
|
1709
|
+
const messageId = `${fieldId}-message`;
|
|
1710
|
+
const error = fieldContext.field.state.meta.errors.find(Boolean);
|
|
1711
|
+
return {
|
|
1712
|
+
...fieldContext,
|
|
1713
|
+
fieldId,
|
|
1714
|
+
descriptionId,
|
|
1715
|
+
messageId,
|
|
1716
|
+
error,
|
|
1717
|
+
hasError: Boolean(error)
|
|
1718
|
+
};
|
|
1719
|
+
}
|
|
1720
|
+
function getErrorMessage(error) {
|
|
1721
|
+
if (!error) return;
|
|
1722
|
+
if (typeof error === "string") return error;
|
|
1723
|
+
if (Array.isArray(error)) return getErrorMessage(error.find(Boolean));
|
|
1724
|
+
if (typeof error === "object" && "message" in error) return String(error.message);
|
|
1725
|
+
return String(error);
|
|
1726
|
+
}
|
|
1727
|
+
function Form({ form, children }) {
|
|
1728
|
+
return /* @__PURE__ */ jsx(FormContext.Provider, {
|
|
1729
|
+
value: { form },
|
|
1730
|
+
children
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
function FormFieldController({ form, name, validators, children }) {
|
|
1734
|
+
const context = React.useContext(FormContext);
|
|
1735
|
+
const formApi = form ?? context?.form;
|
|
1736
|
+
if (!formApi) throw new Error("FormFieldController requires a form prop or a parent <Form>.");
|
|
1737
|
+
const Field = formApi.Field;
|
|
1738
|
+
return /* @__PURE__ */ jsx(Field, {
|
|
1739
|
+
name,
|
|
1740
|
+
validators,
|
|
1741
|
+
children: (field) => /* @__PURE__ */ jsx(FormFieldContext.Provider, {
|
|
1742
|
+
value: {
|
|
1743
|
+
field,
|
|
1744
|
+
name
|
|
1745
|
+
},
|
|
1746
|
+
children: children(field)
|
|
1747
|
+
})
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1750
|
+
function FormItem({ className, ...props }) {
|
|
1751
|
+
const id = React.useId();
|
|
1752
|
+
return /* @__PURE__ */ jsx(FormItemContext.Provider, {
|
|
1753
|
+
value: { id },
|
|
1754
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1755
|
+
className: cn("grid gap-1.5", className),
|
|
1756
|
+
...props
|
|
1757
|
+
})
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
function FormLabel({ className, ...props }) {
|
|
1761
|
+
const { fieldId, hasError } = useFormFieldContext();
|
|
1762
|
+
return /* @__PURE__ */ jsx(Label, {
|
|
1763
|
+
htmlFor: fieldId,
|
|
1764
|
+
className: cn(hasError && "text-destructive", className),
|
|
1765
|
+
...props
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
function FormControl({ children }) {
|
|
1769
|
+
const { fieldId, descriptionId, messageId, hasError } = useFormFieldContext();
|
|
1770
|
+
const describedBy = hasError ? `${descriptionId} ${messageId}` : descriptionId;
|
|
1771
|
+
return React.cloneElement(children, {
|
|
1772
|
+
id: children.props.id ?? fieldId,
|
|
1773
|
+
"aria-describedby": [children.props["aria-describedby"], describedBy].filter(Boolean).join(" "),
|
|
1774
|
+
"aria-invalid": hasError ? true : children.props["aria-invalid"]
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1777
|
+
function FormDescription({ className, ...props }) {
|
|
1778
|
+
const { descriptionId } = useFormFieldContext();
|
|
1779
|
+
return /* @__PURE__ */ jsx("p", {
|
|
1780
|
+
id: descriptionId,
|
|
1781
|
+
className: cn("caption text-muted", className),
|
|
1782
|
+
...props
|
|
1783
|
+
});
|
|
1784
|
+
}
|
|
1785
|
+
function FormMessage({ className, children, ...props }) {
|
|
1786
|
+
const { messageId, error } = useFormFieldContext();
|
|
1787
|
+
const body = children ?? getErrorMessage(error);
|
|
1788
|
+
if (!body) return null;
|
|
1789
|
+
return /* @__PURE__ */ jsx("p", {
|
|
1790
|
+
id: messageId,
|
|
1791
|
+
className: cn("caption text-destructive", className),
|
|
1792
|
+
role: "alert",
|
|
1793
|
+
...props,
|
|
1794
|
+
children: body
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
function getInputFieldProps(field) {
|
|
1798
|
+
return {
|
|
1799
|
+
name: field.name,
|
|
1800
|
+
value: field.state.value ?? "",
|
|
1801
|
+
onBlur: field.handleBlur,
|
|
1802
|
+
onChange: (event) => field.handleChange(event.target.value)
|
|
1803
|
+
};
|
|
1804
|
+
}
|
|
1805
|
+
function getSelectFieldProps(field) {
|
|
1806
|
+
return {
|
|
1807
|
+
value: field.state.value ?? "",
|
|
1808
|
+
onValueChange: (value) => field.handleChange(value)
|
|
1809
|
+
};
|
|
1810
|
+
}
|
|
1811
|
+
function getCheckboxFieldProps(field) {
|
|
1812
|
+
return {
|
|
1813
|
+
checked: Boolean(field.state.value),
|
|
1814
|
+
onCheckedChange: (value) => field.handleChange(value === true)
|
|
1815
|
+
};
|
|
1816
|
+
}
|
|
1817
|
+
function getRadioGroupFieldProps(field) {
|
|
1818
|
+
return {
|
|
1819
|
+
value: field.state.value ?? "",
|
|
1820
|
+
onValueChange: (value) => field.handleChange(value)
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
function getSwitchFieldProps(field) {
|
|
1824
|
+
return {
|
|
1825
|
+
checked: Boolean(field.state.value),
|
|
1826
|
+
onCheckedChange: (value) => field.handleChange(value)
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1829
|
+
function getDatePickerFieldProps(field) {
|
|
1830
|
+
return {
|
|
1831
|
+
value: field.state.value,
|
|
1832
|
+
onValueChange: (value) => field.handleChange(value)
|
|
1833
|
+
};
|
|
1834
|
+
}
|
|
1835
|
+
//#endregion
|
|
1836
|
+
//#region src/components/form-field.tsx
|
|
1837
|
+
function FormField({ id, label, helperText, error, required = false, className, children }) {
|
|
1838
|
+
const generatedId = React.useId();
|
|
1839
|
+
const fieldId = id ?? generatedId;
|
|
1840
|
+
const helperId = helperText ? `${fieldId}-helper` : void 0;
|
|
1841
|
+
const errorId = error ? `${fieldId}-error` : void 0;
|
|
1842
|
+
const describedBy = [helperId, errorId].filter(Boolean).join(" ") || void 0;
|
|
1843
|
+
const child = React.Children.only(children);
|
|
1844
|
+
const control = React.cloneElement(child, {
|
|
1845
|
+
id: child.props.id ?? fieldId,
|
|
1846
|
+
required: child.props.required ?? required,
|
|
1847
|
+
"aria-required": child.props["aria-required"] ?? (required ? true : void 0),
|
|
1848
|
+
"aria-describedby": describedBy,
|
|
1849
|
+
"aria-invalid": error ? true : child.props["aria-invalid"]
|
|
1850
|
+
});
|
|
1851
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1852
|
+
className: cn("flex w-full flex-col gap-1.5", className),
|
|
1853
|
+
children: [
|
|
1854
|
+
/* @__PURE__ */ jsx(Label, {
|
|
1855
|
+
htmlFor: fieldId,
|
|
1856
|
+
required,
|
|
1857
|
+
children: label
|
|
1858
|
+
}),
|
|
1859
|
+
control,
|
|
1860
|
+
helperText && !error ? /* @__PURE__ */ jsx("p", {
|
|
1861
|
+
id: helperId,
|
|
1862
|
+
className: "caption text-muted",
|
|
1863
|
+
children: helperText
|
|
1864
|
+
}) : null,
|
|
1865
|
+
error ? /* @__PURE__ */ jsx("p", {
|
|
1866
|
+
id: errorId,
|
|
1867
|
+
className: "caption text-error",
|
|
1868
|
+
role: "alert",
|
|
1869
|
+
children: error
|
|
1870
|
+
}) : null
|
|
1871
|
+
]
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
//#endregion
|
|
1875
|
+
//#region src/components/input.tsx
|
|
1876
|
+
const inputVariants = cva([
|
|
1877
|
+
"flex h-10 w-full",
|
|
1878
|
+
"rounded-fds-md border bg-surface px-3 py-2",
|
|
1879
|
+
"body-sm text-on-surface",
|
|
1880
|
+
"transition-colors duration-150",
|
|
1881
|
+
"placeholder:text-on-surface-variant",
|
|
1882
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-surface",
|
|
1883
|
+
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
1884
|
+
], {
|
|
1885
|
+
variants: { state: {
|
|
1886
|
+
default: "border-outline focus-visible:border-ring focus-visible:ring-ring",
|
|
1887
|
+
error: "border-error focus-visible:border-error focus-visible:ring-error"
|
|
1888
|
+
} },
|
|
1889
|
+
defaultVariants: { state: "default" }
|
|
1890
|
+
});
|
|
1891
|
+
const Input = React.forwardRef(({ className, state, ...props }, ref) => {
|
|
1892
|
+
return /* @__PURE__ */ jsx("input", {
|
|
1893
|
+
ref,
|
|
1894
|
+
className: cn(inputVariants({ state: props["aria-invalid"] === true || props["aria-invalid"] === "true" ? "error" : state }), className),
|
|
1895
|
+
...props
|
|
1896
|
+
});
|
|
1897
|
+
});
|
|
1898
|
+
Input.displayName = "Input";
|
|
1899
|
+
//#endregion
|
|
1900
|
+
//#region src/components/native-select.tsx
|
|
1901
|
+
const nativeSelectVariants = cva([
|
|
1902
|
+
"h-9 w-full appearance-none",
|
|
1903
|
+
"rounded-fds-md border border-input bg-transparent px-3 py-2 pr-9",
|
|
1904
|
+
"body-sm text-on-surface shadow-sm outline-none",
|
|
1905
|
+
"transition-[color,box-shadow,border-color,background-color] duration-150",
|
|
1906
|
+
"focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/35",
|
|
1907
|
+
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
1908
|
+
], {
|
|
1909
|
+
variants: {
|
|
1910
|
+
state: {
|
|
1911
|
+
default: "",
|
|
1912
|
+
error: "border-destructive focus-visible:border-destructive focus-visible:ring-destructive/25"
|
|
1913
|
+
},
|
|
1914
|
+
fieldSize: {
|
|
1915
|
+
sm: "h-8 px-2 pr-8 text-sm",
|
|
1916
|
+
md: "h-9 px-3 pr-9 text-sm",
|
|
1917
|
+
lg: "h-10 px-4 pr-10 text-base"
|
|
1918
|
+
}
|
|
1919
|
+
},
|
|
1920
|
+
defaultVariants: {
|
|
1921
|
+
state: "default",
|
|
1922
|
+
fieldSize: "md"
|
|
1923
|
+
}
|
|
1924
|
+
});
|
|
1925
|
+
const NativeSelect = React.forwardRef(({ className, state, fieldSize, placeholder = "Selecione uma opção", options, children, ...props }, ref) => {
|
|
1926
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1927
|
+
className: "relative w-full",
|
|
1928
|
+
children: [/* @__PURE__ */ jsxs("select", {
|
|
1929
|
+
ref,
|
|
1930
|
+
className: cn(nativeSelectVariants({
|
|
1931
|
+
state: props["aria-invalid"] === true || props["aria-invalid"] === "true" ? "error" : state,
|
|
1932
|
+
fieldSize
|
|
1933
|
+
}), className),
|
|
1934
|
+
defaultValue: props.defaultValue ?? "",
|
|
1935
|
+
...props,
|
|
1936
|
+
children: [placeholder ? /* @__PURE__ */ jsx("option", {
|
|
1937
|
+
value: "",
|
|
1938
|
+
disabled: true,
|
|
1939
|
+
children: placeholder
|
|
1940
|
+
}) : null, options ? options.map((option) => /* @__PURE__ */ jsx("option", {
|
|
1941
|
+
value: option.value,
|
|
1942
|
+
disabled: option.disabled,
|
|
1943
|
+
children: option.label
|
|
1944
|
+
}, option.value)) : children]
|
|
1945
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1946
|
+
"aria-hidden": "true",
|
|
1947
|
+
className: "pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground",
|
|
1948
|
+
children: /* @__PURE__ */ jsxs("svg", {
|
|
1949
|
+
width: "16",
|
|
1950
|
+
height: "16",
|
|
1951
|
+
viewBox: "0 0 24 24",
|
|
1952
|
+
fill: "none",
|
|
1953
|
+
stroke: "currentColor",
|
|
1954
|
+
strokeWidth: "2",
|
|
1955
|
+
strokeLinecap: "round",
|
|
1956
|
+
strokeLinejoin: "round",
|
|
1957
|
+
children: [/* @__PURE__ */ jsx("title", { children: "▾" }), /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })]
|
|
1958
|
+
})
|
|
1959
|
+
})]
|
|
1960
|
+
});
|
|
1961
|
+
});
|
|
1962
|
+
NativeSelect.displayName = "NativeSelect";
|
|
1963
|
+
//#endregion
|
|
1964
|
+
//#region src/components/page-header.tsx
|
|
1965
|
+
function PageHeader({ className, eyebrow, title, description, actions, ...props }) {
|
|
1966
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1967
|
+
className: cn("flex flex-col gap-4 border-b border-border pb-6", "md:flex-row md:items-end md:justify-between", className),
|
|
1968
|
+
...props,
|
|
1969
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1970
|
+
className: "min-w-0",
|
|
1971
|
+
children: [
|
|
1972
|
+
eyebrow ? /* @__PURE__ */ jsx("div", {
|
|
1973
|
+
className: "mb-2 caption mono uppercase tracking-[0.12em] text-muted",
|
|
1974
|
+
children: eyebrow
|
|
1975
|
+
}) : null,
|
|
1976
|
+
/* @__PURE__ */ jsx("h1", {
|
|
1977
|
+
className: "h1 truncate",
|
|
1978
|
+
children: title
|
|
1979
|
+
}),
|
|
1980
|
+
description ? /* @__PURE__ */ jsx("p", {
|
|
1981
|
+
className: "mt-2 max-w-3xl body text-muted",
|
|
1982
|
+
children: description
|
|
1983
|
+
}) : null
|
|
1984
|
+
]
|
|
1985
|
+
}), actions ? /* @__PURE__ */ jsx("div", {
|
|
1986
|
+
className: "flex shrink-0 flex-wrap items-center gap-2",
|
|
1987
|
+
children: actions
|
|
1988
|
+
}) : null]
|
|
1989
|
+
});
|
|
1990
|
+
}
|
|
1991
|
+
//#endregion
|
|
1992
|
+
//#region src/components/radio-group.tsx
|
|
1993
|
+
const RadioGroup = React.forwardRef(({ className, options, error = false, ...props }, ref) => {
|
|
1994
|
+
const generatedId = React.useId();
|
|
1995
|
+
return /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, {
|
|
1996
|
+
ref,
|
|
1997
|
+
className: cn("grid gap-2", className),
|
|
1998
|
+
...props,
|
|
1999
|
+
children: options.map((option) => {
|
|
2000
|
+
const itemId = `${generatedId}-${option.value}`;
|
|
2001
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2002
|
+
className: cn("flex items-start gap-3 rounded-fds-md border border-border p-3", "transition-colors duration-150", "has-data-[state=checked]:border-primary", "has-data-[state=checked]:bg-primary-container", option.disabled && "opacity-60"),
|
|
2003
|
+
children: [/* @__PURE__ */ jsx(RadioGroupPrimitive.Item, {
|
|
2004
|
+
id: itemId,
|
|
2005
|
+
value: option.value,
|
|
2006
|
+
disabled: option.disabled,
|
|
2007
|
+
className: cn("mt-0.5 size-4 shrink-0 rounded-full border border-input bg-transparent shadow-sm", "transition-[color,box-shadow,border-color,background-color] duration-150", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35", "disabled:cursor-not-allowed disabled:opacity-50", "data-[state=checked]:border-primary", error && "border-destructive focus-visible:ring-destructive/25"),
|
|
2008
|
+
children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, {
|
|
2009
|
+
className: "flex size-full items-center justify-center",
|
|
2010
|
+
children: /* @__PURE__ */ jsx("span", { className: "size-2 rounded-full bg-primary" })
|
|
2011
|
+
})
|
|
2012
|
+
}), /* @__PURE__ */ jsxs("label", {
|
|
2013
|
+
htmlFor: itemId,
|
|
2014
|
+
className: "grid flex-1 gap-1",
|
|
2015
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
2016
|
+
className: "body-sm font-medium text-on-surface",
|
|
2017
|
+
children: option.label
|
|
2018
|
+
}), option.description ? /* @__PURE__ */ jsx("span", {
|
|
2019
|
+
className: "caption text-muted",
|
|
2020
|
+
children: option.description
|
|
2021
|
+
}) : null]
|
|
2022
|
+
})]
|
|
2023
|
+
}, option.value);
|
|
2024
|
+
})
|
|
2025
|
+
});
|
|
2026
|
+
});
|
|
2027
|
+
RadioGroup.displayName = "RadioGroup";
|
|
2028
|
+
//#endregion
|
|
2029
|
+
//#region src/components/select.tsx
|
|
2030
|
+
function isGroupedOptions(options) {
|
|
2031
|
+
return options.length > 0 && "options" in options[0];
|
|
2032
|
+
}
|
|
2033
|
+
const Select = React.forwardRef(({ id, placeholder = "Selecione uma opção", options, className, contentClassName, disabled, required, name, value, defaultValue, onValueChange, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, ...props }, ref) => {
|
|
2034
|
+
const isInvalid = ariaInvalid === true || ariaInvalid === "true";
|
|
2035
|
+
return /* @__PURE__ */ jsxs(SelectPrimitive.Root, {
|
|
2036
|
+
disabled,
|
|
2037
|
+
required,
|
|
2038
|
+
name,
|
|
2039
|
+
value,
|
|
2040
|
+
defaultValue,
|
|
2041
|
+
onValueChange,
|
|
2042
|
+
...props,
|
|
2043
|
+
children: [/* @__PURE__ */ jsxs(SelectPrimitive.Trigger, {
|
|
2044
|
+
ref,
|
|
2045
|
+
id,
|
|
2046
|
+
"aria-describedby": ariaDescribedBy,
|
|
2047
|
+
"aria-invalid": ariaInvalid,
|
|
2048
|
+
"aria-required": required ? true : void 0,
|
|
2049
|
+
className: cn("flex h-9 w-full items-center justify-between gap-2 whitespace-nowrap", "rounded-fds-md border border-input bg-transparent px-3 py-2", "body-sm text-on-surface shadow-sm outline-none", "transition-[color,box-shadow,border-color,background-color] duration-150", "data-placeholder:text-muted-foreground", "hover:bg-accent", "focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/35", "disabled:cursor-not-allowed disabled:opacity-50", isInvalid && "border-destructive focus-visible:border-destructive focus-visible:ring-destructive/25", className),
|
|
2050
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
2051
|
+
className: "min-w-0 truncate text-left",
|
|
2052
|
+
children: /* @__PURE__ */ jsx(SelectPrimitive.Value, { placeholder })
|
|
2053
|
+
}), /* @__PURE__ */ jsx(SelectPrimitive.Icon, {
|
|
2054
|
+
asChild: true,
|
|
2055
|
+
children: /* @__PURE__ */ jsx(ChevronDown, {
|
|
2056
|
+
"aria-hidden": "true",
|
|
2057
|
+
className: "size-4 shrink-0 text-muted-foreground opacity-70"
|
|
2058
|
+
})
|
|
2059
|
+
})]
|
|
2060
|
+
}), /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx(SelectPrimitive.Content, {
|
|
2061
|
+
position: "popper",
|
|
2062
|
+
sideOffset: 4,
|
|
2063
|
+
align: "start",
|
|
2064
|
+
className: cn("relative z-50 max-h-72 min-w-(--radix-select-trigger-width) overflow-hidden", "rounded-fds-md border border-border bg-popover text-popover-foreground", "shadow-md", contentClassName),
|
|
2065
|
+
children: /* @__PURE__ */ jsx(SelectPrimitive.Viewport, {
|
|
2066
|
+
className: "p-1",
|
|
2067
|
+
children: isGroupedOptions(options) ? options.map((group, groupIndex) => /* @__PURE__ */ jsxs(SelectPrimitive.Group, { children: [
|
|
2068
|
+
groupIndex > 0 ? /* @__PURE__ */ jsx(SelectPrimitive.Separator, { className: "my-1 h-px bg-border" }) : null,
|
|
2069
|
+
/* @__PURE__ */ jsx(SelectPrimitive.Label, {
|
|
2070
|
+
className: "px-2 py-1.5 caption mono uppercase tracking-[0.12em] text-muted-foreground",
|
|
2071
|
+
children: group.label
|
|
2072
|
+
}),
|
|
2073
|
+
group.options.map((option) => /* @__PURE__ */ jsx(SelectItem, { option }, option.value))
|
|
2074
|
+
] }, group.label)) : options.map((option) => /* @__PURE__ */ jsx(SelectItem, { option }, option.value))
|
|
2075
|
+
})
|
|
2076
|
+
}) })]
|
|
2077
|
+
});
|
|
2078
|
+
});
|
|
2079
|
+
Select.displayName = "Select";
|
|
2080
|
+
function SelectItem({ option }) {
|
|
2081
|
+
return /* @__PURE__ */ jsxs(SelectPrimitive.Item, {
|
|
2082
|
+
value: option.value,
|
|
2083
|
+
disabled: option.disabled,
|
|
2084
|
+
className: cn("relative flex w-full cursor-default select-none items-center", "rounded-sm py-1.5 pl-2 pr-8 outline-none", "text-sm", "transition-colors duration-100", "data-highlighted:bg-accent data-highlighted:text-accent-foreground", "data-disabled:pointer-events-none data-disabled:opacity-50"),
|
|
2085
|
+
children: [/* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children: /* @__PURE__ */ jsx("span", {
|
|
2086
|
+
className: "truncate",
|
|
2087
|
+
children: option.label
|
|
2088
|
+
}) }), /* @__PURE__ */ jsx("span", {
|
|
2089
|
+
className: "absolute right-2 flex size-4 items-center justify-center",
|
|
2090
|
+
children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "size-4 text-primary" }) })
|
|
2091
|
+
})]
|
|
2092
|
+
});
|
|
2093
|
+
}
|
|
2094
|
+
//#endregion
|
|
2095
|
+
//#region src/components/separator.tsx
|
|
2096
|
+
const Separator = React.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => {
|
|
2097
|
+
return /* @__PURE__ */ jsx(SeparatorPrimitive.Root, {
|
|
2098
|
+
ref,
|
|
2099
|
+
decorative,
|
|
2100
|
+
orientation,
|
|
2101
|
+
className: cn("shrink-0 bg-border", orientation === "horizontal" ? "h-px w-full" : "h-full w-px", className),
|
|
2102
|
+
...props
|
|
2103
|
+
});
|
|
2104
|
+
});
|
|
2105
|
+
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
|
2106
|
+
//#endregion
|
|
2107
|
+
//#region src/components/sheet.tsx
|
|
2108
|
+
const Sheet = DialogPrimitive.Root;
|
|
2109
|
+
const SheetTrigger = DialogPrimitive.Trigger;
|
|
2110
|
+
const SheetClose = DialogPrimitive.Close;
|
|
2111
|
+
const SheetPortal = DialogPrimitive.Portal;
|
|
2112
|
+
const SheetOverlay = React.forwardRef(({ className, ...props }, ref) => {
|
|
2113
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Overlay, {
|
|
2114
|
+
ref,
|
|
2115
|
+
className: cn("fixed inset-0 z-50 bg-black/45", "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0", className),
|
|
2116
|
+
...props
|
|
2117
|
+
});
|
|
2118
|
+
});
|
|
2119
|
+
SheetOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
2120
|
+
const sheetVariants = cva([
|
|
2121
|
+
"fixed z-50 gap-4 bg-popover text-popover-foreground shadow-lg",
|
|
2122
|
+
"transition ease-in-out",
|
|
2123
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
2124
|
+
"data-[state=closed]:duration-300 data-[state=open]:duration-500"
|
|
2125
|
+
], {
|
|
2126
|
+
variants: { side: {
|
|
2127
|
+
top: [
|
|
2128
|
+
"inset-x-0 top-0 border-b border-border",
|
|
2129
|
+
"data-[state=closed]:slide-out-to-top",
|
|
2130
|
+
"data-[state=open]:slide-in-from-top"
|
|
2131
|
+
],
|
|
2132
|
+
bottom: [
|
|
2133
|
+
"inset-x-0 bottom-0 border-t border-border",
|
|
2134
|
+
"data-[state=closed]:slide-out-to-bottom",
|
|
2135
|
+
"data-[state=open]:slide-in-from-bottom"
|
|
2136
|
+
],
|
|
2137
|
+
left: [
|
|
2138
|
+
"inset-y-0 left-0 h-full w-3/4 border-r border-border sm:max-w-sm",
|
|
2139
|
+
"data-[state=closed]:slide-out-to-left",
|
|
2140
|
+
"data-[state=open]:slide-in-from-left"
|
|
2141
|
+
],
|
|
2142
|
+
right: [
|
|
2143
|
+
"inset-y-0 right-0 h-full w-3/4 border-l border-border sm:max-w-sm",
|
|
2144
|
+
"data-[state=closed]:slide-out-to-right",
|
|
2145
|
+
"data-[state=open]:slide-in-from-right"
|
|
2146
|
+
]
|
|
2147
|
+
} },
|
|
2148
|
+
defaultVariants: { side: "right" }
|
|
2149
|
+
});
|
|
2150
|
+
const SheetContent = React.forwardRef(({ side = "right", className, children, showCloseButton = true, ...props }, ref) => {
|
|
2151
|
+
return /* @__PURE__ */ jsxs(SheetPortal, { children: [/* @__PURE__ */ jsx(SheetOverlay, {}), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
|
|
2152
|
+
ref,
|
|
2153
|
+
className: cn(sheetVariants({ side }), className),
|
|
2154
|
+
...props,
|
|
2155
|
+
children: [children, showCloseButton ? /* @__PURE__ */ jsxs(DialogPrimitive.Close, {
|
|
2156
|
+
className: cn("absolute right-4 top-4 rounded-sm opacity-70", "transition-opacity hover:opacity-100", "focus:outline-none focus:ring-2 focus:ring-ring/35", "disabled:pointer-events-none"),
|
|
2157
|
+
children: [/* @__PURE__ */ jsx(X, { className: "size-4" }), /* @__PURE__ */ jsx("span", {
|
|
2158
|
+
className: "sr-only",
|
|
2159
|
+
children: "Fechar"
|
|
2160
|
+
})]
|
|
2161
|
+
}) : null]
|
|
2162
|
+
})] });
|
|
2163
|
+
});
|
|
2164
|
+
SheetContent.displayName = DialogPrimitive.Content.displayName;
|
|
2165
|
+
function SheetHeader({ className, ...props }) {
|
|
2166
|
+
return /* @__PURE__ */ jsx("div", {
|
|
2167
|
+
className: cn("flex flex-col gap-1.5 text-left", className),
|
|
2168
|
+
...props
|
|
2169
|
+
});
|
|
2170
|
+
}
|
|
2171
|
+
function SheetFooter({ className, ...props }) {
|
|
2172
|
+
return /* @__PURE__ */ jsx("div", {
|
|
2173
|
+
className: cn("mt-auto flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
|
|
2174
|
+
...props
|
|
2175
|
+
});
|
|
2176
|
+
}
|
|
2177
|
+
const SheetTitle = React.forwardRef(({ className, ...props }, ref) => {
|
|
2178
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Title, {
|
|
2179
|
+
ref,
|
|
2180
|
+
className: cn("h3 text-on-surface", className),
|
|
2181
|
+
...props
|
|
2182
|
+
});
|
|
2183
|
+
});
|
|
2184
|
+
SheetTitle.displayName = DialogPrimitive.Title.displayName;
|
|
2185
|
+
const SheetDescription = React.forwardRef(({ className, ...props }, ref) => {
|
|
2186
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Description, {
|
|
2187
|
+
ref,
|
|
2188
|
+
className: cn("body-sm text-muted", className),
|
|
2189
|
+
...props
|
|
2190
|
+
});
|
|
2191
|
+
});
|
|
2192
|
+
SheetDescription.displayName = DialogPrimitive.Description.displayName;
|
|
2193
|
+
//#endregion
|
|
2194
|
+
//#region src/components/sidebar.tsx
|
|
2195
|
+
function Sidebar({ className, ...props }) {
|
|
2196
|
+
return /* @__PURE__ */ jsx("div", {
|
|
2197
|
+
className: cn("flex h-full min-h-0 flex-col bg-card text-card-foreground", className),
|
|
2198
|
+
...props
|
|
2199
|
+
});
|
|
2200
|
+
}
|
|
2201
|
+
function SidebarHeader({ className, ...props }) {
|
|
2202
|
+
return /* @__PURE__ */ jsx("div", {
|
|
2203
|
+
className: cn("flex min-h-16 items-center border-b border-border px-4", className),
|
|
2204
|
+
...props
|
|
2205
|
+
});
|
|
2206
|
+
}
|
|
2207
|
+
function SidebarBrand({ title, description, icon, className, ...props }) {
|
|
2208
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2209
|
+
className: cn("flex min-w-0 items-center gap-3", className),
|
|
2210
|
+
...props,
|
|
2211
|
+
children: [icon ? /* @__PURE__ */ jsx("div", {
|
|
2212
|
+
className: "flex size-9 shrink-0 items-center justify-center rounded-fds-md bg-primary text-on-primary",
|
|
2213
|
+
children: icon
|
|
2214
|
+
}) : null, /* @__PURE__ */ jsxs("div", {
|
|
2215
|
+
className: "min-w-0",
|
|
2216
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
2217
|
+
className: "truncate body-sm font-semibold text-on-surface",
|
|
2218
|
+
children: title
|
|
2219
|
+
}), description ? /* @__PURE__ */ jsx("p", {
|
|
2220
|
+
className: "truncate caption text-muted",
|
|
2221
|
+
children: description
|
|
2222
|
+
}) : null]
|
|
2223
|
+
})]
|
|
2224
|
+
});
|
|
2225
|
+
}
|
|
2226
|
+
function SidebarContent({ className, ...props }) {
|
|
2227
|
+
return /* @__PURE__ */ jsx("div", {
|
|
2228
|
+
className: cn("min-h-0 flex-1 overflow-y-auto px-3 py-4", className),
|
|
2229
|
+
...props
|
|
2230
|
+
});
|
|
2231
|
+
}
|
|
2232
|
+
function SidebarSection({ title, className, children, ...props }) {
|
|
2233
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2234
|
+
className: cn("grid gap-1", className),
|
|
2235
|
+
...props,
|
|
2236
|
+
children: [title ? /* @__PURE__ */ jsx("p", {
|
|
2237
|
+
className: "px-3 pb-2 caption mono uppercase tracking-[0.12em] text-muted",
|
|
2238
|
+
children: title
|
|
2239
|
+
}) : null, children]
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2242
|
+
const SidebarNavItem = React.forwardRef(({ icon, active = false, asChild = false, className, children, ...props }, ref) => {
|
|
2243
|
+
return /* @__PURE__ */ jsxs(asChild ? Slot : "button", {
|
|
2244
|
+
ref,
|
|
2245
|
+
className: cn("flex h-9 w-full items-center gap-3 rounded-fds-md px-3 text-left body-sm", "transition-colors duration-150", "hover:bg-accent hover:text-accent-foreground", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35", "disabled:pointer-events-none disabled:opacity-50", active ? "bg-primary-container text-on-primary-container" : "text-muted-foreground", className),
|
|
2246
|
+
...props,
|
|
2247
|
+
children: [icon ? /* @__PURE__ */ jsx("span", {
|
|
2248
|
+
className: "flex size-4 shrink-0 items-center justify-center",
|
|
2249
|
+
children: icon
|
|
2250
|
+
}) : null, /* @__PURE__ */ jsx("span", {
|
|
2251
|
+
className: "min-w-0 truncate",
|
|
2252
|
+
children
|
|
2253
|
+
})]
|
|
2254
|
+
});
|
|
2255
|
+
});
|
|
2256
|
+
SidebarNavItem.displayName = "SidebarNavItem";
|
|
2257
|
+
function SidebarFooter({ className, ...props }) {
|
|
2258
|
+
return /* @__PURE__ */ jsx("div", {
|
|
2259
|
+
className: cn("border-t border-border p-3", className),
|
|
2260
|
+
...props
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2263
|
+
//#endregion
|
|
2264
|
+
//#region src/components/spinner.tsx
|
|
2265
|
+
const spinnerVariants = cva("animate-spin", {
|
|
2266
|
+
variants: {
|
|
2267
|
+
size: {
|
|
2268
|
+
sm: "size-4",
|
|
2269
|
+
md: "size-5",
|
|
2270
|
+
lg: "size-7"
|
|
2271
|
+
},
|
|
2272
|
+
tone: {
|
|
2273
|
+
current: "text-current",
|
|
2274
|
+
primary: "text-primary",
|
|
2275
|
+
muted: "text-muted-foreground",
|
|
2276
|
+
danger: "text-error",
|
|
2277
|
+
success: "text-success",
|
|
2278
|
+
warning: "text-warning",
|
|
2279
|
+
info: "text-info"
|
|
2280
|
+
}
|
|
2281
|
+
},
|
|
2282
|
+
defaultVariants: {
|
|
2283
|
+
size: "md",
|
|
2284
|
+
tone: "current"
|
|
2285
|
+
}
|
|
2286
|
+
});
|
|
2287
|
+
function Spinner({ className, size, tone, ...props }) {
|
|
2288
|
+
return /* @__PURE__ */ jsx(LoaderCircle, {
|
|
2289
|
+
role: "status",
|
|
2290
|
+
"aria-label": "Carregando",
|
|
2291
|
+
className: cn(spinnerVariants({
|
|
2292
|
+
size,
|
|
2293
|
+
tone
|
|
2294
|
+
}), className),
|
|
2295
|
+
...props
|
|
2296
|
+
});
|
|
2297
|
+
}
|
|
2298
|
+
//#endregion
|
|
2299
|
+
//#region src/components/status-badge.tsx
|
|
2300
|
+
const statusConfig = {
|
|
2301
|
+
active: {
|
|
2302
|
+
label: "Ativo",
|
|
2303
|
+
tone: "success"
|
|
2304
|
+
},
|
|
2305
|
+
inactive: {
|
|
2306
|
+
label: "Inativo",
|
|
2307
|
+
tone: "neutral"
|
|
2308
|
+
},
|
|
2309
|
+
pending: {
|
|
2310
|
+
label: "Pendente",
|
|
2311
|
+
tone: "warning"
|
|
2312
|
+
},
|
|
2313
|
+
completed: {
|
|
2314
|
+
label: "Concluído",
|
|
2315
|
+
tone: "success"
|
|
2316
|
+
},
|
|
2317
|
+
canceled: {
|
|
2318
|
+
label: "Cancelado",
|
|
2319
|
+
tone: "danger"
|
|
2320
|
+
},
|
|
2321
|
+
draft: {
|
|
2322
|
+
label: "Rascunho",
|
|
2323
|
+
tone: "info"
|
|
2324
|
+
},
|
|
2325
|
+
blocked: {
|
|
2326
|
+
label: "Bloqueado",
|
|
2327
|
+
tone: "danger"
|
|
2328
|
+
},
|
|
2329
|
+
archived: {
|
|
2330
|
+
label: "Arquivado",
|
|
2331
|
+
tone: "secondary"
|
|
2332
|
+
}
|
|
2333
|
+
};
|
|
2334
|
+
function StatusBadge({ status, label, tone, variant = "soft", ...props }) {
|
|
2335
|
+
const config = statusConfig[status];
|
|
2336
|
+
return /* @__PURE__ */ jsx(Badge, {
|
|
2337
|
+
tone: tone ?? config.tone,
|
|
2338
|
+
variant,
|
|
2339
|
+
...props,
|
|
2340
|
+
children: label ?? config.label
|
|
2341
|
+
});
|
|
2342
|
+
}
|
|
2343
|
+
//#endregion
|
|
2344
|
+
//#region src/components/switch.tsx
|
|
2345
|
+
const Switch = React.forwardRef(({ className, error = false, ...props }, ref) => {
|
|
2346
|
+
return /* @__PURE__ */ jsx(SwitchPrimitive.Root, {
|
|
2347
|
+
ref,
|
|
2348
|
+
className: cn("peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border border-transparent shadow-sm", "transition-colors duration-150", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35", "disabled:cursor-not-allowed disabled:opacity-50", "data-[state=unchecked]:bg-input", "data-[state=checked]:bg-primary", error && "focus-visible:ring-destructive/25", className),
|
|
2349
|
+
...props,
|
|
2350
|
+
children: /* @__PURE__ */ jsx(SwitchPrimitive.Thumb, { className: cn("pointer-events-none block size-4 rounded-full bg-surface shadow-sm ring-0", "transition-transform duration-150", "data-[state=checked]:translate-x-4", "data-[state=unchecked]:translate-x-0") })
|
|
2351
|
+
});
|
|
2352
|
+
});
|
|
2353
|
+
Switch.displayName = "Switch";
|
|
2354
|
+
function SwitchField({ id, label, description, errorMessage, required, className, ...props }) {
|
|
2355
|
+
const generatedId = React.useId();
|
|
2356
|
+
const fieldId = id ?? generatedId;
|
|
2357
|
+
const descriptionId = description ? `${fieldId}-description` : void 0;
|
|
2358
|
+
const errorId = errorMessage ? `${fieldId}-error` : void 0;
|
|
2359
|
+
const describedBy = [descriptionId, errorId].filter(Boolean).join(" ") || void 0;
|
|
2360
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2361
|
+
className: cn("flex flex-col gap-1.5", className),
|
|
2362
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
2363
|
+
className: "flex items-start justify-between gap-4 rounded-fds-md border border-border p-3",
|
|
2364
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
2365
|
+
className: "grid gap-1",
|
|
2366
|
+
children: [/* @__PURE__ */ jsx(Label, {
|
|
2367
|
+
htmlFor: fieldId,
|
|
2368
|
+
required,
|
|
2369
|
+
className: cn(props.disabled && "cursor-not-allowed opacity-60"),
|
|
2370
|
+
children: label
|
|
2371
|
+
}), description ? /* @__PURE__ */ jsx("p", {
|
|
2372
|
+
id: descriptionId,
|
|
2373
|
+
className: "caption text-muted",
|
|
2374
|
+
children: description
|
|
2375
|
+
}) : null]
|
|
2376
|
+
}), /* @__PURE__ */ jsx(Switch, {
|
|
2377
|
+
id: fieldId,
|
|
2378
|
+
required,
|
|
2379
|
+
"aria-describedby": describedBy,
|
|
2380
|
+
"aria-invalid": errorMessage ? true : void 0,
|
|
2381
|
+
error: Boolean(errorMessage),
|
|
2382
|
+
...props
|
|
2383
|
+
})]
|
|
2384
|
+
}), errorMessage ? /* @__PURE__ */ jsx("p", {
|
|
2385
|
+
id: errorId,
|
|
2386
|
+
className: "caption text-destructive",
|
|
2387
|
+
role: "alert",
|
|
2388
|
+
children: errorMessage
|
|
2389
|
+
}) : null]
|
|
2390
|
+
});
|
|
2391
|
+
}
|
|
2392
|
+
//#endregion
|
|
2393
|
+
//#region src/components/tabs.tsx
|
|
2394
|
+
const Tabs = TabsPrimitive.Root;
|
|
2395
|
+
const TabsList = React.forwardRef(({ className, ...props }, ref) => {
|
|
2396
|
+
return /* @__PURE__ */ jsx(TabsPrimitive.List, {
|
|
2397
|
+
ref,
|
|
2398
|
+
className: cn("inline-flex h-9 items-center justify-center rounded-fds-md bg-muted p-1 text-muted-foreground", className),
|
|
2399
|
+
...props
|
|
2400
|
+
});
|
|
2401
|
+
});
|
|
2402
|
+
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
2403
|
+
const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => {
|
|
2404
|
+
return /* @__PURE__ */ jsx(TabsPrimitive.Trigger, {
|
|
2405
|
+
ref,
|
|
2406
|
+
className: cn("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1 text-sm font-medium", "transition-all duration-150", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35", "disabled:pointer-events-none disabled:opacity-50", "data-[state=active]:bg-surface", "data-[state=active]:text-on-surface", "data-[state=active]:shadow-sm", className),
|
|
2407
|
+
...props
|
|
2408
|
+
});
|
|
2409
|
+
});
|
|
2410
|
+
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
2411
|
+
const TabsContent = React.forwardRef(({ className, ...props }, ref) => {
|
|
2412
|
+
return /* @__PURE__ */ jsx(TabsPrimitive.Content, {
|
|
2413
|
+
ref,
|
|
2414
|
+
className: cn("mt-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35", className),
|
|
2415
|
+
...props
|
|
2416
|
+
});
|
|
2417
|
+
});
|
|
2418
|
+
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
2419
|
+
//#endregion
|
|
2420
|
+
//#region src/components/textarea.tsx
|
|
2421
|
+
const textareaVariants = cva([
|
|
2422
|
+
"flex min-h-24 w-full",
|
|
2423
|
+
"rounded-fds-md border bg-surface px-3 py-2",
|
|
2424
|
+
"body-sm text-on-surface",
|
|
2425
|
+
"transition-colors duration-150",
|
|
2426
|
+
"placeholder:text-on-surface-variant",
|
|
2427
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-surface",
|
|
2428
|
+
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
2429
|
+
], {
|
|
2430
|
+
variants: { state: {
|
|
2431
|
+
default: "border-outline focus-visible:border-ring focus-visible:ring-ring",
|
|
2432
|
+
error: "border-error focus-visible:border-error focus-visible:ring-error"
|
|
2433
|
+
} },
|
|
2434
|
+
defaultVariants: { state: "default" }
|
|
2435
|
+
});
|
|
2436
|
+
const Textarea = React.forwardRef(({ className, state, ...props }, ref) => {
|
|
2437
|
+
return /* @__PURE__ */ jsx("textarea", {
|
|
2438
|
+
ref,
|
|
2439
|
+
className: cn(textareaVariants({ state: props["aria-invalid"] === true || props["aria-invalid"] === "true" ? "error" : state }), className),
|
|
2440
|
+
...props
|
|
2441
|
+
});
|
|
2442
|
+
});
|
|
2443
|
+
Textarea.displayName = "Textarea";
|
|
2444
|
+
//#endregion
|
|
2445
|
+
//#region src/components/toast.tsx
|
|
2446
|
+
const toneClasses = {
|
|
2447
|
+
default: "border-border bg-popover text-popover-foreground",
|
|
2448
|
+
success: "border-success/30 bg-success-container text-on-success-container",
|
|
2449
|
+
warning: "border-warning/30 bg-warning-container text-on-warning-container",
|
|
2450
|
+
info: "border-info/30 bg-info-container text-on-info-container",
|
|
2451
|
+
danger: "border-error/30 bg-error-container text-on-error-container"
|
|
2452
|
+
};
|
|
2453
|
+
function normalizeTone(tone = "default") {
|
|
2454
|
+
return tone === "error" ? "danger" : tone;
|
|
2455
|
+
}
|
|
2456
|
+
const ToastProvider = ToastPrimitive.Provider;
|
|
2457
|
+
const ToastAction = ToastPrimitive.Action;
|
|
2458
|
+
const ToastViewport = React.forwardRef(({ className, ...props }, ref) => {
|
|
2459
|
+
return /* @__PURE__ */ jsx(ToastPrimitive.Viewport, {
|
|
2460
|
+
ref,
|
|
2461
|
+
className: cn("fixed inset-x-0 bottom-0 z-50 flex max-h-screen w-full flex-col-reverse gap-2 p-4", "sm:inset-auto sm:bottom-4 sm:right-4 sm:max-w-sm", className),
|
|
2462
|
+
...props
|
|
2463
|
+
});
|
|
2464
|
+
});
|
|
2465
|
+
ToastViewport.displayName = ToastPrimitive.Viewport.displayName;
|
|
2466
|
+
const Toast = React.forwardRef(({ className, tone = "default", role, ...props }, ref) => {
|
|
2467
|
+
const currentTone = normalizeTone(tone);
|
|
2468
|
+
const semanticRole = role ?? (currentTone === "danger" || currentTone === "warning" ? "alert" : "status");
|
|
2469
|
+
return /* @__PURE__ */ jsx(ToastPrimitive.Root, {
|
|
2470
|
+
ref,
|
|
2471
|
+
role: semanticRole,
|
|
2472
|
+
className: cn("group pointer-events-auto relative grid w-full gap-2 overflow-hidden rounded-fds-lg border p-4 pr-11 shadow-lg", "transition-all duration-200", "data-[swipe=move]:translate-x-(--radix-toast-swipe-move-x)", "data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-transform", "data-[swipe=end]:animate-out data-[swipe=end]:slide-out-to-right-full", "data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom-full", "data-[state=closed]:animate-out data-[state=closed]:fade-out-80", "sm:data-[state=open]:slide-in-from-right-full", toneClasses[currentTone], className),
|
|
2473
|
+
...props
|
|
2474
|
+
});
|
|
2475
|
+
});
|
|
2476
|
+
Toast.displayName = ToastPrimitive.Root.displayName;
|
|
2477
|
+
const ToastTitle = React.forwardRef(({ className, ...props }, ref) => {
|
|
2478
|
+
return /* @__PURE__ */ jsx(ToastPrimitive.Title, {
|
|
2479
|
+
ref,
|
|
2480
|
+
className: cn("body-sm font-semibold leading-5", className),
|
|
2481
|
+
...props
|
|
2482
|
+
});
|
|
2483
|
+
});
|
|
2484
|
+
ToastTitle.displayName = ToastPrimitive.Title.displayName;
|
|
2485
|
+
const ToastDescription = React.forwardRef(({ className, ...props }, ref) => {
|
|
2486
|
+
return /* @__PURE__ */ jsx(ToastPrimitive.Description, {
|
|
2487
|
+
ref,
|
|
2488
|
+
className: cn("body-sm opacity-90", className),
|
|
2489
|
+
...props
|
|
2490
|
+
});
|
|
2491
|
+
});
|
|
2492
|
+
ToastDescription.displayName = ToastPrimitive.Description.displayName;
|
|
2493
|
+
const ToastClose = React.forwardRef(({ className, "aria-label": ariaLabel = "Fechar notificação", children, ...props }, ref) => {
|
|
2494
|
+
return /* @__PURE__ */ jsx(ToastPrimitive.Close, {
|
|
2495
|
+
ref,
|
|
2496
|
+
"aria-label": ariaLabel,
|
|
2497
|
+
className: cn("absolute right-3 top-3 rounded-sm opacity-75 transition-opacity hover:opacity-100", "focus:outline-none focus:ring-2 focus:ring-ring/35", "disabled:pointer-events-none", className),
|
|
2498
|
+
...props,
|
|
2499
|
+
children: children ?? /* @__PURE__ */ jsx(X, {
|
|
2500
|
+
"aria-hidden": "true",
|
|
2501
|
+
className: "size-4"
|
|
2502
|
+
})
|
|
2503
|
+
});
|
|
2504
|
+
});
|
|
2505
|
+
ToastClose.displayName = ToastPrimitive.Close.displayName;
|
|
2506
|
+
//#endregion
|
|
2507
|
+
//#region src/hooks/use-toast.ts
|
|
2508
|
+
const ToastContext = React.createContext(null);
|
|
2509
|
+
function useToast() {
|
|
2510
|
+
const context = React.useContext(ToastContext);
|
|
2511
|
+
if (!context) throw new Error("useToast deve ser usado dentro de <Toaster>.");
|
|
2512
|
+
return context;
|
|
2513
|
+
}
|
|
2514
|
+
//#endregion
|
|
2515
|
+
//#region src/components/toaster.tsx
|
|
2516
|
+
let toastCounter = 0;
|
|
2517
|
+
function createToastId() {
|
|
2518
|
+
toastCounter += 1;
|
|
2519
|
+
return `toast-${toastCounter}`;
|
|
2520
|
+
}
|
|
2521
|
+
function Toaster({ children, duration = 5e3, swipeDirection = "right" }) {
|
|
2522
|
+
const [toasts, setToasts] = React.useState([]);
|
|
2523
|
+
const dismiss = React.useCallback((id) => {
|
|
2524
|
+
setToasts((current) => current.map((toast) => toast.id === id ? {
|
|
2525
|
+
...toast,
|
|
2526
|
+
open: false
|
|
2527
|
+
} : toast));
|
|
2528
|
+
}, []);
|
|
2529
|
+
const remove = React.useCallback((id) => {
|
|
2530
|
+
setToasts((current) => current.filter((toast) => toast.id !== id));
|
|
2531
|
+
}, []);
|
|
2532
|
+
const toast = React.useCallback((input) => {
|
|
2533
|
+
const id = createToastId();
|
|
2534
|
+
setToasts((current) => [...current, {
|
|
2535
|
+
...input,
|
|
2536
|
+
id,
|
|
2537
|
+
open: true
|
|
2538
|
+
}]);
|
|
2539
|
+
return {
|
|
2540
|
+
id,
|
|
2541
|
+
dismiss: () => dismiss(id)
|
|
2542
|
+
};
|
|
2543
|
+
}, [dismiss]);
|
|
2544
|
+
const value = React.useMemo(() => ({
|
|
2545
|
+
toasts,
|
|
2546
|
+
toast,
|
|
2547
|
+
dismiss
|
|
2548
|
+
}), [
|
|
2549
|
+
toasts,
|
|
2550
|
+
toast,
|
|
2551
|
+
dismiss
|
|
2552
|
+
]);
|
|
2553
|
+
return /* @__PURE__ */ jsx(ToastContext.Provider, {
|
|
2554
|
+
value,
|
|
2555
|
+
children: /* @__PURE__ */ jsxs(ToastProvider, {
|
|
2556
|
+
duration,
|
|
2557
|
+
swipeDirection,
|
|
2558
|
+
children: [
|
|
2559
|
+
children,
|
|
2560
|
+
toasts.map((toast) => /* @__PURE__ */ jsxs(Toast, {
|
|
2561
|
+
open: toast.open,
|
|
2562
|
+
tone: toast.tone,
|
|
2563
|
+
duration: toast.duration,
|
|
2564
|
+
onOpenChange: (open) => {
|
|
2565
|
+
if (!open) dismiss(toast.id);
|
|
2566
|
+
},
|
|
2567
|
+
onAnimationEnd: () => {
|
|
2568
|
+
if (!toast.open) remove(toast.id);
|
|
2569
|
+
},
|
|
2570
|
+
children: [
|
|
2571
|
+
toast.title ? /* @__PURE__ */ jsx(ToastTitle, { children: toast.title }) : null,
|
|
2572
|
+
toast.description ? /* @__PURE__ */ jsx(ToastDescription, { children: toast.description }) : null,
|
|
2573
|
+
toast.action,
|
|
2574
|
+
/* @__PURE__ */ jsx(ToastClose, {})
|
|
2575
|
+
]
|
|
2576
|
+
}, toast.id)),
|
|
2577
|
+
/* @__PURE__ */ jsx(ToastViewport, {})
|
|
2578
|
+
]
|
|
2579
|
+
})
|
|
2580
|
+
});
|
|
2581
|
+
}
|
|
2582
|
+
//#endregion
|
|
2583
|
+
//#region src/components/tooltip.tsx
|
|
2584
|
+
const TooltipProvider = TooltipPrimitive.Provider;
|
|
2585
|
+
const TooltipRoot = TooltipPrimitive.Root;
|
|
2586
|
+
const TooltipTrigger = TooltipPrimitive.Trigger;
|
|
2587
|
+
function Tooltip({ children, content, side = "top", align = "center", delayDuration = 300, className }) {
|
|
2588
|
+
return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, {
|
|
2589
|
+
delayDuration,
|
|
2590
|
+
children: /* @__PURE__ */ jsxs(TooltipPrimitive.Root, { children: [/* @__PURE__ */ jsx(TooltipPrimitive.Trigger, {
|
|
2591
|
+
asChild: true,
|
|
2592
|
+
children
|
|
2593
|
+
}), /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(TooltipPrimitive.Content, {
|
|
2594
|
+
side,
|
|
2595
|
+
align,
|
|
2596
|
+
sideOffset: 6,
|
|
2597
|
+
className: cn("z-50 overflow-hidden rounded-fds-md border border-border", "bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md", "data-[state=delayed-open]:animate-in data-[state=closed]:animate-out", "data-[state=closed]:fade-out-0 data-[state=delayed-open]:fade-in-0", "data-[state=closed]:zoom-out-95 data-[state=delayed-open]:zoom-in-95", className),
|
|
2598
|
+
children: content
|
|
2599
|
+
}) })] })
|
|
2600
|
+
});
|
|
2601
|
+
}
|
|
2602
|
+
//#endregion
|
|
2603
|
+
//#region src/components/topbar.tsx
|
|
2604
|
+
function Topbar({ start, center, end, className, children, ...props }) {
|
|
2605
|
+
return /* @__PURE__ */ jsx("div", {
|
|
2606
|
+
className: cn("flex min-h-16 items-center gap-4 px-6", className),
|
|
2607
|
+
...props,
|
|
2608
|
+
children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2609
|
+
/* @__PURE__ */ jsx("div", {
|
|
2610
|
+
className: "flex min-w-0 flex-1 items-center gap-3",
|
|
2611
|
+
children: start
|
|
2612
|
+
}),
|
|
2613
|
+
center ? /* @__PURE__ */ jsx("div", {
|
|
2614
|
+
className: "hidden min-w-0 flex-1 items-center justify-center lg:flex",
|
|
2615
|
+
children: center
|
|
2616
|
+
}) : null,
|
|
2617
|
+
/* @__PURE__ */ jsx("div", {
|
|
2618
|
+
className: "flex min-w-0 flex-1 items-center justify-end gap-2",
|
|
2619
|
+
children: end
|
|
2620
|
+
})
|
|
2621
|
+
] })
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
//#endregion
|
|
2625
|
+
//#region src/components/user-menu.tsx
|
|
2626
|
+
const defaultItems = [{
|
|
2627
|
+
label: "Perfil",
|
|
2628
|
+
icon: /* @__PURE__ */ jsx(User, { className: "size-4" })
|
|
2629
|
+
}, {
|
|
2630
|
+
label: "Configurações",
|
|
2631
|
+
icon: /* @__PURE__ */ jsx(Settings, { className: "size-4" }),
|
|
2632
|
+
shortcut: "⌘,"
|
|
2633
|
+
}];
|
|
2634
|
+
const defaultFooterItems = [{
|
|
2635
|
+
label: "Sair",
|
|
2636
|
+
icon: /* @__PURE__ */ jsx(LogOut, { className: "size-4" }),
|
|
2637
|
+
tone: "danger"
|
|
2638
|
+
}];
|
|
2639
|
+
function UserMenu({ name, email, avatarUrl, initials, items = defaultItems, footerItems = defaultFooterItems }) {
|
|
2640
|
+
const fallback = initials ?? getInitials(name);
|
|
2641
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
2642
|
+
asChild: true,
|
|
2643
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
2644
|
+
variant: "ghost",
|
|
2645
|
+
size: "sm",
|
|
2646
|
+
className: "h-10 gap-3 px-2",
|
|
2647
|
+
children: [/* @__PURE__ */ jsxs(Avatar, {
|
|
2648
|
+
className: "size-7",
|
|
2649
|
+
children: [/* @__PURE__ */ jsx(AvatarImage, {
|
|
2650
|
+
src: avatarUrl,
|
|
2651
|
+
alt: name
|
|
2652
|
+
}), /* @__PURE__ */ jsx(AvatarFallback, {
|
|
2653
|
+
className: "text-xs",
|
|
2654
|
+
children: fallback
|
|
2655
|
+
})]
|
|
2656
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
2657
|
+
className: "hidden min-w-0 flex-col items-start sm:flex",
|
|
2658
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
2659
|
+
className: "max-w-32 truncate text-sm font-medium leading-4",
|
|
2660
|
+
children: name
|
|
2661
|
+
}), email ? /* @__PURE__ */ jsx("span", {
|
|
2662
|
+
className: "max-w-32 truncate text-xs font-normal leading-4 text-muted-foreground",
|
|
2663
|
+
children: email
|
|
2664
|
+
}) : null]
|
|
2665
|
+
})]
|
|
2666
|
+
})
|
|
2667
|
+
}), /* @__PURE__ */ jsxs(DropdownMenuContent, {
|
|
2668
|
+
align: "end",
|
|
2669
|
+
className: "w-64",
|
|
2670
|
+
children: [
|
|
2671
|
+
/* @__PURE__ */ jsx(DropdownMenuLabel, { children: /* @__PURE__ */ jsxs("div", {
|
|
2672
|
+
className: "flex min-w-0 items-center gap-3",
|
|
2673
|
+
children: [/* @__PURE__ */ jsxs(Avatar, {
|
|
2674
|
+
className: "size-9",
|
|
2675
|
+
children: [/* @__PURE__ */ jsx(AvatarImage, {
|
|
2676
|
+
src: avatarUrl,
|
|
2677
|
+
alt: name
|
|
2678
|
+
}), /* @__PURE__ */ jsx(AvatarFallback, { children: fallback })]
|
|
2679
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
2680
|
+
className: "min-w-0",
|
|
2681
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
2682
|
+
className: "truncate body-sm font-semibold normal-case tracking-normal text-on-surface",
|
|
2683
|
+
children: name
|
|
2684
|
+
}), email ? /* @__PURE__ */ jsx("p", {
|
|
2685
|
+
className: "truncate caption normal-case tracking-normal text-muted",
|
|
2686
|
+
children: email
|
|
2687
|
+
}) : null]
|
|
2688
|
+
})]
|
|
2689
|
+
}) }),
|
|
2690
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
2691
|
+
items.map((item) => /* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
2692
|
+
disabled: item.disabled,
|
|
2693
|
+
tone: item.tone,
|
|
2694
|
+
onSelect: item.onSelect,
|
|
2695
|
+
children: [
|
|
2696
|
+
item.icon,
|
|
2697
|
+
item.label,
|
|
2698
|
+
item.shortcut ? /* @__PURE__ */ jsx(DropdownMenuShortcut, { children: item.shortcut }) : null
|
|
2699
|
+
]
|
|
2700
|
+
}, item.label)),
|
|
2701
|
+
footerItems.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), footerItems.map((item) => /* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
2702
|
+
disabled: item.disabled,
|
|
2703
|
+
tone: item.tone,
|
|
2704
|
+
onSelect: item.onSelect,
|
|
2705
|
+
children: [
|
|
2706
|
+
item.icon,
|
|
2707
|
+
item.label,
|
|
2708
|
+
item.shortcut ? /* @__PURE__ */ jsx(DropdownMenuShortcut, { children: item.shortcut }) : null
|
|
2709
|
+
]
|
|
2710
|
+
}, item.label))] }) : null
|
|
2711
|
+
]
|
|
2712
|
+
})] });
|
|
2713
|
+
}
|
|
2714
|
+
//#endregion
|
|
2715
|
+
//#region src/provider/freitas-provider.tsx
|
|
2716
|
+
function FreitasProvider({ theme, children }) {
|
|
2717
|
+
const resolvedTheme = React.useMemo(() => {
|
|
2718
|
+
return resolveTheme(theme);
|
|
2719
|
+
}, [theme]);
|
|
2720
|
+
React.useEffect(() => {
|
|
2721
|
+
applyTheme(resolvedTheme);
|
|
2722
|
+
}, [resolvedTheme]);
|
|
2723
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2724
|
+
}
|
|
2725
|
+
//#endregion
|
|
2726
|
+
export { ActionBar, Alert, AlertDialog, AlertDialogAction, AlertDialogActionButton, AlertDialogCancel, AlertDialogCancelButton, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AppShell, AppShellContent, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, Card, CardContent, CardFooter, CardHeader, Checkbox, CheckboxField, Combobox, CommandMenu, DataTable, DataViewRoot as DataView, DataViewRoot, DataViewContent, DataViewEmpty, DataViewHeader, DataViewPagination, DataViewToolbar, DatePicker, DateRangePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, FilterBar, FilterBarItem, Form, FormControl, FormDescription, FormField, FormFieldController, FormItem, FormLabel, FormMessage, FreitasProvider, Input, Kbd, Label, NativeSelect, PageHeader, Pagination, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, RadioGroup, SearchInput, Select, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarBrand, SidebarContent, SidebarFooter, SidebarHeader, SidebarNavItem, SidebarSection, Skeleton, Spinner, StatusBadge, Switch, SwitchField, Table, TableBody, TableCaption, TableCell, TableContainer, TableFooter, TableHead, TableHeader, TableRow, TableScrollArea, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toast, ToastAction, ToastClose, ToastContext, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, Toolbar, ToolbarActions, ToolbarSection, ToolbarTitle, Tooltip, TooltipProvider, TooltipRoot, TooltipTrigger, Topbar, UserMenu, buttonVariants, formatDate, getCheckboxFieldProps, getDatePickerFieldProps, getInitials, getInputFieldProps, getRadioGroupFieldProps, getSelectFieldProps, getSwitchFieldProps, useForm, useToast };
|
|
2727
|
+
|
|
2728
|
+
//# sourceMappingURL=index.mjs.map
|