@rendra-ui/web 2.3.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -61
- package/bin/rendra.mjs +19 -7
- package/dist/base.css +33 -1
- package/dist/{button-DWhICtIG.js → button-BzJgR2gH.js} +86 -21
- package/dist/button-BzJgR2gH.js.map +1 -0
- package/dist/chart.js +61 -15
- package/dist/chart.js.map +1 -1
- package/dist/cli/auditar.js +66 -16
- package/dist/cli/auditar.js.map +1 -1
- package/dist/cli/codigos.js +2 -2
- package/dist/cli/executar-auditar.js +634 -0
- package/dist/cli/executar-auditar.js.map +1 -0
- package/dist/cli/help.js +7 -2
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/trocar.js +2 -2
- package/dist/cli/typescript-loader.js +1 -1
- package/dist/{cn-DDZQKUVV.js → cn-Cw7M5kEP.js} +2 -2
- package/dist/{cn-DDZQKUVV.js.map → cn-Cw7M5kEP.js.map} +1 -1
- package/dist/{components-Cq_PmN4y.js → components-DkpspH9h.js} +21 -4
- package/dist/components-DkpspH9h.js.map +1 -0
- package/dist/components.css +274 -32
- package/dist/document-viewer.js +6 -6
- package/dist/document-viewer.js.map +1 -1
- package/dist/{empty-state-C491qfzf.js → empty-state-Cdb1vkMT.js} +81 -37
- package/dist/empty-state-Cdb1vkMT.js.map +1 -0
- package/dist/features-max--5VEt6M7.js +3 -0
- package/dist/index.js +1170 -390
- package/dist/index.js.map +1 -1
- package/dist/motion-context-5BRIQAJm.js +107 -0
- package/dist/motion-context-5BRIQAJm.js.map +1 -0
- package/dist/{rendra-provider-BRtk5Qa1.js → rendra-provider-CRe0XdOU.js} +9 -5
- package/dist/rendra-provider-CRe0XdOU.js.map +1 -0
- package/dist/rich-text-editor.js +4 -4
- package/dist/router-bridge.js +5 -4
- package/dist/router-bridge.js.map +1 -1
- package/dist/tokens.css +73 -15
- package/dist/tooltip-BAMSaGbS.js +224 -0
- package/dist/tooltip-BAMSaGbS.js.map +1 -0
- package/dist/types/components/app-shell/app-shell.d.ts +22 -2
- package/dist/types/components/app-shell/shell-context.d.ts +7 -1
- package/dist/types/components/app-shell/types.d.ts +23 -0
- package/dist/types/components/layout/page-header.d.ts +17 -1
- package/dist/types/components/rendra-provider.d.ts +7 -1
- package/dist/types/components/rendra-router-bridge.d.ts +3 -1
- package/dist/types/components/ui/accordion.d.ts +1 -1
- package/dist/types/components/ui/badge.d.ts +1 -1
- package/dist/types/components/ui/brand-feedback-icon.d.ts +20 -3
- package/dist/types/components/ui/button-group.d.ts +8 -1
- package/dist/types/components/ui/button.d.ts +1 -1
- package/dist/types/components/ui/dropdown-menu.d.ts +5 -5
- package/dist/types/components/ui/empty-state.d.ts +4 -0
- package/dist/types/components/ui/error-page.d.ts +6 -1
- package/dist/types/components/ui/modal.d.ts +4 -0
- package/dist/types/components/ui/picker-panel.d.ts +1 -1
- package/dist/types/components/ui/popover.d.ts +3 -3
- package/dist/types/components/ui/radio-group.d.ts +1 -1
- package/dist/types/components/ui/skeleton.d.ts +5 -1
- package/dist/types/components/ui/stat-card.d.ts +1 -1
- package/dist/types/components/ui/table.d.ts +0 -6
- package/dist/types/components/ui/tooltip.d.ts +1 -1
- package/dist/types/components/ui/wizard.d.ts +14 -1
- package/dist/types/hooks/use-reduced-motion.d.ts +3 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/lib/initials.d.ts +2 -0
- package/dist/types/lib/motion/count.d.ts +17 -0
- package/dist/types/lib/motion/features-max.d.ts +1 -0
- package/dist/types/lib/motion/index.d.ts +5 -0
- package/dist/types/lib/motion/motion-context.d.ts +43 -0
- package/dist/types/lib/motion/native-events.d.ts +16 -0
- package/dist/types/lib/motion/presets.d.ts +92 -0
- package/dist/types/lib/motion/reorder.d.ts +7 -0
- package/dist/types/lib/motion/tokens.d.ts +66 -0
- package/dist/types/lib/motion/use-motion-presets.d.ts +8 -0
- package/dist/{use-breakpoint-C3ivDt2R.js → use-breakpoint-O9eqFmsF.js} +2 -2
- package/dist/{use-breakpoint-C3ivDt2R.js.map → use-breakpoint-O9eqFmsF.js.map} +1 -1
- package/dist/use-motion-presets-BrkgL8lG.js +401 -0
- package/dist/use-motion-presets-BrkgL8lG.js.map +1 -0
- package/dist/widget-grid.js +3 -3
- package/package.json +4 -1
- package/dist/button-DWhICtIG.js.map +0 -1
- package/dist/components-Cq_PmN4y.js.map +0 -1
- package/dist/empty-state-C491qfzf.js.map +0 -1
- package/dist/rendra-provider-BRtk5Qa1.js.map +0 -1
- package/dist/tooltip-DsNlnBSY.js +0 -105
- package/dist/tooltip-DsNlnBSY.js.map +0 -1
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
2
|
-
import { t as cn } from "./cn-
|
|
3
|
-
import {
|
|
1
|
+
/*! Rendra Design System v2.5.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
|
+
import { t as cn } from "./cn-Cw7M5kEP.js";
|
|
3
|
+
import { r as useMotionMode } from "./motion-context-5BRIQAJm.js";
|
|
4
|
+
import { t as useMotionPresets } from "./use-motion-presets-BrkgL8lG.js";
|
|
5
|
+
import { CircleCheck, CircleX, Info, TriangleAlert } from "lucide-react";
|
|
6
|
+
import { m } from "motion/react";
|
|
4
7
|
import { createContext, useContext } from "react";
|
|
8
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
5
9
|
import { cva } from "class-variance-authority";
|
|
6
10
|
//#region src/brand/brand-context.ts
|
|
7
11
|
var BrandContext = createContext(null);
|
|
@@ -14,27 +18,39 @@ function useBrand() {
|
|
|
14
18
|
}
|
|
15
19
|
//#endregion
|
|
16
20
|
//#region src/components/ui/brand-feedback-icon.tsx
|
|
21
|
+
var sizes = {
|
|
22
|
+
sm: "size-icon-sm",
|
|
23
|
+
md: "size-icon-md",
|
|
24
|
+
lg: "size-icon-lg",
|
|
25
|
+
xl: "size-12",
|
|
26
|
+
"2xl": "size-16"
|
|
27
|
+
};
|
|
17
28
|
var iconVariants = cva("relative inline-flex shrink-0", {
|
|
18
|
-
variants: {
|
|
19
|
-
|
|
20
|
-
success: "text-success",
|
|
21
|
-
error: "text-destructive",
|
|
22
|
-
warning: "text-warning",
|
|
23
|
-
info: "text-info"
|
|
24
|
-
},
|
|
25
|
-
size: {
|
|
26
|
-
sm: "size-icon-sm",
|
|
27
|
-
md: "size-icon-md",
|
|
28
|
-
lg: "size-icon-lg",
|
|
29
|
-
xl: "size-12",
|
|
30
|
-
"2xl": "size-16"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
defaultVariants: {
|
|
34
|
-
type: "info",
|
|
35
|
-
size: "md"
|
|
36
|
-
}
|
|
29
|
+
variants: { size: sizes },
|
|
30
|
+
defaultVariants: { size: "md" }
|
|
37
31
|
});
|
|
32
|
+
/** Cor do estado (tinge o símbolo e, em statusBadge, o ícone ao lado). */
|
|
33
|
+
var stateText = {
|
|
34
|
+
success: "text-success",
|
|
35
|
+
error: "text-destructive",
|
|
36
|
+
warning: "text-warning",
|
|
37
|
+
info: "text-info"
|
|
38
|
+
};
|
|
39
|
+
/** Ícone Lucide do selo ao lado do símbolo (statusBadge). */
|
|
40
|
+
var badgeIcons = {
|
|
41
|
+
success: CircleCheck,
|
|
42
|
+
error: CircleX,
|
|
43
|
+
warning: TriangleAlert,
|
|
44
|
+
info: Info
|
|
45
|
+
};
|
|
46
|
+
/** Tamanho do ícone ao lado, proporcional ao do símbolo. */
|
|
47
|
+
var badgeIconSize = {
|
|
48
|
+
sm: "size-3",
|
|
49
|
+
md: "size-icon-sm",
|
|
50
|
+
lg: "size-icon-md",
|
|
51
|
+
xl: "size-icon-lg",
|
|
52
|
+
"2xl": "size-icon-lg"
|
|
53
|
+
};
|
|
38
54
|
var badgeTone = {
|
|
39
55
|
success: "bg-success text-success-foreground",
|
|
40
56
|
error: "bg-destructive text-destructive-foreground",
|
|
@@ -100,7 +116,7 @@ function StatusGlyph({ type, animated, ...props }) {
|
|
|
100
116
|
* semântica, com um selo de status para que o significado não dependa só da cor.
|
|
101
117
|
* Cada tipo pode ser substituído por um SVG próprio em brand.config.ts (feedbackIcons).
|
|
102
118
|
*/
|
|
103
|
-
function BrandFeedbackIcon({ type, size, label, animated = false, className }) {
|
|
119
|
+
function BrandFeedbackIcon({ type, size, label, animated = false, symbolTone = "state", statusBadge = false, animation = "pop", className }) {
|
|
104
120
|
const { brand } = useBrand();
|
|
105
121
|
const Custom = brand.feedbackIcons?.[type];
|
|
106
122
|
const Symbol = brand.symbol;
|
|
@@ -108,19 +124,26 @@ function BrandFeedbackIcon({ type, size, label, animated = false, className }) {
|
|
|
108
124
|
role: "img",
|
|
109
125
|
"aria-label": label
|
|
110
126
|
} : { "aria-hidden": true };
|
|
127
|
+
const encaixe = animation === "encaixe";
|
|
128
|
+
const rootTone = symbolTone === "state" ? stateText[type] : void 0;
|
|
129
|
+
const symbolTonal = symbolTone === "brand" && "text-primary-text";
|
|
130
|
+
const symbolAnim = animated && (encaixe ? "animate-encaixe" : "animate-pop");
|
|
131
|
+
const badgeAnim = animated && (encaixe ? "animate-encaixe" : "animate-pop anim-delay-1");
|
|
132
|
+
const BadgeIcon = badgeIcons[type];
|
|
133
|
+
const sideBadge = statusBadge && !Custom;
|
|
111
134
|
return /* @__PURE__ */ jsx("span", {
|
|
112
135
|
"data-slot": "feedback-icon",
|
|
113
136
|
"data-rendra": "BFI-001",
|
|
114
|
-
className: cn(iconVariants({
|
|
115
|
-
type,
|
|
116
|
-
size
|
|
117
|
-
}), animated && type === "error" && "animate-shake", className),
|
|
137
|
+
className: cn(sideBadge ? "relative inline-flex shrink-0 items-center gap-1" : iconVariants({ size }), rootTone, animated && !encaixe && type === "error" && "animate-shake", className),
|
|
118
138
|
...a11y,
|
|
119
|
-
children: Custom ? /* @__PURE__ */ jsx(Custom, { className: cn("size-full",
|
|
120
|
-
|
|
139
|
+
children: Custom ? /* @__PURE__ */ jsx(Custom, { className: cn("size-full", symbolTonal, symbolAnim) }) : sideBadge ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Symbol, { className: cn(sizes[size ?? "md"], symbolTonal, symbolAnim) }), /* @__PURE__ */ jsx(BadgeIcon, {
|
|
140
|
+
"aria-hidden": true,
|
|
141
|
+
className: cn("shrink-0", badgeIconSize[size ?? "md"], stateText[type], badgeAnim)
|
|
142
|
+
})] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Symbol, { className: cn("size-full mask-status-cutout", symbolTonal, symbolAnim) }), /* @__PURE__ */ jsx("span", {
|
|
143
|
+
className: cn("absolute right-0 bottom-0 flex size-1/2 items-center justify-center rounded-full", badgeTone[type], badgeAnim),
|
|
121
144
|
children: /* @__PURE__ */ jsx(StatusGlyph, {
|
|
122
145
|
type,
|
|
123
|
-
animated,
|
|
146
|
+
animated: animated && !encaixe,
|
|
124
147
|
className: "size-full"
|
|
125
148
|
})
|
|
126
149
|
})] })
|
|
@@ -130,12 +153,30 @@ function BrandFeedbackIcon({ type, size, label, animated = false, className }) {
|
|
|
130
153
|
//#region src/components/ui/empty-state.tsx
|
|
131
154
|
/** Estado vazio (e de erro) com o ícone de feedback da marca. */
|
|
132
155
|
function EmptyState({ title, description, type = "info", actions, size = "default", className }) {
|
|
156
|
+
const on = useMotionMode() === "on";
|
|
157
|
+
const presets = useMotionPresets();
|
|
158
|
+
const Icon = on ? m.span : "span";
|
|
159
|
+
const Title = on ? m.p : "p";
|
|
160
|
+
const Description = on ? m.p : "p";
|
|
161
|
+
const Actions = on ? m.div : "div";
|
|
162
|
+
const part = (index) => {
|
|
163
|
+
if (!on) return {};
|
|
164
|
+
const enter = presets.slide("bottom", "short");
|
|
165
|
+
return {
|
|
166
|
+
...enter,
|
|
167
|
+
transition: {
|
|
168
|
+
...enter.transition,
|
|
169
|
+
...presets.stagger(index)
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
};
|
|
133
173
|
return /* @__PURE__ */ jsxs("div", {
|
|
134
174
|
"data-rendra": "VAZ-001",
|
|
135
175
|
className: cn("flex flex-col items-center justify-center gap-4 text-center", size === "compact" ? "px-4 py-8" : "px-4 py-12 md:py-16", className),
|
|
136
176
|
children: [
|
|
137
|
-
/* @__PURE__ */ jsxs(
|
|
177
|
+
/* @__PURE__ */ jsxs(Icon, {
|
|
138
178
|
className: "relative flex items-center justify-center",
|
|
179
|
+
...part(0),
|
|
139
180
|
children: [/* @__PURE__ */ jsx("span", {
|
|
140
181
|
"aria-hidden": true,
|
|
141
182
|
className: "absolute size-16 rounded-full bg-gradient-soft"
|
|
@@ -147,16 +188,19 @@ function EmptyState({ title, description, type = "info", actions, size = "defaul
|
|
|
147
188
|
}),
|
|
148
189
|
/* @__PURE__ */ jsxs("div", {
|
|
149
190
|
className: "flex w-full flex-col gap-1",
|
|
150
|
-
children: [/* @__PURE__ */ jsx(
|
|
151
|
-
className: "text-base font-semibold",
|
|
191
|
+
children: [/* @__PURE__ */ jsx(Title, {
|
|
192
|
+
className: "text-base font-semibold wrap-break-word",
|
|
193
|
+
...part(1),
|
|
152
194
|
children: title
|
|
153
|
-
}), description && /* @__PURE__ */ jsx(
|
|
154
|
-
className: "text-sm text-muted-foreground",
|
|
195
|
+
}), description && /* @__PURE__ */ jsx(Description, {
|
|
196
|
+
className: "text-sm wrap-break-word text-muted-foreground",
|
|
197
|
+
...part(2),
|
|
155
198
|
children: description
|
|
156
199
|
})]
|
|
157
200
|
}),
|
|
158
|
-
actions && /* @__PURE__ */ jsx(
|
|
201
|
+
actions && /* @__PURE__ */ jsx(Actions, {
|
|
159
202
|
className: "flex flex-wrap justify-center gap-3",
|
|
203
|
+
...part(3),
|
|
160
204
|
children: actions
|
|
161
205
|
})
|
|
162
206
|
]
|
|
@@ -165,4 +209,4 @@ function EmptyState({ title, description, type = "info", actions, size = "defaul
|
|
|
165
209
|
//#endregion
|
|
166
210
|
export { BrandContext as a, useBrand as i, BrandFeedbackIcon as n, feedbackLabels as r, EmptyState as t };
|
|
167
211
|
|
|
168
|
-
//# sourceMappingURL=empty-state-
|
|
212
|
+
//# sourceMappingURL=empty-state-Cdb1vkMT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty-state-Cdb1vkMT.js","names":[],"sources":["../src/brand/brand-context.ts","../src/brand/use-brand.ts","../src/components/ui/brand-feedback-icon.tsx","../src/components/ui/empty-state.tsx"],"sourcesContent":["import { createContext } from 'react'\nimport type { Shape } from '@/lib/shape'\nimport type { BrandConfig, PaletteConfig } from './types'\n\nexport type ColorMode = 'light' | 'dark' | 'system'\n\nexport interface BrandContextValue {\n brand: BrandConfig\n brands: BrandConfig[]\n setBrandId: (id: string) => void\n mode: ColorMode\n resolvedMode: 'light' | 'dark'\n setMode: (mode: ColorMode) => void\n /** Formato do template ativo (fixo por template). */\n shape: Shape\n /** Paleta de cores em uso (por padrão, a do próprio modelo). */\n palette: PaletteConfig\n palettes: PaletteConfig[]\n /** Usa a paleta de outro template; null volta às cores do próprio modelo. */\n setPaletteId: (id: string | null) => void\n /** Logotipo adequado para a sidebar com a paleta atual. */\n sidebarLogoVariant: 'light' | 'dark'\n}\n\nexport const BrandContext = createContext<BrandContextValue | null>(null)\n","import { useContext } from 'react'\nimport { BrandContext } from './brand-context'\n\nexport function useBrand() {\n const ctx = useContext(BrandContext)\n if (!ctx) throw new Error('useBrand precisa estar dentro de <BrandProvider>.')\n return ctx\n}\n","import { cva, type VariantProps } from 'class-variance-authority'\nimport { CircleCheck, CircleX, Info, TriangleAlert, type LucideIcon } from 'lucide-react'\nimport type { SVGProps } from 'react'\nimport { useBrand } from '@/brand/use-brand'\nimport type { FeedbackType } from '@/brand/types'\nimport { cn } from '@/lib/cn'\n\nconst sizes = {\n sm: 'size-icon-sm',\n md: 'size-icon-md',\n lg: 'size-icon-lg',\n xl: 'size-12',\n '2xl': 'size-16',\n} as const\n\nconst iconVariants = cva('relative inline-flex shrink-0', {\n variants: { size: sizes },\n defaultVariants: { size: 'md' },\n})\n\n/** Cor do estado (tinge o símbolo e, em statusBadge, o ícone ao lado). */\nconst stateText: Record<FeedbackType, string> = {\n success: 'text-success',\n error: 'text-destructive',\n warning: 'text-warning',\n info: 'text-info',\n}\n\n/** Ícone Lucide do selo ao lado do símbolo (statusBadge). */\nconst badgeIcons: Record<FeedbackType, LucideIcon> = {\n success: CircleCheck,\n error: CircleX,\n warning: TriangleAlert,\n info: Info,\n}\n\n/** Tamanho do ícone ao lado, proporcional ao do símbolo. */\nconst badgeIconSize: Record<keyof typeof sizes, string> = {\n sm: 'size-3',\n md: 'size-icon-sm',\n lg: 'size-icon-md',\n xl: 'size-icon-lg',\n '2xl': 'size-icon-lg',\n}\n\nconst badgeTone: Record<FeedbackType, string> = {\n success: 'bg-success text-success-foreground',\n error: 'bg-destructive text-destructive-foreground',\n warning: 'bg-warning text-warning-foreground',\n info: 'bg-info text-info-foreground',\n}\n\nexport const feedbackLabels: Record<FeedbackType, string> = {\n success: 'Sucesso',\n error: 'Erro',\n warning: 'Atenção',\n info: 'Informação',\n}\n\n/** Glifos universais de status desenhados em traço, herdando currentColor. */\nfunction StatusGlyph({\n type,\n animated,\n ...props\n}: { type: FeedbackType; animated?: boolean } & SVGProps<SVGSVGElement>) {\n // pathLength=1 normaliza o traço: o desenho anima de 1 a 0 em qualquer glifo.\n const draw = animated\n ? ({ pathLength: 1, strokeDasharray: 1, className: 'animate-draw' } as const)\n : {}\n const common = {\n viewBox: '0 0 12 12',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n 'aria-hidden': true,\n ...props,\n }\n switch (type) {\n case 'success':\n return (\n <svg {...common}>\n <path d=\"M3 6.2 5.1 8.2 9 4\" {...draw} />\n </svg>\n )\n case 'error':\n return (\n <svg {...common}>\n <path d=\"M4 4l4 4M8 4 4 8\" {...draw} />\n </svg>\n )\n case 'warning':\n return (\n <svg {...common}>\n <path d=\"M6 3.2v3.3M6 8.8v0\" {...draw} />\n </svg>\n )\n case 'info':\n return (\n <svg {...common}>\n <path d=\"M6 3.2v0M6 5.5v3.3\" {...draw} />\n </svg>\n )\n }\n}\n\nexport interface BrandFeedbackIconProps extends VariantProps<typeof iconVariants> {\n type: FeedbackType\n /** Texto para leitores de tela. Sem ele o ícone é decorativo (o texto ao lado informa). */\n label?: string\n /**\n * Anima a entrada: o símbolo entra com mola e o glifo se desenha (check se formando,\n * X se riscando). O erro treme ao final. Respeita reduzir movimento.\n * Troque a key do componente para repetir a animação.\n */\n animated?: boolean\n /**\n * Cor do símbolo. `state` (padrão): a cor do estado (verde, vermelho, amarelo, azul).\n * `brand`: a cor primária da marca (`text-primary-text`); o selo de estado mantém a cor do\n * estado, para o significado não depender só da cor.\n */\n symbolTone?: 'state' | 'brand'\n /**\n * `false` (padrão): selo de estado sobreposto ao símbolo. `true`: o ícone do estado\n * (Lucide, na cor do estado) fica ao lado do símbolo, no lugar do selo sobreposto. Com um\n * SVG próprio em `brand.feedbackIcons[type]`, o SVG vence e nenhum selo é desenhado.\n */\n statusBadge?: boolean\n /**\n * Só vale com `animated`. `pop` (padrão): entra com mola, o glifo se desenha e o erro\n * treme. `encaixe`: entra em 240 ms, curva de saída suave, sem quique, sem desenho e sem\n * tremor. Com \"reduzir movimento\" do sistema, nenhuma animação roda.\n */\n animation?: 'pop' | 'encaixe'\n className?: string\n}\n\n/**\n * Ícone de feedback da marca: o símbolo da marca em currentColor, tingido pela cor\n * semântica, com um selo de status para que o significado não dependa só da cor.\n * Cada tipo pode ser substituído por um SVG próprio em brand.config.ts (feedbackIcons).\n */\nexport function BrandFeedbackIcon({\n type,\n size,\n label,\n animated = false,\n symbolTone = 'state',\n statusBadge = false,\n animation = 'pop',\n className,\n}: BrandFeedbackIconProps) {\n const { brand } = useBrand()\n const Custom = brand.feedbackIcons?.[type]\n const Symbol = brand.symbol\n const a11y = label\n ? ({ role: 'img', 'aria-label': label } as const)\n : ({ 'aria-hidden': true } as const)\n const encaixe = animation === 'encaixe'\n // Com `symbolTone=\"state\"` o texto do estado fica na raiz (como sempre); com `brand` sai da raiz.\n const rootTone = symbolTone === 'state' ? stateText[type] : undefined\n const symbolTonal = symbolTone === 'brand' && 'text-primary-text'\n const symbolAnim = animated && (encaixe ? 'animate-encaixe' : 'animate-pop')\n const badgeAnim = animated && (encaixe ? 'animate-encaixe' : 'animate-pop anim-delay-1')\n const BadgeIcon = badgeIcons[type]\n const sideBadge = statusBadge && !Custom\n\n return (\n <span\n data-slot=\"feedback-icon\"\n data-rendra=\"BFI-001\"\n className={cn(\n sideBadge ? 'relative inline-flex shrink-0 items-center gap-1' : iconVariants({ size }),\n rootTone,\n animated && !encaixe && type === 'error' && 'animate-shake',\n className,\n )}\n {...a11y}\n >\n {Custom ? (\n <Custom className={cn('size-full', symbolTonal, symbolAnim)} />\n ) : sideBadge ? (\n <>\n <Symbol className={cn(sizes[size ?? 'md'], symbolTonal, symbolAnim)} />\n <BadgeIcon\n aria-hidden\n className={cn('shrink-0', badgeIconSize[size ?? 'md'], stateText[type], badgeAnim)}\n />\n </>\n ) : (\n <>\n <Symbol className={cn('size-full mask-status-cutout', symbolTonal, symbolAnim)} />\n <span\n className={cn(\n 'absolute right-0 bottom-0 flex size-1/2 items-center justify-center rounded-full',\n badgeTone[type],\n badgeAnim,\n )}\n >\n <StatusGlyph type={type} animated={animated && !encaixe} className=\"size-full\" />\n </span>\n </>\n )}\n </span>\n )\n}\n","import { m } from 'motion/react'\nimport type { ElementType, ReactNode } from 'react'\nimport type { FeedbackType } from '@/brand/types'\nimport { BrandFeedbackIcon } from '@/components/ui/brand-feedback-icon'\nimport { cn } from '@/lib/cn'\nimport { useMotionMode, useMotionPresets } from '@/lib/motion'\n\nexport interface EmptyStateProps {\n title: string\n description?: ReactNode\n /** Tipo do ícone de feedback da marca. info para \"sem dados\", error para falha. */\n type?: FeedbackType\n /** Ações: no máximo uma principal e uma secundária. */\n actions?: ReactNode\n /** compact: dentro de tabela ou card pequeno. */\n size?: 'default' | 'compact'\n /**\n * Classes extras, que vencem as do componente. Para zerar o respiro vertical (por exemplo,\n * dentro de um card que já tem o seu) use `className=\"py-0 md:py-0\"`.\n */\n className?: string\n}\n\n/** Estado vazio (e de erro) com o ícone de feedback da marca. */\nexport function EmptyState({\n title,\n description,\n type = 'info',\n actions,\n size = 'default',\n className,\n}: EmptyStateProps) {\n const on = useMotionMode() === 'on'\n const presets = useMotionPresets()\n // Em `on` as quatro partes (ícone, título, descrição e ações) sobem em cascata de 60 ms, cada\n // uma com o deslize curto; a raiz em si não anima. Estado vazio é cota de encanto: ocasional,\n // sem teclado no caminho. Em `off` o HTML é o de sempre.\n const Icon: ElementType = on ? m.span : 'span'\n const Title: ElementType = on ? m.p : 'p'\n const Description: ElementType = on ? m.p : 'p'\n const Actions: ElementType = on ? m.div : 'div'\n const part = (index: number) => {\n if (!on) return {}\n const enter = presets.slide('bottom', 'short')\n return { ...enter, transition: { ...enter.transition, ...presets.stagger(index) } }\n }\n return (\n <div\n data-rendra=\"VAZ-001\"\n className={cn(\n 'flex flex-col items-center justify-center gap-4 text-center',\n size === 'compact' ? 'px-4 py-8' : 'px-4 py-12 md:py-16',\n className,\n )}\n >\n <Icon className=\"relative flex items-center justify-center\" {...part(0)}>\n <span aria-hidden className=\"absolute size-16 rounded-full bg-gradient-soft\" />\n <BrandFeedbackIcon\n type={type}\n size={size === 'compact' ? 'xl' : '2xl'}\n className=\"relative\"\n />\n </Icon>\n <div className=\"flex w-full flex-col gap-1\">\n <Title className=\"text-base font-semibold wrap-break-word\" {...part(1)}>\n {title}\n </Title>\n {description && (\n <Description className=\"text-sm wrap-break-word text-muted-foreground\" {...part(2)}>\n {description}\n </Description>\n )}\n </div>\n {actions && (\n <Actions className=\"flex flex-wrap justify-center gap-3\" {...part(3)}>\n {actions}\n </Actions>\n )}\n </div>\n )\n}\n"],"mappings":"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"}
|