@wonderflow/react-components
Version:
UI components from Wonderflow's Wanda design system
54 lines (53 loc) • 2.78 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
/*
* Copyright 2023-2025 Wonderflow Design Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { forwardRef, useEffect, useState, } from 'react';
import { AspectRatio, Grid, Skeleton, } from '../../..';
import * as styles from './product-card-media.module.css';
export const ProductCardMedia = forwardRef(({ source = [], ratio = '1', isLoading = false, className, style, ...otherProps }, forwardedRef) => {
const [imgs, setImgs] = useState([]);
useEffect(() => {
const preloadImage = async (url) => new Promise((resolve) => {
const img = new Image();
const placeholder = 'https://wonderimages.gumlet.io/placeholders/image-placeholder.png';
img.src = url;
img.onload = () => resolve(url);
img.onerror = () => resolve(placeholder);
img.onabort = () => resolve(placeholder);
});
const images = source.slice(0, 4).map(async (s) => preloadImage(s));
Promise.all(images)
.then((urls) => {
const t = urls.map((el, i) => ({
row: i < 2 ? '1' : '2',
col: i % 2 === 0 ? '1' : '2',
val: el,
}));
if (t.length === 3)
t[1].row = '1 / 3';
setImgs(t);
})
// eslint-disable-next-line no-console
.catch(err => console.error(err));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
if (source.length === 0)
return null;
return (_jsx("div", { ref: forwardedRef, className: className, style: { ...style }, ...otherProps, children: _jsx(AspectRatio, { ratio: ratio, children: isLoading
? (_jsx(Skeleton, { style: { borderRadius: '0', lineHeight: '2rem' }, width: "inherit", height: "inherit" }))
: (_jsx(Grid, { "aria-label": "", rows: imgs.length > 2 ? 2 : 1, rowMinHeight: "1fr", columns: imgs.length > 2 ? 2 : 1, colMinWidth: "1fr", children: imgs.map((el) => (_jsx(Grid.Item, { className: styles.Image, row: el.row, column: el.col, style: { backgroundImage: `url("${el.val}")` } }, `${el.val}-${el.row}-${el.col}`))) })) }) }));
});
ProductCardMedia.displayName = 'ProductCardMedia';