Skip to content

Commit e5329db

Browse files
feat: LiveKit OSS Shadcn initial components (#1249)
1 parent 53b7804 commit e5329db

File tree

20 files changed

+1463
-4
lines changed

20 files changed

+1463
-4
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import * as React from 'react';
2+
import { StoryObj } from '@storybook/react-vite';
3+
import {
4+
AgentSessionProvider,
5+
useMicrophone,
6+
} from '../../.storybook/lk-decorators/AgentSessionProvider';
7+
import { AgentControlBar, AgentControlBarProps } from '@agents-ui';
8+
9+
export default {
10+
component: AgentControlBar,
11+
decorators: [AgentSessionProvider],
12+
render: (args: AgentControlBarProps) => {
13+
useMicrophone();
14+
return <AgentControlBar {...args} className="min-w-lg mx-auto" />;
15+
},
16+
args: {
17+
isConnected: true,
18+
controls: {
19+
microphone: true,
20+
camera: true,
21+
screenShare: true,
22+
chat: true,
23+
leave: true,
24+
},
25+
className: 'w-full',
26+
},
27+
argTypes: {
28+
controls: { control: { type: 'object' } },
29+
isConnected: { control: { type: 'boolean' } },
30+
isChatOpen: { control: { type: 'boolean' } },
31+
},
32+
parameters: {
33+
layout: 'centered',
34+
actions: {
35+
handles: [],
36+
},
37+
},
38+
};
39+
40+
export const Default: StoryObj<AgentControlBarProps> = {
41+
args: {},
42+
};
43+
44+
export const Outline: StoryObj<AgentControlBarProps> = {
45+
args: {
46+
variant: 'outline',
47+
},
48+
};
49+
50+
export const Livekit: StoryObj<AgentControlBarProps> = {
51+
args: {
52+
variant: 'livekit',
53+
},
54+
};
55+
56+
export const NoControls: StoryObj<AgentControlBarProps> = {
57+
args: {
58+
controls: {
59+
microphone: false,
60+
camera: false,
61+
screenShare: false,
62+
chat: false,
63+
leave: false,
64+
},
65+
},
66+
render: (args: AgentControlBarProps) => {
67+
return (
68+
<>
69+
<p className="text-center">
70+
This control bar does not render
71+
<br />
72+
because <code className="text-muted-foreground text-sm">visibleControls</code> contains
73+
only false values.
74+
</p>
75+
<AgentControlBar {...args} className="min-w-lg mx-auto" />
76+
</>
77+
);
78+
},
79+
};
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as React from 'react';
2+
import { StoryObj } from '@storybook/react-vite';
3+
import { AgentSessionProvider } from '../../.storybook/lk-decorators/AgentSessionProvider';
4+
import { AgentDisconnectButton, type AgentDisconnectButtonProps } from '@agents-ui';
5+
6+
export default {
7+
component: AgentDisconnectButton,
8+
decorators: [AgentSessionProvider],
9+
render: (args: AgentDisconnectButtonProps) => (
10+
<AgentDisconnectButton {...args}></AgentDisconnectButton>
11+
),
12+
argTypes: {
13+
size: {
14+
options: ['default', 'sm', 'lg', 'icon', 'icon-sm', 'icon-lg'],
15+
control: { type: 'select' },
16+
},
17+
onClick: { action: 'onClick' },
18+
className: { control: { type: 'text' } },
19+
},
20+
parameters: {
21+
layout: 'centered',
22+
actions: {
23+
handles: [],
24+
},
25+
},
26+
};
27+
28+
export const Default: StoryObj<AgentDisconnectButtonProps> = {
29+
args: {},
30+
};
31+
32+
export const Icon: StoryObj<AgentDisconnectButtonProps> = {
33+
args: {
34+
size: 'icon',
35+
},
36+
};
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import * as React from 'react';
2+
import { StoryObj } from '@storybook/react-vite';
3+
import {
4+
AgentSessionProvider,
5+
useMicrophone,
6+
} from '../../.storybook/lk-decorators/AgentSessionProvider';
7+
import { AgentTrackControl, type AgentTrackControlProps } from '@agents-ui';
8+
import { Track } from 'livekit-client';
9+
10+
export default {
11+
component: AgentTrackControl,
12+
decorators: [AgentSessionProvider],
13+
render: (args: AgentTrackControlProps) => {
14+
const [isPressed, setIsPressed] = React.useState(
15+
args.source === Track.Source.Microphone ? true : false,
16+
);
17+
18+
const microphoneTrack = useMicrophone();
19+
20+
return (
21+
<AgentTrackControl
22+
{...args}
23+
pressed={isPressed}
24+
onPressedChange={(pressed: boolean) => setIsPressed(pressed)}
25+
audioTrack={args.source === Track.Source.Microphone ? microphoneTrack : undefined}
26+
/>
27+
);
28+
},
29+
argTypes: {
30+
size: {
31+
options: ['default', 'sm', 'lg'],
32+
control: { type: 'radio' },
33+
},
34+
pending: { control: { type: 'boolean' } },
35+
className: { control: { type: 'text' } },
36+
},
37+
parameters: {
38+
layout: 'centered',
39+
actions: {
40+
handles: [],
41+
},
42+
},
43+
};
44+
45+
export const Default: StoryObj<AgentTrackControlProps> = {
46+
render: (args: AgentTrackControlProps) => {
47+
const [isCameraPressed, setIsCameraPressed] = React.useState(true);
48+
const [isMicrophonePressed, setIsMicrophonePressed] = React.useState(false);
49+
const [isScreenSharePressed, setIsScreenSharePressed] = React.useState(true);
50+
51+
const microphoneTrack = useMicrophone();
52+
53+
return (
54+
<div className="flex gap-2">
55+
<AgentTrackControl
56+
{...args}
57+
kind="audioinput"
58+
source={Track.Source.Microphone}
59+
pressed={isMicrophonePressed}
60+
audioTrack={microphoneTrack}
61+
onPressedChange={(pressed: boolean) => setIsMicrophonePressed(pressed)}
62+
/>
63+
<AgentTrackControl
64+
{...args}
65+
kind="videoinput"
66+
source={Track.Source.Camera}
67+
pressed={isCameraPressed}
68+
onPressedChange={(pressed: boolean) => setIsCameraPressed(pressed)}
69+
/>
70+
<AgentTrackControl
71+
{...args}
72+
source={Track.Source.ScreenShare}
73+
pressed={isScreenSharePressed}
74+
onPressedChange={(pressed: boolean) => setIsScreenSharePressed(pressed)}
75+
/>
76+
</div>
77+
);
78+
},
79+
args: {},
80+
};
81+
82+
export const Outlined: StoryObj<AgentTrackControlProps> = {
83+
args: {
84+
variant: 'outline',
85+
},
86+
render: (args: AgentTrackControlProps) => {
87+
const [isCameraPressed, setIsCameraPressed] = React.useState(true);
88+
const [isMicrophonePressed, setIsMicrophonePressed] = React.useState(false);
89+
const [isScreenSharePressed, setIsScreenSharePressed] = React.useState(true);
90+
91+
const microphoneTrack = useMicrophone();
92+
93+
return (
94+
<div className="flex gap-2">
95+
<AgentTrackControl
96+
{...args}
97+
kind="audioinput"
98+
source={Track.Source.Microphone}
99+
pressed={isMicrophonePressed}
100+
audioTrack={args.source === Track.Source.Microphone ? microphoneTrack : undefined}
101+
onPressedChange={(pressed: boolean) => setIsMicrophonePressed(pressed)}
102+
/>
103+
<AgentTrackControl
104+
{...args}
105+
kind="videoinput"
106+
source={Track.Source.Camera}
107+
pressed={isCameraPressed}
108+
onPressedChange={(pressed: boolean) => setIsCameraPressed(pressed)}
109+
/>
110+
<AgentTrackControl
111+
{...args}
112+
source={Track.Source.ScreenShare}
113+
pressed={isScreenSharePressed}
114+
onPressedChange={(pressed: boolean) => setIsScreenSharePressed(pressed)}
115+
/>
116+
</div>
117+
);
118+
},
119+
};
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import * as React from 'react';
2+
import { StoryObj } from '@storybook/react-vite';
3+
import { AgentSessionProvider } from '../../.storybook/lk-decorators/AgentSessionProvider';
4+
import { AgentTrackToggle, AgentTrackToggleProps } from '@agents-ui';
5+
import { Track } from 'livekit-client';
6+
7+
export default {
8+
component: AgentTrackToggle,
9+
decorators: [AgentSessionProvider],
10+
render: (args: AgentTrackToggleProps) => {
11+
const [isPressed, setIsPressed] = React.useState(
12+
args.source === Track.Source.Microphone ? true : false,
13+
);
14+
15+
return (
16+
<AgentTrackToggle
17+
{...args}
18+
pressed={isPressed}
19+
onPressedChange={(pressed: boolean) => setIsPressed(pressed)}
20+
/>
21+
);
22+
},
23+
args: {
24+
size: 'default',
25+
},
26+
argTypes: {
27+
size: {
28+
options: ['default', 'sm', 'lg'],
29+
control: { type: 'radio' },
30+
},
31+
pending: { control: { type: 'boolean' } },
32+
className: { control: { type: 'text' } },
33+
},
34+
parameters: {
35+
layout: 'centered',
36+
actions: {
37+
handles: [],
38+
},
39+
},
40+
};
41+
42+
export const Default: StoryObj<AgentTrackToggleProps> = {
43+
render: (args: AgentTrackToggleProps) => {
44+
const [isCameraPressed, setIsCameraPressed] = React.useState(true);
45+
const [isMicrophonePressed, setIsMicrophonePressed] = React.useState(false);
46+
const [isScreenSharePressed, setIsScreenSharePressed] = React.useState(true);
47+
48+
return (
49+
<div className="flex gap-2">
50+
<AgentTrackToggle
51+
{...args}
52+
source={Track.Source.Microphone}
53+
pressed={isMicrophonePressed}
54+
onPressedChange={(pressed: boolean) => setIsMicrophonePressed(pressed)}
55+
/>
56+
<AgentTrackToggle
57+
{...args}
58+
source={Track.Source.Camera}
59+
pressed={isCameraPressed}
60+
onPressedChange={(pressed: boolean) => setIsCameraPressed(pressed)}
61+
/>
62+
<AgentTrackToggle
63+
{...args}
64+
source={Track.Source.ScreenShare}
65+
pressed={isScreenSharePressed}
66+
onPressedChange={(pressed: boolean) => setIsScreenSharePressed(pressed)}
67+
/>
68+
</div>
69+
);
70+
},
71+
args: {},
72+
};
73+
74+
export const Outlined: StoryObj<AgentTrackToggleProps> = {
75+
args: {
76+
variant: 'outline',
77+
},
78+
render: (args: AgentTrackToggleProps) => {
79+
const [isCameraPressed, setIsCameraPressed] = React.useState(true);
80+
const [isMicrophonePressed, setIsMicrophonePressed] = React.useState(false);
81+
const [isScreenSharePressed, setIsScreenSharePressed] = React.useState(true);
82+
83+
return (
84+
<div className="flex gap-2">
85+
<AgentTrackToggle
86+
{...args}
87+
source={Track.Source.Microphone}
88+
pressed={isMicrophonePressed}
89+
onPressedChange={(pressed: boolean) => setIsMicrophonePressed(pressed)}
90+
/>
91+
<AgentTrackToggle
92+
{...args}
93+
source={Track.Source.Camera}
94+
pressed={isCameraPressed}
95+
onPressedChange={(pressed: boolean) => setIsCameraPressed(pressed)}
96+
/>
97+
<AgentTrackToggle
98+
{...args}
99+
source={Track.Source.ScreenShare}
100+
pressed={isScreenSharePressed}
101+
onPressedChange={(pressed: boolean) => setIsScreenSharePressed(pressed)}
102+
/>
103+
</div>
104+
);
105+
},
106+
};

0 commit comments

Comments
 (0)