Skip to content

Commit 4ab1a3a

Browse files
ellatrixjasmussen
andauthored
Default appender: try editable paragraph instead of text area (#30986)
* Default appender: try editable paragraph instead of text area * Move wp-block class * Port over CSS from 30656 that's still useful. * Update snapshots. * Remove content editable in favour of tab index * Fix tests * Fix e2e test Co-authored-by: jasmussen <[email protected]>
1 parent c64f996 commit 4ab1a3a

File tree

5 files changed

+60
-91
lines changed

5 files changed

+60
-91
lines changed

packages/block-editor/src/components/default-block-appender/index.js

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
/**
2-
* External dependencies
3-
*/
4-
import TextareaAutosize from 'react-autosize-textarea';
5-
61
/**
72
* WordPress dependencies
83
*/
@@ -18,6 +13,12 @@ import { withSelect, withDispatch } from '@wordpress/data';
1813
import Inserter from '../inserter';
1914
import { store as blockEditorStore } from '../../store';
2015

16+
/**
17+
* Zero width non-breaking space, used as padding for the paragraph when it is
18+
* empty.
19+
*/
20+
export const ZWNBSP = '\ufeff';
21+
2122
export function DefaultBlockAppender( {
2223
isLocked,
2324
isVisible,
@@ -33,34 +34,30 @@ export function DefaultBlockAppender( {
3334
const value =
3435
decodeEntities( placeholder ) || __( 'Type / to choose a block' );
3536

36-
// The appender "button" is in-fact a text field so as to support
37-
// transitions by WritingFlow occurring by arrow key press. WritingFlow
38-
// only supports tab transitions into text fields and to the block focus
39-
// boundary.
40-
//
41-
// See: https://github.com/WordPress/gutenberg/issues/4829#issuecomment-374213658
42-
//
43-
// If it were ever to be made to be a proper `button` element, it is
44-
// important to note that `onFocus` alone would not be sufficient to
45-
// capture click events, notably in Firefox.
46-
//
47-
// See: https://gist.github.com/cvrebert/68659d0333a578d75372
48-
49-
// The wp-block className is important for editor styles.
50-
5137
return (
5238
<div
5339
data-root-client-id={ rootClientId || '' }
54-
className="wp-block block-editor-default-block-appender"
40+
className="block-editor-default-block-appender"
5541
>
56-
<TextareaAutosize
42+
<p
43+
tabIndex="0"
44+
// Only necessary for `useCanvasClickRedirect` to consider it
45+
// as a target. Ideally it should consider any tabbable target,
46+
// but the inserter is rendered in place while it should be
47+
// rendered in a popover, just like it does for an empty
48+
// paragraph block.
49+
contentEditable
50+
suppressContentEditableWarning
51+
// We want this element to be styled as a paragraph by themes.
52+
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
5753
role="button"
5854
aria-label={ __( 'Add block' ) }
59-
className="block-editor-default-block-appender__content"
60-
readOnly
55+
// The wp-block className is important for editor styles.
56+
className="wp-block block-editor-default-block-appender__content"
6157
onFocus={ onAppend }
62-
value={ showPrompt ? value : '' }
63-
/>
58+
>
59+
{ showPrompt ? value : ZWNBSP }
60+
</p>
6461
<Inserter
6562
rootClientId={ rootClientId }
6663
position="bottom right"

packages/block-editor/src/components/default-block-appender/style.scss

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,9 @@
1212
outline: 1px solid transparent;
1313
}
1414

15-
textarea.block-editor-default-block-appender__content { // Needs specificity in order to override input field styles from WP-admin styles.
16-
font-family: inherit;
17-
font-size: inherit;
18-
border: none;
19-
background: none;
20-
box-shadow: none;
21-
display: block;
22-
cursor: text;
23-
width: 100%;
24-
outline: $border-width solid transparent;
25-
transition: 0.2s outline;
26-
@include reduce-motion("transition");
27-
margin-top: $default-block-margin;
28-
margin-bottom: $default-block-margin;
29-
30-
// This needs high specificity as it's output as an inline style by the library.
31-
resize: none !important;
32-
33-
// Emulate the dimensions of a paragraph block.
34-
// On mobile and in nested contexts, the plus to add blocks shows up on the right.
35-
// The rightmost padding makes sure it doesn't overlap text.
36-
padding: 0 #{ $block-padding + $button-size } 0 0;
37-
38-
// Use opacity to work in various editor styles.
39-
color: $dark-gray-placeholder;
40-
.is-dark-theme & {
41-
color: $light-gray-placeholder;
42-
}
15+
.block-editor-default-block-appender__content {
16+
// Set the opacity of the initial block appender to the same as placeholder text in an empty Paragraph block.
17+
opacity: 0.62;
4318
}
4419

4520
// Dropzone.
@@ -48,11 +23,6 @@
4823
}
4924
}
5025

51-
// Ensure that the height of the first appender, and the one between blocks, is the same as text.
52-
.block-editor-default-block-appender__content {
53-
line-height: $editor-line-height;
54-
}
55-
5626
// Empty / default block side inserter.
5727
.block-editor-block-list__empty-block-inserter.block-editor-block-list__empty-block-inserter, // Empty paragraph, needs specificity to override inherited popover styles.
5828
.block-editor-default-block-appender .block-editor-inserter { // Empty appender.
@@ -79,9 +49,3 @@
7949
display: none;
8050
}
8151
}
82-
83-
.block-editor-default-block-appender .block-editor-inserter {
84-
@include break-small {
85-
align-items: center;
86-
}
87-
}

packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
exports[`DefaultBlockAppender should append a default block when input focused 1`] = `
44
<div
5-
className="wp-block block-editor-default-block-appender"
5+
className="block-editor-default-block-appender"
66
data-root-client-id=""
77
>
8-
<ForwardRef
8+
<p
99
aria-label="Add block"
10-
className="block-editor-default-block-appender__content"
10+
className="wp-block block-editor-default-block-appender__content"
11+
contentEditable={true}
1112
onFocus={
1213
[MockFunction] {
1314
"calls": Array [
@@ -21,10 +22,12 @@ exports[`DefaultBlockAppender should append a default block when input focused 1
2122
],
2223
}
2324
}
24-
readOnly={true}
2525
role="button"
26-
value="Type / to choose a block"
27-
/>
26+
suppressContentEditableWarning={true}
27+
tabIndex="0"
28+
>
29+
Type / to choose a block
30+
</p>
2831
<WithSelect(WithDispatch(IfCondition(Inserter)))
2932
__experimentalIsQuick={true}
3033
isAppender={true}
@@ -35,17 +38,20 @@ exports[`DefaultBlockAppender should append a default block when input focused 1
3538

3639
exports[`DefaultBlockAppender should match snapshot 1`] = `
3740
<div
38-
className="wp-block block-editor-default-block-appender"
41+
className="block-editor-default-block-appender"
3942
data-root-client-id=""
4043
>
41-
<ForwardRef
44+
<p
4245
aria-label="Add block"
43-
className="block-editor-default-block-appender__content"
46+
className="wp-block block-editor-default-block-appender__content"
47+
contentEditable={true}
4448
onFocus={[MockFunction]}
45-
readOnly={true}
4649
role="button"
47-
value="Type / to choose a block"
48-
/>
50+
suppressContentEditableWarning={true}
51+
tabIndex="0"
52+
>
53+
Type / to choose a block
54+
</p>
4955
<WithSelect(WithDispatch(IfCondition(Inserter)))
5056
__experimentalIsQuick={true}
5157
isAppender={true}
@@ -56,17 +62,20 @@ exports[`DefaultBlockAppender should match snapshot 1`] = `
5662

5763
exports[`DefaultBlockAppender should optionally show without prompt 1`] = `
5864
<div
59-
className="wp-block block-editor-default-block-appender"
65+
className="block-editor-default-block-appender"
6066
data-root-client-id=""
6167
>
62-
<ForwardRef
68+
<p
6369
aria-label="Add block"
64-
className="block-editor-default-block-appender__content"
70+
className="wp-block block-editor-default-block-appender__content"
71+
contentEditable={true}
6572
onFocus={[MockFunction]}
66-
readOnly={true}
6773
role="button"
68-
value=""
69-
/>
74+
suppressContentEditableWarning={true}
75+
tabIndex="0"
76+
>
77+

78+
</p>
7079
<WithSelect(WithDispatch(IfCondition(Inserter)))
7180
__experimentalIsQuick={true}
7281
isAppender={true}

packages/block-editor/src/components/default-block-appender/test/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { shallow } from 'enzyme';
66
/**
77
* Internal dependencies
88
*/
9-
import { DefaultBlockAppender } from '../';
9+
import { DefaultBlockAppender, ZWNBSP } from '../';
1010

1111
describe( 'DefaultBlockAppender', () => {
1212
const expectOnAppendCalled = ( onAppend ) => {
@@ -35,7 +35,7 @@ describe( 'DefaultBlockAppender', () => {
3535
<DefaultBlockAppender isVisible onAppend={ onAppend } showPrompt />
3636
);
3737

38-
wrapper.find( 'ForwardRef' ).simulate( 'focus' );
38+
wrapper.find( 'p' ).simulate( 'focus' );
3939

4040
expect( wrapper ).toMatchSnapshot();
4141

@@ -51,9 +51,9 @@ describe( 'DefaultBlockAppender', () => {
5151
showPrompt={ false }
5252
/>
5353
);
54-
const input = wrapper.find( 'ForwardRef' );
54+
const input = wrapper.find( 'p' );
5555

56-
expect( input.prop( 'value' ) ).toEqual( '' );
56+
expect( input.prop( 'children' ) ).toEqual( ZWNBSP );
5757

5858
expect( wrapper ).toMatchSnapshot();
5959
} );

packages/edit-post/src/components/visual-editor/style.scss

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,9 @@
5555
margin-left: auto;
5656
margin-right: auto;
5757

58-
// Apply default block margin below the post title.
59-
// This ensures the first block on the page is in a good position.
60-
// This rule can be retired once the title becomes an actual block.
61-
margin-bottom: $default-block-margin;
58+
// Margins between the title and the first block, or appender, do not collapse.
59+
// By explicitly setting this to zero, we avoid "double margin".
60+
margin-bottom: 0;
6261
}
6362
}
6463

0 commit comments

Comments
 (0)