Skip to content

Commit a77a52e

Browse files
authored
Add dataprops and allow a template child for BarVisualizer @lukasIO (#965)
1 parent c2ae183 commit a77a52e

File tree

13 files changed

+50
-42
lines changed

13 files changed

+50
-42
lines changed

.changeset/big-mugs-rhyme.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@livekit/components-core": patch
3+
"@livekit/components-react": patch
4+
"@livekit/components-styles": patch
5+
---
6+
7+
Add dataprops and allow a template child for BarVisualizer @lukasIO

examples/nextjs/turbo.json

-8
This file was deleted.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"build:react": "turbo run build --filter=@livekit/components-react...",
1212
"build:storybook": "turbo run build --filter=@livekit/component-docs-storybook...",
1313
"build:styles": "turbo run build --filter=@livekit/components-styles...",
14-
"dev:next": "turbo watch dev --filter=@livekit/component-example-next",
14+
"dev:next": "turbo run dev --filter=@livekit/component-example-next...",
1515
"dev:storybook": "turbo run dev --filter=@livekit/component-docs-storybook...",
1616
"format:check": "prettier --check \"**/src/**/*.{ts,tsx,md}\"",
1717
"format:write": "prettier --write \"**/src/**/*.{ts,tsx,md}\"",

packages/core/.gitignore

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@
22
.DS_Store
33
node_modules
44
dist
5-
temp
6-
.turbo
5+
temp

packages/core/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
],
2626
"scripts": {
2727
"build": "tsup --onSuccess \"tsc --declaration --emitDeclarationOnly\"",
28-
"dev": "tsup --onSuccess \"tsc --declaration --emitDeclarationOnly\"",
28+
"dev": "tsup --watch --onSuccess \"tsc --declaration --emitDeclarationOnly\"",
2929
"lint": "eslint -f unix \"src/**/*.{ts,tsx}\"",
3030
"test": "vitest --run",
3131
"test:watch": "vitest",

packages/react/.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,3 @@ node_modules
44
.cache
55
dist
66
temp
7-
.turbo

packages/react/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
],
3535
"scripts": {
3636
"build": "pnpm gen:svg && tsup --onSuccess \"tsc --declaration --emitDeclarationOnly\"",
37-
"dev": "tsup --onSuccess \"tsc --declaration --emitDeclarationOnly\"",
37+
"dev": "tsup --watch --onSuccess \"tsc --declaration --emitDeclarationOnly\"",
3838
"gen:icons": "rimraf -I -g ./src/assets/icons/*Icon.tsx && svgr --template ./src/assets/template.js --out-dir ./src/assets/icons --typescript ../styles/assets/icons",
3939
"gen:images": "rimraf -I -g ./src/assets/images/*.tsx && svgr --template ./src/assets/template.js --out-dir ./src/assets/images --typescript --no-svgo ../styles/assets/images",
4040
"gen:svg": "pnpm gen:images && pnpm gen:icons",

packages/react/src/components/participant/BarVisualizer.tsx

+26-13
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useBarAnimator } from './animators/useBarAnimator';
33
import { useMultibandTrackVolume, type VoiceAssistantState } from '../../hooks';
44
import type { TrackReferenceOrPlaceholder } from '@livekit/components-core';
55
import { useMaybeTrackRefContext } from '../../context';
6-
import { mergeProps } from '../../utils';
6+
import { cloneSingleChild, mergeProps } from '../../utils';
77

88
/**
99
* @beta
@@ -25,6 +25,8 @@ export interface BarVisualizerProps extends React.HTMLProps<HTMLDivElement> {
2525
barCount?: number;
2626
trackRef?: TrackReferenceOrPlaceholder;
2727
options?: BarVisualizerOptions;
28+
/** The template component to be used in the visualizer. */
29+
children?: React.ReactNode;
2830
}
2931

3032
const sequencerIntervals = new Map<VoiceAssistantState, number>([
@@ -76,7 +78,7 @@ const getSequencerInterval = (
7678
*/
7779
export const BarVisualizer = /* @__PURE__ */ React.forwardRef<HTMLDivElement, BarVisualizerProps>(
7880
function BarVisualizer(
79-
{ state, options, barCount = 15, trackRef, ...props }: BarVisualizerProps,
81+
{ state, options, barCount = 15, trackRef, children, ...props }: BarVisualizerProps,
8082
ref,
8183
) {
8284
const elementProps = mergeProps(props, { className: 'lk-audio-bar-visualizer' });
@@ -102,17 +104,28 @@ export const BarVisualizer = /* @__PURE__ */ React.forwardRef<HTMLDivElement, Ba
102104

103105
return (
104106
<div ref={ref} {...elementProps} data-lk-va-state={state}>
105-
{volumeBands.map((volume, idx) => (
106-
<span
107-
key={idx}
108-
className={`lk-audio-bar ${highlightedIndices.includes(idx) && 'lk-highlighted'}`}
109-
style={{
110-
// TODO transform animations would be more performant, however the border-radius gets distorted when using scale transforms. a 9-slice approach (or 3 in this case) could work
111-
// transform: `scale(1, ${Math.min(maxHeight, Math.max(minHeight, volume))}`,
112-
height: `${Math.min(maxHeight, Math.max(minHeight, volume * 100 + 5))}%`,
113-
}}
114-
></span>
115-
))}
107+
{volumeBands.map((volume, idx) =>
108+
children ? (
109+
cloneSingleChild(children, {
110+
'data-lk-highlighted': highlightedIndices.includes(idx),
111+
'data-lk-bar-index': idx,
112+
class: 'lk-audio-bar',
113+
style: { height: `${Math.min(maxHeight, Math.max(minHeight, volume * 100 + 5))}%` },
114+
})
115+
) : (
116+
<span
117+
key={idx}
118+
data-lk-highlighted={highlightedIndices.includes(idx)}
119+
data-lk-bar-index={idx}
120+
className={`lk-audio-bar ${highlightedIndices.includes(idx) && 'lk-highlighted'}`}
121+
style={{
122+
// TODO transform animations would be more performant, however the border-radius gets distorted when using scale transforms. a 9-slice approach (or 3 in this case) could work
123+
// transform: `scale(1, ${Math.min(maxHeight, Math.max(minHeight, volume))}`,
124+
height: `${Math.min(maxHeight, Math.max(minHeight, volume * 100 + 5))}%`,
125+
}}
126+
></span>
127+
),
128+
)}
116129
</div>
117130
);
118131
},

packages/react/src/utils.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from 'react';
22
import { mergeProps as mergePropsReactAria } from './mergeProps';
33
import { log } from '@livekit/components-core';
4+
import clsx from 'clsx';
45

56
/** @internal */
67
export function isProp<U extends HTMLElement, T extends React.HTMLAttributes<U>>(
@@ -27,6 +28,12 @@ export function cloneSingleChild(
2728
// Checking isValidElement is the safe way and avoids a typescript
2829
// error too.
2930
if (React.isValidElement(child) && React.Children.only(children)) {
31+
if (child.props.class) {
32+
// make sure we retain classnames of both passed props and child
33+
props ??= {};
34+
props.class = clsx(child.props.class, props.class);
35+
props.style = { ...child.props.style, ...props.style };
36+
}
3037
return React.cloneElement(child, { ...props, key });
3138
}
3239
return child;

packages/styles/.gitignore

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
dist/
22
node_modules/
3-
.temp/
4-
.turbo
3+
.temp/

packages/styles/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"prebuild": "rimraf .temp dist",
6868
"build": "pnpm compile:sass && pnpm postcss && pnpm generate:types",
6969
"compile:sass": "sass scss:.temp/general --style compressed",
70-
"dev": "pnpm build",
70+
"dev": "nodemon -e scss,js -x \"pnpm build\"",
7171
"generate:types": "pnpm generate:types:unprefixed && pnpm generate:types:prefixed",
7272
"generate:types:prefixed": "cd dist && typed-scss-modules \"**/*.css\" --exportType default --outputFolder ../dist/types --nameFormat kebab",
7373
"generate:types:unprefixed": "cd scss && typed-scss-modules \"**/*.scss\" --exportType default --outputFolder ../dist/types_unprefixed --nameFormat kebab --exportTypeName UnprefixedClassNames",

packages/styles/scss/components/participant/_audio-visualizer.scss

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ deprecated
4949
}
5050

5151
&[data-va-state='speaking'] > .audio-bar,
52-
& > .audio-bar.highlighted {
52+
& > .audio-bar.highlighted,
53+
& > [data-highlighted='true'] {
5354
background-color: var(--fg, #fff);
5455
filter: drop-shadow(var(--drop-shadow, rgba(255, 255, 255, 0.2) 0px 0px 24px));
5556
transition: none;

turbo.json

+2-11
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,7 @@
33
"tasks": {
44
"build": {
55
"dependsOn": ["^build"],
6-
"outputs": [
7-
"dist/**",
8-
".next/**",
9-
"!.next/cache/**",
10-
"storybook-static/**",
11-
"lib/**",
12-
"src/assets/icons/**",
13-
"src/assets/images/**"
14-
]
6+
"outputs": ["dist/**", ".next/**", "storybook-static/**", "lib/**"]
157
},
168
"lint": {
179
"outputs": []
@@ -25,9 +17,8 @@
2517
"outputs": []
2618
},
2719
"dev": {
28-
"dependsOn": ["^dev"],
2920
"cache": false,
30-
"outputs": ["dist/**", ".next/**", "!.next/cache/**", "storybook-static/**", "lib/**"]
21+
"persistent": true
3122
},
3223
"deploy": {
3324
"dependsOn": ["^build"]

0 commit comments

Comments
 (0)