summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js')
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js104
1 files changed, 104 insertions, 0 deletions
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js
new file mode 100644
index 00000000..8c56b164
--- /dev/null
+++ b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js
@@ -0,0 +1,104 @@
+/**
+ * External dependencies
+ */
+import { Component, createRef } from '@wordpress/element';
+import ResizeObserver from 'resize-observer-polyfill';
+
+/**
+ * Internal dependencies
+ */
+import Column from '../column';
+import Gallery from '../gallery';
+import Row from '../row';
+import { getGalleryRows, handleRowResize } from './resize';
+import { imagesToRatios, ratiosToColumns, ratiosToMosaicRows } from './ratios';
+
+export default class Mosaic extends Component {
+ gallery = createRef();
+ pendingRaf = null;
+ ro = null; // resizeObserver instance
+
+ componentDidMount() {
+ this.observeResize();
+ }
+
+ componentWillUnmount() {
+ this.unobserveResize();
+ }
+
+ componentDidUpdate( prevProps ) {
+ if ( prevProps.images !== this.props.images || prevProps.align !== this.props.align ) {
+ this.triggerResize();
+ } else if ( 'columns' === this.props.layoutStyle && prevProps.columns !== this.props.columns ) {
+ this.triggerResize();
+ }
+ }
+
+ handleGalleryResize = entries => {
+ if ( this.pendingRaf ) {
+ cancelAnimationFrame( this.pendingRaf );
+ this.pendingRaf = null;
+ }
+ this.pendingRaf = requestAnimationFrame( () => {
+ for ( const { contentRect, target } of entries ) {
+ const { width } = contentRect;
+ getGalleryRows( target ).forEach( row => handleRowResize( row, width ) );
+ }
+ } );
+ };
+
+ triggerResize() {
+ if ( this.gallery.current ) {
+ this.handleGalleryResize( [
+ {
+ target: this.gallery.current,
+ contentRect: { width: this.gallery.current.clientWidth },
+ },
+ ] );
+ }
+ }
+
+ observeResize() {
+ this.triggerResize();
+ this.ro = new ResizeObserver( this.handleGalleryResize );
+ if ( this.gallery.current ) {
+ this.ro.observe( this.gallery.current );
+ }
+ }
+
+ unobserveResize() {
+ if ( this.ro ) {
+ this.ro.disconnect();
+ this.ro = null;
+ }
+ if ( this.pendingRaf ) {
+ cancelAnimationFrame( this.pendingRaf );
+ this.pendingRaf = null;
+ }
+ }
+
+ render() {
+ const { align, columns, images, layoutStyle, renderedImages } = this.props;
+
+ const ratios = imagesToRatios( images );
+ const rows =
+ 'columns' === layoutStyle
+ ? ratiosToColumns( ratios, columns )
+ : ratiosToMosaicRows( ratios, { isWide: [ 'full', 'wide' ].includes( align ) } );
+
+ let cursor = 0;
+ return (
+ <Gallery galleryRef={ this.gallery }>
+ { rows.map( ( row, rowIndex ) => (
+ <Row key={ rowIndex }>
+ { row.map( ( colSize, colIndex ) => {
+ const columnImages = renderedImages.slice( cursor, cursor + colSize );
+ cursor += colSize;
+ return <Column key={ colIndex }>{ columnImages }</Column>;
+ } ) }
+ </Row>
+ ) ) }
+ </Gallery>
+ );
+ }
+}