Skip to content

Commit 0e5ef94

Browse files
authored
Stateful BarVisualizer and VoiceAssistantControlBar (#954)
1 parent 9b1a259 commit 0e5ef94

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+867
-277
lines changed

.changeset/healthy-donkeys-reply.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@livekit/components-react": minor
3+
---
4+
5+
Stateful BarVisualizer and VoiceAssistantControlBar

docs/storybook/.storybook/lk-decorators/ParticipantContext.tsx

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import React, { HTMLAttributes } from 'react';
2-
import { ParticipantContext, useLocalParticipant } from '@livekit/components-react';
2+
import {
3+
ParticipantContext,
4+
TrackRefContext,
5+
useLocalParticipant,
6+
useTracks,
7+
} from '@livekit/components-react';
38
import { Decorator } from '@storybook/react';
9+
import { Track } from 'livekit-client';
410

511
/**
612
* Wraps a Storybook Story into a LiveKit participant context.
@@ -12,6 +18,16 @@ export const LkParticipantContext: Decorator = (Story, _) => {
1218
return <LocalParticipantContext>{Story()}</LocalParticipantContext>;
1319
};
1420

21+
export const LkLocalMicTrackContext: Decorator = (Story, _) => {
22+
return <LocalMicTrackContext>{Story()}</LocalMicTrackContext>;
23+
};
24+
25+
const LocalMicTrackContext = (props: HTMLAttributes<HTMLDivElement>) => {
26+
const p = useTracks([Track.Source.Microphone])[0];
27+
28+
return p && <TrackRefContext.Provider value={p}>{props.children}</TrackRefContext.Provider>;
29+
};
30+
1531
const LocalParticipantContext = (props: HTMLAttributes<HTMLDivElement>) => {
1632
const p = useLocalParticipant();
1733

docs/storybook/stories/components/ChatEntry.stories.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { Meta, StoryObj } from '@storybook/react';
33

44
import { ChatEntry, ChatEntryProps, formatChatMessageLinks } from '@livekit/components-react';
55
import { LkRoomContext } from '../../.storybook/lk-decorators';
66
import { Participant } from 'livekit-client';
77

88
const participant = new Participant('dummy-sid', 'dummy-identity', 'dummy-name', 'dummy-metadata');
99

10-
export default {
10+
const Story: Meta<typeof ChatEntry> = {
1111
component: ChatEntry,
1212
decorators: [LkRoomContext],
1313
render: (args: ChatEntryProps) => <ChatEntry {...args}></ChatEntry>,
@@ -19,15 +19,18 @@ export default {
1919
},
2020
};
2121

22+
export default Story;
23+
2224
export const Default: StoryObj<ChatEntryProps> = {
23-
args: { entry: { timestamp: 1, message: 'Hello world!', from: participant } },
25+
args: { entry: { timestamp: 1, id: '234', message: 'Hello world!', from: participant } },
2426
parameters: { roomContext: { audio: false, video: false, connect: true } },
2527
};
2628

2729
export const LongMessage: StoryObj<ChatEntryProps> = {
2830
...Default,
2931
args: {
3032
entry: {
33+
id: '234',
3134
timestamp: 1,
3235
message:
3336
'Niklas tog tag i datorn och lyfte den mot himmeln. Så nu tar vi en paus och inväntar resultatet av dagens skrivande. Sociala nätverk kan aldrig fånga en fisk. Kan vi få fram något resultat på hur många som kom idag? En annan sak är att man ibland går ensam till de olika festerna.',
@@ -41,6 +44,7 @@ export const MessageWithLinks: StoryObj<ChatEntryProps> = {
4144
...Default,
4245
args: {
4346
entry: {
47+
id: '234',
4448
timestamp: 1,
4549
message: 'a google.com message with links [email protected].',
4650
from: participant,

docs/storybook/stories/components/ConnectionState.stories.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { StoryObj, Meta } from '@storybook/react';
33

44
import { ConnectionState, ConnectionStatusProps } from '@livekit/components-react';
55
import { LkRoomContext } from '../../.storybook/lk-decorators';
66

7-
export default {
7+
const Story: Meta<typeof ConnectionState> = {
88
component: ConnectionState,
99
decorators: [LkRoomContext],
1010
render: (args: ConnectionStatusProps) => <ConnectionState {...args}></ConnectionState>,
@@ -16,6 +16,8 @@ export default {
1616
},
1717
};
1818

19+
export default Story;
20+
1921
export const Default: StoryObj<ConnectionStatusProps> = {
2022
args: {},
2123
parameters: { roomContext: { audio: false, video: false, connect: true } },

docs/storybook/stories/components/ConnectionStateToast.stories.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { StoryObj, Meta } from '@storybook/react';
33

44
import {
55
// ConnectionState,
@@ -9,7 +9,7 @@ import {
99
// import { LkRoomContext } from '../../.storybook/lk-decorators';
1010
import { Room, ConnectionState as State } from 'livekit-client';
1111

12-
export default {
12+
const Story: Meta<typeof ConnectionStateToast> = {
1313
component: ConnectionStateToast,
1414
// decorators: [LkRoomContext],
1515
render: (args: ConnectionStatusProps) => <ConnectionStateToast {...args}></ConnectionStateToast>,
@@ -21,6 +21,8 @@ export default {
2121
},
2222
};
2323

24+
export default Story;
25+
2426
function getRoomWithState(state: State) {
2527
const room = new Room();
2628
room.state = state;

docs/storybook/stories/components/RoomName.stories.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { Meta, StoryObj } from '@storybook/react';
33

44
import { RoomName, RoomNameProps } from '@livekit/components-react';
55
import { LkRoomContext } from '../../.storybook/lk-decorators';
66

7-
export default {
7+
const Story: Meta<typeof RoomName> = {
88
component: RoomName,
99
decorators: [LkRoomContext],
1010
render: (args: RoomNameProps) => <RoomName {...args}></RoomName>,
@@ -21,6 +21,8 @@ export default {
2121
},
2222
};
2323

24+
export default Story;
25+
2426
export const Default: StoryObj<RoomNameProps> = {
2527
args: { childrenPosition: 'before' },
2628
parameters: { roomContext: { audio: false, video: false, connect: true } },

docs/storybook/stories/components/controls/ClearPinButton.stories.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { Meta, StoryObj } from '@storybook/react';
33

44
import { ClearPinButton, ClearPinButtonProps } from '@livekit/components-react';
55
import { LkLayoutContext, LkRoomContext } from '../../../.storybook/lk-decorators';
66

7-
export default {
7+
const Story: Meta<typeof ClearPinButton> = {
88
component: ClearPinButton,
99
decorators: [LkLayoutContext, LkRoomContext],
1010
render: (args: ClearPinButtonProps) => <ClearPinButton {...args}>Back to Grid</ClearPinButton>,
@@ -21,6 +21,8 @@ export default {
2121
},
2222
};
2323

24+
export default Story;
25+
2426
export const Default: StoryObj<ClearPinButtonProps> = {
2527
args: {},
2628
parameters: {

docs/storybook/stories/components/controls/DisconnectButton.stories.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { Meta, StoryObj } from '@storybook/react';
33

44
import { DisconnectButton, DisconnectButtonProps } from '@livekit/components-react';
55
import { LkRoomContext } from '../../../.storybook/lk-decorators';
66

7-
export default {
7+
const Story: Meta<typeof DisconnectButton> = {
88
component: DisconnectButton,
99
decorators: [LkRoomContext],
1010
render: (args: DisconnectButtonProps) => <DisconnectButton {...args}>Leave</DisconnectButton>,
@@ -15,6 +15,8 @@ export default {
1515
},
1616
};
1717

18+
export default Story;
19+
1820
export const Connected: StoryObj<DisconnectButtonProps> = {
1921
args: {
2022
stopTracks: true,

docs/storybook/stories/components/controls/MediaDeviceSelect.stories.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { Meta, StoryObj } from '@storybook/react';
33

44
import { MediaDeviceSelect, MediaDeviceSelectProps } from '@livekit/components-react';
55
import { LkRoomContext } from '../../../.storybook/lk-decorators';
66

77
const kinds: MediaDeviceKind[] = ['audioinput', 'audiooutput', 'videoinput'];
88

9-
export default {
10-
name: 'MediaDeviceSelect',
9+
const Story: Meta<typeof MediaDeviceSelect> = {
1110
component: MediaDeviceSelect,
1211
decorators: [LkRoomContext],
1312
render: (args: MediaDeviceSelectProps) => (
@@ -27,6 +26,8 @@ export default {
2726
},
2827
};
2928

29+
export default Story;
30+
3031
export const AudioInputDevices: StoryObj<MediaDeviceSelectProps> = {
3132
args: { kind: 'audioinput' },
3233
parameters: { roomContext: { audio: true, video: false, connect: true } },

docs/storybook/stories/components/controls/TrackToggle.stories.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { Meta, StoryObj } from '@storybook/react';
33

44
import { TrackToggle, TrackToggleProps } from '@livekit/components-react';
55
import { LkRoomContext } from '../../../.storybook/lk-decorators';
66
import { Track } from 'livekit-client';
77
import { ToggleSource } from '@livekit/components-core';
88

9-
export default {
9+
const Story: Meta<typeof TrackToggle> = {
1010
component: TrackToggle,
1111
decorators: [LkRoomContext],
1212
render: (args: TrackToggleProps<ToggleSource>) => (
@@ -29,6 +29,8 @@ export default {
2929
},
3030
};
3131

32+
export default Story;
33+
3234
export const Camera: StoryObj<TrackToggleProps<Track.Source.Camera>> = {
3335
args: { source: Track.Source.Camera, initialState: true },
3436
parameters: { roomContext: { audio: false, video: true, connect: true } },

docs/storybook/stories/components/layout/CarouselLayout.stories.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import * as React from 'react';
22

33
import { CarouselLayout, CarouselLayoutProps } from '@livekit/components-react';
44
import { LkRoomContext } from '../../../.storybook/lk-decorators';
5+
import { Meta } from '@storybook/react';
56

6-
export default {
7+
const Story: Meta<typeof CarouselLayout> = {
78
component: CarouselLayout,
89
decorators: [LkRoomContext],
910
render: (args: CarouselLayoutProps) => (
@@ -19,6 +20,8 @@ export default {
1920
},
2021
};
2122

23+
export default Story;
24+
2225
export const Default = {
2326
args: {},
2427
parameters: { roomContext: { audio: true, video: true, connect: true } },

docs/storybook/stories/components/layout/FocusLayoutContainer.stories.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import * as React from 'react';
22

33
import { FocusLayoutContainerProps, FocusLayoutContainer } from '@livekit/components-react';
44
import { LkLayoutContext, LkRoomContext } from '../../../.storybook/lk-decorators';
5+
import { Meta } from '@storybook/react';
56

6-
export default {
7+
const Story: Meta<typeof FocusLayoutContainer> = {
78
component: FocusLayoutContainer,
89
decorators: [LkLayoutContext, LkRoomContext],
910
render: (args: FocusLayoutContainerProps) => <FocusLayoutContainer {...args} />,
@@ -15,6 +16,8 @@ export default {
1516
},
1617
};
1718

19+
export default Story;
20+
1821
export const Default = {
1922
args: {},
2023
parameters: { roomContext: { audio: true, video: true, connect: true } },

docs/storybook/stories/components/layout/GridLayout.stories.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import * as React from 'react';
33
import { GridLayout, GridLayoutProps, useTracks } from '@livekit/components-react';
44
import { LkRoomContext } from '../../../.storybook/lk-decorators';
55
import { Track } from 'livekit-client';
6+
import { Meta } from '@storybook/react';
67

7-
export default {
8+
const Story: Meta<typeof GridLayout> = {
89
component: GridLayout,
910
decorators: [LkRoomContext],
1011
render: (args: Omit<GridLayoutProps, 'tracks'>) => {
@@ -14,6 +15,8 @@ export default {
1415
argTypes: {},
1516
};
1617

18+
export default Story;
19+
1720
export const Default = {
1821
args: {},
1922
parameters: { roomContext: { audio: true, video: true, connect: true } },
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { Meta, StoryObj } from '@storybook/react';
33

44
import { AudioVisualizer, AudioVisualizerProps } from '@livekit/components-react';
5-
import { LkParticipantContext, LkRoomContext } from '../../../.storybook/lk-decorators';
5+
import { LkLocalMicTrackContext, LkRoomContext } from '../../../.storybook/lk-decorators';
66

7-
export default {
7+
const Story: Meta<typeof AudioVisualizer> = {
88
/*
99
* This is some docs for connection quality
1010
*/
1111
component: AudioVisualizer,
12-
decorators: [LkParticipantContext, LkRoomContext],
12+
decorators: [LkLocalMicTrackContext, LkRoomContext],
1313
render: (args: AudioVisualizerProps) => <AudioVisualizer {...args} />,
14-
argTypes: {},
14+
argTypes: {
15+
barCount: {
16+
name: 'Bar count',
17+
control: { type: 'range', min: 1, max: 1024, step: 1 },
18+
default: 32,
19+
},
20+
},
1521
parameters: {
1622
actions: {
1723
handles: [],
@@ -22,4 +28,9 @@ export default {
2228
},
2329
};
2430

25-
export const Default: StoryObj<AudioVisualizerProps> = {};
31+
export default Story;
32+
33+
export const Default: StoryObj<AudioVisualizerProps> = { args: { barCount: 1024 } };
34+
export const Abstract: StoryObj<AudioVisualizerProps> = {
35+
args: { barCount: 6, gap: '0.5rem', barWidth: '0.5rem', borderRadius: '1rem' },
36+
};

docs/storybook/stories/components/participant/ConnectionQualityIndicator.stories.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { Meta, StoryObj } from '@storybook/react';
33

44
import {
55
ConnectionQualityIndicator,
@@ -8,14 +8,15 @@ import {
88
import { MockParticipantContext } from '../../../.storybook/lk-decorators';
99
import { ConnectionQuality } from 'livekit-client';
1010

11-
export default {
11+
const Story: Meta<typeof ConnectionQualityIndicator> = {
1212
/*
1313
* This is some docs for connection quality
1414
*/
1515
component: ConnectionQualityIndicator,
1616
decorators: [MockParticipantContext],
1717
render: (args: ConnectionQualityIndicatorProps) => <ConnectionQualityIndicator {...args} />,
1818
argTypes: {
19+
// @ts-ignore the arg will be used from within the MockParticipantContext
1920
connectionQuality: {
2021
control: { type: 'select' },
2122
options: [
@@ -37,4 +38,6 @@ export default {
3738
},
3839
};
3940

41+
export default Story;
42+
4043
export const Default: StoryObj<ConnectionQualityIndicatorProps> = {};

docs/storybook/stories/components/participant/ParticipantName.stories.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as React from 'react';
2-
import { StoryObj } from '@storybook/react';
2+
import { StoryObj, Meta } from '@storybook/react';
33

44
import { ParticipantName, ParticipantNameProps } from '@livekit/components-react';
55
import { LkParticipantContext, LkRoomContext } from '../../../.storybook/lk-decorators';
66

7-
export default {
7+
const Story: Meta<typeof ParticipantName> = {
88
component: ParticipantName,
99
decorators: [LkParticipantContext, LkRoomContext],
1010
render: (args: ParticipantNameProps) => <ParticipantName {...args}></ParticipantName>,
@@ -16,6 +16,8 @@ export default {
1616
},
1717
};
1818

19+
export default Story;
20+
1921
export const Default: StoryObj<ParticipantNameProps> = {
2022
args: {},
2123
parameters: { roomContext: { audio: false, video: false, connect: true } },

0 commit comments

Comments
 (0)