diff --git a/docs/designers-developers/developers/richtext.md b/docs/designers-developers/developers/richtext.md index 6e0752f64f8752..e662ce41b7cf94 100644 --- a/docs/designers-developers/developers/richtext.md +++ b/docs/designers-developers/developers/richtext.md @@ -49,7 +49,6 @@ wp.blocks.registerBlockType( /* ... */, { props.setAttributes( { content: content } ); // Store updated content as a block attribute }, placeholder: __( 'Heading...' ), // Display this text before any content has been added by the user - keepPlaceholderOnFocus: true // Keep the placeholder text showing even when the field is focused (leave this property off to remove placeholder content on focus) } ); }, @@ -85,7 +84,6 @@ registerBlockType( /* ... */, { formattingControls={ [ 'bold', 'italic' ] } // Allow the content to be made bold or italic, but do not allow other formatting options onChange={ ( content ) => setAttributes( { content } ) } // Store updated content as a block attribute placeholder={ __( 'Heading...' ) } // Display this text before any content has been added by the user - keepPlaceholderOnFocus // Keep the placeholder text showing even when the field is focused (leave this property off to remove placeholder content on focus) /> ); }, diff --git a/packages/block-editor/src/components/rich-text/README.md b/packages/block-editor/src/components/rich-text/README.md index 9cc0b3e93fccdd..e271bc5200e658 100644 --- a/packages/block-editor/src/components/rich-text/README.md +++ b/packages/block-editor/src/components/rich-text/README.md @@ -53,10 +53,6 @@ Render a rich [`contenteditable` input](https://developer.mozilla.org/en-US/docs *Optional.* Whether to show the input is selected or not in order to show the formatting controls. By default it renders the controls when the block is selected. -### `keepPlaceholderOnFocus: Boolean` - -*Optional.* By default, the placeholder will hide as soon as the editable field receives focus. With this setting it can be be kept while the field is focussed and empty. - ### `autocompleters: Array` *Optional.* A list of autocompleters to use instead of the default. diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index 8a3ef0550045bc..1cf2c6225afaa0 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -293,7 +293,6 @@ class RichTextWrapper extends Component { isSelected: originalIsSelected, onCreateUndoLevel, placeholder, - keepPlaceholderOnFocus, // eslint-disable-next-line no-unused-vars allowedFormats, withoutInteractiveFormatting, @@ -338,9 +337,8 @@ class RichTextWrapper extends Component { onSelectionChange={ onSelectionChange } tagName={ tagName } wrapperClassName={ classnames( wrapperClasses, wrapperClassName ) } - className={ classnames( classes, className ) } + className={ classnames( classes, className, { 'is-selected': originalIsSelected } ) } placeholder={ placeholder } - keepPlaceholderOnFocus={ keepPlaceholderOnFocus } allowedFormats={ adjustedAllowedFormats } withoutInteractiveFormatting={ withoutInteractiveFormatting } onEnter={ this.onEnter } diff --git a/packages/block-editor/src/components/rich-text/index.native.js b/packages/block-editor/src/components/rich-text/index.native.js index 61cbf2551751a1..ccb5e0d15bf7ec 100644 --- a/packages/block-editor/src/components/rich-text/index.native.js +++ b/packages/block-editor/src/components/rich-text/index.native.js @@ -49,7 +49,6 @@ function RichTextWraper( { isSelected: originalIsSelected, onCreateUndoLevel, placeholder, - keepPlaceholderOnFocus, // From experimental filter. ...experimentalProps } ) { @@ -68,7 +67,6 @@ function RichTextWraper( { wrapperClassName={ classnames( wrapperClasses, wrapperClassName ) } className={ classnames( classes, className ) } placeholder={ placeholder } - keepPlaceholderOnFocus={ keepPlaceholderOnFocus } __unstableIsSelected={ originalIsSelected } //__unstablePatterns={ getPatterns() } //__unstableEnterPatterns={ getEnterPatterns() } diff --git a/packages/block-editor/src/components/rich-text/style.scss b/packages/block-editor/src/components/rich-text/style.scss index d4a7e39978a4aa..e5498676c60159 100644 --- a/packages/block-editor/src/components/rich-text/style.scss +++ b/packages/block-editor/src/components/rich-text/style.scss @@ -34,39 +34,26 @@ } } - &[data-is-placeholder-visible="true"] { - position: absolute; - top: 0; - width: 100%; - margin-top: 0; - - & > p { - margin-top: 0; - } - - // Ensure that if placeholder wraps (mobile/nested contexts) the clickable area is full-height. - height: 100%; - } - - // Placeholder text. - & + .block-editor-rich-text__editable { + [data-rich-text-placeholder]::after { + content: attr(data-rich-text-placeholder); pointer-events: none; - // Use opacity to work in various editor styles. // We don't specify the color here, because blocks or editor styles might provide their own. - &, - p { - opacity: 0.62; - } + opacity: 0.62; } - // Captions may have lighter (gray) text, or be shown on a range of different background luminosites. - // To ensure legibility, we increase the default placeholder opacity to ensure contrast. - &[data-is-placeholder-visible="true"] + figcaption.block-editor-rich-text__editable { - opacity: 0.8; + // Could be unset for individual rich text instances. + &.is-selected [data-rich-text-placeholder]::after { + display: none; } } +// Captions may have lighter (gray) text, or be shown on a range of different background luminosites. +// To ensure legibility, we increase the default placeholder opacity to ensure contrast. +figcaption.block-editor-rich-text__editable [data-rich-text-placeholder]::before { + opacity: 0.8; +} + .block-editor-rich-text__inline-toolbar { display: flex; justify-content: center; diff --git a/packages/block-library/src/button/edit.js b/packages/block-library/src/button/edit.js index a5f70204d6557c..967dc29c9e44cb 100644 --- a/packages/block-library/src/button/edit.js +++ b/packages/block-library/src/button/edit.js @@ -127,7 +127,6 @@ class ButtonEdit extends Component { backgroundColor: backgroundColor.color, color: textColor.color, } } - keepPlaceholderOnFocus /> setAttributes( { fileName: text } ) } /> @@ -225,7 +224,6 @@ class FileEdit extends Component { value={ downloadButtonText } withoutInteractiveFormatting placeholder={ __( 'Add text…' ) } - keepPlaceholderOnFocus onChange={ ( text ) => setAttributes( { downloadButtonText: text } ) } /> diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index 21623fad95abc9..910bed783e67f4 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -35,11 +35,6 @@ ul.wp-block-gallery { overflow-y: auto; } - .block-editor-rich-text figcaption:not([data-is-placeholder-visible="true"]) { - position: relative; - overflow: hidden; - } - .is-selected .block-editor-rich-text { // IE calculates this incorrectly, so leave it to modern browsers. @supports (position: sticky) { @@ -74,6 +69,9 @@ ul.wp-block-gallery { } .block-editor-rich-text figcaption { + position: relative; + overflow: hidden; + a { color: $white; } diff --git a/packages/block-library/src/paragraph/editor.scss b/packages/block-library/src/paragraph/editor.scss index 8efa8e47f73e0c..1ea726dcbb552a 100644 --- a/packages/block-library/src/paragraph/editor.scss +++ b/packages/block-library/src/paragraph/editor.scss @@ -1,7 +1,8 @@ // Specific to the empty paragraph placeholder: // when shown on mobile and in nested contexts, one or more icons show up on the right. // This padding makes sure it doesn't overlap text. -.block-editor-rich-text__editable[data-is-placeholder-visible="true"] + .block-editor-rich-text__editable.wp-block-paragraph { +.block-editor-rich-text__editable.wp-block-paragraph:not(.is-selected) [data-rich-text-placeholder]::after { + display: inline-block; padding-right: $icon-button-size * 3; // In nested contexts only one icon shows up. diff --git a/packages/block-library/src/search/edit.js b/packages/block-library/src/search/edit.js index 40834ab63f3ab3..81c2ec63d8acb4 100644 --- a/packages/block-library/src/search/edit.js +++ b/packages/block-library/src/search/edit.js @@ -13,7 +13,6 @@ export default function SearchEdit( { className, attributes, setAttributes } ) { wrapperClassName="wp-block-search__label" aria-label={ __( 'Label text' ) } placeholder={ __( 'Add label…' ) } - keepPlaceholderOnFocus withoutInteractiveFormatting value={ label } onChange={ ( html ) => setAttributes( { label: html } ) } @@ -33,7 +32,6 @@ export default function SearchEdit( { className, attributes, setAttributes } ) { className="wp-block-search__button-rich-text" aria-label={ __( 'Button text' ) } placeholder={ __( 'Add button text…' ) } - keepPlaceholderOnFocus withoutInteractiveFormatting value={ buttonText } onChange={ ( html ) => setAttributes( { buttonText: html } ) } diff --git a/packages/edit-post/src/components/visual-editor/style.scss b/packages/edit-post/src/components/visual-editor/style.scss index 8b46a1f9dfc8a4..c02a1c7dbcacc8 100644 --- a/packages/edit-post/src/components/visual-editor/style.scss +++ b/packages/edit-post/src/components/visual-editor/style.scss @@ -105,7 +105,7 @@ } // Ensure that the height of the first appender, and the one between blocks, is the same as text. - .block-editor-block-list__block[data-type="core/paragraph"] p[data-is-placeholder-visible="true"] + p, + .block-editor-block-list__block[data-type="core/paragraph"] p, .block-editor-default-block-appender__content { min-height: $empty-paragraph-height / 2; line-height: $editor-line-height; diff --git a/packages/edit-widgets/src/components/customizer-edit-widgets-initializer/style.scss b/packages/edit-widgets/src/components/customizer-edit-widgets-initializer/style.scss index f7ac0e338ce99c..fda5b9c84944ed 100644 --- a/packages/edit-widgets/src/components/customizer-edit-widgets-initializer/style.scss +++ b/packages/edit-widgets/src/components/customizer-edit-widgets-initializer/style.scss @@ -11,8 +11,4 @@ .block-editor-block-list__empty-block-inserter { left: -18px; } - - .block-editor-rich-text__editable[data-is-placeholder-visible="true"] + .block-editor-rich-text__editable.wp-block-paragraph { - padding: 0; - } } diff --git a/packages/rich-text/src/component/editable.js b/packages/rich-text/src/component/editable.js index b4054a883c0d27..c5407fc308582c 100644 --- a/packages/rich-text/src/component/editable.js +++ b/packages/rich-text/src/component/editable.js @@ -81,8 +81,6 @@ function applyInternetExplorerInputFix( editorNode ) { }; } -const IS_PLACEHOLDER_VISIBLE_ATTR_NAME = 'data-is-placeholder-visible'; - /** * Whether or not the user agent is Internet Explorer. * @@ -106,8 +104,6 @@ export default class Editable extends Component { // update the attributes on the wrapper nodes here. `componentDidUpdate` // will never be called. shouldComponentUpdate( nextProps ) { - this.configureIsPlaceholderVisible( nextProps.isPlaceholderVisible ); - if ( ! isEqual( this.props.style, nextProps.style ) ) { this.editorNode.setAttribute( 'style', '' ); Object.assign( this.editorNode.style, { @@ -129,13 +125,6 @@ export default class Editable extends Component { return false; } - configureIsPlaceholderVisible( isPlaceholderVisible ) { - const isPlaceholderVisibleString = String( !! isPlaceholderVisible ); - if ( this.editorNode.getAttribute( IS_PLACEHOLDER_VISIBLE_ATTR_NAME ) !== isPlaceholderVisibleString ) { - this.editorNode.setAttribute( IS_PLACEHOLDER_VISIBLE_ATTR_NAME, isPlaceholderVisibleString ); - } - } - bindEditorNode( editorNode ) { this.editorNode = editorNode; this.props.setRef( editorNode ); @@ -158,7 +147,6 @@ export default class Editable extends Component { record, valueToEditableHTML, className, - isPlaceholderVisible, ...remainingProps } = this.props; @@ -190,7 +178,6 @@ export default class Editable extends Component { 'aria-multiline': true, className, contentEditable: true, - [ IS_PLACEHOLDER_VISIBLE_ATTR_NAME ]: isPlaceholderVisible, ref: this.bindEditorNode, style: { ...style, diff --git a/packages/rich-text/src/component/index.js b/packages/rich-text/src/component/index.js index 34792ad1d2b3aa..d16598417e2f78 100644 --- a/packages/rich-text/src/component/index.js +++ b/packages/rich-text/src/component/index.js @@ -181,6 +181,7 @@ class RichText extends Component { multilineWrapperTags: this.multilineWrapperTags, prepareEditableTree: createPrepareEditableTree( this.props, 'format_prepare_functions' ), __unstableDomOnly: domOnly, + placeholder: this.props.placeholder, } ); } @@ -725,6 +726,7 @@ class RichText extends Component { value, selectionStart, selectionEnd, + placeholder, __unstableIsSelected: isSelected, } = this.props; @@ -752,6 +754,10 @@ class RichText extends Component { shouldReapply = shouldReapply || ! isShallowEqual( prepareProps, prevPrepareProps ); + // Rerender if the placeholder changed. + shouldReapply = shouldReapply || + placeholder !== prevProps.placeholder; + const { activeFormats = [] } = this.record; if ( shouldReapply ) { @@ -808,6 +814,7 @@ class RichText extends Component { value, multilineTag: this.multilineTag, prepareEditableTree: createPrepareEditableTree( this.props, 'format_prepare_functions' ), + placeholder: this.props.placeholder, } ).body.innerHTML; } @@ -857,7 +864,6 @@ class RichText extends Component { wrapperClassName, className, placeholder, - keepPlaceholderOnFocus = false, __unstableIsSelected: isSelected, children, // To do: move autocompletion logic to rich-text. @@ -872,10 +878,8 @@ class RichText extends Component { // changes, we replace the relevant element. This is needed because we // prevent Editable component updates. const key = Tagname; - const MultilineTag = this.multilineTag; const ariaProps = pickAriaProps( this.props ); const record = this.getRecord(); - const isPlaceholderVisible = placeholder && ( ! isSelected || keepPlaceholderOnFocus ) && isEmpty( record ); const autoCompleteContent = ( { listBoxId, activeId } ) => ( <> @@ -884,7 +888,6 @@ class RichText extends Component { style={ style } record={ record } valueToEditableHTML={ this.valueToEditableHTML } - isPlaceholderVisible={ isPlaceholderVisible } aria-label={ placeholder } aria-autocomplete={ listBoxId ? 'list' : undefined } aria-owns={ listBoxId } @@ -902,14 +905,6 @@ class RichText extends Component { onTouchStart={ this.onPointerDown } setRef={ this.setRef } /> - { isPlaceholderVisible && - - { MultilineTag ? { placeholder } : placeholder } - - } { isSelected &&