Skip to content

Commit 53b7804

Browse files
feat: LiveKit OSS Shadcn setup (#1248)
1 parent 7790393 commit 53b7804

Some content is hidden

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

57 files changed

+6595
-5091
lines changed

docs/storybook/.env.example

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# LiveKit
2-
# Create a project on livekit.cloud or use a local LiveKit server instance to generate a test token.
2+
# Create a project on cloud.livekit.io
3+
# or use a local LiveKit server instance to generate a test token.
34
# Increase the token TTL to something big so you don't have to update it so often.
45
VITE_PUBLIC_LK_SERVER_URL=wss://<domain>.livekit.cloud
56
VITE_PUBLIC_TEST_TOKEN=
67

8+
# For agents-ui, create a sandbox token server on cloud.livekit.io
9+
# or modify tokenSource in docs/storybook/.storybook/lk-decorators/AgentSessionProvider.tsx
10+
VITE_PUBLIC_LK_SANDBOX_TOKEN_SERVER_ID=
711

812
# STORYBOOK
913
# https://storybook.js.org/docs/react/configure/telemetry#how-to-opt-out

docs/storybook/.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55
module.exports = {
66
root: true,
7-
extends: ['custom'],
7+
extends: ['custom', 'plugin:storybook/recommended'],
88
rules: {
99
'import/no-anonymous-default-export': [
1010
'warn',

docs/storybook/.storybook/env.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
interface ImportMetaEnv {
33
readonly VITE_PUBLIC_LK_SERVER_URL: string;
44
readonly VITE_PUBLIC_TEST_TOKEN: string;
5+
readonly VITE_PUBLIC_LK_SANDBOX_TOKEN_SERVER_ID: string;
56
// more env variables...
67
}
78

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React, { useEffect, useMemo } from 'react';
2+
import { Decorator } from '@storybook/react-vite';
3+
import {
4+
useLocalParticipant,
5+
SessionProvider,
6+
useSession,
7+
type TrackReference,
8+
} from '@livekit/components-react';
9+
import { TokenSource, Track } from 'livekit-client';
10+
11+
const TOKEN_SOURCE = TokenSource.sandboxTokenServer(
12+
import.meta.env.VITE_PUBLIC_LK_SANDBOX_TOKEN_SERVER_ID,
13+
);
14+
15+
export const AgentSessionProvider: Decorator = (Story: StoryFn) => {
16+
const session = useSession(TOKEN_SOURCE);
17+
18+
useEffect(() => {
19+
session.start();
20+
return () => session.end();
21+
}, []);
22+
23+
return (
24+
<SessionProvider session={session}>
25+
<Story />
26+
</SessionProvider>
27+
);
28+
};
29+
30+
export function useMicrophone() {
31+
const { microphoneTrack, localParticipant } = useLocalParticipant();
32+
33+
useEffect(() => {
34+
localParticipant.setMicrophoneEnabled(true, undefined);
35+
}, []);
36+
37+
return useMemo(
38+
() =>
39+
({
40+
participant: localParticipant,
41+
source: Track.Source.Microphone,
42+
publication: microphoneTrack,
43+
}) as TrackReference,
44+
[microphoneTrack],
45+
);
46+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import { Decorator } from '@storybook/react';
2+
import { Decorator } from '@storybook/react-vite';
33
import {
44
LayoutContextProvider,
55
useParticipants,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ParticipantContext } from '@livekit/components-react';
2-
import { Decorator } from '@storybook/react';
2+
import { Decorator } from '@storybook/react-vite';
33
import { ConnectionQuality, Participant, ParticipantEvent } from 'livekit-client';
44
import * as React from 'react';
55

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
useLocalParticipant,
66
useTracks,
77
} from '@livekit/components-react';
8-
import { Decorator } from '@storybook/react';
8+
import { Decorator } from '@storybook/react-vite';
99
import { Track } from 'livekit-client';
1010

1111
/**

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
22
import { LiveKitRoom } from '@livekit/components-react';
3-
import { Decorator } from '@storybook/react';
3+
import { Decorator } from '@storybook/react-vite';
44
import { Room } from 'livekit-client';
55

66
export type RoomContextSettings = Partial<{
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { DecoratorHelpers } from '@storybook/addon-themes';
2+
import type { ReactRenderer } from '@storybook/react';
3+
import { ThemeProvider, type ThemeProviderProps, useTheme } from 'next-themes';
4+
import { type PropsWithChildren, useEffect } from 'react';
5+
import type { DecoratorFunction } from 'storybook/internal/types';
6+
7+
type ThemeSwitcherProps = PropsWithChildren<{
8+
theme: string;
9+
}>;
10+
11+
const ThemeSwitcher = ({ theme, children }: ThemeSwitcherProps) => {
12+
const { setTheme } = useTheme();
13+
useEffect(() => setTheme(theme), [theme]);
14+
/**
15+
* If you're using tailwind and want your background to be displayed in the preview,
16+
* use <div className="bg-background">{children}</div> instead
17+
*/
18+
return children;
19+
};
20+
21+
type NextThemesDecorator = Omit<ThemeProviderProps, 'defaultTheme' | 'themes'> & {
22+
themes: Record<string, string>;
23+
defaultTheme: string;
24+
};
25+
26+
const { initializeThemeState, pluckThemeFromContext } = DecoratorHelpers;
27+
28+
export const withNextThemes = ({
29+
themes,
30+
defaultTheme,
31+
...props
32+
}: NextThemesDecorator): DecoratorFunction<ReactRenderer> => {
33+
initializeThemeState(Object.keys(themes), defaultTheme);
34+
35+
return (Story, context) => {
36+
const selectedTheme = pluckThemeFromContext(context);
37+
const { themeOverride } = context.parameters.themes ?? {};
38+
const selected = themeOverride ?? selectedTheme ?? defaultTheme;
39+
40+
return (
41+
<ThemeProvider defaultTheme={defaultTheme} {...props}>
42+
<ThemeSwitcher theme={selected}>
43+
<Story />
44+
</ThemeSwitcher>
45+
</ThemeProvider>
46+
);
47+
};
48+
};

docs/storybook/.storybook/main.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// @ts-check
22
const path = require('path');
33
module.exports = {
4-
stories: ['../stories/**/*.stories.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'],
4+
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'],
55
addons: [
66
'@storybook/addon-links',
7-
'@storybook/addon-essentials',
8-
'@storybook/addon-interactions',
7+
'@storybook/addon-docs',
8+
'@storybook/addon-styling-webpack',
9+
'@storybook/addon-themes'
910
],
1011
framework: {
1112
name: '@storybook/react-vite',
@@ -20,4 +21,23 @@ module.exports = {
2021
typescript: {
2122
reactDocgen: 'react-docgen-typescript',
2223
},
24+
async viteFinal(config) {
25+
const { default: tailwindcss } = await import('@tailwindcss/vite');
26+
27+
return {
28+
...config,
29+
plugins: [...config.plugins, tailwindcss()],
30+
esbuild: {
31+
...config.esbuild,
32+
jsx: 'automatic',
33+
},
34+
resolve: {
35+
...config.resolve,
36+
alias: {
37+
...config.resolve?.alias,
38+
'@': path.resolve(__dirname, '../../../packages/shadcn'),
39+
},
40+
},
41+
};
42+
},
2343
};

0 commit comments

Comments
 (0)