-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RNMobile] Gallery - Native gallery component draft (#18176)
* Add native gallery * Add native gallery block behind DEV flag * Refactor gallery to accept props more directly * Pass isBlockSelected prop to gallery-image * Pass isCropped prop to gallery-image * Limit displayed columns on mobile for gallery * Fix lint errors * Use renamed tiles spacing prop in native gallery component * [RNMobile] Gallery - Add append logic to MediaPlaceholder (#18262) * Add append logic to MediaPlaceholder for gallery * Fix lint errors * Add margin-bottom to tiles in native gallery * Limit displayed gallery columns to 4 for viewports < large * Fix lint * Add darkmode styles for MediaPlaceholder appender * Use child-first approach for gallery image UI components * Limit displayed columns in gallery to 4 on native * Add block-level caption to native gallery * Fix scss imports for jest * Fix lint * Use "narrow" instead of "mobile" semantics for viewport flag
- Loading branch information
Showing
5 changed files
with
163 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
packages/block-library/src/gallery/gallery-styles.native.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.galleryTilesContainerSelected { | ||
margin-bottom: 16px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { View } from 'react-native'; | ||
import { isEmpty } from 'lodash'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import GalleryImage from './gallery-image'; | ||
import { defaultColumnsNumber } from './shared'; | ||
import styles from './gallery-styles.scss'; | ||
import Tiles from './tiles'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __, sprintf } from '@wordpress/i18n'; | ||
import { Caption } from '@wordpress/block-editor'; | ||
import { useState } from '@wordpress/element'; | ||
|
||
const TILE_SPACING = 15; | ||
|
||
// we must limit displayed columns since readable content max-width is 580px | ||
const MAX_DISPLAYED_COLUMNS = 4; | ||
const MAX_DISPLAYED_COLUMNS_NARROW = 2; | ||
|
||
export const Gallery = ( props ) => { | ||
const [ isCaptionSelected, setIsCaptionSelected ] = useState( false ); | ||
|
||
const { | ||
clientId, | ||
selectedImage, | ||
mediaPlaceholder, | ||
onBlur, | ||
onMoveBackward, | ||
onMoveForward, | ||
onRemoveImage, | ||
onSelectImage, | ||
onSetImageAttributes, | ||
onFocusGalleryCaption, | ||
attributes, | ||
isSelected, | ||
isNarrow, | ||
onFocus, | ||
} = props; | ||
|
||
const { | ||
columns = defaultColumnsNumber( attributes ), | ||
imageCrop, | ||
images, | ||
} = attributes; | ||
|
||
// limit displayed columns when isNarrow is true (i.e. when viewport width is | ||
// less than "small", where small = 600) | ||
const displayedColumns = isNarrow ? | ||
Math.min( columns, MAX_DISPLAYED_COLUMNS_NARROW ) : | ||
Math.min( columns, MAX_DISPLAYED_COLUMNS ); | ||
|
||
const selectImage = ( index ) => { | ||
return () => { | ||
if ( isCaptionSelected ) { | ||
setIsCaptionSelected( false ); | ||
} | ||
// we need to fully invoke the curried function here | ||
onSelectImage( index )(); | ||
}; | ||
}; | ||
|
||
const focusGalleryCaption = () => { | ||
if ( ! isCaptionSelected ) { | ||
setIsCaptionSelected( true ); | ||
} | ||
onFocusGalleryCaption(); | ||
}; | ||
|
||
return ( | ||
<View> | ||
<Tiles | ||
columns={ displayedColumns } | ||
spacing={ TILE_SPACING } | ||
style={ isSelected ? styles.galleryTilesContainerSelected : undefined } | ||
> | ||
{ images.map( ( img, index ) => { | ||
/* translators: %1$d is the order number of the image, %2$d is the total number of images. */ | ||
const ariaLabel = sprintf( __( 'image %1$d of %2$d in gallery' ), ( index + 1 ), images.length ); | ||
|
||
return ( | ||
<GalleryImage | ||
key={ img.id || img.url } | ||
url={ img.url } | ||
alt={ img.alt } | ||
id={ img.id } | ||
isCropped={ imageCrop } | ||
isFirstItem={ index === 0 } | ||
isLastItem={ ( index + 1 ) === images.length } | ||
isSelected={ isSelected && selectedImage === index } | ||
isBlockSelected={ isSelected } | ||
onMoveBackward={ onMoveBackward( index ) } | ||
onMoveForward={ onMoveForward( index ) } | ||
onRemove={ onRemoveImage( index ) } | ||
onSelect={ selectImage( index ) } | ||
onSelectBlock={ onFocus } | ||
setAttributes={ ( attrs ) => onSetImageAttributes( index, attrs ) } | ||
caption={ img.caption } | ||
aria-label={ ariaLabel } | ||
/> | ||
); | ||
} ) } | ||
</Tiles> | ||
{ mediaPlaceholder } | ||
<Caption | ||
clientId={ clientId } | ||
isSelected={ isCaptionSelected } | ||
accessible={ true } | ||
accessibilityLabelCreator={ ( caption ) => | ||
isEmpty( caption ) ? | ||
/* translators: accessibility text. Empty gallery caption. */ | ||
( 'Gallery caption. Empty' ) : | ||
sprintf( | ||
/* translators: accessibility text. %s: gallery caption. */ | ||
__( 'Gallery caption. %s' ), | ||
caption ) | ||
} | ||
onFocus={ focusGalleryCaption } | ||
onBlur={ onBlur } // always assign onBlur as props | ||
/> | ||
</View> | ||
); | ||
}; | ||
|
||
export default Gallery; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters