Skip to content

Commit 77bd4ab

Browse files
feat(shadcn): theme mode for aura visualizer and all registry item (#1327)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent cb5698b commit 77bd4ab

11 files changed

Lines changed: 685 additions & 23 deletions

File tree

docs/storybook/stories/agents-ui/AgentSessionView-01.stories.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import React from 'react';
22
import { StoryObj } from '@storybook/react-vite';
3+
import { useTheme } from 'next-themes';
34
import { AgentSessionProvider } from '../../.storybook/lk-decorators/AgentSessionProvider';
45
import { AgentSessionView_01, AgentSessionView_01Props } from '@agents-ui';
56

67
export default {
78
component: AgentSessionView_01,
89
decorators: [AgentSessionProvider],
9-
render: (args: AgentSessionView_01Props) => <AgentSessionView_01 {...args} />,
10+
render: (args: AgentSessionView_01Props) => {
11+
const { resolvedTheme = 'dark' } = useTheme();
12+
return (
13+
<AgentSessionView_01 themeMode={resolvedTheme as 'dark' | 'light'} {...args} />
14+
);
15+
},
1016
args: {
1117
className: 'h-screen w-screen',
1218
supportsChatInput: true,

packages/shadcn/components/agents-ui/blocks/agent-session-view-01/components/agent-session-block.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ export function Fade({ top = false, bottom = false, className }: FadeProps) {
102102
}
103103

104104
export interface AgentSessionView_01Props {
105+
/**
106+
* Theme mode forwarded to the aura visualizer (`audioVisualizerType="aura"`) so
107+
* the shader's blend mode adapts to the theme mode.
108+
* Ignored by other visualizer types.
109+
*/
110+
themeMode?: 'dark' | 'light';
105111
/**
106112
* Message shown above the controls before the first chat message is sent.
107113
*
@@ -161,7 +167,6 @@ export function AgentSessionView_01({
161167
supportsVideoInput = true,
162168
supportsScreenShare = true,
163169
isPreConnectBufferEnabled = true,
164-
165170
audioVisualizerType,
166171
audioVisualizerColor,
167172
audioVisualizerColorShift,
@@ -171,13 +176,14 @@ export function AgentSessionView_01({
171176
audioVisualizerRadialBarCount,
172177
audioVisualizerRadialRadius,
173178
audioVisualizerWaveLineWidth,
179+
themeMode,
174180
ref,
175181
className,
176182
...props
177183
}: React.ComponentProps<'section'> & AgentSessionView_01Props) {
178184
const session = useSessionContext();
179185
const { messages } = useSessionMessages(session);
180-
const [chatOpen, setChatOpen] = useState(false);
186+
const [isChatOpen, setIsChatOpen] = useState(false);
181187
const scrollAreaRef = useRef<HTMLDivElement>(null);
182188
const { state: agentState } = useAgent();
183189

@@ -209,7 +215,7 @@ export function AgentSessionView_01({
209215

210216
<div className="absolute top-0 bottom-[135px] flex w-full flex-col md:bottom-[170px]">
211217
<AnimatePresence>
212-
{chatOpen && (
218+
{isChatOpen && (
213219
<motion.div
214220
{...CHAT_MOTION_PROPS}
215221
className="flex h-full w-full flex-col gap-4 space-y-3 transition-opacity duration-300 ease-out"
@@ -225,7 +231,8 @@ export function AgentSessionView_01({
225231
</div>
226232
{/* Tile layout */}
227233
<TileLayout
228-
chatOpen={chatOpen}
234+
isChatOpen={isChatOpen}
235+
themeMode={themeMode}
229236
audioVisualizerType={audioVisualizerType}
230237
audioVisualizerColor={audioVisualizerColor}
231238
audioVisualizerColorShift={audioVisualizerColorShift}
@@ -262,10 +269,10 @@ export function AgentSessionView_01({
262269
<AgentControlBar
263270
variant="livekit"
264271
controls={controls}
265-
isChatOpen={chatOpen}
272+
isChatOpen={isChatOpen}
266273
isConnected={session.isConnected}
267274
onDisconnect={session.end}
268-
onIsChatOpenChange={setChatOpen}
275+
onIsChatOpenChange={setIsChatOpen}
269276
/>
270277
</div>
271278
</motion.div>

packages/shadcn/components/agents-ui/blocks/agent-session-view-01/components/audio-visualizer.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const MotionAgentAudioVisualizerRadial = motion.create(AgentAudioVisualizerRadia
1818
const MotionAgentAudioVisualizerWave = motion.create(AgentAudioVisualizerWave);
1919

2020
interface AudioVisualizerProps extends MotionProps {
21+
themeMode?: 'dark' | 'light';
2122
isChatOpen: boolean;
2223
audioVisualizerType?: 'bar' | 'wave' | 'grid' | 'radial' | 'aura';
2324
audioVisualizerColor?: `#${string}`;
@@ -32,6 +33,8 @@ interface AudioVisualizerProps extends MotionProps {
3233
}
3334

3435
export function AudioVisualizer({
36+
themeMode,
37+
isChatOpen,
3538
audioVisualizerType = 'bar',
3639
audioVisualizerColor,
3740
audioVisualizerColorShift = 0.3,
@@ -41,7 +44,6 @@ export function AudioVisualizer({
4144
audioVisualizerGridRowCount = 15,
4245
audioVisualizerGridColumnCount = 15,
4346
audioVisualizerWaveLineWidth = 3,
44-
isChatOpen,
4547
className,
4648
...props
4749
}: AudioVisualizerProps) {
@@ -55,6 +57,7 @@ export function AudioVisualizer({
5557
audioTrack={audioTrack}
5658
color={audioVisualizerColor}
5759
colorShift={audioVisualizerColorShift}
60+
themeMode={themeMode}
5861
className={cn('size-[300px] md:size-[450px]', className)}
5962
{...props}
6063
/>

packages/shadcn/components/agents-ui/blocks/agent-session-view-01/components/tile-view.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ export function useLocalTrackRef(source: Track.Source) {
6969
}
7070

7171
interface TileLayoutProps {
72-
chatOpen: boolean;
72+
themeMode?: 'dark' | 'light';
73+
isChatOpen: boolean;
7374
audioVisualizerType?: 'bar' | 'wave' | 'grid' | 'radial' | 'aura';
7475
audioVisualizerColor?: `#${string}`;
7576
audioVisualizerColorShift?: number;
@@ -82,7 +83,8 @@ interface TileLayoutProps {
8283
}
8384

8485
export function TileLayout({
85-
chatOpen,
86+
themeMode,
87+
isChatOpen,
8688
audioVisualizerType,
8789
audioVisualizerColor,
8890
audioVisualizerColorShift,
@@ -101,7 +103,7 @@ export function TileLayout({
101103
const isScreenShareEnabled = screenShareTrack && !screenShareTrack.publication.isMuted;
102104
const hasSecondTile = isCameraEnabled || isScreenShareEnabled;
103105

104-
const animationDelay = chatOpen ? 0 : 0.15;
106+
const animationDelay = isChatOpen ? 0 : 0.15;
105107
const isAvatar = agentVideoTrack !== undefined;
106108
const videoWidth = agentVideoTrack?.publication.dimensions?.width ?? 0;
107109
const videoHeight = agentVideoTrack?.publication.dimensions?.height ?? 0;
@@ -114,9 +116,9 @@ export function TileLayout({
114116
<div
115117
className={cn([
116118
'grid',
117-
!chatOpen && tileViewClassNames.agentChatClosed,
118-
chatOpen && hasSecondTile && tileViewClassNames.agentChatOpenWithSecondTile,
119-
chatOpen && !hasSecondTile && tileViewClassNames.agentChatOpenWithoutSecondTile,
119+
!isChatOpen && tileViewClassNames.agentChatClosed,
120+
isChatOpen && hasSecondTile && tileViewClassNames.agentChatOpenWithSecondTile,
121+
isChatOpen && !hasSecondTile && tileViewClassNames.agentChatOpenWithoutSecondTile,
120122
])}
121123
>
122124
<AnimatePresence mode="popLayout">
@@ -136,7 +138,7 @@ export function TileLayout({
136138
<AudioVisualizer
137139
key="audio-visualizer"
138140
initial={{ scale: 1 }}
139-
animate={{ scale: chatOpen ? 0.2 : 1 }}
141+
animate={{ scale: isChatOpen ? 0.2 : 1 }}
140142
transition={{
141143
...ANIMATION_TRANSITION,
142144
delay: animationDelay,
@@ -150,11 +152,12 @@ export function TileLayout({
150152
audioVisualizerGridRowCount={audioVisualizerGridRowCount}
151153
audioVisualizerGridColumnCount={audioVisualizerGridColumnCount}
152154
audioVisualizerWaveLineWidth={audioVisualizerWaveLineWidth}
153-
isChatOpen={chatOpen}
155+
themeMode={themeMode}
156+
isChatOpen={isChatOpen}
154157
className={cn(
155158
'absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2',
156159
'bg-background rounded-[50px] border border-transparent transition-[border,drop-shadow]',
157-
chatOpen && 'border-input shadow-2xl/10 delay-200',
160+
isChatOpen && 'border-input shadow-2xl/10 delay-200',
158161
)}
159162
style={{ color: audioVisualizerColor }}
160163
/>
@@ -177,7 +180,7 @@ export function TileLayout({
177180
maskImage:
178181
'radial-gradient(circle, rgba(0, 0, 0, 1) 0, rgba(0, 0, 0, 1) 500px, transparent 500px)',
179182
filter: 'blur(0px)',
180-
borderRadius: chatOpen ? 6 : 12,
183+
borderRadius: isChatOpen ? 6 : 12,
181184
}}
182185
transition={{
183186
...ANIMATION_TRANSITION,
@@ -191,14 +194,14 @@ export function TileLayout({
191194
}}
192195
className={cn(
193196
'overflow-hidden bg-black drop-shadow-xl/80',
194-
chatOpen ? 'h-[90px]' : 'h-auto w-full',
197+
isChatOpen ? 'h-[90px]' : 'h-auto w-full',
195198
)}
196199
>
197200
<VideoTrack
198201
width={videoWidth}
199202
height={videoHeight}
200203
trackRef={agentVideoTrack}
201-
className={cn(chatOpen && 'size-[90px] object-cover')}
204+
className={cn(isChatOpen && 'size-[90px] object-cover')}
202205
/>
203206
</motion.div>
204207
)}
@@ -208,8 +211,8 @@ export function TileLayout({
208211
<div
209212
className={cn([
210213
'grid',
211-
chatOpen && tileViewClassNames.secondTileChatOpen,
212-
!chatOpen && tileViewClassNames.secondTileChatClosed,
214+
isChatOpen && tileViewClassNames.secondTileChatOpen,
215+
!isChatOpen && tileViewClassNames.secondTileChatClosed,
213216
])}
214217
>
215218
{/* Camera & Screen Share */}

packages/shadcn/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"type": "module",
77
"main": "index.ts",
88
"scripts": {
9-
"registry:build": "rm -rf dist && shadcn build --output ./dist/r && pnpm registry:doc-gen",
9+
"registry:build": "pnpm test && rm -rf dist && shadcn build --output ./dist/r && pnpm registry:doc-gen",
1010
"registry:serve": "python3 -m http.server 3210 -d ./dist",
1111
"registry:doc-gen": "node --experimental-strip-types --env-file=.env.local ./scripts/doc-gen.ts",
1212
"registry:update": "pnpm registry:build && node --experimental-strip-types --env-file=.env.local ./scripts/update.ts",

packages/shadcn/registry.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,30 @@
326326
],
327327
"dependencies": ["@livekit/components-react@^2.0.0", "livekit-client@^2.0.0", "motion"],
328328
"categories": ["agents", "blocks"]
329+
},
330+
{
331+
"name": "all",
332+
"type": "registry:item",
333+
"title": "All",
334+
"description": "Installs every component in the @agents-ui registry (excluding the nextjs-api-token-route).",
335+
"files": [],
336+
"registryDependencies": [
337+
"@agents-ui/agent-disconnect-button",
338+
"@agents-ui/agent-track-toggle",
339+
"@agents-ui/agent-track-control",
340+
"@agents-ui/agent-control-bar",
341+
"@agents-ui/agent-audio-visualizer-bar",
342+
"@agents-ui/agent-audio-visualizer-radial",
343+
"@agents-ui/agent-audio-visualizer-grid",
344+
"@agents-ui/agent-audio-visualizer-wave",
345+
"@agents-ui/agent-audio-visualizer-aura",
346+
"@agents-ui/agent-session-provider",
347+
"@agents-ui/start-audio-button",
348+
"@agents-ui/agent-chat-indicator",
349+
"@agents-ui/agent-chat-transcript",
350+
"@agents-ui/react-shader-toy",
351+
"@agents-ui/agent-session-view-01"
352+
]
329353
}
330354
]
331355
}

0 commit comments

Comments
 (0)