@motor-hero/ui-kit 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +52 -0
  2. package/dist/components/auth-card.d.ts +10 -0
  3. package/dist/components/auth-card.d.ts.map +1 -0
  4. package/dist/components/confirm-dialog.d.ts +15 -0
  5. package/dist/components/confirm-dialog.d.ts.map +1 -0
  6. package/dist/components/data-table-wrapper.d.ts +16 -0
  7. package/dist/components/data-table-wrapper.d.ts.map +1 -0
  8. package/dist/components/empty-state.d.ts +11 -0
  9. package/dist/components/empty-state.d.ts.map +1 -0
  10. package/dist/components/form-dialog.d.ts +14 -0
  11. package/dist/components/form-dialog.d.ts.map +1 -0
  12. package/dist/components/form-field.d.ts +12 -0
  13. package/dist/components/form-field.d.ts.map +1 -0
  14. package/dist/components/mobile-card-list.d.ts +12 -0
  15. package/dist/components/mobile-card-list.d.ts.map +1 -0
  16. package/dist/components/mode-toggle.d.ts +2 -0
  17. package/dist/components/mode-toggle.d.ts.map +1 -0
  18. package/dist/components/page-header.d.ts +10 -0
  19. package/dist/components/page-header.d.ts.map +1 -0
  20. package/dist/components/pagination.d.ts +10 -0
  21. package/dist/components/pagination.d.ts.map +1 -0
  22. package/dist/components/responsive-data-view.d.ts +14 -0
  23. package/dist/components/responsive-data-view.d.ts.map +1 -0
  24. package/dist/components/search-input.d.ts +7 -0
  25. package/dist/components/search-input.d.ts.map +1 -0
  26. package/dist/components/stat-card.d.ts +11 -0
  27. package/dist/components/stat-card.d.ts.map +1 -0
  28. package/dist/components/status-dot.d.ts +8 -0
  29. package/dist/components/status-dot.d.ts.map +1 -0
  30. package/dist/components/table-skeleton.d.ts +7 -0
  31. package/dist/components/table-skeleton.d.ts.map +1 -0
  32. package/dist/components/theme-provider.d.ts +14 -0
  33. package/dist/components/theme-provider.d.ts.map +1 -0
  34. package/dist/components/toaster.d.ts +5 -0
  35. package/dist/components/toaster.d.ts.map +1 -0
  36. package/dist/hooks/use-disclosure.d.ts +8 -0
  37. package/dist/hooks/use-disclosure.d.ts.map +1 -0
  38. package/dist/hooks/use-toast.d.ts +5 -0
  39. package/dist/hooks/use-toast.d.ts.map +1 -0
  40. package/dist/index.cjs +620 -0
  41. package/dist/index.cjs.map +1 -0
  42. package/dist/index.d.ts +23 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +561 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/lib/api-error.d.ts +2 -0
  47. package/dist/lib/api-error.d.ts.map +1 -0
  48. package/dist/lib/utils.d.ts +3 -0
  49. package/dist/lib/utils.d.ts.map +1 -0
  50. package/dist/styles.css +45 -0
  51. package/package.json +80 -0
  52. package/src/components/auth-card.tsx +25 -0
  53. package/src/components/confirm-dialog.tsx +58 -0
  54. package/src/components/data-table-wrapper.tsx +65 -0
  55. package/src/components/empty-state.tsx +22 -0
  56. package/src/components/form-dialog.tsx +48 -0
  57. package/src/components/form-field.tsx +26 -0
  58. package/src/components/mobile-card-list.tsx +54 -0
  59. package/src/components/mode-toggle.tsx +47 -0
  60. package/src/components/page-header.tsx +22 -0
  61. package/src/components/pagination.tsx +31 -0
  62. package/src/components/responsive-data-view.tsx +31 -0
  63. package/src/components/search-input.tsx +36 -0
  64. package/src/components/stat-card.tsx +35 -0
  65. package/src/components/status-dot.tsx +16 -0
  66. package/src/components/table-skeleton.tsx +20 -0
  67. package/src/components/theme-provider.tsx +69 -0
  68. package/src/components/toaster.tsx +31 -0
  69. package/src/hooks/use-disclosure.ts +9 -0
  70. package/src/hooks/use-toast.ts +30 -0
  71. package/src/index.ts +29 -0
  72. package/src/lib/api-error.ts +7 -0
  73. package/src/lib/utils.ts +6 -0
  74. package/src/styles.css +45 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,620 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AuthCard: () => AuthCard,
34
+ ConfirmDialog: () => ConfirmDialog,
35
+ DataTableWrapper: () => DataTableWrapper,
36
+ EmptyState: () => EmptyState,
37
+ FormDialogLayout: () => FormDialogLayout,
38
+ FormField: () => FormField,
39
+ MobileCardList: () => MobileCardList,
40
+ ModeToggle: () => ModeToggle,
41
+ PageHeader: () => PageHeader,
42
+ Pagination: () => Pagination,
43
+ ResponsiveDataView: () => ResponsiveDataView,
44
+ SearchInput: () => SearchInput,
45
+ StatCard: () => StatCard,
46
+ StatusDot: () => StatusDot,
47
+ TableSkeleton: () => TableSkeleton,
48
+ ThemeProvider: () => ThemeProvider,
49
+ Toaster: () => Toaster,
50
+ cn: () => cn,
51
+ extractApiError: () => extractApiError,
52
+ toast: () => import_sonner2.toast,
53
+ useCustomToast: () => useCustomToast,
54
+ useDisclosure: () => useDisclosure,
55
+ useTheme: () => useTheme
56
+ });
57
+ module.exports = __toCommonJS(index_exports);
58
+
59
+ // src/components/theme-provider.tsx
60
+ var import_react = require("react");
61
+ var import_jsx_runtime = require("react/jsx-runtime");
62
+ var initialState = {
63
+ theme: "system",
64
+ setTheme: () => null
65
+ };
66
+ var ThemeProviderContext = (0, import_react.createContext)(initialState);
67
+ function ThemeProvider({
68
+ children,
69
+ defaultTheme = "system",
70
+ storageKey = "ui-theme",
71
+ ...props
72
+ }) {
73
+ const [theme, setTheme] = (0, import_react.useState)(
74
+ () => localStorage.getItem(storageKey) || defaultTheme
75
+ );
76
+ (0, import_react.useEffect)(() => {
77
+ const root = window.document.documentElement;
78
+ root.classList.remove("light", "dark");
79
+ if (theme === "system") {
80
+ const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
81
+ root.classList.add(systemTheme);
82
+ return;
83
+ }
84
+ root.classList.add(theme);
85
+ }, [theme]);
86
+ const value = {
87
+ theme,
88
+ setTheme: (theme2) => {
89
+ localStorage.setItem(storageKey, theme2);
90
+ setTheme(theme2);
91
+ }
92
+ };
93
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeProviderContext.Provider, { ...props, value, children });
94
+ }
95
+ function useTheme() {
96
+ const context = (0, import_react.useContext)(ThemeProviderContext);
97
+ if (context === void 0) {
98
+ throw new Error("useTheme must be used within a ThemeProvider");
99
+ }
100
+ return context;
101
+ }
102
+
103
+ // src/components/mode-toggle.tsx
104
+ var DropdownMenu = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
105
+ var import_lucide_react = require("lucide-react");
106
+ var import_jsx_runtime2 = require("react/jsx-runtime");
107
+ function ModeToggle() {
108
+ const { setTheme } = useTheme();
109
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(DropdownMenu.Root, { children: [
110
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
111
+ "button",
112
+ {
113
+ type: "button",
114
+ className: "inline-flex h-9 w-9 items-center justify-center rounded-md border border-input bg-background text-sm font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
115
+ "aria-label": "Alternar tema",
116
+ children: [
117
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Sun, { className: "h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" }),
118
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Moon, { className: "absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" })
119
+ ]
120
+ }
121
+ ) }),
122
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DropdownMenu.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
123
+ DropdownMenu.Content,
124
+ {
125
+ align: "end",
126
+ className: "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95",
127
+ children: [
128
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
129
+ DropdownMenu.Item,
130
+ {
131
+ className: "flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent",
132
+ onClick: () => setTheme("light"),
133
+ children: [
134
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Sun, { className: "h-4 w-4" }),
135
+ " Claro"
136
+ ]
137
+ }
138
+ ),
139
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
140
+ DropdownMenu.Item,
141
+ {
142
+ className: "flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent",
143
+ onClick: () => setTheme("dark"),
144
+ children: [
145
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Moon, { className: "h-4 w-4" }),
146
+ " Escuro"
147
+ ]
148
+ }
149
+ ),
150
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
151
+ DropdownMenu.Item,
152
+ {
153
+ className: "flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent",
154
+ onClick: () => setTheme("system"),
155
+ children: [
156
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Monitor, { className: "h-4 w-4" }),
157
+ " Sistema"
158
+ ]
159
+ }
160
+ )
161
+ ]
162
+ }
163
+ ) })
164
+ ] });
165
+ }
166
+
167
+ // src/components/empty-state.tsx
168
+ var import_jsx_runtime3 = require("react/jsx-runtime");
169
+ function EmptyState({ icon, title, description, action, className }) {
170
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `flex flex-col items-center justify-center py-16 text-center ${className ?? ""}`, children: [
171
+ icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mb-4 text-muted-foreground", children: icon }),
172
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "text-lg font-semibold tracking-tight", children: title }),
173
+ description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: description }),
174
+ action && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mt-4", children: action })
175
+ ] });
176
+ }
177
+
178
+ // src/components/confirm-dialog.tsx
179
+ var AlertDialog = __toESM(require("@radix-ui/react-alert-dialog"), 1);
180
+ var import_jsx_runtime4 = require("react/jsx-runtime");
181
+ function ConfirmDialog({
182
+ open,
183
+ onOpenChange,
184
+ onConfirm,
185
+ title,
186
+ description,
187
+ confirmLabel = "Confirmar",
188
+ cancelLabel = "Cancelar",
189
+ loading = false,
190
+ variant = "default"
191
+ }) {
192
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AlertDialog.Root, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(AlertDialog.Portal, { children: [
193
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AlertDialog.Overlay, { className: "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" }),
194
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(AlertDialog.Content, { className: "fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg", children: [
195
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-col space-y-2 text-center sm:text-left", children: [
196
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AlertDialog.Title, { className: "text-lg font-semibold", children: title }),
197
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AlertDialog.Description, { className: "text-sm text-muted-foreground", children: description })
198
+ ] }),
199
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", children: [
200
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AlertDialog.Cancel, { className: "inline-flex h-9 items-center justify-center rounded-md border border-input bg-background px-4 text-sm font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 cursor-pointer", children: cancelLabel }),
201
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
202
+ AlertDialog.Action,
203
+ {
204
+ onClick: onConfirm,
205
+ disabled: loading,
206
+ className: `inline-flex h-9 items-center justify-center rounded-md px-4 text-sm font-medium shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 cursor-pointer ${variant === "destructive" ? "bg-destructive text-destructive-foreground hover:bg-destructive/90" : "bg-primary text-primary-foreground hover:bg-primary/90"}`,
207
+ children: loading ? "Aguarde..." : confirmLabel
208
+ }
209
+ )
210
+ ] })
211
+ ] })
212
+ ] }) });
213
+ }
214
+
215
+ // src/components/page-header.tsx
216
+ var import_jsx_runtime5 = require("react/jsx-runtime");
217
+ function PageHeader({ title, description, action, className }) {
218
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `flex items-center justify-between ${className ?? ""}`, children: [
219
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
220
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h1", { className: "text-2xl font-semibold tracking-tight", children: title }),
221
+ description && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm text-muted-foreground", children: description })
222
+ ] }),
223
+ action && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: action })
224
+ ] });
225
+ }
226
+
227
+ // src/components/status-dot.tsx
228
+ var import_jsx_runtime6 = require("react/jsx-runtime");
229
+ function StatusDot({ active, label, className }) {
230
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: `inline-flex items-center gap-2 ${className ?? ""}`, children: [
231
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
232
+ "span",
233
+ {
234
+ className: `h-2 w-2 rounded-full ${active ? "bg-green-500" : "bg-red-500"}`
235
+ }
236
+ ),
237
+ label && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: label })
238
+ ] });
239
+ }
240
+
241
+ // src/components/form-field.tsx
242
+ var import_jsx_runtime7 = require("react/jsx-runtime");
243
+ function FormField({ label, htmlFor, error, required, children, className }) {
244
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, children: [
245
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
246
+ "label",
247
+ {
248
+ htmlFor,
249
+ className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
250
+ children: [
251
+ label,
252
+ required && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ml-1 text-destructive", children: "*" })
253
+ ]
254
+ }
255
+ ),
256
+ children,
257
+ error && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-sm text-destructive", children: error })
258
+ ] });
259
+ }
260
+
261
+ // src/components/form-dialog.tsx
262
+ var import_jsx_runtime8 = require("react/jsx-runtime");
263
+ function FormDialogLayout({
264
+ title,
265
+ children,
266
+ onSubmit,
267
+ submitLabel = "Salvar",
268
+ cancelLabel = "Cancelar",
269
+ onCancel,
270
+ isSubmitting = false,
271
+ isDisabled = false
272
+ }) {
273
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { onSubmit, children: [
274
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex flex-col space-y-1.5 text-center sm:text-left", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { className: "text-lg font-semibold leading-none tracking-tight", children: title }) }),
275
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "space-y-4 py-4", children }),
276
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", children: [
277
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
278
+ "button",
279
+ {
280
+ type: "button",
281
+ onClick: onCancel,
282
+ className: "inline-flex h-9 items-center justify-center rounded-md border border-input bg-background px-4 text-sm font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground cursor-pointer disabled:pointer-events-none disabled:opacity-50",
283
+ children: cancelLabel
284
+ }
285
+ ),
286
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
287
+ "button",
288
+ {
289
+ type: "submit",
290
+ disabled: isSubmitting || isDisabled,
291
+ className: "inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground shadow transition-colors hover:bg-primary/90 cursor-pointer disabled:pointer-events-none disabled:opacity-50",
292
+ children: isSubmitting ? "Salvando..." : submitLabel
293
+ }
294
+ )
295
+ ] })
296
+ ] });
297
+ }
298
+
299
+ // src/components/auth-card.tsx
300
+ var import_jsx_runtime9 = require("react/jsx-runtime");
301
+ function AuthCard({ title, description, children, footer }) {
302
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex min-h-screen items-center justify-center px-4", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "w-full max-w-sm rounded-lg border bg-card p-6 shadow-sm", children: [
303
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mb-6 text-center", children: [
304
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h1", { className: "text-2xl font-semibold tracking-tight", children: title }),
305
+ description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
306
+ ] }),
307
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "space-y-4", children }),
308
+ footer && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-4", children: footer })
309
+ ] }) });
310
+ }
311
+
312
+ // src/components/pagination.tsx
313
+ var import_jsx_runtime10 = require("react/jsx-runtime");
314
+ function Pagination({ page, onPageChange, hasNextPage, hasPreviousPage, className }) {
315
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `flex items-center justify-end gap-4 ${className ?? ""}`, children: [
316
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
317
+ "button",
318
+ {
319
+ type: "button",
320
+ onClick: () => onPageChange(page - 1),
321
+ disabled: !hasPreviousPage,
322
+ className: "inline-flex h-8 items-center justify-center rounded-md border border-input bg-background px-3 text-xs font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground cursor-pointer disabled:pointer-events-none disabled:opacity-50",
323
+ children: "Anterior"
324
+ }
325
+ ),
326
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
327
+ "P\xE1gina ",
328
+ page
329
+ ] }),
330
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
331
+ "button",
332
+ {
333
+ type: "button",
334
+ onClick: () => onPageChange(page + 1),
335
+ disabled: !hasNextPage,
336
+ className: "inline-flex h-8 items-center justify-center rounded-md border border-input bg-background px-3 text-xs font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground cursor-pointer disabled:pointer-events-none disabled:opacity-50",
337
+ children: "Pr\xF3ximo"
338
+ }
339
+ )
340
+ ] });
341
+ }
342
+
343
+ // src/components/table-skeleton.tsx
344
+ var import_jsx_runtime11 = require("react/jsx-runtime");
345
+ function TableSkeleton({ rows = 5, columns = 4 }) {
346
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tr", { className: "border-b transition-colors", children: Array.from({ length: columns }).map((_2, j) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { className: "p-4 align-middle", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-5 w-full animate-pulse rounded bg-muted" }) }, j)) }, i)) });
347
+ }
348
+
349
+ // src/components/search-input.tsx
350
+ var React = __toESM(require("react"), 1);
351
+ var import_jsx_runtime12 = require("react/jsx-runtime");
352
+ var SearchInput = React.forwardRef(
353
+ ({ containerClassName, className, ...props }, ref) => {
354
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `relative flex-1 ${containerClassName ?? ""}`, children: [
355
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
356
+ "svg",
357
+ {
358
+ xmlns: "http://www.w3.org/2000/svg",
359
+ width: "16",
360
+ height: "16",
361
+ viewBox: "0 0 24 24",
362
+ fill: "none",
363
+ stroke: "currentColor",
364
+ strokeWidth: "2",
365
+ strokeLinecap: "round",
366
+ strokeLinejoin: "round",
367
+ className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground",
368
+ children: [
369
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
370
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m21 21-4.3-4.3" })
371
+ ]
372
+ }
373
+ ),
374
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
375
+ "input",
376
+ {
377
+ ref,
378
+ type: "text",
379
+ className: `flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 pl-10 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 ${className ?? ""}`,
380
+ ...props
381
+ }
382
+ )
383
+ ] });
384
+ }
385
+ );
386
+ SearchInput.displayName = "SearchInput";
387
+
388
+ // src/components/stat-card.tsx
389
+ var import_jsx_runtime13 = require("react/jsx-runtime");
390
+ function StatCard({ label, value, detail, icon, isLoading }) {
391
+ if (isLoading) {
392
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "rounded-lg border bg-card p-6 shadow-sm", children: [
393
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between pb-2", children: [
394
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-4 w-24 animate-pulse rounded bg-muted" }),
395
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-4 w-4 animate-pulse rounded bg-muted" })
396
+ ] }),
397
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mt-2 h-7 w-16 animate-pulse rounded bg-muted" }),
398
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mt-1 h-4 w-20 animate-pulse rounded bg-muted" })
399
+ ] });
400
+ }
401
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "rounded-lg border bg-card p-6 shadow-sm", children: [
402
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between pb-2", children: [
403
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm font-medium text-muted-foreground", children: label }),
404
+ icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-muted-foreground", children: icon })
405
+ ] }),
406
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-2xl font-bold", children: value }),
407
+ detail && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-xs text-muted-foreground", children: detail })
408
+ ] });
409
+ }
410
+
411
+ // src/components/data-table-wrapper.tsx
412
+ var import_jsx_runtime14 = require("react/jsx-runtime");
413
+ function DataTableWrapper({
414
+ children,
415
+ isEmpty,
416
+ isLoading,
417
+ emptyIcon,
418
+ emptyTitle = "Nenhum registro encontrado",
419
+ emptyDescription,
420
+ page,
421
+ onPageChange,
422
+ hasNextPage = false,
423
+ hasPreviousPage = false
424
+ }) {
425
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "space-y-4", children: [
426
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "overflow-x-auto rounded-md border", children }),
427
+ !isLoading && isEmpty && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
428
+ emptyIcon && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "mb-4 text-muted-foreground", children: emptyIcon }),
429
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "text-lg font-semibold tracking-tight", children: emptyTitle }),
430
+ emptyDescription && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: emptyDescription })
431
+ ] }),
432
+ page !== void 0 && onPageChange && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-end gap-4", children: [
433
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
434
+ "button",
435
+ {
436
+ type: "button",
437
+ onClick: () => onPageChange(page - 1),
438
+ disabled: !hasPreviousPage,
439
+ className: "inline-flex h-8 items-center justify-center rounded-md border border-input bg-background px-3 text-xs font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground cursor-pointer disabled:pointer-events-none disabled:opacity-50",
440
+ children: "Anterior"
441
+ }
442
+ ),
443
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
444
+ "P\xE1gina ",
445
+ page
446
+ ] }),
447
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
448
+ "button",
449
+ {
450
+ type: "button",
451
+ onClick: () => onPageChange(page + 1),
452
+ disabled: !hasNextPage,
453
+ className: "inline-flex h-8 items-center justify-center rounded-md border border-input bg-background px-3 text-xs font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground cursor-pointer disabled:pointer-events-none disabled:opacity-50",
454
+ children: "Pr\xF3ximo"
455
+ }
456
+ )
457
+ ] })
458
+ ] });
459
+ }
460
+
461
+ // src/components/mobile-card-list.tsx
462
+ var import_jsx_runtime15 = require("react/jsx-runtime");
463
+ function MobileCardList({
464
+ data,
465
+ renderCard,
466
+ keyExtractor,
467
+ isLoading = false,
468
+ loadingCount = 5,
469
+ className
470
+ }) {
471
+ if (isLoading) {
472
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: `space-y-3 ${className ?? ""}`, children: Array.from({ length: loadingCount }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "rounded-xl border p-4", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "space-y-3", children: [
473
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex justify-between", children: [
474
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "h-5 w-32 animate-pulse rounded bg-muted" }),
475
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "h-5 w-16 animate-pulse rounded bg-muted" })
476
+ ] }),
477
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "h-4 w-48 animate-pulse rounded bg-muted" }),
478
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex justify-between", children: [
479
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "h-4 w-24 animate-pulse rounded bg-muted" }),
480
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "h-4 w-20 animate-pulse rounded bg-muted" })
481
+ ] })
482
+ ] }) }, i)) });
483
+ }
484
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: `space-y-3 ${className ?? ""}`, children: data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
485
+ "div",
486
+ {
487
+ className: "rounded-xl border p-4 transition-all duration-150 hover:border-foreground/20 active:scale-[0.99]",
488
+ children: renderCard(item, index)
489
+ },
490
+ keyExtractor(item)
491
+ )) });
492
+ }
493
+
494
+ // src/components/responsive-data-view.tsx
495
+ var import_jsx_runtime16 = require("react/jsx-runtime");
496
+ function ResponsiveDataView({
497
+ table,
498
+ cards,
499
+ isEmpty,
500
+ isLoading,
501
+ emptyIcon,
502
+ emptyTitle = "Nenhum registro encontrado",
503
+ emptyDescription,
504
+ pagination
505
+ }) {
506
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "space-y-4", children: [
507
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "hidden overflow-x-auto rounded-md border md:block", children: table }),
508
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "md:hidden", children: cards }),
509
+ !isLoading && isEmpty && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
510
+ emptyIcon && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "mb-4 text-muted-foreground", children: emptyIcon }),
511
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { className: "text-lg font-semibold tracking-tight", children: emptyTitle }),
512
+ emptyDescription && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: emptyDescription })
513
+ ] }),
514
+ pagination
515
+ ] });
516
+ }
517
+
518
+ // src/components/toaster.tsx
519
+ var import_sonner = require("sonner");
520
+ var import_jsx_runtime17 = require("react/jsx-runtime");
521
+ function Toaster(props) {
522
+ const { theme = "system" } = useTheme();
523
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
524
+ import_sonner.Toaster,
525
+ {
526
+ theme,
527
+ className: "toaster group",
528
+ toastOptions: {
529
+ classNames: {
530
+ toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-md",
531
+ description: "group-[.toast]:text-muted-foreground",
532
+ actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
533
+ cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
534
+ success: "group-[.toaster]:!bg-background group-[.toaster]:!text-foreground group-[.toaster]:!border-success/40",
535
+ error: "group-[.toaster]:!bg-background group-[.toaster]:!text-foreground group-[.toaster]:!border-destructive/40"
536
+ }
537
+ },
538
+ ...props
539
+ }
540
+ );
541
+ }
542
+
543
+ // src/lib/utils.ts
544
+ var import_clsx = require("clsx");
545
+ var import_tailwind_merge = require("tailwind-merge");
546
+ function cn(...inputs) {
547
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
548
+ }
549
+
550
+ // src/lib/api-error.ts
551
+ function extractApiError(err, fallbackMessage = "Ocorreu um erro inesperado.") {
552
+ const detail = err?.body?.detail || err?.message;
553
+ if (Array.isArray(detail) && detail.length > 0) {
554
+ return detail[0].msg;
555
+ }
556
+ return detail || fallbackMessage;
557
+ }
558
+
559
+ // src/hooks/use-disclosure.ts
560
+ var import_react2 = require("react");
561
+ function useDisclosure(initial = false) {
562
+ const [open, setOpen] = (0, import_react2.useState)(initial);
563
+ const onOpen = (0, import_react2.useCallback)(() => setOpen(true), []);
564
+ const onClose = (0, import_react2.useCallback)(() => setOpen(false), []);
565
+ const onToggle = (0, import_react2.useCallback)(() => setOpen((v) => !v), []);
566
+ return { open, onOpen, onClose, onToggle, setOpen };
567
+ }
568
+
569
+ // src/hooks/use-toast.ts
570
+ var import_sonner2 = require("sonner");
571
+ var import_react3 = require("react");
572
+ function useCustomToast() {
573
+ const showToast = (0, import_react3.useCallback)(
574
+ (title, description, status = "success") => {
575
+ switch (status) {
576
+ case "success":
577
+ import_sonner2.toast.success(title, { description });
578
+ break;
579
+ case "error":
580
+ import_sonner2.toast.error(title, { description });
581
+ break;
582
+ case "info":
583
+ import_sonner2.toast.info(title, { description });
584
+ break;
585
+ case "warning":
586
+ import_sonner2.toast.warning(title, { description });
587
+ break;
588
+ }
589
+ },
590
+ []
591
+ );
592
+ return showToast;
593
+ }
594
+ // Annotate the CommonJS export names for ESM import in node:
595
+ 0 && (module.exports = {
596
+ AuthCard,
597
+ ConfirmDialog,
598
+ DataTableWrapper,
599
+ EmptyState,
600
+ FormDialogLayout,
601
+ FormField,
602
+ MobileCardList,
603
+ ModeToggle,
604
+ PageHeader,
605
+ Pagination,
606
+ ResponsiveDataView,
607
+ SearchInput,
608
+ StatCard,
609
+ StatusDot,
610
+ TableSkeleton,
611
+ ThemeProvider,
612
+ Toaster,
613
+ cn,
614
+ extractApiError,
615
+ toast,
616
+ useCustomToast,
617
+ useDisclosure,
618
+ useTheme
619
+ });
620
+ //# sourceMappingURL=index.cjs.map