react-vite-themes
Version:
A test/experimental React theme system created for learning purposes. Features atomic design components, SCSS variables, and dark/light theme support. Not intended for production use.
49 lines (48 loc) • 3.12 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { useState } from 'react';
import { cn } from '../../../utils';
export const Image = ({ src, alt = '', variant = 'default', size = 'md', style = 'natural', isRounded = false, isResponsive = false, isLoading = false, isHoverable = true, noBorder = false, fallback, overlay = 'none', overlayOpacity = 0.5, label, labelPosition = 'bottom', labelColor, labelBackground, labelPadding, onClick, className, ...props }) => {
const [imageState, setImageState] = useState(isLoading ? 'loading' : 'loaded');
const handleLoad = () => {
setImageState('loaded');
};
const handleError = () => {
setImageState('error');
};
const imageClasses = cn('image', `image--${variant}`, `image--${size}`, `image--${style}`, isRounded && 'image--rounded', isResponsive && 'image--responsive', imageState === 'loading' && 'image--loading', imageState === 'error' && 'image--error', isHoverable && 'image--hoverable', noBorder && 'image--no-border', overlay !== 'none' && 'image--with-overlay', label && 'image--with-label', onClick && 'image--clickable', className);
if (imageState === 'error' && fallback) {
return (_jsx("div", { className: imageClasses, ...props, children: _jsx("div", { className: "image__fallback", children: typeof fallback === 'string' ? (_jsx("img", { src: fallback, alt: alt })) : (fallback) }) }));
}
// Generate overlay styles
const getOverlayStyle = () => {
if (overlay === 'none')
return {};
let backgroundColor = '';
if (overlay === 'black') {
backgroundColor = `rgba(0, 0, 0, ${overlayOpacity})`;
}
else if (overlay === 'white') {
backgroundColor = `rgba(255, 255, 255, ${overlayOpacity})`;
}
else if (overlay === 'gradient') {
backgroundColor = `linear-gradient(45deg, rgba(0, 0, 0, ${overlayOpacity}), rgba(0, 0, 0, ${overlayOpacity * 0.7}))`;
}
else {
// Custom color
backgroundColor = overlay.includes('rgba') ? overlay : `rgba(${overlay}, ${overlayOpacity})`;
}
return { background: backgroundColor };
};
// Generate label styles
const getLabelStyle = () => {
const styles = {};
if (labelColor)
styles.color = labelColor;
if (labelBackground)
styles.backgroundColor = labelBackground;
if (labelPadding)
styles.padding = labelPadding;
return styles;
};
return (_jsxs("div", { className: imageClasses, onClick: onClick, ...props, children: [imageState === 'loading' && (_jsx("div", { className: "image__loading", children: _jsx("div", { className: "image__spinner" }) })), _jsx("img", { src: src, alt: alt, onLoad: handleLoad, onError: handleError, className: "image__element" }), overlay !== 'none' && (_jsx("div", { className: "image__overlay", style: getOverlayStyle() })), label && (_jsx("div", { className: cn('image__label', `image__label--${labelPosition}`), style: getLabelStyle(), children: label }))] }));
};