@react-spectrum/s2
Version:
Spectrum 2 UI components in React
240 lines (226 loc) • 9.21 kB
JavaScript
require("./Image.css");
var $914a06b3a1c679bc$exports = require("./Provider.cjs");
var $a4f1585b527b9b7a$exports = require("./ImageCoordinator.cjs");
var $5eb75e0c130e0669$exports = require("../icons/Skeleton.cjs");
var $308b180f49d82d28$exports = require("../icons/runtime.cjs");
var $ac757a4c2bd72aee$exports = require("../icons/useSpectrumContextProps.cjs");
var $kwMay$reactjsxruntime = require("react/jsx-runtime");
var $kwMay$react = require("react");
var $kwMay$reactariautils = require("@react-aria/utils");
function $parcel$export(e, n, v, s) {
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
}
$parcel$export(module.exports, "ImageContext", () => $053b76ed3d29e13b$export$8151eb379fcf2442);
$parcel$export(module.exports, "Image", () => $053b76ed3d29e13b$export$3e431a229df88919);
const $053b76ed3d29e13b$export$8151eb379fcf2442 = /*#__PURE__*/ (0, $kwMay$react.createContext)(null);
function $053b76ed3d29e13b$var$createState(src) {
return {
state: 'loading',
src: src,
startTime: Date.now(),
loadTime: 0
};
}
function $053b76ed3d29e13b$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 $053b76ed3d29e13b$var$wrapperStyles = " gH1 _Nc1 Pc1";
const $053b76ed3d29e13b$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 $053b76ed3d29e13b$export$3e431a229df88919 = /*#__PURE__*/ (0, $kwMay$react.forwardRef)(function Image(props, domRef) {
[props, domRef] = (0, $ac757a4c2bd72aee$exports.useSpectrumContextProps)(props, domRef, $053b76ed3d29e13b$export$8151eb379fcf2442);
let { src: srcProp = '', styles: styles, UNSAFE_className: UNSAFE_className = '', UNSAFE_style: UNSAFE_style, renderError: renderError, group: group = (0, $a4f1585b527b9b7a$exports.DefaultImageGroup), 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, $kwMay$react.useContext)((0, $914a06b3a1c679bc$exports.ColorSchemeContext));
let cacheKey = (0, $kwMay$react.useMemo)(()=>typeof srcProp === 'object' ? JSON.stringify(srcProp) : srcProp, [
srcProp
]);
let { revealAll: revealAll, register: register, unregister: unregister, load: load } = (0, $kwMay$react.useContext)(group);
let [{ state: state, src: lastCacheKey, loadTime: loadTime }, dispatch] = (0, $kwMay$react.useReducer)($053b76ed3d29e13b$var$reducer, cacheKey, $053b76ed3d29e13b$var$createState);
if (cacheKey !== lastCacheKey && !hidden) dispatch({
type: 'update',
src: cacheKey
});
if (state === 'loaded' && revealAll && !hidden) dispatch({
type: 'revealed'
});
let imgRef = (0, $kwMay$react.useRef)(null);
(0, $kwMay$reactariautils.useLayoutEffect)(()=>{
if (hidden) return;
register(cacheKey);
return ()=>{
unregister(cacheKey);
};
}, [
hidden,
register,
unregister,
cacheKey
]);
let onLoad = (0, $kwMay$react.useCallback)(()=>{
load(cacheKey);
dispatch({
type: 'loaded'
});
}, [
load,
cacheKey
]);
let onError = (0, $kwMay$react.useCallback)(()=>{
dispatch({
type: 'error'
});
unregister(cacheKey);
}, [
unregister,
cacheKey
]);
let isSkeleton = (0, $5eb75e0c130e0669$exports.useIsSkeleton)();
let isAnimating = isSkeleton || state === 'loading' || state === 'loaded';
let animation = (0, $5eb75e0c130e0669$exports.useLoadingAnimation)(isAnimating);
(0, $kwMay$reactariautils.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, $kwMay$react.useMemo)(()=>{
let img = /*#__PURE__*/ (0, $kwMay$reactjsxruntime.jsx)("img", {
...$053b76ed3d29e13b$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: $053b76ed3d29e13b$var$imgStyles({
isRevealed: isRevealed,
isTransitioning: isTransitioning
})
});
if (Array.isArray(srcProp)) img = /*#__PURE__*/ (0, $kwMay$reactjsxruntime.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, $kwMay$reactjsxruntime.jsx)("source", {
...sourceProps,
media: `${source.media ? `${source.media} and ` : ''}(prefers-color-scheme: ${sourceColorScheme})`
}, i);
return sourceColorScheme === colorScheme ? /*#__PURE__*/ (0, $kwMay$reactjsxruntime.jsx)("source", {
...sourceProps
}, i) : null;
} else return /*#__PURE__*/ (0, $kwMay$reactjsxruntime.jsx)("source", {
...sourceProps
}, i);
}),
img
]
});
return hidden ? null : /*#__PURE__*/ (0, $kwMay$reactjsxruntime.jsxs)("div", {
ref: domRef,
slot: slot || undefined,
style: UNSAFE_style,
className: UNSAFE_className + (0, $308b180f49d82d28$exports.mergeStyles)($053b76ed3d29e13b$var$wrapperStyles, styles) + ' ' + (isAnimating ? (0, $5eb75e0c130e0669$exports.loadingStyle) : ''),
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 $053b76ed3d29e13b$var$getFetchPriorityProp(fetchPriority) {
const pieces = (0, $kwMay$react.version).split('.');
const major = parseInt(pieces[0], 10);
if (major >= 19) return {
fetchPriority: fetchPriority
};
return {
fetchpriority: fetchPriority
};
}
//# sourceMappingURL=Image.cjs.map