Skip to content

Commit

Permalink
Tiled Gallery: Increasing accessibility of gallery images with respec…
Browse files Browse the repository at this point in the history
…t to opening carousels (#37792)
  • Loading branch information
coder-karen authored Jun 19, 2024
1 parent 9882b4d commit f3abe0a
Show file tree
Hide file tree
Showing 21 changed files with 904 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: enhancement

Tiled Gallery: Increase accessibility of Tiled Gallery carousel images.
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,13 @@ import * as deprecatedV2 from './v2';
import * as deprecatedV3 from './v3';
import * as deprecatedV4 from './v4';
import * as deprecatedV5 from './v5';
import * as deprecatedV6 from './v6';

export default [ deprecatedV5, deprecatedV4, deprecatedV3, deprecatedV2, deprecatedV1 ];
export default [
deprecatedV6,
deprecatedV5,
deprecatedV4,
deprecatedV3,
deprecatedV2,
deprecatedV1,
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
export default {
align: {
type: 'string',
default: 'center',
},
className: {
type: 'string',
default: 'is-style-rectangular',
},
columns: {
type: 'number',
},
columnWidths: {
type: 'array',
default: [],
},
ids: {
type: 'array',
default: [],
},
imageFilter: {
type: 'string',
},
images: {
type: 'array',
default: [],
source: 'query',
selector: '.tiled-gallery__item',
query: {
alt: {
attribute: 'alt',
default: '',
selector: 'img',
source: 'attribute',
},
height: {
attribute: 'data-height',
type: 'number',
selector: 'img',
source: 'attribute',
},
id: {
attribute: 'data-id',
selector: 'img',
source: 'attribute',
},
link: {
attribute: 'data-link',
selector: 'img',
source: 'attribute',
},
url: {
attribute: 'data-url',
selector: 'img',
source: 'attribute',
},
width: {
attribute: 'data-width',
selector: 'img',
source: 'attribute',
type: 'number',
},
},
},
imageCrop: {
type: 'boolean',
default: true,
},
linkTo: {
default: 'none',
type: 'string',
},
roundedCorners: {
type: 'integer',
default: 0,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const ALLOWED_MEDIA_TYPES = [ 'image' ];
export const DEFAULT_GALLERY_WIDTH = 580;
export const GUTTER_WIDTH = 4;
export const MAX_COLUMNS = 20;
export const MAX_ROUNDED_CORNERS = 20;
export const PHOTON_MAX_RESIZE = 2000;

/**
* Layouts
*/
export const LAYOUT_CIRCLE = 'circle';
export const LAYOUT_COLUMN = 'columns';
export const LAYOUT_DEFAULT = 'rectangular';
export const LAYOUT_SQUARE = 'square';
export const LAYOUT_STYLES = [
{
isDefault: true,
name: LAYOUT_DEFAULT,
},
{
name: LAYOUT_CIRCLE,
},
{
name: LAYOUT_SQUARE,
},
{
name: LAYOUT_COLUMN,
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { isBlobURL } from '@wordpress/blob';
import clsx from 'clsx';

export default function GalleryImageSave( props ) {
const { alt, imageFilter, height, id, link, linkTo, origUrl, url, width } = props;

if ( isBlobURL( origUrl ) ) {
return null;
}

let href;

switch ( linkTo ) {
case 'media':
href = origUrl;
break;
case 'attachment':
href = link;
break;
}

const img = (
<img
alt={ alt }
data-height={ height }
data-id={ id }
data-link={ link }
data-url={ origUrl }
data-width={ width }
src={ url }
data-amp-layout={ 'responsive' }
/>
);

return (
<figure
className={ clsx( 'tiled-gallery__item', {
[ `filter__${ imageFilter }` ]: !! imageFilter,
} ) }
>
{ href ? <a href={ href }>{ img }</a> : img }
</figure>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as attributes } from './attributes';
export { default as supports } from './supports';
export { default as save } from './save';
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function Column( { children, width } ) {
// This deprecation fixes inconsistent precision of flex-basis style decimal.
// It needs to be adjusted here so that the style value matches the post
// content to then trigger re-saving the block.
const precision = Math.pow( 10, 12 ); // 1000000000000.
const roundedWidth = Math.round( width * precision ) / precision;
const style = width ? { flexBasis: `${ roundedWidth }%` } : undefined;

return (
<div className="tiled-gallery__col" style={ style }>
{ children }
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Gallery( { children, galleryRef } ) {
return (
<div className="tiled-gallery__gallery" ref={ galleryRef }>
{ children }
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Component } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import clsx from 'clsx';
import { LAYOUT_CIRCLE, MAX_ROUNDED_CORNERS } from '../constants';
import GalleryImageSave from '../gallery-image/save';
import { isSquareishLayout, photonizedImgProps } from '../utils';
import Mosaic from './mosaic';
import Square from './square';

export default class Layout extends Component {
// This is tricky:
// - We need to "photonize" to resize the images at appropriate dimensions
// - The resize will depend on the image size and the layout in some cases
// - Handlers need to be created by index so that the image changes can be applied correctly.
// This is because the images are stored in an array in the block attributes.
renderImage( img, i ) {
const {
columns,
imageFilter,
images,
isSave,
linkTo,
layoutStyle,
onMoveBackward,
onMoveForward,
onRemoveImage,
onSelectImage,
selectedImage,
setImageAttributes,
} = this.props;

const ariaLabel = sprintf(
/* translators: %1$d is the order number of the image, %2$d is the total number of images. */
__( 'image %1$d of %2$d in gallery', 'jetpack' ),
i + 1,
images.length
);

const { src, srcSet } = photonizedImgProps( img, { layoutStyle } );

return (
<GalleryImageSave
alt={ img.alt }
aria-label={ ariaLabel }
columns={ columns }
height={ img.height }
id={ img.id }
imageFilter={ imageFilter }
isFirstItem={ i === 0 }
isLastItem={ i + 1 === images.length }
isSelected={ selectedImage === i }
key={ i }
link={ img.link }
linkTo={ linkTo }
onMoveBackward={ isSave ? undefined : onMoveBackward( i ) }
onMoveForward={ isSave ? undefined : onMoveForward( i ) }
onRemove={ isSave ? undefined : onRemoveImage( i ) }
onSelect={ isSave ? undefined : onSelectImage( i ) }
origUrl={ img.url }
setAttributes={ isSave ? undefined : setImageAttributes( i ) }
showMovers={ images.length > 1 }
srcSet={ srcSet }
url={ src }
width={ img.width }
/>
);
}

render() {
const {
align,
children,
className,
columns,
images,
layoutStyle,
roundedCorners,
onResize,
isSave,
columnWidths,
} = this.props;
const LayoutRenderer = isSquareishLayout( layoutStyle ) ? Square : Mosaic;
const renderedImages = this.props.images.map( this.renderImage, this );
const roundedCornersValue =
layoutStyle !== LAYOUT_CIRCLE ? Math.min( roundedCorners, MAX_ROUNDED_CORNERS ) : 0;

return (
<div
className={ clsx( className, {
[ `has-rounded-corners-${ roundedCornersValue }` ]: roundedCornersValue > 0,
} ) }
>
<LayoutRenderer
align={ align }
columns={ columns }
columnWidths={ isSave ? columnWidths : undefined }
images={ images }
layoutStyle={ layoutStyle }
renderedImages={ renderedImages }
onResize={ isSave ? undefined : onResize }
/>
{ children }
</div>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Component, createRef } from '@wordpress/element';
import Column from '../column';
import Gallery from '../gallery';
import Row from '../row';
import { imagesToRatios, ratiosToColumns, ratiosToMosaicRows } from './ratios';

export default class Mosaic extends Component {
gallery = createRef();
pendingRaf = null;

render() {
const { align, columns, images, layoutStyle, renderedImages, columnWidths } = 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 } width={ columnWidths?.[ rowIndex ]?.[ colIndex ] }>
{ columnImages }
</Column>
);
} ) }
</Row>
) ) }
</Gallery>
);
}
}
Loading

0 comments on commit f3abe0a

Please sign in to comment.