UNPKG

nano-jsx

Version:

SSR first, lightweight 1kB JSX library.

76 lines 2.92 kB
import { Component } from '../component.js'; import { h, strToHash } from '../core.js'; /** * A useful Image component * Add <Img lazy ..., to lazy load the img source * Add <Img width="100" height="100" ..., to specify img element's size. * Add <Img placeholder="src or element" ...., to prepare placeholder for img. */ export class Img extends Component { constructor(props) { super(props); const { src, key } = props; // id has to be unique this.id = `${strToHash(src)}-${strToHash(JSON.stringify(props))}`; if (key) this.id += `key-${key}`; // this could also be done in willMount() if (!this.state) this.setState({ isLoaded: false, image: undefined }); } didMount() { const { lazy = true, placeholder, children, key, ref, ...rest } = this.props; if (typeof lazy === 'boolean' && lazy === false) return; const observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { observer.disconnect(); this.state.image = h('img', { ...rest }); if (this.state.image.complete) { this.state.isLoaded = true; this.update(); } else { this.state.image.onload = () => { this.state.isLoaded = true; this.update(); }; } } }); }, { threshold: [0, 1] }); observer.observe(this.elements[0]); } render() { const { src, placeholder, children, lazy = true, key, ref, ...rest } = this.props; // return the img tag if not lazy loaded if (typeof lazy === 'boolean' && lazy === false) { this.state.image = h('img', { src, ...rest }); return this.state.image; } // if it is visible and loaded, show the image if (this.state.isLoaded) { return this.state.image; // if the placeholder is an image src } else if (placeholder && typeof placeholder === 'string') { return h('img', { src: placeholder, ...rest }); // if the placeholder is an JSX element } else if (placeholder && typeof placeholder === 'function') { return placeholder(); } else { // render a simple box const style = {}; if (rest.width) style.width = `${rest.width}px`; if (rest.height) style.height = `${rest.height}px`; const { width, height, ...others } = rest; return h('div', { style, ...others }); } } } //# sourceMappingURL=img.js.map