/** * React Fabric * @version 1.0.0 * @license MIT * @copyright 2024 Adarsh Pastakia * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import { cn, getImageColorset } from "@react-fabric/utilities"; import { Fragment, useRef, useState } from "react"; import { usePropWatcher } from "../../hooks/usePropState"; import type { CssProp, TestProps } from "../../types"; import { Button } from "../button/Button"; import { Icon } from "../icon/Icon"; export interface BaseProps extends CssProp, TestProps { /** * media source */ src: string; /** * show media reel decoration */ reel?: boolean; /** * media content fit */ fit?: "cover" | "contain" | "fill"; } const cover = { fill: "object-fill", cover: "object-cover", contain: "object-contain", }; export interface ImageProps extends BaseProps { /** * image alt text */ alt?: string; } export interface VideoProps extends BaseProps { /** * video poster */ poster?: string; /** * auto play video */ autoPlay?: boolean; /** * play on mouse over */ playOnHover?: boolean; } const loadIndicator = (
); /** * Component for displaying images with optional reel decoration. * A versatile media component that supports images and videos with various display options. * It can display images with a reel decoration, handle loading states, and show error icons if the media fails to load. * This component is useful for displaying images in a visually appealing way, with support for lazy loading and error handling. * It automatically adjusts the display based on the provided fit property, allowing for different styles such as cover, contain, or fill. * * @example * ```jsx * Example Image * // Renders an image with reel decoration, cover fit, and a custom class name. * ``` */ export function Image({ src, alt, reel, fit = "cover", className, ...aria }: ImageProps) { const [colorSet, setColorSet] = useState("light"); const [loaded, setLoaded] = usePropWatcher(false, src); const [errored, setErrored] = usePropWatcher(false, src); return (
{!loaded && !errored && loadIndicator} {!errored && ( {alt { setLoaded(true); setColorSet(getImageColorset(e.currentTarget)); }} onError={() => setErrored(true)} /> )} {errored && ( )}
); } /** * Component for displaying videos with optional controls and reel decoration. * A versatile video component that supports autoplay, hover play, and various display options. * It can display videos with a reel decoration, handle loading states, and show error icons if the video fails to load. * This component is useful for displaying videos in a visually appealing way, with support for controls, autoplay, and error handling. * It automatically adjusts the display based on the provided fit property, allowing for different styles such as cover, contain, or fill. * It also includes controls for play/pause and volume, enhancing user interaction with the video content. * This component is ideal for media-rich applications where video content needs to be displayed with user-friendly controls and visual effects. * It supports features like autoplay, play on hover, and custom fit options for the video display. * It also includes a reel decoration for a more engaging visual presentation. * * @example * ```jsx *