From 8c7843371b17b800e288782bb43e38868aca34b5 Mon Sep 17 00:00:00 2001 From: Jorge Date: Sun, 23 Jan 2022 17:01:11 +0000 Subject: [PATCH] Revert additions to the interface package. --- packages/base-styles/_z-index.scss | 3 +- .../src/components/text-editor/index.js | 65 +++++++----- .../src/components/text-editor/style.scss | 80 +++++++++++--- packages/edit-site/package.json | 1 + .../code-editor/code-editor-text-area.js} | 13 ++- .../src/components/code-editor/index.js | 42 +++++--- .../src/components/code-editor/style.scss | 100 ++++++++++++++++++ packages/edit-site/src/style.scss | 1 + packages/editor/package.json | 1 - .../src/components/post-text-editor/index.js | 77 ++++++++++++-- .../components/post-text-editor}/style.scss | 2 +- packages/editor/src/style.scss | 1 + packages/interface/package.json | 3 +- .../components/code-editor-screen/index.js | 42 -------- .../components/code-editor-screen/style.scss | 52 --------- packages/interface/src/components/index.js | 2 - packages/interface/src/style.scss | 2 - 17 files changed, 313 insertions(+), 174 deletions(-) rename packages/{interface/src/components/code-editor/index.js => edit-site/src/components/code-editor/code-editor-text-area.js} (84%) create mode 100644 packages/edit-site/src/components/code-editor/style.scss rename packages/{interface/src/components/code-editor => editor/src/components/post-text-editor}/style.scss (94%) delete mode 100644 packages/interface/src/components/code-editor-screen/index.js delete mode 100644 packages/interface/src/components/code-editor-screen/style.scss diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index dfcba5d7a886b6..a350d7efe05a8b 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -10,7 +10,8 @@ $z-layers: ( ".block-editor-block-list__layout .reusable-block-indicator": 1, ".block-editor-block-list__block-selection-button": 22, ".components-form-toggle__input": 1, - ".interface-code-editor-screen__toolbar": 1, + ".edit-post-text-editor__toolbar": 1, + ".edit-site-code-editor__toolbar": 1, ".edit-post-sidebar__panel-tab.is-active": 1, // These next three share a stacking context diff --git a/packages/edit-post/src/components/text-editor/index.js b/packages/edit-post/src/components/text-editor/index.js index f39153f09cff84..47f5d1107d76e1 100644 --- a/packages/edit-post/src/components/text-editor/index.js +++ b/packages/edit-post/src/components/text-editor/index.js @@ -4,43 +4,54 @@ import { PostTextEditor, PostTitle, - store as editorStore, TextEditorGlobalKeyboardShortcuts, + store as editorStore, } from '@wordpress/editor'; -import { useDispatch, useSelect } from '@wordpress/data'; -import { CodeEditorScreen } from '@wordpress/interface'; -import { useCallback } from '@wordpress/element'; -import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; +import { Button } from '@wordpress/components'; +import { withDispatch, withSelect } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; +import { displayShortcut } from '@wordpress/keycodes'; +import { compose } from '@wordpress/compose'; /** * Internal dependencies */ import { store as editPostStore } from '../../store'; -export default function TextEditor() { - const { isRichEditingEnabled, shortcut } = useSelect( ( select ) => { - const { getEditorSettings } = select( editorStore ); - const { getShortcutRepresentation } = select( keyboardShortcutsStore ); - return { - isRichEditingEnabled: getEditorSettings().richEditingEnabled, - shortcut: getShortcutRepresentation( 'core/edit-post/toggle-mode' ), - }; - }, [] ); - const { switchEditorMode } = useDispatch( editPostStore ); - const onExit = useCallback( () => switchEditorMode( 'visual' ), [ - switchEditorMode, - ] ); +function TextEditor( { onExit, isRichEditingEnabled } ) { return ( - <> - - +
+ { isRichEditingEnabled && ( +
+

{ __( 'Editing code' ) }

+ + +
+ ) } +
- - +
+
); } + +export default compose( + withSelect( ( select ) => ( { + isRichEditingEnabled: select( editorStore ).getEditorSettings() + .richEditingEnabled, + } ) ), + withDispatch( ( dispatch ) => { + return { + onExit() { + dispatch( editPostStore ).switchEditorMode( 'visual' ); + }, + }; + } ) +)( TextEditor ); diff --git a/packages/edit-post/src/components/text-editor/style.scss b/packages/edit-post/src/components/text-editor/style.scss index 9502ee97ff7336..925e88df27180b 100644 --- a/packages/edit-post/src/components/text-editor/style.scss +++ b/packages/edit-post/src/components/text-editor/style.scss @@ -1,23 +1,75 @@ -// Post title. -.edit-post-text-editor .editor-post-title { - max-width: none; - line-height: $default-line-height; +.edit-post-text-editor { + position: relative; + width: 100%; + background-color: $white; + flex-grow: 1; - font-family: $editor-html-font; - font-size: 2.5em; - font-weight: normal; + // Post title. + .editor-post-title { + max-width: none; + line-height: $default-line-height; - border: $border-width solid $gray-600; + font-family: $editor-html-font; + font-size: 2.5em; + font-weight: normal; - // Same padding as body. - padding: $grid-unit-20; + border: $border-width solid $gray-600; + + // Same padding as body. + padding: $grid-unit-20; + + @include break-small() { + padding: $grid-unit-30; + } + + &:focus { + border-color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + } + } +} + +.edit-post-text-editor__body { + width: 100%; + padding: 0 $grid-unit-15 $grid-unit-15 $grid-unit-15; + max-width: $break-xlarge; + margin-left: auto; + margin-right: auto; + + @include break-large() { + padding: $grid-unit-20 $grid-unit-30 #{ $grid-unit-60 * 2 } $grid-unit-30; + padding: 0 $grid-unit-30 $grid-unit-30 $grid-unit-30; + } + +} + +// Exit code editor toolbar. +.edit-post-text-editor__toolbar { + position: sticky; + z-index: z-index(".edit-post-text-editor__toolbar"); + top: 0; + left: 0; + right: 0; + display: flex; + background: rgba($white, 0.8); + padding: $grid-unit-05 $grid-unit-15; @include break-small() { - padding: $grid-unit-30; + padding: $grid-unit-15; + } + + @include break-large() { + padding: $grid-unit-15 $grid-unit-30; + } + + h2 { + line-height: $button-size; + margin: 0 auto 0 0; + font-size: $default-font-size; + color: $gray-900; } - &:focus { - border-color: var(--wp-admin-theme-color); - box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + .components-button svg { + order: 1; } } diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index 325f86ff5a1011..1d4c1f49cb1f76 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -59,6 +59,7 @@ "history": "^5.1.0", "jszip": "^3.2.2", "lodash": "^4.17.21", + "react-autosize-textarea": "^7.1.0", "rememo": "^3.0.0" }, "publishConfig": { diff --git a/packages/interface/src/components/code-editor/index.js b/packages/edit-site/src/components/code-editor/code-editor-text-area.js similarity index 84% rename from packages/interface/src/components/code-editor/index.js rename to packages/edit-site/src/components/code-editor/code-editor-text-area.js index 9c57357ad06d84..69fd848b1f724d 100644 --- a/packages/interface/src/components/code-editor/index.js +++ b/packages/edit-site/src/components/code-editor/code-editor-text-area.js @@ -9,15 +9,18 @@ import Textarea from 'react-autosize-textarea'; /** * WordPress dependencies */ +/** + * WordPress dependencies + */ import { __ } from '@wordpress/i18n'; import { useState } from '@wordpress/element'; import { useInstanceId } from '@wordpress/compose'; import { VisuallyHidden } from '@wordpress/components'; -export default function CodeEditor( { value, onChange, onInput } ) { +export default function CodeEditorTextArea( { value, onChange, onInput } ) { const [ stateValue, setStateValue ] = useState( value ); const [ isDirty, setIsDirty ] = useState( false ); - const instanceId = useInstanceId( CodeEditor ); + const instanceId = useInstanceId( CodeEditorTextArea ); if ( ! isDirty && stateValue !== value ) { setStateValue( value ); @@ -57,7 +60,7 @@ export default function CodeEditor( { value, onChange, onInput } ) { <> { __( 'Type text or HTML' ) } @@ -67,8 +70,8 @@ export default function CodeEditor( { value, onChange, onInput } ) { value={ stateValue } onChange={ onChangeHandler } onBlur={ stopEditing } - className="interface-code-editor" - id={ `post-content-${ instanceId }` } + className="edit-site-code-editor-text-area" + id={ `code-editor-text-area-${ instanceId }` } placeholder={ __( 'Start writing with text or HTML' ) } /> diff --git a/packages/edit-site/src/components/code-editor/index.js b/packages/edit-site/src/components/code-editor/index.js index bd7d29c603087c..f1a3ea0a13f073 100644 --- a/packages/edit-site/src/components/code-editor/index.js +++ b/packages/edit-site/src/components/code-editor/index.js @@ -1,19 +1,18 @@ /** * WordPress dependencies */ -import { - CodeEditorScreen, - CodeEditor as InterfaceCodeEditor, -} from '@wordpress/interface'; import { parse } from '@wordpress/blocks'; import { useEntityBlockEditor, useEntityProp } from '@wordpress/core-data'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; +import { __ } from '@wordpress/i18n'; +import { Button } from '@wordpress/components'; /** * Internal dependencies */ import { store as editSiteStore } from '../../store'; +import CodeEditorTextArea from './code-editor-text-area'; export default function CodeEditor() { const { templateType, shortcut } = useSelect( ( select ) => { @@ -39,17 +38,28 @@ export default function CodeEditor() { : contentStructure; const { switchEditorMode } = useDispatch( editSiteStore ); return ( - switchEditorMode( 'visual' ) } - exitShortcut={ shortcut } - > - { - onChange( parse( newContent ), { selection: undefined } ); - } } - onInput={ setContent } - /> - +
+
+

{ __( 'Editing code' ) }

+ +
+
+ { + onChange( parse( newContent ), { + selection: undefined, + } ); + } } + onInput={ setContent } + /> +
+
); } diff --git a/packages/edit-site/src/components/code-editor/style.scss b/packages/edit-site/src/components/code-editor/style.scss new file mode 100644 index 00000000000000..a54199788de1b7 --- /dev/null +++ b/packages/edit-site/src/components/code-editor/style.scss @@ -0,0 +1,100 @@ +.edit-site-code-editor { + position: relative; + width: 100%; + background-color: $white; + flex-grow: 1; + + &__body { + width: 100%; + padding: 0 $grid-unit-15 $grid-unit-15 $grid-unit-15; + max-width: $break-xlarge; + margin-left: auto; + margin-right: auto; + + @include break-large() { + padding: $grid-unit-20 $grid-unit-30 #{ $grid-unit-60 * 2 } $grid-unit-30; + padding: 0 $grid-unit-30 $grid-unit-30 $grid-unit-30; + } + } + + // Exit code editor toolbar. + &__toolbar { + position: sticky; + z-index: z-index(".edit-site-code-editor__toolbar"); + top: 0; + left: 0; + right: 0; + display: flex; + background: rgba($white, 0.8); + padding: $grid-unit-05 $grid-unit-15; + + @include break-small() { + padding: $grid-unit-15; + } + + @include break-large() { + padding: $grid-unit-15 $grid-unit-30; + } + + h2 { + line-height: $button-size; + margin: 0 auto 0 0; + font-size: $default-font-size; + color: $gray-900; + } + + .components-button svg { + order: 1; + } + } +} + +textarea.edit-site-code-editor-text-area.edit-site-code-editor-text-area { + border: $border-width solid $gray-600; + border-radius: 0; + display: block; + margin: 0; + width: 100%; + box-shadow: none; + resize: none; + overflow: hidden; + font-family: $editor-html-font; + line-height: 2.4; + min-height: 200px; + transition: border 0.1s ease-out, box-shadow 0.1s linear; + @include reduce-motion("transition"); + + // Same padding as title. + padding: $grid-unit-20; + @include break-small() { + padding: $grid-unit-30; + } + + /* Fonts smaller than 16px causes mobile safari to zoom. */ + font-size: $mobile-text-min-font-size !important; + @include break-small { + font-size: $text-editor-font-size !important; + } + + &:focus { + border-color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + + // Elevate the z-index on focus so the focus style is uncropped. + position: relative; + } + + &::-webkit-input-placeholder { + color: $dark-gray-placeholder; + } + + &::-moz-placeholder { + color: $dark-gray-placeholder; + // Override Firefox default. + opacity: 1; + } + + &:-ms-input-placeholder { + color: $dark-gray-placeholder; + } +} diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index 90f7133f6ae91e..569a443034c886 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -1,6 +1,7 @@ @import "../../interface/src/style.scss"; @import "./components/block-editor/style.scss"; +@import "./components/code-editor/style.scss"; @import "./components/global-styles/style.scss"; @import "./components/header/style.scss"; @import "./components/header/document-actions/style.scss"; diff --git a/packages/editor/package.json b/packages/editor/package.json index 750c994f58b5ca..311b62ced238fa 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -49,7 +49,6 @@ "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", - "@wordpress/interface": "file:../interface", "@wordpress/is-shallow-equal": "file:../is-shallow-equal", "@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts", "@wordpress/keycodes": "file:../keycodes", diff --git a/packages/editor/src/components/post-text-editor/index.js b/packages/editor/src/components/post-text-editor/index.js index edd9b74042386d..55bcb7228bf016 100644 --- a/packages/editor/src/components/post-text-editor/index.js +++ b/packages/editor/src/components/post-text-editor/index.js @@ -1,9 +1,17 @@ +/** + * External dependencies + */ +import Textarea from 'react-autosize-textarea'; + /** * WordPress dependencies */ +import { __ } from '@wordpress/i18n'; +import { useState } from '@wordpress/element'; import { parse } from '@wordpress/blocks'; import { useDispatch, useSelect } from '@wordpress/data'; -import { CodeEditor } from '@wordpress/interface'; +import { useInstanceId } from '@wordpress/compose'; +import { VisuallyHidden } from '@wordpress/components'; /** * Internal dependencies @@ -15,15 +23,66 @@ export default function PostTextEditor() { ( select ) => select( editorStore ).getEditedPostContent(), [] ); + const { editPost, resetEditorBlocks } = useDispatch( editorStore ); + + const [ value, setValue ] = useState( postContent ); + const [ isDirty, setIsDirty ] = useState( false ); + const instanceId = useInstanceId( PostTextEditor ); + + if ( ! isDirty && value !== postContent ) { + setValue( postContent ); + } + + /** + * Handles a textarea change event to notify the onChange prop callback and + * reflect the new value in the component's own state. This marks the start + * of the user's edits, if not already changed, preventing future props + * changes to value from replacing the rendered value. This is expected to + * be followed by a reset to dirty state via `stopEditing`. + * + * @see stopEditing + * + * @param {Event} event Change event. + */ + const onChange = ( event ) => { + const newValue = event.target.value; + editPost( { content: newValue } ); + setValue( newValue ); + setIsDirty( true ); + }; + + /** + * Function called when the user has completed their edits, responsible for + * ensuring that changes, if made, are surfaced to the onPersist prop + * callback and resetting dirty state. + */ + const stopEditing = () => { + if ( isDirty ) { + const blocks = parse( value ); + resetEditorBlocks( blocks ); + setIsDirty( false ); + } + }; + return ( - editPost( { content: newContent } ) } - onChange={ ( newContent ) => { - const blocks = parse( newContent ); - resetEditorBlocks( blocks ); - } } - /> + <> + + { __( 'Type text or HTML' ) } + +