UNPKG

@react-spectrum/s2

Version:
234 lines (222 loc) 9.39 kB
import "./Image.css"; import {ColorSchemeContext as $9affbfa4e13b9582$export$374e0245597d19a3} from "./Provider.mjs"; import {DefaultImageGroup as $4b5e069e9e001e8b$export$a37e899304e5fef0} from "./ImageCoordinator.mjs"; import {loadingStyle as $5ad421ec19460c48$export$d2353276f167b21f, useIsSkeleton as $5ad421ec19460c48$export$4f8dc7555740235c, useLoadingAnimation as $5ad421ec19460c48$export$6b288fe07640c94c} from "../icons/Skeleton.mjs"; import {mergeStyles as $feb886035e0d4633$export$e618dc39ac9ad607} from "../icons/runtime.mjs"; import {useSpectrumContextProps as $5ce63c423902f47d$export$764f6146fadd77f7} from "../icons/useSpectrumContextProps.mjs"; import {jsx as $5AH9h$jsx, jsxs as $5AH9h$jsxs} from "react/jsx-runtime"; import {createContext as $5AH9h$createContext, forwardRef as $5AH9h$forwardRef, useContext as $5AH9h$useContext, useMemo as $5AH9h$useMemo, useReducer as $5AH9h$useReducer, useRef as $5AH9h$useRef, useCallback as $5AH9h$useCallback, version as $5AH9h$version} from "react"; import {useLayoutEffect as $5AH9h$useLayoutEffect} from "@react-aria/utils"; const $dbd6f0b2503b938c$export$8151eb379fcf2442 = /*#__PURE__*/ (0, $5AH9h$createContext)(null); function $dbd6f0b2503b938c$var$createState(src) { return { state: 'loading', src: src, startTime: Date.now(), loadTime: 0 }; } function $dbd6f0b2503b938c$var$reducer(state, action) { switch(action.type){ case 'update': return { state: 'loading', src: action.src, startTime: Date.now(), loadTime: 0 }; case 'loaded': case 'error': return { ...state, state: action.type }; case 'revealed': return { ...state, state: 'revealed', loadTime: Date.now() - state.startTime }; default: return state; } } const $dbd6f0b2503b938c$var$wrapperStyles = " gH1 _Nc1 Pc1"; const $dbd6f0b2503b938c$var$imgStyles = function anonymous(props) { let rules = " "; rules += ' sb1'; rules += ' Za1'; rules += ' Fb1'; rules += ' _H40ub4c1'; rules += ' __D40ub4c1'; if (props.isRevealed) rules += ' _Ib1'; else rules += ' _Ia1'; if (props.isTransitioning) rules += ' Yf1'; else rules += ' Ye1'; rules += ' Xe1'; if (props.isTransitioning) rules += ' _2b1'; else rules += ' _2b1'; return rules; }; const $dbd6f0b2503b938c$export$3e431a229df88919 = /*#__PURE__*/ (0, $5AH9h$forwardRef)(function Image(props, domRef) { [props, domRef] = (0, $5ce63c423902f47d$export$764f6146fadd77f7)(props, domRef, $dbd6f0b2503b938c$export$8151eb379fcf2442); let { src: srcProp = '', styles: styles, UNSAFE_className: UNSAFE_className = '', UNSAFE_style: UNSAFE_style, renderError: renderError, group: group = (0, $4b5e069e9e001e8b$export$a37e899304e5fef0), alt: // TODO // srcSet, // sizes, alt, crossOrigin: crossOrigin, decoding: decoding, fetchPriority: fetchPriority, loading: loading, referrerPolicy: referrerPolicy, slot: slot, width: width, height: height, itemProp: itemProp } = props; let hidden = props.hidden; let colorScheme = (0, $5AH9h$useContext)((0, $9affbfa4e13b9582$export$374e0245597d19a3)); let cacheKey = (0, $5AH9h$useMemo)(()=>typeof srcProp === 'object' ? JSON.stringify(srcProp) : srcProp, [ srcProp ]); let { revealAll: revealAll, register: register, unregister: unregister, load: load } = (0, $5AH9h$useContext)(group); let [{ state: state, src: lastCacheKey, loadTime: loadTime }, dispatch] = (0, $5AH9h$useReducer)($dbd6f0b2503b938c$var$reducer, cacheKey, $dbd6f0b2503b938c$var$createState); if (cacheKey !== lastCacheKey && !hidden) dispatch({ type: 'update', src: cacheKey }); if (state === 'loaded' && revealAll && !hidden) dispatch({ type: 'revealed' }); let imgRef = (0, $5AH9h$useRef)(null); (0, $5AH9h$useLayoutEffect)(()=>{ if (hidden) return; register(cacheKey); return ()=>{ unregister(cacheKey); }; }, [ hidden, register, unregister, cacheKey ]); let onLoad = (0, $5AH9h$useCallback)(()=>{ load(cacheKey); dispatch({ type: 'loaded' }); }, [ load, cacheKey ]); let onError = (0, $5AH9h$useCallback)(()=>{ dispatch({ type: 'error' }); unregister(cacheKey); }, [ unregister, cacheKey ]); let isSkeleton = (0, $5ad421ec19460c48$export$4f8dc7555740235c)(); let isAnimating = isSkeleton || state === 'loading' || state === 'loaded'; let animation = (0, $5ad421ec19460c48$export$6b288fe07640c94c)(isAnimating); (0, $5AH9h$useLayoutEffect)(()=>{ if (hidden) return; // In React act environments, run immediately. // @ts-ignore let isTestEnv = typeof IS_REACT_ACT_ENVIRONMENT === 'boolean' ? IS_REACT_ACT_ENVIRONMENT : typeof jest !== 'undefined'; let runTask = isTestEnv ? (fn)=>fn() : queueMicrotask; // If the image is already loaded, update state immediately instead of waiting for onLoad. let img = imgRef.current; if (state === 'loading' && img?.complete) { if (img.naturalWidth === 0 && img.naturalHeight === 0) // Queue a microtask so we don't hit React's update limit. // TODO: is this necessary? runTask(onError); else runTask(onLoad); } animation(domRef.current); }); if (props.alt == null && process.env.NODE_ENV !== 'production') console.warn('The `alt` prop was not provided to an image. Add `alt` text for screen readers, or set `alt=""` prop to indicate that the image is decorative or redundant with displayed text and should not be announced by screen readers.'); let errorState = !isSkeleton && state === 'error' && renderError?.(); let isRevealed = state === 'revealed' && !isSkeleton; let isTransitioning = isRevealed && loadTime > 200; return (0, $5AH9h$useMemo)(()=>{ let img = /*#__PURE__*/ (0, $5AH9h$jsx)("img", { ...$dbd6f0b2503b938c$var$getFetchPriorityProp(fetchPriority), src: typeof srcProp === 'string' && srcProp ? srcProp : undefined, alt: alt, crossOrigin: crossOrigin, decoding: decoding, loading: loading, referrerPolicy: referrerPolicy, width: width, height: height, ref: imgRef, itemProp: itemProp, onLoad: onLoad, onError: onError, className: $dbd6f0b2503b938c$var$imgStyles({ isRevealed: isRevealed, isTransitioning: isTransitioning }) }); if (Array.isArray(srcProp)) img = /*#__PURE__*/ (0, $5AH9h$jsxs)("picture", { className: " _H40ub4c1 __D40ub4c1", children: [ srcProp.map((source, i)=>{ let { colorScheme: sourceColorScheme, ...sourceProps } = source; if (sourceColorScheme) { if (!colorScheme || colorScheme === 'light dark') return /*#__PURE__*/ (0, $5AH9h$jsx)("source", { ...sourceProps, media: `${source.media ? `${source.media} and ` : ''}(prefers-color-scheme: ${sourceColorScheme})` }, i); return sourceColorScheme === colorScheme ? /*#__PURE__*/ (0, $5AH9h$jsx)("source", { ...sourceProps }, i) : null; } else return /*#__PURE__*/ (0, $5AH9h$jsx)("source", { ...sourceProps }, i); }), img ] }); return hidden ? null : /*#__PURE__*/ (0, $5AH9h$jsxs)("div", { ref: domRef, slot: slot || undefined, style: UNSAFE_style, className: UNSAFE_className + (0, $feb886035e0d4633$export$e618dc39ac9ad607)($dbd6f0b2503b938c$var$wrapperStyles, styles) + ' ' + (isAnimating ? (0, $5ad421ec19460c48$export$d2353276f167b21f) : ''), children: [ errorState, !errorState && img ] }); }, [ slot, hidden, domRef, UNSAFE_style, UNSAFE_className, styles, isAnimating, errorState, alt, crossOrigin, decoding, fetchPriority, loading, referrerPolicy, width, height, onLoad, onError, isRevealed, isTransitioning, srcProp, itemProp, colorScheme ]); }); function $dbd6f0b2503b938c$var$getFetchPriorityProp(fetchPriority) { const pieces = (0, $5AH9h$version).split('.'); const major = parseInt(pieces[0], 10); if (major >= 19) return { fetchPriority: fetchPriority }; return { fetchpriority: fetchPriority }; } export {$dbd6f0b2503b938c$export$8151eb379fcf2442 as ImageContext, $dbd6f0b2503b938c$export$3e431a229df88919 as Image}; //# sourceMappingURL=Image.mjs.map