|
1 | 1 | import { ReactNode, useId } from "react"; |
2 | 2 | import { IconBadge } from "@shellhub/design-system/primitives"; |
| 3 | +import { GlowOrbs } from "@shellhub/design-system/components"; |
3 | 4 |
|
4 | 5 | export type EmptyStateAccent = "primary" | "yellow"; |
5 | 6 |
|
@@ -28,31 +29,26 @@ interface AccentStyles { |
28 | 29 | badge: string; |
29 | 30 | icon: string; |
30 | 31 | overline: string; |
31 | | - orbPrimary: string; |
32 | | - orbSecondary: string; |
33 | 32 | } |
34 | 33 |
|
35 | 34 | /** |
36 | 35 | * Accent styles. Full literal class strings (never interpolated fragments) so |
37 | 36 | * the Tailwind JIT keeps them. The hero icon inherits the badge's text color |
38 | 37 | * via `currentColor`; feature-card icons stay primary-accented in all variants. |
39 | 38 | * Typed as `Record<EmptyStateAccent, …>` so adding an accent without a matching |
40 | | - * entry is a compile error rather than a runtime `undefined`. |
| 39 | + * entry is a compile error rather than a runtime `undefined`. The decorative |
| 40 | + * orbs are driven by `<GlowOrbs preset="ambient">` (see below), not these tokens. |
41 | 41 | */ |
42 | 42 | const ACCENT = { |
43 | 43 | primary: { |
44 | 44 | badge: "bg-primary/10 border-primary/20 shadow-primary/5", |
45 | 45 | icon: "text-primary", |
46 | 46 | overline: "text-primary/80", |
47 | | - orbPrimary: "bg-primary/5", |
48 | | - orbSecondary: "bg-accent-blue/5", |
49 | 47 | }, |
50 | 48 | yellow: { |
51 | 49 | badge: "bg-accent-yellow/10 border-accent-yellow/20 shadow-accent-yellow/5", |
52 | 50 | icon: "text-accent-yellow", |
53 | 51 | overline: "text-accent-yellow/80", |
54 | | - orbPrimary: "bg-accent-yellow/5", |
55 | | - orbSecondary: "bg-primary/5", |
56 | 52 | }, |
57 | 53 | } satisfies Record<EmptyStateAccent, AccentStyles>; |
58 | 54 |
|
@@ -86,12 +82,9 @@ export default function EmptyState({ |
86 | 82 | aria-hidden="true" |
87 | 83 | className="absolute inset-0 overflow-hidden pointer-events-none -mx-8 -mt-8 -mb-4" |
88 | 84 | > |
89 | | - <div |
90 | | - className={`absolute -top-32 left-1/3 w-[500px] h-[500px] rounded-full blur-[120px] animate-pulse-subtle ${styles.orbPrimary}`} |
91 | | - /> |
92 | | - <div |
93 | | - className={`absolute bottom-0 right-1/4 w-[400px] h-[400px] rounded-full blur-[100px] animate-pulse-subtle ${styles.orbSecondary}`} |
94 | | - style={{ animationDelay: "1s" }} |
| 85 | + <GlowOrbs |
| 86 | + preset="ambient" |
| 87 | + tone={accent === "yellow" ? "warning" : "brand"} |
95 | 88 | /> |
96 | 89 | <div className="absolute inset-0 grid-bg opacity-30" /> |
97 | 90 | </div> |
@@ -123,9 +116,7 @@ export default function EmptyState({ |
123 | 116 |
|
124 | 117 | {/* Feature highlights */} |
125 | 118 | {features?.length ? ( |
126 | | - <ul |
127 | | - className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-10" |
128 | | - > |
| 119 | + <ul className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-10"> |
129 | 120 | {features.map((feature, idx) => ( |
130 | 121 | <li |
131 | 122 | key={feature.title} |
|
0 commit comments