From a77a52eeb415701f0e233e9f2304b7de2d754397 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 12 Sep 2024 16:20:46 +0200 Subject: [PATCH] Add dataprops and allow a template child for BarVisualizer @lukasIO (#965) --- .changeset/big-mugs-rhyme.md | 7 ++++ examples/nextjs/turbo.json | 8 ---- package.json | 2 +- packages/core/.gitignore | 3 +- packages/core/package.json | 2 +- packages/react/.gitignore | 1 - packages/react/package.json | 2 +- .../components/participant/BarVisualizer.tsx | 39 ++++++++++++------- packages/react/src/utils.ts | 7 ++++ packages/styles/.gitignore | 3 +- packages/styles/package.json | 2 +- .../participant/_audio-visualizer.scss | 3 +- turbo.json | 13 +------ 13 files changed, 50 insertions(+), 42 deletions(-) create mode 100644 .changeset/big-mugs-rhyme.md delete mode 100644 examples/nextjs/turbo.json diff --git a/.changeset/big-mugs-rhyme.md b/.changeset/big-mugs-rhyme.md new file mode 100644 index 000000000..65754fdcb --- /dev/null +++ b/.changeset/big-mugs-rhyme.md @@ -0,0 +1,7 @@ +--- +"@livekit/components-core": patch +"@livekit/components-react": patch +"@livekit/components-styles": patch +--- + +Add dataprops and allow a template child for BarVisualizer @lukasIO diff --git a/examples/nextjs/turbo.json b/examples/nextjs/turbo.json deleted file mode 100644 index 1e9868c25..000000000 --- a/examples/nextjs/turbo.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": ["//"], - "tasks": { - "dev": { - "persistent": true - } - } -} diff --git a/package.json b/package.json index c1ed75dcb..21c65da06 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "build:react": "turbo run build --filter=@livekit/components-react...", "build:storybook": "turbo run build --filter=@livekit/component-docs-storybook...", "build:styles": "turbo run build --filter=@livekit/components-styles...", - "dev:next": "turbo watch dev --filter=@livekit/component-example-next", + "dev:next": "turbo run dev --filter=@livekit/component-example-next...", "dev:storybook": "turbo run dev --filter=@livekit/component-docs-storybook...", "format:check": "prettier --check \"**/src/**/*.{ts,tsx,md}\"", "format:write": "prettier --write \"**/src/**/*.{ts,tsx,md}\"", diff --git a/packages/core/.gitignore b/packages/core/.gitignore index b4cfeb2ba..299629ca6 100644 --- a/packages/core/.gitignore +++ b/packages/core/.gitignore @@ -2,5 +2,4 @@ .DS_Store node_modules dist -temp -.turbo \ No newline at end of file +temp \ No newline at end of file diff --git a/packages/core/package.json b/packages/core/package.json index 31d1ee8b6..3e1400c8a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -25,7 +25,7 @@ ], "scripts": { "build": "tsup --onSuccess \"tsc --declaration --emitDeclarationOnly\"", - "dev": "tsup --onSuccess \"tsc --declaration --emitDeclarationOnly\"", + "dev": "tsup --watch --onSuccess \"tsc --declaration --emitDeclarationOnly\"", "lint": "eslint -f unix \"src/**/*.{ts,tsx}\"", "test": "vitest --run", "test:watch": "vitest", diff --git a/packages/react/.gitignore b/packages/react/.gitignore index 918005b44..1734597ac 100644 --- a/packages/react/.gitignore +++ b/packages/react/.gitignore @@ -4,4 +4,3 @@ node_modules .cache dist temp -.turbo diff --git a/packages/react/package.json b/packages/react/package.json index b5856fcce..740d6e55d 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -34,7 +34,7 @@ ], "scripts": { "build": "pnpm gen:svg && tsup --onSuccess \"tsc --declaration --emitDeclarationOnly\"", - "dev": "tsup --onSuccess \"tsc --declaration --emitDeclarationOnly\"", + "dev": "tsup --watch --onSuccess \"tsc --declaration --emitDeclarationOnly\"", "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", "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", "gen:svg": "pnpm gen:images && pnpm gen:icons", diff --git a/packages/react/src/components/participant/BarVisualizer.tsx b/packages/react/src/components/participant/BarVisualizer.tsx index 381ff524d..c289417dd 100644 --- a/packages/react/src/components/participant/BarVisualizer.tsx +++ b/packages/react/src/components/participant/BarVisualizer.tsx @@ -3,7 +3,7 @@ import { useBarAnimator } from './animators/useBarAnimator'; import { useMultibandTrackVolume, type VoiceAssistantState } from '../../hooks'; import type { TrackReferenceOrPlaceholder } from '@livekit/components-core'; import { useMaybeTrackRefContext } from '../../context'; -import { mergeProps } from '../../utils'; +import { cloneSingleChild, mergeProps } from '../../utils'; /** * @beta @@ -25,6 +25,8 @@ export interface BarVisualizerProps extends React.HTMLProps { barCount?: number; trackRef?: TrackReferenceOrPlaceholder; options?: BarVisualizerOptions; + /** The template component to be used in the visualizer. */ + children?: React.ReactNode; } const sequencerIntervals = new Map([ @@ -76,7 +78,7 @@ const getSequencerInterval = ( */ export const BarVisualizer = /* @__PURE__ */ React.forwardRef( function BarVisualizer( - { state, options, barCount = 15, trackRef, ...props }: BarVisualizerProps, + { state, options, barCount = 15, trackRef, children, ...props }: BarVisualizerProps, ref, ) { const elementProps = mergeProps(props, { className: 'lk-audio-bar-visualizer' }); @@ -102,17 +104,28 @@ export const BarVisualizer = /* @__PURE__ */ React.forwardRef - {volumeBands.map((volume, idx) => ( - - ))} + {volumeBands.map((volume, idx) => + children ? ( + cloneSingleChild(children, { + 'data-lk-highlighted': highlightedIndices.includes(idx), + 'data-lk-bar-index': idx, + class: 'lk-audio-bar', + style: { height: `${Math.min(maxHeight, Math.max(minHeight, volume * 100 + 5))}%` }, + }) + ) : ( + + ), + )} ); }, diff --git a/packages/react/src/utils.ts b/packages/react/src/utils.ts index c7f720125..5486a6671 100644 --- a/packages/react/src/utils.ts +++ b/packages/react/src/utils.ts @@ -1,6 +1,7 @@ import * as React from 'react'; import { mergeProps as mergePropsReactAria } from './mergeProps'; import { log } from '@livekit/components-core'; +import clsx from 'clsx'; /** @internal */ export function isProp>( @@ -27,6 +28,12 @@ export function cloneSingleChild( // Checking isValidElement is the safe way and avoids a typescript // error too. if (React.isValidElement(child) && React.Children.only(children)) { + if (child.props.class) { + // make sure we retain classnames of both passed props and child + props ??= {}; + props.class = clsx(child.props.class, props.class); + props.style = { ...child.props.style, ...props.style }; + } return React.cloneElement(child, { ...props, key }); } return child; diff --git a/packages/styles/.gitignore b/packages/styles/.gitignore index c71e34940..867edf396 100644 --- a/packages/styles/.gitignore +++ b/packages/styles/.gitignore @@ -1,4 +1,3 @@ dist/ node_modules/ -.temp/ -.turbo \ No newline at end of file +.temp/ \ No newline at end of file diff --git a/packages/styles/package.json b/packages/styles/package.json index 1e546d0b2..1f51e4018 100644 --- a/packages/styles/package.json +++ b/packages/styles/package.json @@ -67,7 +67,7 @@ "prebuild": "rimraf .temp dist", "build": "pnpm compile:sass && pnpm postcss && pnpm generate:types", "compile:sass": "sass scss:.temp/general --style compressed", - "dev": "pnpm build", + "dev": "nodemon -e scss,js -x \"pnpm build\"", "generate:types": "pnpm generate:types:unprefixed && pnpm generate:types:prefixed", "generate:types:prefixed": "cd dist && typed-scss-modules \"**/*.css\" --exportType default --outputFolder ../dist/types --nameFormat kebab", "generate:types:unprefixed": "cd scss && typed-scss-modules \"**/*.scss\" --exportType default --outputFolder ../dist/types_unprefixed --nameFormat kebab --exportTypeName UnprefixedClassNames", diff --git a/packages/styles/scss/components/participant/_audio-visualizer.scss b/packages/styles/scss/components/participant/_audio-visualizer.scss index 24f8d6af8..53b721486 100644 --- a/packages/styles/scss/components/participant/_audio-visualizer.scss +++ b/packages/styles/scss/components/participant/_audio-visualizer.scss @@ -49,7 +49,8 @@ deprecated } &[data-va-state='speaking'] > .audio-bar, - & > .audio-bar.highlighted { + & > .audio-bar.highlighted, + & > [data-highlighted='true'] { background-color: var(--fg, #fff); filter: drop-shadow(var(--drop-shadow, rgba(255, 255, 255, 0.2) 0px 0px 24px)); transition: none; diff --git a/turbo.json b/turbo.json index f5c607470..8349aff41 100644 --- a/turbo.json +++ b/turbo.json @@ -3,15 +3,7 @@ "tasks": { "build": { "dependsOn": ["^build"], - "outputs": [ - "dist/**", - ".next/**", - "!.next/cache/**", - "storybook-static/**", - "lib/**", - "src/assets/icons/**", - "src/assets/images/**" - ] + "outputs": ["dist/**", ".next/**", "storybook-static/**", "lib/**"] }, "lint": { "outputs": [] @@ -25,9 +17,8 @@ "outputs": [] }, "dev": { - "dependsOn": ["^dev"], "cache": false, - "outputs": ["dist/**", ".next/**", "!.next/cache/**", "storybook-static/**", "lib/**"] + "persistent": true }, "deploy": { "dependsOn": ["^build"]