@motor-hero/ui-kit 0.37.4 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/responsive-data-view.d.ts +3 -1
- package/dist/components/responsive-data-view.d.ts.map +1 -1
- package/dist/components/status-badge.d.ts.map +1 -1
- package/dist/components/table-skeleton.d.ts.map +1 -1
- package/dist/index.cjs +30 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +30 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/confirm-dialog.tsx +1 -1
- package/src/components/form-dialog.tsx +1 -1
- package/src/components/responsive-data-view.tsx +31 -9
- package/src/components/status-badge.tsx +23 -10
- package/src/components/table-skeleton.tsx +5 -2
package/package.json
CHANGED
|
@@ -63,7 +63,7 @@ export function ConfirmDialog({
|
|
|
63
63
|
<AlertDialog.Action
|
|
64
64
|
onClick={onConfirm}
|
|
65
65
|
disabled={loading}
|
|
66
|
-
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 ${
|
|
66
|
+
className={`inline-flex h-9 items-center justify-center rounded-md px-4 text-sm font-medium shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 cursor-pointer ${
|
|
67
67
|
variant === "destructive"
|
|
68
68
|
? "bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
|
69
69
|
: "bg-primary text-primary-foreground hover:bg-primary/90"
|
|
@@ -41,7 +41,7 @@ export function FormDialogLayout({
|
|
|
41
41
|
<button
|
|
42
42
|
type="submit"
|
|
43
43
|
disabled={isSubmitting || isDisabled}
|
|
44
|
-
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"
|
|
44
|
+
className="inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground shadow-sm transition-colors hover:bg-primary/90 cursor-pointer disabled:pointer-events-none disabled:opacity-50"
|
|
45
45
|
>
|
|
46
46
|
{isSubmitting ? "Salvando..." : submitLabel}
|
|
47
47
|
</button>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from "react"
|
|
2
|
+
import { EmptyState } from "./empty-state"
|
|
2
3
|
|
|
3
4
|
interface ResponsiveDataViewProps {
|
|
4
5
|
table: ReactNode
|
|
@@ -8,23 +9,44 @@ interface ResponsiveDataViewProps {
|
|
|
8
9
|
emptyIcon?: ReactNode
|
|
9
10
|
emptyTitle?: string
|
|
10
11
|
emptyDescription?: string
|
|
12
|
+
/** CTA do estado vazio — normalmente o mesmo botão "Adicionar X" da página. */
|
|
13
|
+
emptyAction?: ReactNode
|
|
11
14
|
pagination?: ReactNode
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
export function ResponsiveDataView({
|
|
15
|
-
table,
|
|
18
|
+
table,
|
|
19
|
+
cards,
|
|
20
|
+
isEmpty,
|
|
21
|
+
isLoading,
|
|
22
|
+
emptyIcon,
|
|
23
|
+
emptyTitle = "Nenhum registro encontrado",
|
|
24
|
+
emptyDescription,
|
|
25
|
+
emptyAction,
|
|
26
|
+
pagination,
|
|
16
27
|
}: ResponsiveDataViewProps) {
|
|
28
|
+
// Lista vazia mostra só o EmptyState. Antes renderizava a caixa com o
|
|
29
|
+
// cabeçalho da tabela vazio, o bloco de texto por fora dela e a paginação
|
|
30
|
+
// desabilitada — três blocos empilhados para zero registro.
|
|
31
|
+
if (!isLoading && isEmpty) {
|
|
32
|
+
return (
|
|
33
|
+
<div className="rounded-md border">
|
|
34
|
+
<EmptyState
|
|
35
|
+
icon={emptyIcon}
|
|
36
|
+
title={emptyTitle}
|
|
37
|
+
description={emptyDescription}
|
|
38
|
+
action={emptyAction}
|
|
39
|
+
/>
|
|
40
|
+
</div>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
17
44
|
return (
|
|
18
45
|
<div className="space-y-4">
|
|
19
|
-
<div className="hidden overflow-x-auto rounded-md border md:block">
|
|
46
|
+
<div className="hidden overflow-x-auto rounded-md border md:block">
|
|
47
|
+
{table}
|
|
48
|
+
</div>
|
|
20
49
|
<div className="md:hidden">{cards}</div>
|
|
21
|
-
{!isLoading && isEmpty && (
|
|
22
|
-
<div className="flex flex-col items-center justify-center py-16 text-center">
|
|
23
|
-
{emptyIcon && <div className="mb-4 text-muted-foreground">{emptyIcon}</div>}
|
|
24
|
-
<h3 className="text-lg font-semibold tracking-tight">{emptyTitle}</h3>
|
|
25
|
-
{emptyDescription && <p className="mt-1 max-w-sm text-sm text-muted-foreground">{emptyDescription}</p>}
|
|
26
|
-
</div>
|
|
27
|
-
)}
|
|
28
50
|
{pagination}
|
|
29
51
|
</div>
|
|
30
52
|
)
|
|
@@ -14,29 +14,42 @@ interface StatusBadgeProps {
|
|
|
14
14
|
children: ReactNode
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Cada variante lê os tokens semânticos `--status-*` do app, com fallback para
|
|
19
|
+
* a paleta Tailwind que o componente já usava. Um app que define os tokens
|
|
20
|
+
* (ex.: IMMA, de neutros quentes) ganha as cores do seu design system; um app
|
|
21
|
+
* que não define continua com a aparência de antes — a troca não quebra nenhum
|
|
22
|
+
* consumidor. Também dispensa `dark:`, já que os tokens de quem os define
|
|
23
|
+
* mudam sozinhos no escopo `.dark`.
|
|
24
|
+
*/
|
|
17
25
|
const variantClasses: Record<
|
|
18
26
|
StatusBadgeVariant,
|
|
19
27
|
{ badge: string; dot: string }
|
|
20
28
|
> = {
|
|
21
29
|
neutral: {
|
|
22
|
-
badge:
|
|
23
|
-
|
|
30
|
+
badge:
|
|
31
|
+
"bg-[var(--status-neutral-surface,#f3f4f6)] text-[var(--status-neutral-text,#374151)]",
|
|
32
|
+
dot: "bg-[var(--status-neutral,#9ca3af)]",
|
|
24
33
|
},
|
|
25
34
|
info: {
|
|
26
|
-
badge:
|
|
27
|
-
|
|
35
|
+
badge:
|
|
36
|
+
"bg-[var(--status-info-surface,#dbeafe)] text-[var(--status-info-text,#1d4ed8)]",
|
|
37
|
+
dot: "bg-[var(--status-info,#3b82f6)]",
|
|
28
38
|
},
|
|
29
39
|
success: {
|
|
30
|
-
badge:
|
|
31
|
-
|
|
40
|
+
badge:
|
|
41
|
+
"bg-[var(--status-success-surface,#dcfce7)] text-[var(--status-success-text,#15803d)]",
|
|
42
|
+
dot: "bg-[var(--status-success,#22c55e)]",
|
|
32
43
|
},
|
|
33
44
|
danger: {
|
|
34
|
-
badge:
|
|
35
|
-
|
|
45
|
+
badge:
|
|
46
|
+
"bg-[var(--status-danger-surface,#fee2e2)] text-[var(--status-danger-text,#b91c1c)]",
|
|
47
|
+
dot: "bg-[var(--status-danger,#ef4444)]",
|
|
36
48
|
},
|
|
37
49
|
warning: {
|
|
38
|
-
badge:
|
|
39
|
-
|
|
50
|
+
badge:
|
|
51
|
+
"bg-[var(--status-warning-surface,#fef3c7)] text-[var(--status-warning-text,#b45309)]",
|
|
52
|
+
dot: "bg-[var(--status-warning,#f59e0b)]",
|
|
40
53
|
},
|
|
41
54
|
}
|
|
42
55
|
|
|
@@ -7,10 +7,13 @@ export function TableSkeleton({ rows = 5, columns = 4 }: TableSkeletonProps) {
|
|
|
7
7
|
return (
|
|
8
8
|
<>
|
|
9
9
|
{Array.from({ length: rows }).map((_, i) => (
|
|
10
|
+
// p-2/h-4 espelha o TableCell real. Com p-4/h-5 a linha do skeleton
|
|
11
|
+
// ficava ~16px mais alta que a linha de dados, e a tabela encolhia
|
|
12
|
+
// visivelmente quando a resposta chegava.
|
|
10
13
|
<tr key={i} className="border-b transition-colors">
|
|
11
14
|
{Array.from({ length: columns }).map((_, j) => (
|
|
12
|
-
<td key={j} className="p-
|
|
13
|
-
<div className="h-
|
|
15
|
+
<td key={j} className="p-2 align-middle first:pl-4 last:pr-4">
|
|
16
|
+
<div className="h-4 w-full animate-pulse rounded bg-muted" />
|
|
14
17
|
</td>
|
|
15
18
|
))}
|
|
16
19
|
</tr>
|