playback-control

PreviousNext
Docs
limeplayui

Preview

Loading preview…
registry/default/ui/playback-control.tsx
"use client"

import { Slot } from "@radix-ui/react-slot"
import * as React from "react"

import { Button } from "@/components/ui/button"
import { MediaReadyState, usePlayer } from "@/registry/default/hooks/use-player"
import { useMediaStore } from "@/registry/default/ui/media-provider"

export type PlaybackControlPropsDocs = Pick<
  PlaybackControlProps,
  "asChild" | "shortcut"
>

interface PlaybackControlProps extends React.ComponentProps<typeof Button> {
  /**
   * Render as child component using Radix Slot
   * @default false
   */
  asChild?: boolean
  /**
   * Keyboard shortcut hint displayed in aria-label
   * @example "Space"
   */
  shortcut?: string
}

export const PlaybackControl = React.forwardRef<
  HTMLButtonElement,
  PlaybackControlProps
>((props, forwardedRef) => {
  const status = useMediaStore((state) => state.status)
  const readyState = useMediaStore((state) => state.readyState)
  const { togglePaused } = usePlayer()

  const {
    "aria-label": ariaLabelProp,
    asChild = false,
    children,
    disabled: userDisabled,
    onClick,
    shortcut,
    ...restProps
  } = props

  const Comp = asChild ? Slot : Button

  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    onClick?.(event)
    if (!event.defaultPrevented) {
      togglePaused()
    }
  }

  const isDisabled =
    readyState < MediaReadyState.HAVE_CURRENT_DATA ||
    status === "buffering" ||
    userDisabled

  const getDefaultAriaLabel = () => {
    const shortcutText = shortcut ? ` (keyboard shortcut ${shortcut})` : ""
    const labels = {
      default: "Play",
      ended: "Replay",
      playing: "Pause",
    }

    const label =
      status === "ended"
        ? labels.ended
        : status === "playing"
          ? labels.playing
          : labels.default
    return `${label}${shortcutText}`
  }

  return (
    <Comp
      aria-keyshortcuts={shortcut}
      aria-label={ariaLabelProp ?? getDefaultAriaLabel()}
      data-label="lp-playback-control"
      disabled={isDisabled}
      {...restProps}
      onClick={handleClick}
      ref={forwardedRef}
    >
      {children}
    </Comp>
  )
})

PlaybackControl.displayName = "PlaybackControl"

Installation

npx shadcn@latest add @limeplay/playback-control

Usage

import { PlaybackControl } from "@/components/ui/playback-control"
<PlaybackControl />