{"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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"}