@wakastellar/ui 2.1.2 → 2.3.2

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 (123) hide show
  1. package/dist/blocks/apm-overview/index.d.ts +58 -0
  2. package/dist/blocks/cicd-builder/index.d.ts +47 -0
  3. package/dist/blocks/cloud-cost-dashboard/index.d.ts +49 -0
  4. package/dist/blocks/container-orchestrator/index.d.ts +63 -0
  5. package/dist/blocks/database-admin/index.d.ts +84 -0
  6. package/dist/blocks/gitops-sync-status/index.d.ts +45 -0
  7. package/dist/blocks/incident-manager/index.d.ts +44 -0
  8. package/dist/blocks/index.d.ts +10 -0
  9. package/dist/blocks/infrastructure-map/index.d.ts +32 -0
  10. package/dist/blocks/on-call-schedule/index.d.ts +43 -0
  11. package/dist/blocks/release-notes/index.d.ts +49 -0
  12. package/dist/components/index.d.ts +34 -0
  13. package/dist/components/waka-ad-banner/index.d.ts +36 -0
  14. package/dist/components/waka-ad-fallback/index.d.ts +33 -0
  15. package/dist/components/waka-ad-inline/index.d.ts +15 -0
  16. package/dist/components/waka-ad-interstitial/index.d.ts +26 -0
  17. package/dist/components/waka-ad-placeholder/index.d.ts +17 -0
  18. package/dist/components/waka-ad-provider/index.d.ts +103 -0
  19. package/dist/components/waka-ad-sidebar/index.d.ts +18 -0
  20. package/dist/components/waka-ad-sticky-footer/index.d.ts +17 -0
  21. package/dist/components/waka-alert-panel/index.d.ts +45 -0
  22. package/dist/components/waka-artifact-list/index.d.ts +32 -0
  23. package/dist/components/waka-build-matrix/index.d.ts +36 -0
  24. package/dist/components/waka-config-comparator/index.d.ts +37 -0
  25. package/dist/components/waka-container-list/index.d.ts +51 -0
  26. package/dist/components/waka-content-recommendation/index.d.ts +23 -0
  27. package/dist/components/waka-database-card/index.d.ts +46 -0
  28. package/dist/components/waka-dependency-tree/index.d.ts +38 -0
  29. package/dist/components/waka-env-var-editor/index.d.ts +30 -0
  30. package/dist/components/waka-feature-flag-row/index.d.ts +45 -0
  31. package/dist/components/waka-kubernetes-overview/index.d.ts +98 -0
  32. package/dist/components/waka-log-viewer/index.d.ts +38 -0
  33. package/dist/components/waka-migration-list/index.d.ts +36 -0
  34. package/dist/components/waka-outstream-video/index.d.ts +24 -0
  35. package/dist/components/waka-pod-card/index.d.ts +73 -0
  36. package/dist/components/waka-query-explain/index.d.ts +48 -0
  37. package/dist/components/waka-secret-card/index.d.ts +43 -0
  38. package/dist/components/waka-security-scan-result/index.d.ts +45 -0
  39. package/dist/components/waka-service-graph/index.d.ts +44 -0
  40. package/dist/components/waka-sponsored-badge/index.d.ts +20 -0
  41. package/dist/components/waka-sponsored-card/index.d.ts +25 -0
  42. package/dist/components/waka-sponsored-feed/index.d.ts +31 -0
  43. package/dist/components/waka-test-report/index.d.ts +60 -0
  44. package/dist/components/waka-trace-viewer/index.d.ts +36 -0
  45. package/dist/components/waka-video-ad/index.d.ts +32 -0
  46. package/dist/components/waka-video-overlay/index.d.ts +26 -0
  47. package/dist/index.cjs.js +251 -200
  48. package/dist/index.d.ts +1 -0
  49. package/dist/index.es.js +47315 -35823
  50. package/dist/utils/security.d.ts +96 -0
  51. package/package.json +4 -4
  52. package/src/blocks/apm-overview/index.tsx +672 -0
  53. package/src/blocks/cicd-builder/index.tsx +738 -0
  54. package/src/blocks/cloud-cost-dashboard/index.tsx +597 -0
  55. package/src/blocks/container-orchestrator/index.tsx +729 -0
  56. package/src/blocks/database-admin/index.tsx +679 -0
  57. package/src/blocks/gitops-sync-status/index.tsx +557 -0
  58. package/src/blocks/incident-manager/index.tsx +586 -0
  59. package/src/blocks/index.ts +119 -0
  60. package/src/blocks/infrastructure-map/index.tsx +638 -0
  61. package/src/blocks/on-call-schedule/index.tsx +615 -0
  62. package/src/blocks/release-notes/index.tsx +643 -0
  63. package/src/blocks/sidebar/index.tsx +6 -6
  64. package/src/components/DataTable/templates/index.tsx +3 -2
  65. package/src/components/index.ts +283 -0
  66. package/src/components/waka-3d-pie-chart/index.tsx +11 -11
  67. package/src/components/waka-achievement-unlock/index.tsx +16 -16
  68. package/src/components/waka-ad-banner/index.tsx +275 -0
  69. package/src/components/waka-ad-fallback/index.tsx +181 -0
  70. package/src/components/waka-ad-inline/index.tsx +103 -0
  71. package/src/components/waka-ad-interstitial/index.tsx +278 -0
  72. package/src/components/waka-ad-placeholder/index.tsx +84 -0
  73. package/src/components/waka-ad-provider/index.tsx +329 -0
  74. package/src/components/waka-ad-sidebar/index.tsx +113 -0
  75. package/src/components/waka-ad-sticky-footer/index.tsx +125 -0
  76. package/src/components/waka-alert-panel/index.tsx +493 -0
  77. package/src/components/waka-artifact-list/index.tsx +416 -0
  78. package/src/components/waka-badge-showcase/index.tsx +12 -11
  79. package/src/components/waka-build-matrix/index.tsx +396 -0
  80. package/src/components/waka-command-bar/index.tsx +2 -1
  81. package/src/components/waka-config-comparator/index.tsx +416 -0
  82. package/src/components/waka-container-list/index.tsx +475 -0
  83. package/src/components/waka-content-recommendation/index.tsx +294 -0
  84. package/src/components/waka-cost-breakdown/index.tsx +10 -10
  85. package/src/components/waka-database-card/index.tsx +473 -0
  86. package/src/components/waka-dependency-tree/index.tsx +542 -0
  87. package/src/components/waka-env-var-editor/index.tsx +417 -0
  88. package/src/components/waka-feature-flag-row/index.tsx +386 -0
  89. package/src/components/waka-funnel-chart/index.tsx +8 -8
  90. package/src/components/waka-health-pulse/index.tsx +6 -6
  91. package/src/components/waka-kubernetes-overview/index.tsx +536 -0
  92. package/src/components/waka-leaderboard/index.tsx +9 -9
  93. package/src/components/waka-log-viewer/index.tsx +386 -0
  94. package/src/components/waka-loot-box/index.tsx +20 -20
  95. package/src/components/waka-migration-list/index.tsx +487 -0
  96. package/src/components/waka-outstream-video/index.tsx +240 -0
  97. package/src/components/waka-player-card/index.tsx +5 -5
  98. package/src/components/waka-pod-card/index.tsx +528 -0
  99. package/src/components/waka-query-explain/index.tsx +657 -0
  100. package/src/components/waka-quota-bar/index.tsx +4 -4
  101. package/src/components/waka-radar-score/index.tsx +10 -10
  102. package/src/components/waka-scratch-card/index.tsx +5 -4
  103. package/src/components/waka-secret-card/index.tsx +371 -0
  104. package/src/components/waka-security-scan-result/index.tsx +473 -0
  105. package/src/components/waka-server-rack/index.tsx +28 -27
  106. package/src/components/waka-service-graph/index.tsx +445 -0
  107. package/src/components/waka-sponsored-badge/index.tsx +97 -0
  108. package/src/components/waka-sponsored-card/index.tsx +275 -0
  109. package/src/components/waka-sponsored-feed/index.tsx +127 -0
  110. package/src/components/waka-spotlight/index.tsx +2 -1
  111. package/src/components/waka-success-explosion/index.tsx +4 -4
  112. package/src/components/waka-test-report/index.tsx +469 -0
  113. package/src/components/waka-trace-viewer/index.tsx +490 -0
  114. package/src/components/waka-video-ad/index.tsx +406 -0
  115. package/src/components/waka-video-overlay/index.tsx +257 -0
  116. package/src/components/waka-xp-bar/index.tsx +13 -13
  117. package/src/styles/base.css +16 -0
  118. package/src/styles/tailwind.preset.js +12 -0
  119. package/src/styles/themes/forest.css +16 -0
  120. package/src/styles/themes/monochrome.css +16 -0
  121. package/src/styles/themes/perpetuity.css +16 -0
  122. package/src/styles/themes/sunset.css +16 -0
  123. package/src/styles/themes/twilight.css +16 -0
@@ -0,0 +1,240 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { useRef, useState, useEffect } from "react"
5
+ import { cn } from "../../utils/cn"
6
+ import { useAdContext, useAdVisibility, type CustomAd } from "../waka-ad-provider"
7
+ import { WakaSponsoredBadge } from "../waka-sponsored-badge"
8
+ import { X, Volume2, VolumeX } from "lucide-react"
9
+
10
+ export interface WakaOutstreamVideoProps {
11
+ /** Unique slot ID */
12
+ slotId: string
13
+ /** Collapse when video ends or is closed */
14
+ collapseOnEnd?: boolean
15
+ /** Collapse animation duration (ms) */
16
+ collapseDuration?: number
17
+ /** Start muted */
18
+ muted?: boolean
19
+ /** Show close button */
20
+ showClose?: boolean
21
+ /** Close after seconds (0 = manual only) */
22
+ closeAfter?: number
23
+ /** Minimum visibility to start playing (0-1) */
24
+ visibilityThreshold?: number
25
+ /** Custom class name */
26
+ className?: string
27
+ /** Callback when video completes */
28
+ onComplete?: () => void
29
+ /** Callback when closed */
30
+ onClose?: () => void
31
+ }
32
+
33
+ export function WakaOutstreamVideo({
34
+ slotId,
35
+ collapseOnEnd = true,
36
+ collapseDuration = 300,
37
+ muted = true,
38
+ showClose = true,
39
+ closeAfter = 0,
40
+ visibilityThreshold = 0.5,
41
+ className,
42
+ onComplete,
43
+ onClose,
44
+ }: WakaOutstreamVideoProps) {
45
+ const containerRef = useRef<HTMLDivElement>(null)
46
+ const videoRef = useRef<HTMLVideoElement>(null)
47
+ const { config, isReady, hasConsent, getCustomAd, trackEvent } = useAdContext()
48
+ const { isVisible } = useAdVisibility(containerRef, visibilityThreshold)
49
+
50
+ const [status, setStatus] = useState<"loading" | "loaded" | "error" | "collapsed">("loading")
51
+ const [ad, setAd] = useState<CustomAd | null>(null)
52
+ const [isMuted, setIsMuted] = useState(muted)
53
+ const [isCollapsing, setIsCollapsing] = useState(false)
54
+ const [containerHeight, setContainerHeight] = useState<number | "auto">("auto")
55
+ const [hasStarted, setHasStarted] = useState(false)
56
+
57
+ // Load ad
58
+ useEffect(() => {
59
+ if (!isReady || hasConsent === false) return
60
+
61
+ const loadAd = async () => {
62
+ try {
63
+ const customAd = await getCustomAd(slotId)
64
+ if (customAd?.videoUrl) {
65
+ setAd(customAd)
66
+ setStatus("loaded")
67
+ trackEvent({ type: "loaded", slotId, timestamp: new Date() })
68
+ } else {
69
+ setStatus("collapsed")
70
+ }
71
+ } catch {
72
+ setStatus("collapsed")
73
+ }
74
+ }
75
+
76
+ loadAd()
77
+ }, [isReady, hasConsent, slotId, getCustomAd, trackEvent])
78
+
79
+ // Play/pause based on visibility
80
+ useEffect(() => {
81
+ if (!videoRef.current || status !== "loaded") return
82
+
83
+ if (isVisible) {
84
+ videoRef.current.play().then(() => {
85
+ if (!hasStarted) {
86
+ setHasStarted(true)
87
+ trackEvent({ type: "impression", slotId, timestamp: new Date() })
88
+ if (ad?.impressionUrl) {
89
+ fetch(ad.impressionUrl, { mode: "no-cors" }).catch(() => {})
90
+ }
91
+ }
92
+ }).catch(() => {})
93
+ } else {
94
+ videoRef.current.pause()
95
+ }
96
+ }, [isVisible, status, hasStarted, slotId, ad, trackEvent])
97
+
98
+ // Auto-close timer
99
+ useEffect(() => {
100
+ if (closeAfter === 0 || !hasStarted) return
101
+
102
+ const timer = setTimeout(() => {
103
+ handleCollapse()
104
+ }, closeAfter * 1000)
105
+
106
+ return () => clearTimeout(timer)
107
+ }, [closeAfter, hasStarted])
108
+
109
+ // Set initial height after load
110
+ useEffect(() => {
111
+ if (status === "loaded" && containerRef.current) {
112
+ setContainerHeight(containerRef.current.offsetHeight)
113
+ }
114
+ }, [status])
115
+
116
+ const handleCollapse = () => {
117
+ if (collapseOnEnd) {
118
+ setIsCollapsing(true)
119
+ setContainerHeight(0)
120
+ setTimeout(() => {
121
+ setStatus("collapsed")
122
+ onClose?.()
123
+ }, collapseDuration)
124
+ } else {
125
+ setStatus("collapsed")
126
+ onClose?.()
127
+ }
128
+ }
129
+
130
+ const handleEnded = () => {
131
+ trackEvent({ type: "viewable", slotId, timestamp: new Date(), data: { completed: true } })
132
+ onComplete?.()
133
+ handleCollapse()
134
+ }
135
+
136
+ const handleToggleMute = () => {
137
+ if (videoRef.current) {
138
+ videoRef.current.muted = !isMuted
139
+ setIsMuted(!isMuted)
140
+ }
141
+ }
142
+
143
+ const handleClick = () => {
144
+ if (!ad) return
145
+
146
+ trackEvent({ type: "click", slotId, timestamp: new Date() })
147
+ if (ad.clickUrl) {
148
+ fetch(ad.clickUrl, { mode: "no-cors" }).catch(() => {})
149
+ }
150
+ if (ad.targetUrl) {
151
+ window.open(ad.targetUrl, "_blank", "noopener,noreferrer")
152
+ }
153
+ }
154
+
155
+ if (status === "collapsed" || status === "error") {
156
+ return null
157
+ }
158
+
159
+ if (status === "loading") {
160
+ return (
161
+ <div
162
+ ref={containerRef}
163
+ className={cn("w-full aspect-video bg-muted animate-pulse rounded-lg", className)}
164
+ />
165
+ )
166
+ }
167
+
168
+ return (
169
+ <div
170
+ ref={containerRef}
171
+ className={cn(
172
+ "relative w-full overflow-hidden rounded-lg bg-black",
173
+ isCollapsing && "transition-all",
174
+ className
175
+ )}
176
+ style={{
177
+ height: containerHeight,
178
+ transitionDuration: `${collapseDuration}ms`,
179
+ }}
180
+ >
181
+ <div className="relative aspect-video">
182
+ {/* Video */}
183
+ <video
184
+ ref={videoRef}
185
+ src={ad?.videoUrl}
186
+ muted={isMuted}
187
+ playsInline
188
+ loop={false}
189
+ onClick={handleClick}
190
+ onEnded={handleEnded}
191
+ className="w-full h-full object-contain cursor-pointer"
192
+ />
193
+
194
+ {/* Overlay controls */}
195
+ <div className="absolute inset-0 pointer-events-none">
196
+ {/* Top bar */}
197
+ <div className="absolute top-0 left-0 right-0 p-3 flex items-center justify-between bg-gradient-to-b from-black/50 to-transparent pointer-events-auto">
198
+ <WakaSponsoredBadge variant="dark" size="sm" sponsor={ad?.sponsor} />
199
+
200
+ <div className="flex items-center gap-2">
201
+ <button
202
+ onClick={handleToggleMute}
203
+ className="p-1.5 rounded-full bg-black/50 hover:bg-black/70 transition-colors"
204
+ >
205
+ {isMuted ? (
206
+ <VolumeX className="h-4 w-4 text-white" />
207
+ ) : (
208
+ <Volume2 className="h-4 w-4 text-white" />
209
+ )}
210
+ </button>
211
+
212
+ {showClose && (
213
+ <button
214
+ onClick={handleCollapse}
215
+ className="p-1.5 rounded-full bg-black/50 hover:bg-black/70 transition-colors"
216
+ >
217
+ <X className="h-4 w-4 text-white" />
218
+ </button>
219
+ )}
220
+ </div>
221
+ </div>
222
+
223
+ {/* CTA button */}
224
+ {ad?.cta && (
225
+ <div className="absolute bottom-3 left-3 right-3 pointer-events-auto">
226
+ <button
227
+ onClick={handleClick}
228
+ className="w-full px-4 py-2 bg-primary text-primary-foreground rounded-lg font-medium hover:bg-primary/90 transition-colors text-center"
229
+ >
230
+ {ad.cta}
231
+ </button>
232
+ </div>
233
+ )}
234
+ </div>
235
+ </div>
236
+ </div>
237
+ )
238
+ }
239
+
240
+ export default WakaOutstreamVideo
@@ -59,7 +59,7 @@ const rarityConfig: Record<PlayerRarity, {
59
59
  common: {
60
60
  borderColor: "border-zinc-400 dark:border-zinc-500",
61
61
  bgGradient: "from-zinc-100 to-zinc-200 dark:from-zinc-800 dark:to-zinc-900",
62
- glowColor: "rgba(161, 161, 170, 0.3)",
62
+ glowColor: "hsl(var(--muted-foreground) / 0.3)",
63
63
  textColor: "text-zinc-600 dark:text-zinc-400",
64
64
  label: "Common",
65
65
  frameGradient: "from-zinc-300 via-zinc-400 to-zinc-300 dark:from-zinc-600 dark:via-zinc-500 dark:to-zinc-600",
@@ -67,7 +67,7 @@ const rarityConfig: Record<PlayerRarity, {
67
67
  rare: {
68
68
  borderColor: "border-blue-400 dark:border-blue-500",
69
69
  bgGradient: "from-blue-50 to-blue-100 dark:from-blue-950 dark:to-blue-900",
70
- glowColor: "rgba(59, 130, 246, 0.4)",
70
+ glowColor: "hsl(var(--info) / 0.4)",
71
71
  textColor: "text-blue-600 dark:text-blue-400",
72
72
  label: "Rare",
73
73
  frameGradient: "from-blue-300 via-blue-500 to-blue-300 dark:from-blue-600 dark:via-blue-400 dark:to-blue-600",
@@ -75,7 +75,7 @@ const rarityConfig: Record<PlayerRarity, {
75
75
  epic: {
76
76
  borderColor: "border-purple-400 dark:border-purple-500",
77
77
  bgGradient: "from-purple-50 to-purple-100 dark:from-purple-950 dark:to-purple-900",
78
- glowColor: "rgba(168, 85, 247, 0.5)",
78
+ glowColor: "hsl(var(--chart-2) / 0.5)",
79
79
  textColor: "text-purple-600 dark:text-purple-400",
80
80
  label: "Epic",
81
81
  frameGradient: "from-purple-300 via-purple-500 to-purple-300 dark:from-purple-600 dark:via-purple-400 dark:to-purple-600",
@@ -83,7 +83,7 @@ const rarityConfig: Record<PlayerRarity, {
83
83
  legendary: {
84
84
  borderColor: "border-amber-400 dark:border-amber-500",
85
85
  bgGradient: "from-amber-50 to-orange-100 dark:from-amber-950 dark:to-orange-900",
86
- glowColor: "rgba(245, 158, 11, 0.5)",
86
+ glowColor: "hsl(var(--warning) / 0.5)",
87
87
  textColor: "text-amber-600 dark:text-amber-400",
88
88
  label: "Legendary",
89
89
  frameGradient: "from-yellow-300 via-amber-500 to-orange-400 dark:from-yellow-500 dark:via-amber-400 dark:to-orange-500",
@@ -91,7 +91,7 @@ const rarityConfig: Record<PlayerRarity, {
91
91
  mythic: {
92
92
  borderColor: "border-rose-400 dark:border-rose-500",
93
93
  bgGradient: "from-rose-50 via-pink-50 to-violet-50 dark:from-rose-950 dark:via-pink-950 dark:to-violet-950",
94
- glowColor: "rgba(244, 63, 94, 0.6)",
94
+ glowColor: "hsl(var(--destructive) / 0.6)",
95
95
  textColor: "text-rose-600 dark:text-rose-400",
96
96
  label: "Mythic",
97
97
  frameGradient: "from-rose-400 via-pink-500 to-violet-500 dark:from-rose-500 dark:via-pink-400 dark:to-violet-400",