Skip to content

Commit

Permalink
video container -> video
Browse files Browse the repository at this point in the history
  • Loading branch information
bbohlender committed Jun 4, 2024
1 parent 7254717 commit 0c25264
Show file tree
Hide file tree
Showing 14 changed files with 52 additions and 54 deletions.
2 changes: 1 addition & 1 deletion apps/html23/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { copyLink, importV0, toggleFullscreen } from './shared.js'
import { ImportV0Dialog } from './components/import.js'
import { MaterialsPopover } from './components/popover/materials.js'

export const componentMap = { ...defaultComponentMap, video: defaultComponentMap.VideoContainer, ...lucideComponentMap }
export const componentMap = { ...defaultComponentMap, video: defaultComponentMap.Video, ...lucideComponentMap }

const sessionConfig: XRSessionInit = {
requiredFeatures: ['local-floor'],
Expand Down
10 changes: 5 additions & 5 deletions docs/getting-started/components-and-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,20 +223,20 @@ The `Portal` component uses the `Image` component under the hood to render its c
</Root>
```

## VideoContainer
## Video

The `VideoContainer` component has the same properties and functionalities as a `Image` component but allows you to render an video inside it. The `VideoContainer` component corresponds to the HTML `video` element. The `VideoContainer` component has the `src`, `volume`, `preservesPitch`, `playbackRate`, `muted`, `loop`, and `autoplay` property to setip the video and can even be used to play media streams.
The `Video` component has the same properties and functionalities as a `Image` component but allows you to render an video inside it. The `Video` component corresponds to the HTML `video` element. The `Video` component has the `src`, `volume`, `preservesPitch`, `playbackRate`, `muted`, `loop`, and `autoplay` property to setip the video and can even be used to play media streams.

To control playing the video the `VideoContainer` provide the html video element through a provide, that can be consumed by its children through `useVideoContainerElement` to create video controls. Additionally, the html video element can be received from the parent of the `VideoContainer` using `ref.current.element`.
To control playing the video the `Video` provide the html video element through a provide, that can be consumed by its children through `useVideoElement` to create video controls. Additionally, the html video element can be received from the parent of the `Video` using `ref.current.element`.

```jsx
<Root>
<VideoContainer src="example.mp4" autoplay width={100} />
<Video src="example.mp4" autoplay width={100} />
</Root>
```

<details>
<summary>View all properties specific to the `VideoContainer` component</summary>
<summary>View all properties specific to the `Video` component</summary>

| Property | Type |
| -------------- | ------------------- |
Expand Down
4 changes: 2 additions & 2 deletions docs/kits/default.md
Original file line number Diff line number Diff line change
Expand Up @@ -950,10 +950,10 @@ npx uikit component add default input
<summary>Code</summary>

```tsx
import { VideoContainer } from '@/video.js'
import { Video } from '@/video.js'

export function VideoDemo() {
return <VideoContainer src="example.mp4" controls width={500} />
return <Video src="example.mp4" controls width={500} />
}

```
Expand Down
4 changes: 2 additions & 2 deletions examples/default/src/components/video.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { VideoContainer } from '@/video.js'
import { Video } from '@/video.js'

export function VideoDemo() {
return <VideoContainer src="example.mp4" controls width={500} />
return <Video src="example.mp4" controls width={500} />
}
4 changes: 2 additions & 2 deletions examples/market/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { DialogAnchor } from '@/dialog.js'
import { Tabs, TabsList, TabsContent, TabsTrigger } from '@/tabs.js'
import { Separator } from '@/separator.js'
import { Button } from '@/button.js'
import { VideoContainer } from '@/video.js'
import { Video } from '@/video.js'
import { AlbumArtwork } from './components/album-artwork.js'
import { listenNowAlbums, madeForYouAlbums } from './data/albums.js'
import { Sidebar } from './components/sidebar.js'
Expand Down Expand Up @@ -109,7 +109,7 @@ export function MarketPage() {
</Container>
<Separator marginY={16} />
<Container flexShrink={1} flexDirection="row" overflow="scroll" gap={16} paddingBottom={16}>
<VideoContainer controls borderRadius={6} flexShrink={0} src="example.mp4" />
<Video controls borderRadius={6} flexShrink={0} src="example.mp4" />
{madeForYouAlbums.map((album) => (
<AlbumArtwork key={album.name} album={album} aspectRatio="square" width={150} height={150} />
))}
Expand Down
25 changes: 13 additions & 12 deletions packages/kits/default/src/video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import React, {
import { Signal, computed, signal } from '@preact/signals-core'
import {
Container,
VideoContainer as VideoContainerImpl,
VideoContainerProperties as BaseVideoContainerProperties,
Video as VideoImpl,
VideoProperties as BaseVideoProperties,
Text,
VideoInternals,
ContainerProperties,
useVideoContainerElement,
useVideoElement,
ComponentInternals,
} from '@react-three/uikit'
import { Play, Pause, VolumeX, Volume2 } from '@react-three/uikit-lucide'
Expand All @@ -26,15 +26,15 @@ import { Button } from './button.js'
import { colors } from './theme.js'
import { EventHandlers } from '@react-three/fiber/dist/declarations/src/core/events.js'

export type VideoContainerProperties = { controls?: boolean } & BaseVideoContainerProperties
export type VideoProperties = { controls?: boolean } & BaseVideoProperties

//for getting the correct types for conversion
type _VideoContainerProperties = VideoContainerProperties
type _VideoProperties = VideoProperties

const movingContext = createContext<Signal<boolean> | undefined>(undefined)

export const VideoContainer: (props: VideoContainerProperties & RefAttributes<VideoInternals>) => ReactNode =
forwardRef(({ controls, children, ...rest }: VideoContainerProperties, ref) => {
export const Video: (props: VideoProperties & RefAttributes<VideoInternals>) => ReactNode = forwardRef(
({ controls, children, ...rest }: VideoProperties, ref) => {
const moving = useMemo(() => signal(false), [])
const handlers = useMemo<EventHandlers>(() => {
let timeoutRef: NodeJS.Timeout | undefined
Expand All @@ -58,19 +58,20 @@ export const VideoContainer: (props: VideoContainerProperties & RefAttributes<Vi
}
}, [moving])
return (
<VideoContainerImpl {...rest} {...handlers} positionType="relative" ref={ref}>
<VideoImpl {...rest} {...handlers} positionType="relative" ref={ref}>
<movingContext.Provider value={moving}>{controls && <VideoControls />}</movingContext.Provider>
{children}
</VideoContainerImpl>
</VideoImpl>
)
})
},
)

export type VideoControlsProperties = Omit<ContainerProperties, 'children'>

export const VideoControls: (
props: VideoControlsProperties & RefAttributes<ComponentInternals<ContainerProperties>>,
) => ReactNode = forwardRef((props: VideoControlsProperties, ref) => {
const videoElement = useVideoContainerElement()
const videoElement = useVideoElement()
const [paused, setPaused] = useState(videoElement.paused)
useEffect(() => {
const listener = () => setPaused(videoElement.paused)
Expand All @@ -94,7 +95,7 @@ export const VideoControls: (

const moving = useContext(movingContext)
if (moving == null) {
throw new Error(`VideoControls form the default kit can only be used inside a VideoContainer from the default kit`)
throw new Error(`VideoControls form the default kit can only be used inside a Video from the default kit`)
}
const displaySignal = useMemo(() => computed(() => (moving.value ? 'flex' : 'none')), [moving])

Expand Down
6 changes: 3 additions & 3 deletions packages/react/src/convert/html/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Input } from '../../input.js'
import { Text } from '../../text.js'
import { Svg } from '../../svg.js'
import { Image } from '../../image.js'
import { VideoContainer } from '../../video.js'
import { Video } from '../../video.js'
import { Icon } from '../../icon.js'
import { ComponentInternals } from '../../ref.js'

Expand Down Expand Up @@ -96,8 +96,8 @@ function createRenderElement(componentMap?: ConversionComponentMap, customHook?:
)
}
switch (typeName) {
case 'VideoContainer':
return <VideoContainer {...props} ref={ref} />
case 'Video':
return <Video {...props} ref={ref} />
case 'Image':
return (
<Image {...props} ref={ref}>
Expand Down
25 changes: 13 additions & 12 deletions packages/react/src/video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,32 @@ import {
import { Image } from './image.js'
import { Texture, VideoTexture } from 'three'
import { signal } from '@preact/signals-core'
import { VideoContainerProperties as BaseVideoContainerProperties, ImageProperties } from '@pmndrs/uikit'
import { VideoProperties as BaseVideoProperties, ImageProperties } from '@pmndrs/uikit'
import { updateVideoElement } from '@pmndrs/uikit/internals'
import { EventHandlers } from '@react-three/fiber/dist/declarations/src/core/events.js'
import { ComponentInternals } from './ref.js'

const VideoContainerContext = createContext<HTMLVideoElement | undefined>(undefined)
const VideoContext = createContext<HTMLVideoElement | undefined>(undefined)

export function useVideoContainerElement(): HTMLVideoElement {
const element = useContext(VideoContainerContext)
export function useVideoElement(): HTMLVideoElement {
const element = useContext(VideoContext)
if (element == null) {
throw new Error(`useVideoContainerElement can only be executed inside a VideoContainer`)
throw new Error(`useVideoElement can only be executed inside a Video component`)
}
return element
}

export type VideoContainerInternals = ComponentInternals<Omit<ImageProperties, 'src'> & EventHandlers> & {
export type VideoInternals = ComponentInternals<Omit<ImageProperties, 'src'> & EventHandlers> & {
element: HTMLVideoElement
}

export type VideoContainerProperties = BaseVideoContainerProperties &
export type VideoProperties = BaseVideoProperties &
EventHandlers & {
children?: ReactNode
}

export const VideoContainer: (props: VideoContainerProperties & RefAttributes<VideoContainerInternals>) => ReactNode =
forwardRef((props: VideoContainerProperties, ref) => {
export const Video: (props: VideoProperties & RefAttributes<VideoInternals>) => ReactNode = forwardRef(
(props: VideoProperties, ref) => {
const texture = useMemo(() => signal<Texture | undefined>(undefined), [])
const aspectRatio = useMemo(() => signal<number>(1), [])
const video = useMemo(() => document.createElement('video'), [])
Expand Down Expand Up @@ -65,8 +65,9 @@ export const VideoContainer: (props: VideoContainerProperties & RefAttributes<Vi
const internalRef = useRef<ComponentInternals<ImageProperties>>(null)
useImperativeHandle(ref, () => ({ ...internalRef.current!, element: video }), [video])
return (
<VideoContainerContext.Provider value={video}>
<VideoContext.Provider value={video}>
<Image aspectRatio={aspectRatio} {...props} ref={internalRef} src={texture} />
</VideoContainerContext.Provider>
</VideoContext.Provider>
)
})
},
)
4 changes: 2 additions & 2 deletions packages/uikit/scripts/extract-core-component-properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ const result = {
),
),
Text: {},
VideoContainer: mapToRecord(
Video: mapToRecord(
converter.extractPropertyTypes(
converter.getSchema('VideoContainerProperties'),
converter.getSchema('VideoProperties'),
containerProperties,
inheritableProperties,
removeConditionalsAndClasses,
Expand Down
2 changes: 1 addition & 1 deletion packages/uikit/src/components/video.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ImageProperties } from './image.js'

export type VideoContainerProperties = Omit<ImageProperties, 'src'> & {
export type VideoProperties = Omit<ImageProperties, 'src'> & {
src?: string | MediaStream
volume?: number
preservesPitch?: boolean
Expand Down
4 changes: 2 additions & 2 deletions packages/uikit/src/convert/html/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ConversionComponentData } from './internals.js'
export const htmlDefaults: Record<
string,
Partial<Omit<ConversionComponentData, 'hasProperty'>> & {
renderAs?: 'Image' | 'Input' | 'VideoContainer' | 'Icon' | 'Container' | 'Text'
renderAs?: 'Image' | 'Input' | 'Video' | 'Icon' | 'Container' | 'Text'
}
> = {
h1: {
Expand Down Expand Up @@ -80,7 +80,7 @@ export const htmlDefaults: Record<
defaultProperties: { multiline: true },
},
video: {
renderAs: 'VideoContainer',
renderAs: 'Video',
},
}
//TBD select option
6 changes: 1 addition & 5 deletions packages/uikit/src/convert/html/internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,7 @@ export const conversionPropertyTypes = {
Input: [generatedPropertyTypes.Inheriting, generatedPropertyTypes.Shared, generatedPropertyTypes.Input],
Svg: [generatedPropertyTypes.Inheriting, generatedPropertyTypes.Shared, generatedPropertyTypes.Svg],
Text: [generatedPropertyTypes.Inheriting, generatedPropertyTypes.Shared, generatedPropertyTypes.Text],
VideoContainer: [
generatedPropertyTypes.Inheriting,
generatedPropertyTypes.Shared,
generatedPropertyTypes.VideoContainer,
],
Video: [generatedPropertyTypes.Inheriting, generatedPropertyTypes.Shared, generatedPropertyTypes.Video],
} satisfies Record<string, ConversionPropertyTypes>

function convertParsedHtmlRecursive<T>(
Expand Down
2 changes: 1 addition & 1 deletion packages/uikit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type {
RootProperties,
SvgProperties,
TextProperties,
VideoContainerProperties,
VideoProperties,
} from './components/index.js'
export * from './vanilla/index.js'
export { htmlToCode } from './convert/html/index.js'
Expand Down
8 changes: 4 additions & 4 deletions packages/uikit/src/vanilla/video.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { Image } from './image.js'
import { VideoTexture } from 'three'
import { Signal, signal } from '@preact/signals-core'
import { ImageProperties, VideoContainerProperties, updateVideoElement } from '../components/index.js'
import { ImageProperties, VideoProperties, updateVideoElement } from '../components/index.js'
import { AllOptionalProperties } from '../properties/index.js'

export class VideoContainer extends Image {
export class Video extends Image {
public readonly element: HTMLVideoElement
private readonly texture: VideoTexture
private readonly aspectRatio: Signal<number>
private readonly updateAspectRatio: () => void

constructor(
{ src, autoplay, volume, preservesPitch, playbackRate, muted, loop, ...rest }: VideoContainerProperties = {},
{ src, autoplay, volume, preservesPitch, playbackRate, muted, loop, ...rest }: VideoProperties = {},
defaultProperties?: AllOptionalProperties,
) {
const element = document.createElement('video')
Expand Down Expand Up @@ -39,7 +39,7 @@ export class VideoContainer extends Image {
muted,
loop,
...rest
}: VideoContainerProperties & ImageProperties): void {
}: VideoProperties & ImageProperties): void {
if (autoplay) {
this.element.remove()
document.body.append(this.element)
Expand Down

0 comments on commit 0c25264

Please sign in to comment.