initial commit

This commit is contained in:
Rami Bitar
2026-04-13 15:34:57 -04:00
commit 9778f24862
125 changed files with 39760 additions and 0 deletions

View File

@@ -0,0 +1,231 @@
"use client";
import { Button } from "@/components/ui/button";
import {
ButtonGroup,
ButtonGroupText,
} from "@/components/ui/button-group";
import { cn } from "@/lib/utils";
import type { Experimental_SpeechResult as SpeechResult } from "ai";
import {
MediaControlBar,
MediaController,
MediaDurationDisplay,
MediaMuteButton,
MediaPlayButton,
MediaSeekBackwardButton,
MediaSeekForwardButton,
MediaTimeDisplay,
MediaTimeRange,
MediaVolumeRange,
} from "media-chrome/react";
import type { ComponentProps, CSSProperties } from "react";
export type AudioPlayerProps = Omit<
ComponentProps<typeof MediaController>,
"audio"
>;
export const AudioPlayer = ({
children,
style,
...props
}: AudioPlayerProps) => (
<MediaController
audio
data-slot="audio-player"
style={
{
"--media-background-color": "transparent",
"--media-button-icon-height": "1rem",
"--media-button-icon-width": "1rem",
"--media-control-background": "transparent",
"--media-control-hover-background": "var(--color-accent)",
"--media-control-padding": "0",
"--media-font": "var(--font-sans)",
"--media-font-size": "10px",
"--media-icon-color": "currentColor",
"--media-preview-time-background": "var(--color-background)",
"--media-preview-time-border-radius": "var(--radius-md)",
"--media-preview-time-text-shadow": "none",
"--media-primary-color": "var(--color-primary)",
"--media-range-bar-color": "var(--color-primary)",
"--media-range-track-background": "var(--color-secondary)",
"--media-secondary-color": "var(--color-secondary)",
"--media-text-color": "var(--color-foreground)",
"--media-tooltip-arrow-display": "none",
"--media-tooltip-background": "var(--color-background)",
"--media-tooltip-border-radius": "var(--radius-md)",
...style,
} as CSSProperties
}
{...props}
>
{children}
</MediaController>
);
export type AudioPlayerElementProps = Omit<ComponentProps<"audio">, "src"> &
(
| {
data: SpeechResult["audio"];
}
| {
src: string;
}
);
export const AudioPlayerElement = ({ ...props }: AudioPlayerElementProps) => (
// oxlint-disable-next-line eslint-plugin-jsx-a11y(media-has-caption) -- audio player captions are provided by consumer
<audio
data-slot="audio-player-element"
slot="media"
src={
"src" in props
? props.src
: `data:${props.data.mediaType};base64,${props.data.base64}`
}
{...props}
/>
);
export type AudioPlayerControlBarProps = ComponentProps<typeof MediaControlBar>;
export const AudioPlayerControlBar = ({
children,
...props
}: AudioPlayerControlBarProps) => (
<MediaControlBar data-slot="audio-player-control-bar" {...props}>
<ButtonGroup orientation="horizontal">{children}</ButtonGroup>
</MediaControlBar>
);
export type AudioPlayerPlayButtonProps = ComponentProps<typeof MediaPlayButton>;
export const AudioPlayerPlayButton = ({
className,
...props
}: AudioPlayerPlayButtonProps) => (
<Button asChild size="icon-sm" variant="outline">
<MediaPlayButton
className={cn("bg-transparent", className)}
data-slot="audio-player-play-button"
{...props}
/>
</Button>
);
export type AudioPlayerSeekBackwardButtonProps = ComponentProps<
typeof MediaSeekBackwardButton
>;
export const AudioPlayerSeekBackwardButton = ({
seekOffset = 10,
...props
}: AudioPlayerSeekBackwardButtonProps) => (
<Button asChild size="icon-sm" variant="outline">
<MediaSeekBackwardButton
data-slot="audio-player-seek-backward-button"
seekOffset={seekOffset}
{...props}
/>
</Button>
);
export type AudioPlayerSeekForwardButtonProps = ComponentProps<
typeof MediaSeekForwardButton
>;
export const AudioPlayerSeekForwardButton = ({
seekOffset = 10,
...props
}: AudioPlayerSeekForwardButtonProps) => (
<Button asChild size="icon-sm" variant="outline">
<MediaSeekForwardButton
data-slot="audio-player-seek-forward-button"
seekOffset={seekOffset}
{...props}
/>
</Button>
);
export type AudioPlayerTimeDisplayProps = ComponentProps<
typeof MediaTimeDisplay
>;
export const AudioPlayerTimeDisplay = ({
className,
...props
}: AudioPlayerTimeDisplayProps) => (
<ButtonGroupText asChild className="bg-transparent">
<MediaTimeDisplay
className={cn("tabular-nums", className)}
data-slot="audio-player-time-display"
{...props}
/>
</ButtonGroupText>
);
export type AudioPlayerTimeRangeProps = ComponentProps<typeof MediaTimeRange>;
export const AudioPlayerTimeRange = ({
className,
...props
}: AudioPlayerTimeRangeProps) => (
<ButtonGroupText asChild className="bg-transparent">
<MediaTimeRange
className={cn("", className)}
data-slot="audio-player-time-range"
{...props}
/>
</ButtonGroupText>
);
export type AudioPlayerDurationDisplayProps = ComponentProps<
typeof MediaDurationDisplay
>;
export const AudioPlayerDurationDisplay = ({
className,
...props
}: AudioPlayerDurationDisplayProps) => (
<ButtonGroupText asChild className="bg-transparent">
<MediaDurationDisplay
className={cn("tabular-nums", className)}
data-slot="audio-player-duration-display"
{...props}
/>
</ButtonGroupText>
);
export type AudioPlayerMuteButtonProps = ComponentProps<typeof MediaMuteButton>;
export const AudioPlayerMuteButton = ({
className,
...props
}: AudioPlayerMuteButtonProps) => (
<ButtonGroupText asChild className="bg-transparent">
<MediaMuteButton
className={cn("", className)}
data-slot="audio-player-mute-button"
{...props}
/>
</ButtonGroupText>
);
export type AudioPlayerVolumeRangeProps = ComponentProps<
typeof MediaVolumeRange
>;
export const AudioPlayerVolumeRange = ({
className,
...props
}: AudioPlayerVolumeRangeProps) => (
<ButtonGroupText asChild className="bg-transparent">
<MediaVolumeRange
className={cn("", className)}
data-slot="audio-player-volume-range"
{...props}
/>
</ButtonGroupText>
);