Skip to content

Commit

Permalink
Add preview mode
Browse files Browse the repository at this point in the history
  • Loading branch information
t-hamano committed Oct 15, 2023
1 parent b7d8148 commit 991f1a3
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 26 deletions.
85 changes: 85 additions & 0 deletions src/block-edit-preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import {
RichText,
useBlockProps,
// @ts-ignore: has no exported member
__experimentalGetElementClassName,
// @ts-ignore: has no exported member
__experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import type { BlockEditProps } from '@wordpress/blocks';

/**
* Internal dependencies
*/
import type { BlockAttributes } from './types';

export default function BlockEditPreview( { attributes }: BlockEditProps< BlockAttributes > ) {
const { url, alt, caption, align, width, height, aspectRatio, scale, id, sizeSlug, sources } =
attributes;

const borderProps = getBorderClassesAndStyles( attributes );

const filteredSources = sources.filter( ( { srcset, mediaType, mediaValue } ) => {
return srcset && mediaType && mediaValue;
} );

const classes = classnames( {
[ `align${ align }` ]: align,
[ `size-${ sizeSlug }` ]: sizeSlug,
'is-resized': width || height,
'has-custom-border':
!! borderProps.className ||
( borderProps.style && Object.keys( borderProps.style ).length > 0 ),
} );

const imageClasses = classnames( borderProps.className, {
[ `wp-image-${ id }` ]: !! id,
} );

const blockProps = useBlockProps( {
className: classes,
} );

return (
<figure { ...blockProps }>
<picture>
{ filteredSources.length > 0 &&
filteredSources.map( ( { srcset, mediaType, mediaValue }, index ) => (
<source
key={ index }
srcSet={ srcset }
media={ `(${ mediaType }: ${ mediaValue }px)` }
/>
) ) }
<img
src={ url }
className={ imageClasses || undefined }
style={ {
...borderProps.style,
aspectRatio,
objectFit: scale,
width,
height,
} }
alt={ alt }
/>
</picture>
{ ! RichText.isEmpty( caption ) && (
<RichText.Content
className={ __experimentalGetElementClassName( 'caption' ) }
tagName="figcaption"
value={ caption }
/>
) }
</figure>
);
}
21 changes: 21 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

export const DEFAULT_MEDIA_VALUE = isNaN(
parseInt( window?.enableResponsiveImage?.defaultMediaValue )
)
? 600
: parseInt( window?.enableResponsiveImage?.defaultMediaValue );

export const MEDIA_TYPES = [
{
label: __( 'max-width', 'enable-responsive-image' ),
value: 'max-width',
},
{
label: __( 'min-width', 'enable-responsive-image' ),
value: 'min-width',
},
];
66 changes: 59 additions & 7 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { addFilter } from '@wordpress/hooks';
import { InspectorControls } from '@wordpress/block-editor';
import { useSelect, useDispatch } from '@wordpress/data';
import { BlockControls, InspectorControls } from '@wordpress/block-editor';
import { seen } from '@wordpress/icons';
import type { BlockEditProps } from '@wordpress/blocks';
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';

/**
* Internal dependencies
*/
import BlockEditPreview from './block-edit-preview';
import SourceList from './source-list';
import './editor.scss';
import './store';
import type { BlockAttributes } from './types';

const addImageSourceAttributes = ( settings: { [ key: string ]: any } ) => {
Expand Down Expand Up @@ -39,22 +45,68 @@ addFilter(
addImageSourceAttributes
);

function ImageBlockControls( { isPreview }: { isPreview: false } ) {
const { setIsPreview } = useDispatch( 'enable-responsive-image' );

return (
// @ts-ignore
<BlockControls group="parent">
<ToolbarGroup>
<ToolbarButton
icon={ seen }
isPressed={ isPreview }
label={
isPreview
? __( 'Disable responsive image preview', 'enable-responsive-image' )
: __( 'Enable responsive image preview', 'enable-responsive-image' )
}
onClick={ () => setIsPreview( ! isPreview ) }
/>
</ToolbarGroup>
</BlockControls>
);
}

const withInspectorControl =
( BlockEdit: React.ComponentType< BlockEditProps< BlockAttributes > > ) =>
(
props: BlockEditProps< BlockAttributes > & {
name: string;
}
) => {
return props.name === 'core/image' ? (
if ( props.name !== 'core/image' ) {
return <BlockEdit { ...props } />;
}

const { attributes } = props;
const { url, sources } = attributes;

// @ts-ignore
const isPreview = useSelect( ( select ) => select( 'enable-responsive-image' ).getIsPreview() );

if ( url && isPreview ) {
return (
<>
<BlockEditPreview { ...props } />
<ImageBlockControls isPreview={ isPreview } />
<InspectorControls>
<SourceList { ...props } />
</InspectorControls>
</>
);
}

return (
<>
<BlockEdit { ...props } />
<InspectorControls>
<SourceList { ...props } />
</InspectorControls>
{ /* @ts-ignore */ }
{ url && sources?.length > 0 && <ImageBlockControls isPreview={ isPreview } /> }
{ url && (
<InspectorControls>
<SourceList { ...props } />
</InspectorControls>
) }
</>
) : (
<BlockEdit { ...props } />
);
};

Expand Down
18 changes: 4 additions & 14 deletions src/source-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,10 @@ import { store as coreStore } from '@wordpress/core-data';
import { chevronUp, chevronDown } from '@wordpress/icons';
import type { Media, Source } from './types';

const DEFAULT_MEDIA_VALUE = isNaN( parseInt( window?.enableResponsiveImage?.defaultMediaValue ) )
? 600
: parseInt( window?.enableResponsiveImage?.defaultMediaValue );

const MEDIA_TYPES = [
{
label: __( 'max-width', 'enable-responsive-image' ),
value: 'max-width',
},
{
label: __( 'min-width', 'enable-responsive-image' ),
value: 'min-width',
},
];
/**
* Internal dependencies
*/
import { DEFAULT_MEDIA_VALUE, MEDIA_TYPES } from './constants';

type Props = {
source?: Source;
Expand Down
6 changes: 1 addition & 5 deletions src/source-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import type { BlockAttributes, Source } from './types';

export default function ImageList( props: BlockEditProps< BlockAttributes > ) {
const { attributes, setAttributes } = props;
const { sources, url } = attributes;
const { sources } = attributes;

function onChange( newSource: Source, index: number ) {
const newSources = [ ...sources ];
Expand Down Expand Up @@ -54,10 +54,6 @@ export default function ImageList( props: BlockEditProps< BlockAttributes > ) {
setAttributes( { sources: newSources } );
}

if ( ! url ) {
return null;
}

return (
<PanelBody
title={ __( 'Image sources', 'enable-responsive-image' ) }
Expand Down
36 changes: 36 additions & 0 deletions src/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* WordPress dependencies
*/
import { createReduxStore, register } from '@wordpress/data';

const DEFAULT_STATE = {
isPreview: false,
};

export const store = createReduxStore( 'enable-responsive-image', {
reducer: ( state = DEFAULT_STATE, action ) => {
if ( action.type === 'UPDATE_IS_PREVIEW' ) {
return {
...state,
isPreview: ! state.isPreview,
};
}

return state;
},
selectors: {
getIsPreview( state: { isPreview: boolean } ) {
return state.isPreview;
},
},
actions: {
setIsPreview( value ) {
return {
type: 'UPDATE_IS_PREVIEW',
value,
};
},
},
} );

register( store );

0 comments on commit 991f1a3

Please sign in to comment.