UNPKG

@wordpress/editor

Version:
94 lines (90 loc) 3.08 kB
/** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; import { ExternalLink, TextareaControl } from '@wordpress/components'; import { useDispatch, useSelect } from '@wordpress/data'; import { useState } from '@wordpress/element'; import { decodeEntities } from '@wordpress/html-entities'; /** * Internal dependencies */ import { store as editorStore } from '../../store'; /** * Renders an editable textarea for the post excerpt. * Templates, template parts and patterns use the `excerpt` field as a description semantically. * Additionally templates and template parts override the `excerpt` field as `description` in * REST API. So this component handles proper labeling and updating the edited entity. * * @param {Object} props - Component props. * @param {boolean} [props.hideLabelFromVision=false] - Whether to visually hide the textarea's label. * @param {boolean} [props.updateOnBlur=false] - Whether to update the post on change or use local state and update on blur. */ export default function PostExcerpt( { hideLabelFromVision = false, updateOnBlur = false, } ) { const { excerpt, shouldUseDescriptionLabel, usedAttribute } = useSelect( ( select ) => { const { getCurrentPostType, getEditedPostAttribute } = select( editorStore ); const postType = getCurrentPostType(); // This special case is unfortunate, but the REST API of wp_template and wp_template_part // support the excerpt field through the "description" field rather than "excerpt". const _usedAttribute = [ 'wp_template', 'wp_template_part', ].includes( postType ) ? 'description' : 'excerpt'; return { excerpt: getEditedPostAttribute( _usedAttribute ), // There are special cases where we want to label the excerpt as a description. shouldUseDescriptionLabel: [ 'wp_template', 'wp_template_part', 'wp_block', ].includes( postType ), usedAttribute: _usedAttribute, }; }, [] ); const { editPost } = useDispatch( editorStore ); const [ localExcerpt, setLocalExcerpt ] = useState( decodeEntities( excerpt ) ); const updatePost = ( value ) => { editPost( { [ usedAttribute ]: value } ); }; const label = shouldUseDescriptionLabel ? __( 'Write a description (optional)' ) : __( 'Write an excerpt (optional)' ); return ( <div className="editor-post-excerpt"> <TextareaControl label={ label } hideLabelFromVision={ hideLabelFromVision } className="editor-post-excerpt__textarea" onChange={ updateOnBlur ? setLocalExcerpt : updatePost } onBlur={ updateOnBlur ? () => updatePost( localExcerpt ) : undefined } value={ updateOnBlur ? localExcerpt : excerpt } help={ ! shouldUseDescriptionLabel ? ( <ExternalLink href={ __( 'https://wordpress.org/documentation/article/page-post-settings-sidebar/#excerpt' ) } > { __( 'Learn more about manual excerpts' ) } </ExternalLink> ) : ( __( 'Write a description' ) ) } /> </div> ); }