Add the summary field to the product form (#37302)
* Add summary block * Add changelog files * Add text alignment * Add RTL and type definitions * Add justify text alignment * Fix rebasing errors
This commit is contained in:
parent
f899b43d91
commit
62ca7a266b
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Add summary block
|
|
@ -14,4 +14,5 @@ export const settings = {
|
|||
edit: Edit,
|
||||
};
|
||||
|
||||
export const init = () => initBlock( { name, metadata, settings } );
|
||||
export const init = () =>
|
||||
initBlock( { name, metadata: metadata as never, settings } );
|
||||
|
|
|
@ -14,4 +14,9 @@ export const settings = {
|
|||
edit: Edit,
|
||||
};
|
||||
|
||||
export const init = () => initBlock( { name, metadata, settings } );
|
||||
export const init = () =>
|
||||
initBlock( {
|
||||
name,
|
||||
metadata: metadata as never,
|
||||
settings,
|
||||
} );
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"$schema": "https://schemas.wp.org/trunk/block.json",
|
||||
"apiVersion": 2,
|
||||
"name": "woocommerce/product-summary",
|
||||
"title": "Product summary",
|
||||
"category": "widgets",
|
||||
"description": "The product summary.",
|
||||
"keywords": [ "products", "summary", "excerpt" ],
|
||||
"textdomain": "default",
|
||||
"attributes": {
|
||||
"align": {
|
||||
"type": "string"
|
||||
},
|
||||
"direction": {
|
||||
"type": "string",
|
||||
"enum": [ "ltr", "rtl" ]
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"supports": {
|
||||
"align": false,
|
||||
"html": false,
|
||||
"multiple": false,
|
||||
"reusable": false,
|
||||
"inserter": false,
|
||||
"lock": false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import {
|
||||
alignCenter,
|
||||
alignJustify,
|
||||
alignLeft,
|
||||
alignRight,
|
||||
} from '@wordpress/icons';
|
||||
|
||||
export const ALIGNMENT_CONTROLS = [
|
||||
{
|
||||
icon: alignLeft,
|
||||
title: __( 'Align text left', 'woocommerce' ),
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
icon: alignCenter,
|
||||
title: __( 'Align text center', 'woocommerce' ),
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
icon: alignRight,
|
||||
title: __( 'Align text right', 'woocommerce' ),
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
icon: alignJustify,
|
||||
title: __( 'Align text justify', 'woocommerce' ),
|
||||
align: 'justify',
|
||||
},
|
||||
];
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { createElement } from '@wordpress/element';
|
||||
import { BlockEditProps } from '@wordpress/blocks';
|
||||
import { BaseControl } from '@wordpress/components';
|
||||
import { useEntityProp } from '@wordpress/core-data';
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore No types for this exist yet.
|
||||
AlignmentControl,
|
||||
BlockControls,
|
||||
RichText,
|
||||
useBlockProps,
|
||||
} from '@wordpress/block-editor';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { ParagraphRTLControl } from './paragraph-rtl-control';
|
||||
import { SummaryAttributes } from './types';
|
||||
import { ALIGNMENT_CONTROLS } from './constants';
|
||||
|
||||
export function Edit( {
|
||||
attributes,
|
||||
setAttributes,
|
||||
}: BlockEditProps< SummaryAttributes > ) {
|
||||
const { align, direction, label } = attributes;
|
||||
const blockProps = useBlockProps( {
|
||||
style: { direction },
|
||||
} );
|
||||
const id = uniqueId();
|
||||
const [ summary, setSummary ] = useEntityProp< string >(
|
||||
'postType',
|
||||
'product',
|
||||
'short_description'
|
||||
);
|
||||
|
||||
function handleAlignmentChange( value: SummaryAttributes[ 'align' ] ) {
|
||||
setAttributes( { align: value } );
|
||||
}
|
||||
|
||||
function handleDirectionChange( value: SummaryAttributes[ 'direction' ] ) {
|
||||
setAttributes( { direction: value } );
|
||||
}
|
||||
|
||||
return (
|
||||
<div { ...blockProps }>
|
||||
{ /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ }
|
||||
{ /* @ts-ignore No types for this exist yet. */ }
|
||||
<BlockControls group="block">
|
||||
<AlignmentControl
|
||||
alignmentControls={ ALIGNMENT_CONTROLS }
|
||||
value={ align }
|
||||
onChange={ handleAlignmentChange }
|
||||
/>
|
||||
|
||||
<ParagraphRTLControl
|
||||
direction={ direction }
|
||||
onChange={ handleDirectionChange }
|
||||
/>
|
||||
</BlockControls>
|
||||
|
||||
<BaseControl
|
||||
id={ id }
|
||||
label={ label || __( 'Summary', 'woocommerce' ) }
|
||||
>
|
||||
<RichText
|
||||
id={ id }
|
||||
identifier="content"
|
||||
tagName="p"
|
||||
value={ summary }
|
||||
onChange={ setSummary }
|
||||
placeholder={ __(
|
||||
"Summarize this product in 1-2 short sentences. We'll show it at the top of the page.",
|
||||
'woocommerce'
|
||||
) }
|
||||
data-empty={ Boolean( summary ) }
|
||||
className={ classNames( 'components-summary-control', {
|
||||
[ `has-text-align-${ align }` ]: align,
|
||||
} ) }
|
||||
dir={ direction }
|
||||
/>
|
||||
</BaseControl>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { BlockConfiguration } from '@wordpress/blocks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { initBlock } from '../../utils';
|
||||
import blockConfiguration from './block.json';
|
||||
import { Edit } from './edit';
|
||||
import { SummaryAttributes } from './types';
|
||||
|
||||
const { name, ...metadata } =
|
||||
blockConfiguration as BlockConfiguration< SummaryAttributes >;
|
||||
|
||||
export { name, metadata };
|
||||
|
||||
export const settings = {
|
||||
example: {},
|
||||
edit: Edit,
|
||||
};
|
||||
|
||||
export function init() {
|
||||
return initBlock< SummaryAttributes >( {
|
||||
name,
|
||||
metadata,
|
||||
settings,
|
||||
} );
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './paragraph-rtl-control';
|
||||
export * from './types';
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { createElement, Fragment } from '@wordpress/element';
|
||||
import { ToolbarButton } from '@wordpress/components';
|
||||
import { _x, isRTL } from '@wordpress/i18n';
|
||||
import { formatLtr } from '@wordpress/icons';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { ParagraphRTLControlProps } from './types';
|
||||
|
||||
export function ParagraphRTLControl( {
|
||||
direction,
|
||||
onChange,
|
||||
}: ParagraphRTLControlProps ) {
|
||||
function handleClick() {
|
||||
if ( typeof onChange === 'function' ) {
|
||||
onChange( direction === 'ltr' ? undefined : 'ltr' );
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{ isRTL() && (
|
||||
<ToolbarButton
|
||||
icon={ formatLtr }
|
||||
title={ _x(
|
||||
'Left to right',
|
||||
'editor button',
|
||||
'woocommerce'
|
||||
) }
|
||||
isActive={ direction === 'ltr' }
|
||||
onClick={ handleClick }
|
||||
/>
|
||||
) }
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { SummaryAttributes } from '../types';
|
||||
|
||||
export type ParagraphRTLControlProps = Pick<
|
||||
SummaryAttributes,
|
||||
'direction'
|
||||
> & {
|
||||
onChange( direction?: SummaryAttributes[ 'direction' ] ): void;
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
// This alignment class does not exists in
|
||||
// https://github.com/WordPress/gutenberg/blob/trunk/packages/block-library/src/common.scss
|
||||
.has-text-align-justify {
|
||||
/*rtl:ignore*/
|
||||
text-align: justify;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
export type SummaryAttributes = {
|
||||
align: 'left' | 'center' | 'right' | 'justify';
|
||||
direction: 'ltr' | 'rtl';
|
||||
label: string;
|
||||
};
|
|
@ -6,7 +6,7 @@ import {
|
|||
EditorSettings,
|
||||
EditorBlockListSettings,
|
||||
} from '@wordpress/block-editor';
|
||||
import { SlotFillProvider } from '@wordpress/components';
|
||||
import { Popover, SlotFillProvider } from '@wordpress/components';
|
||||
import { Product } from '@woocommerce/data';
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore No types for this exist yet.
|
||||
|
@ -60,6 +60,8 @@ export function Editor( { product, settings }: EditorProps ) {
|
|||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<Popover.Slot />
|
||||
</SlotFillProvider>
|
||||
</ShortcutProvider>
|
||||
</EntityProvider>
|
||||
|
|
|
@ -7,6 +7,7 @@ import { registerCoreBlocks } from '@wordpress/block-library';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { init as initName } from '../details-name-block';
|
||||
import { init as initSummary } from '../details-summary-block';
|
||||
import { init as initSection } from '../section';
|
||||
import { init as initTab } from '../tab';
|
||||
import { init as initPricing } from '../pricing-block';
|
||||
|
@ -15,6 +16,7 @@ import { init as initCollapsible } from '../collapsible-block';
|
|||
export const initBlocks = () => {
|
||||
registerCoreBlocks();
|
||||
initName();
|
||||
initSummary();
|
||||
initSection();
|
||||
initTab();
|
||||
initPricing();
|
||||
|
|
|
@ -14,4 +14,9 @@ export const settings = {
|
|||
edit: Edit,
|
||||
};
|
||||
|
||||
export const init = () => initBlock( { name, metadata, settings } );
|
||||
export const init = () =>
|
||||
initBlock( {
|
||||
name,
|
||||
metadata: metadata as never,
|
||||
settings,
|
||||
} );
|
||||
|
|
|
@ -8,3 +8,4 @@
|
|||
@import 'components/section/style.scss';
|
||||
@import 'components/tab/style.scss';
|
||||
@import 'components/tabs/style.scss';
|
||||
@import 'components/details-summary-block/style.scss';
|
||||
|
|
|
@ -1,26 +1,31 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { BlockConfiguration, registerBlockType } from '@wordpress/blocks';
|
||||
import {
|
||||
Block,
|
||||
BlockConfiguration,
|
||||
registerBlockType,
|
||||
} from '@wordpress/blocks';
|
||||
|
||||
interface BlockRepresentation {
|
||||
name: string;
|
||||
metadata: BlockConfiguration;
|
||||
settings: Partial< BlockConfiguration >;
|
||||
interface BlockRepresentation< T extends Record< string, object > > {
|
||||
name?: string;
|
||||
metadata: BlockConfiguration< T >;
|
||||
settings: Partial< BlockConfiguration< T > >;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to register an individual block.
|
||||
*
|
||||
* @param {Object} block The block to be registered.
|
||||
*
|
||||
* @return {?WPBlockType} The block, if it has been successfully registered;
|
||||
* otherwise `undefined`.
|
||||
* @param block The block to be registered.
|
||||
* @return The block, if it has been successfully registered; otherwise `undefined`.
|
||||
*/
|
||||
export const initBlock = ( block: BlockRepresentation ) => {
|
||||
export function initBlock<
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
T extends Record< string, any > = Record< string, any >
|
||||
>( block: BlockRepresentation< T > ): Block< T > | undefined {
|
||||
if ( ! block ) {
|
||||
return;
|
||||
}
|
||||
const { metadata, settings, name } = block;
|
||||
return registerBlockType( { name, ...metadata }, settings );
|
||||
};
|
||||
return registerBlockType< T >( { name, ...metadata }, settings );
|
||||
}
|
||||
|
|
|
@ -19,6 +19,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
.components-summary-control {
|
||||
width: 100%;
|
||||
min-height: calc($gap-larger * 3);
|
||||
background-color: $white;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #757575;
|
||||
border-radius: 2px;
|
||||
padding: $gap-smaller;
|
||||
margin: 0;
|
||||
appearance: textarea;
|
||||
resize: vertical;
|
||||
overflow: hidden;
|
||||
|
||||
&:focus {
|
||||
box-shadow: inset 0 0 0 1px var(--wp-admin-theme-color-darker-10, --wp-admin-theme-color);
|
||||
border-color: var(--wp-admin-theme-color-darker-10, --wp-admin-theme-color);
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-product-form {
|
||||
&__custom-label-input {
|
||||
display: flex;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Add summary block
|
|
@ -387,6 +387,9 @@ class WC_Post_Types {
|
|||
'name' => 'Product name',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-summary',
|
||||
),
|
||||
array(
|
||||
'core/columns',
|
||||
array(),
|
||||
|
|
Loading…
Reference in New Issue