UNPKG

koval-ui

Version:

React components collection with minimalistic design. Supports theming, layout, and input validation.

1 lines 12.3 kB
{"version":3,"file":"Audio.cjs","sources":["../../../../src/lib/Audio/Audio.tsx"],"sourcesContent":["import type {ReactNode, SyntheticEvent} from 'react';\nimport {forwardRef, useMemo, useState} from 'react';\nimport classNames from 'classnames';\nimport {useLocalTheme} from 'css-vars-hook';\n\nimport {Picture} from '@/lib';\nimport {\n IconPlay,\n IconPause,\n IconVolume,\n IconVolumeOff,\n IconAudio,\n IconDownloadVideo,\n} from '@/internal/Icons';\nimport {useInternalRef} from '@/internal/hooks/useInternalRef.ts';\nimport type {DataAttributes, LibraryProps} from '@/internal/LibraryAPI';\nimport type {Source} from '@/internal/MediaEmbeds';\nimport {\n PlayModes,\n usePlay,\n getFileName,\n useLoadingState,\n getFormattedTime,\n useTime,\n useSound,\n} from '@/internal/MediaEmbeds';\nimport rangeInputClasses from '@/internal/MediaEmbeds/RangeInput.module.css';\n\nimport classes from './Audio.module.css';\n\ntype Element = HTMLAudioElement;\n\nexport type Props = DataAttributes &\n LibraryProps & {\n /**\n * A URL for an image to be shown left to audio controls.\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio#poster\n */\n poster?: string;\n /**\n * Set a callback to run when the audio is buffered enough to play on the user side\n */\n onReady?: (event: SyntheticEvent<Element>) => void;\n /**\n * Set a callback to capture audio errors\n */\n onError?: (event: SyntheticEvent<Element>) => void;\n /**\n * Set a callback to run when the user plays the audio\n */\n onPlay?: (event: SyntheticEvent<Element>) => void;\n /**\n * Set a callback to run when the user pauses the audio\n */\n onPause?: (event: SyntheticEvent<Element>) => void;\n /**\n * Provide audio file url\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio\n */\n src?: string;\n /**\n * Provide audio sources configs array. An advanced alternative to `src` prop\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio\n */\n sources?: Source[];\n /**\n * Provide a title for the audio\n */\n title?: string;\n children?: ReactNode;\n };\n\nexport const Audio = forwardRef<HTMLAudioElement, Props>(\n (\n {\n children,\n className,\n onReady = () => {},\n onPlay = () => {},\n onPause = () => {},\n onError = () => {},\n src,\n poster,\n title,\n sources = [],\n ...nativeProps\n },\n refProp\n ) => {\n const embedRef = useInternalRef(refProp);\n\n const [duration, setDuration] = useState(0);\n\n const {handleLoadedMetaData, handleError, handleCanPlay, readyToPlay} = useLoadingState({\n embedRef,\n onError,\n onReady,\n setDuration,\n });\n\n const {handlePlay, handleTogglePlay, handlePause, playMode} = usePlay({\n embedRef,\n onPlay,\n onPause,\n });\n\n const {handleSetTime, currentTime} = useTime({embedRef, playMode});\n\n const {volume, handleSetVolume, muted, handleToggleMuted} = useSound({\n embedRef,\n mutedProp: false,\n });\n\n const {LocalRoot} = useLocalTheme();\n\n const theme = useMemo(() => ({background: `url(${poster})`}), [poster]);\n\n const PlayIcon =\n playMode === PlayModes.pause || playMode === PlayModes.pristine ? IconPlay : IconPause;\n\n return (\n <LocalRoot\n {...nativeProps}\n theme={theme}\n className={classNames(classes.wrapper, className)}>\n <div className={classes.title}>\n <IconAudio className={classes.icon} />\n <span className={classes.text}>\n {title || getFileName(embedRef.current?.currentSrc)}\n </span>\n <a\n className={classes.download}\n href={embedRef.current?.currentSrc}\n download={getFileName(embedRef.current?.currentSrc)}>\n <IconDownloadVideo />\n </a>\n </div>\n <div className={classNames(classes.audio, {[classes.noPoster]: !poster})}>\n {poster && (\n <Picture className={classes.poster} src={poster} height={111} width={111} />\n )}\n <div className={classes.playWrapper}>\n <button\n onClick={handleTogglePlay}\n className={classNames(classes.playControl, {\n [classes.loading]: !readyToPlay,\n })}>\n <PlayIcon className={classes.icon} />\n </button>\n </div>\n <div className={classes.rangeControls}>\n <div className={classes.control}>\n <div className={classes.time}>\n {getFormattedTime(currentTime)}/{getFormattedTime(duration)}\n </div>\n <div className={classes.volumeControl}>\n <button className={classes.mutedButton} onClick={handleToggleMuted}>\n {muted ? (\n <IconVolumeOff className={classes.volumeIcon} />\n ) : (\n <IconVolume className={classes.volumeIcon} />\n )}\n </button>\n <input\n min={0}\n max={1}\n step={0.01}\n type=\"range\"\n value={muted ? 0 : volume}\n onChange={handleSetVolume}\n className={classNames(\n rangeInputClasses.range,\n classes.volumeInput\n )}\n />\n </div>\n </div>\n <div className={classes.control}>\n <input\n onChange={handleSetTime}\n value={currentTime}\n type=\"range\"\n className={classNames(\n rangeInputClasses.range,\n classes.navigationInput\n )}\n name=\"seek\"\n min={0}\n max={duration}\n step={1}\n />\n </div>\n </div>\n <audio\n className={classes.nativePlayer}\n ref={embedRef}\n src={src}\n onPlay={handlePlay}\n onPause={handlePause}\n onLoadedMetadata={handleLoadedMetaData}\n onCanPlay={handleCanPlay}\n onError={handleError}\n muted={muted}>\n {sources.map(({src, type, mediaCondition}) => {\n return (\n <source key={src} src={src} type={type} media={mediaCondition} />\n );\n })}\n </audio>\n {children}\n </div>\n </LocalRoot>\n );\n }\n);\n\nAudio.displayName = 'Audio';\n"],"names":["Audio","forwardRef","children","className","onReady","onPlay","onPause","onError","src","poster","title","sources","nativeProps","refProp","embedRef","useInternalRef","duration","setDuration","useState","handleLoadedMetaData","handleError","handleCanPlay","readyToPlay","useLoadingState","handlePlay","handleTogglePlay","handlePause","playMode","usePlay","handleSetTime","currentTime","useTime","volume","handleSetVolume","muted","handleToggleMuted","useSound","LocalRoot","useLocalTheme","theme","useMemo","PlayIcon","PlayModes","IconPlay","IconPause","jsxs","classNames","classes","jsx","IconAudio","getFileName","_a","_b","_c","IconDownloadVideo","Picture","getFormattedTime","IconVolumeOff","IconVolume","rangeInputClasses","type","mediaCondition"],"mappings":"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"}