@nvq/flowtoken
Version:
Animated React components for streaming text and markdown with GitHub theme syntax highlighting (forked from flowtoken)
30 lines (29 loc) • 1.87 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importDefault(require("react"));
const AnimatedImage = ({ src, alt, animation, animationDuration, animationTimingFunction, animationIterationCount, height, width, objectFit = 'contain' // Default to 'contain' to maintain aspect ratio
}) => {
const [isLoaded, setIsLoaded] = react_1.default.useState(false);
// Base styles that apply both before and after loading
const baseStyle = {
height: height || 'auto',
width: width || 'auto',
objectFit: objectFit, // This maintains aspect ratio
maxWidth: '100%', // Ensure image doesn't overflow container
};
const imageStyle = isLoaded ? Object.assign(Object.assign({}, baseStyle), { animationName: animation, animationDuration: animationDuration, animationTimingFunction: animationTimingFunction, animationIterationCount: animationIterationCount, whiteSpace: 'pre-wrap' }) : Object.assign(Object.assign({}, baseStyle), { opacity: 0.0, backgroundColor: '#f0f0f0' });
return (react_1.default.createElement("img", { src: src, alt: alt, onLoad: () => setIsLoaded(true), style: imageStyle }));
};
// メモ化:同じsrcの場合は再レンダリングを防ぐ
exports.default = react_1.default.memo(AnimatedImage, (prevProps, nextProps) => {
return prevProps.src === nextProps.src &&
prevProps.alt === nextProps.alt &&
prevProps.animation === nextProps.animation &&
prevProps.animationDuration === nextProps.animationDuration &&
prevProps.animationTimingFunction === nextProps.animationTimingFunction &&
prevProps.height === nextProps.height &&
prevProps.width === nextProps.width;
});