UNPKG

@tamagui/react-native-web-lite

Version:
260 lines (259 loc) 11 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: !0 }); }, __copyProps = (to, from, except, desc) => { if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target, mod )), __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod); var Image_exports = {}; __export(Image_exports, { default: () => Image_default }); module.exports = __toCommonJS(Image_exports); var import_jsx_runtime = require("react/jsx-runtime"), React = __toESM(require("react")), import_react_native_web_internals = require("@tamagui/react-native-web-internals"), import_react_native_web_internals2 = require("@tamagui/react-native-web-internals"), import_createElement = __toESM(require("../createElement/index")), import_PixelRatio = __toESM(require("../PixelRatio/index")), import_View = __toESM(require("../View/index")), ERRORED = "ERRORED", LOADED = "LOADED", LOADING = "LOADING", IDLE = "IDLE", _filterId = 0, svgDataUriPattern = /^(data:image\/svg\+xml;utf8,)(.*)/; function createTintColorSVG(tintColor, id) { return tintColor && id != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { style: { position: "absolute", height: 0, visibility: "hidden", width: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: ( /* @ts-ignore */ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("filter", { id: `tint-${id}`, suppressHydrationWarning: !0, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("feFlood", { floodColor: `${tintColor}` }, tintColor), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("feComposite", { in2: "SourceAlpha", operator: "atop" }) ] }) ) }) }) : null; } function getFlatStyle(style, blurRadius, filterId) { var flatStyle = import_react_native_web_internals.StyleSheet.flatten(style), { filter, resizeMode, shadowOffset, tintColor } = flatStyle, filters = [], _filter = null; if (filter && filters.push(filter), blurRadius && filters.push(`blur(${blurRadius}px)`), shadowOffset) { var shadowString = (0, import_react_native_web_internals.createBoxShadowValue)(flatStyle); shadowString && filters.push(`drop-shadow(${shadowString})`); } return tintColor && filterId != null && filters.push(`url(#tint-${filterId})`), filters.length > 0 && (_filter = filters.join(" ")), delete flatStyle.blurRadius, delete flatStyle.shadowColor, delete flatStyle.shadowOpacity, delete flatStyle.shadowOffset, delete flatStyle.shadowRadius, delete flatStyle.tintColor, delete flatStyle.overlayColor, delete flatStyle.resizeMode, [ flatStyle, resizeMode, _filter, tintColor ]; } function resolveAssetDimensions(source) { if (typeof source == "number") { var { height, width } = (0, import_react_native_web_internals2.getAssetByID)(source); return { height, width }; } else if (source != null && !Array.isArray(source) && typeof source == "object") { var { height: height1, width: width1 } = source; return { height: height1, width: width1 }; } } function resolveAssetUri(source) { var uri = null; if (typeof source == "number") { var asset = (0, import_react_native_web_internals2.getAssetByID)(source), scale = asset.scales[0]; if (asset.scales.length > 1) { var preferredScale = import_PixelRatio.default.get(); scale = asset.scales.reduce(function(prev, curr) { return Math.abs(curr - preferredScale) < Math.abs(prev - preferredScale) ? curr : prev; }); } var scaleSuffix = scale !== 1 ? `@${scale}x` : ""; uri = asset ? `${asset.httpServerLocation}/${asset.name}${scaleSuffix}.${asset.type}` : ""; } else typeof source == "string" ? uri = source : source && typeof source.uri == "string" && (uri = source.uri); if (uri) { var match = uri.match(svgDataUriPattern); if (match) { var [, prefix, svg] = match, encodedSvg = encodeURIComponent(svg); return `${prefix}${encodedSvg}`; } } return uri; } var Image = /* @__PURE__ */ React.forwardRef(function(props, ref) { var { accessibilityLabel, blurRadius, defaultSource, draggable, onError, onLayout, onLoad, onLoadEnd, onLoadStart, pointerEvents, source, style, ...rest } = props; if (process.env.NODE_ENV !== "production" && props.children) throw new Error("The <Image> component cannot contain children. If you want to render content on top of the image, consider using the <ImageBackground> component or absolute positioning."); var [state, updateState] = React.useState(function() { var uri2 = resolveAssetUri(source); if (uri2 != null) { var isLoaded = import_react_native_web_internals2.ImageLoader.has(uri2); if (isLoaded) return LOADED; } return IDLE; }), [layout, updateLayout] = React.useState({}), hasTextAncestor = React.useContext(import_react_native_web_internals.TextAncestorContext), hiddenImageRef = React.useRef(null), filterRef = React.useRef(_filterId++), requestRef = React.useRef(null), shouldDisplaySource = state === LOADED || state === LOADING && defaultSource == null, [flatStyle, _resizeMode, filter, tintColor] = getFlatStyle({}, blurRadius, filterRef.current), resizeMode = props.resizeMode || _resizeMode || "cover", selectedSource = shouldDisplaySource ? source : defaultSource, displayImageUri = resolveAssetUri(selectedSource), imageSizeStyle = resolveAssetDimensions(selectedSource), backgroundImage = displayImageUri ? `url("${displayImageUri}")` : null, backgroundSize = getBackgroundSize(), hiddenImage = displayImageUri ? (0, import_createElement.default)("img", { alt: accessibilityLabel || "", style: styles.accessibilityImage$raw, draggable: draggable || !1, ref: hiddenImageRef, src: displayImageUri }) : null; function getBackgroundSize() { if (hiddenImageRef.current != null && (resizeMode === "center" || resizeMode === "repeat")) { var { naturalHeight, naturalWidth } = hiddenImageRef.current, { height, width } = layout; if (naturalHeight && naturalWidth && height && width) { var scaleFactor = Math.min(1, width / naturalWidth, height / naturalHeight), x = Math.ceil(scaleFactor * naturalWidth), y = Math.ceil(scaleFactor * naturalHeight); return `${x}px ${y}px`; } } } function handleLayout(e) { if (resizeMode === "center" || resizeMode === "repeat" || onLayout) { var { layout: layout2 } = e.nativeEvent; onLayout && onLayout(e), updateLayout(layout2); } } var uri = resolveAssetUri(source); return React.useEffect(function() { abortPendingRequest(), uri != null && (updateState(LOADING), onLoadStart && onLoadStart(), requestRef.current = import_react_native_web_internals2.ImageLoader.load(uri, function(e) { updateState(LOADED), onLoad && onLoad(e), onLoadEnd && onLoadEnd(); }, function() { updateState(ERRORED), onError && onError({ nativeEvent: { error: `Failed to load resource ${uri} (404)` } }), onLoadEnd && onLoadEnd(); })); function abortPendingRequest() { requestRef.current != null && (import_react_native_web_internals2.ImageLoader.abort(requestRef.current), requestRef.current = null); } return abortPendingRequest; }, [ uri, requestRef, updateState, onError, onLoad, onLoadEnd, onLoadStart ]), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_View.default, { ...rest, accessibilityLabel, onLayout: handleLayout, pointerEvents, ref, style: [ style, styles.root, hasTextAncestor && styles.inline, imageSizeStyle, flatStyle ], children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_View.default, { style: [ ...[].concat(styles.image), resizeModeStyles[resizeMode], { backgroundImage, filter }, backgroundSize != null && { backgroundSize } ], // @ts-ignore suppressHydrationWarning: !0 }), hiddenImage, createTintColorSVG(tintColor, filterRef.current) ] }); }); Image.displayName = "Image"; var ImageWithStatics = Image; ImageWithStatics.getSize = function(uri, success, failure) { import_react_native_web_internals2.ImageLoader.getSize(uri, success, failure); }; ImageWithStatics.prefetch = function(uri) { return import_react_native_web_internals2.ImageLoader.prefetch(uri); }; ImageWithStatics.queryCache = function(uris) { return import_react_native_web_internals2.ImageLoader.queryCache(uris); }; var styles = import_react_native_web_internals.StyleSheet.create({ root: { flexBasis: "auto", overflow: "hidden", zIndex: 0 }, inline: { display: "inline-flex" }, image: { ...import_react_native_web_internals.StyleSheet.absoluteFillObject, backgroundColor: "transparent", backgroundPosition: "center", backgroundRepeat: "no-repeat", backgroundSize: "cover", height: "100%", width: "100%", zIndex: -1 }, accessibilityImage$raw: { ...import_react_native_web_internals.StyleSheet.absoluteFillObject, height: "100%", opacity: 0, width: "100%", zIndex: -1 } }), resizeModeStyles = import_react_native_web_internals.StyleSheet.create({ center: { backgroundSize: "auto" }, contain: { backgroundSize: "contain" }, cover: { backgroundSize: "cover" }, none: { backgroundPosition: "0", backgroundSize: "auto" }, repeat: { backgroundPosition: "0", backgroundRepeat: "repeat", backgroundSize: "auto" }, stretch: { backgroundSize: "100% 100%" } }), Image_default = ImageWithStatics; //# sourceMappingURL=index.js.map