From e72841df8a77404ddbca29f84fc7613a15062061 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 8 Jan 2024 11:32:37 +0100 Subject: [PATCH 1/4] Unify the preferences modal UI between post and site editor --- lib/client-assets.php | 21 +- package-lock.json | 4 + packages/base-styles/_z-index.scss | 4 +- .../{options => }/enable-custom-fields.js | 13 +- .../{options => }/enable-panel.js | 11 +- .../{options => }/enable-publish-sidebar.js | 11 +- .../src/components/preferences-modal/index.js | 311 ++---------- .../preferences-modal/meta-boxes-section.js | 8 +- .../options/enable-feature.js | 31 -- .../preferences-modal/options/index.js | 5 - .../enable-custom-fields.js.snap | 0 .../test/enable-custom-fields.js | 0 .../plugin-document-setting-panel/index.js | 8 +- packages/edit-post/src/editor.js | 140 +++--- packages/edit-post/src/editor.native.js | 37 +- packages/edit-post/src/index.js | 2 +- packages/edit-post/src/index.native.js | 2 +- packages/edit-post/src/store/actions.js | 10 +- packages/edit-post/src/store/selectors.js | 34 +- packages/edit-post/src/style.scss | 1 - .../src/components/preferences-modal/index.js | 219 +-------- .../src/components/block-manager/category.js | 62 +-- .../src/components/block-manager/checklist.js | 4 +- .../src/components/block-manager/index.js | 31 +- .../src/components/block-manager/style.scss | 28 +- .../preferences-modal/enable-panel.js} | 13 +- .../enable-plugin-document-setting-panel.js | 2 +- .../src/components/preferences-modal/index.js | 269 ++++++++++ .../__snapshots__/meta-boxes-section.js.snap | 464 ++++++++++++++++++ .../preferences-modal/test/index.js | 28 ++ .../provider/use-block-editor-settings.js | 29 +- packages/editor/src/private-apis.js | 8 +- packages/editor/src/store/private-actions.js | 49 ++ packages/editor/src/style.scss | 1 + packages/interface/src/components/index.js | 4 - .../preferences-modal-section/index.js | 19 - packages/interface/src/style.scss | 4 - .../convert-editor-settings.js | 1 + packages/preferences/package.json | 2 + .../preference-base-option}/README.md | 10 +- .../preference-base-option}/index.js | 2 +- .../preference-base-option}/style.scss | 2 +- .../preference-toggle-control/index.js} | 17 +- .../preferences-modal-section/README.md | 1 + .../preferences-modal-section/index.js | 15 + .../preferences-modal-section/style.scss | 10 +- .../preferences-modal-tabs/README.md | 0 .../preferences-modal-tabs/index.js | 12 +- .../preferences-modal-tabs/style.scss | 8 +- .../components/preferences-modal/README.md | 2 +- .../src/components/preferences-modal/index.js | 2 +- .../components/preferences-modal/style.scss | 2 +- packages/preferences/src/index.js | 1 + packages/preferences/src/lock-unlock.js | 9 + packages/preferences/src/private-apis.js | 18 + packages/preferences/src/store/index.js | 2 +- packages/preferences/src/style.scss | 4 + packages/private-apis/src/implementation.js | 1 + 58 files changed, 1202 insertions(+), 806 deletions(-) rename packages/edit-post/src/components/preferences-modal/{options => }/enable-custom-fields.js (87%) rename packages/edit-post/src/components/preferences-modal/{options => }/enable-panel.js (72%) rename packages/edit-post/src/components/preferences-modal/{options => }/enable-publish-sidebar.js (75%) delete mode 100644 packages/edit-post/src/components/preferences-modal/options/enable-feature.js delete mode 100644 packages/edit-post/src/components/preferences-modal/options/index.js rename packages/edit-post/src/components/preferences-modal/{options => }/test/__snapshots__/enable-custom-fields.js.snap (100%) rename packages/edit-post/src/components/preferences-modal/{options => }/test/enable-custom-fields.js (100%) rename packages/{edit-post => editor}/src/components/block-manager/category.js (57%) rename packages/{edit-post => editor}/src/components/block-manager/checklist.js (85%) rename packages/{edit-post => editor}/src/components/block-manager/index.js (84%) rename packages/{edit-post => editor}/src/components/block-manager/style.scss (66%) rename packages/{edit-site/src/components/preferences-modal/enable-panel-option.js => editor/src/components/preferences-modal/enable-panel.js} (66%) rename packages/{edit-post/src/components/preferences-modal/options => editor/src/components/preferences-modal}/enable-plugin-document-setting-panel.js (90%) create mode 100644 packages/editor/src/components/preferences-modal/index.js create mode 100644 packages/editor/src/components/preferences-modal/test/__snapshots__/meta-boxes-section.js.snap create mode 100644 packages/editor/src/components/preferences-modal/test/index.js delete mode 100644 packages/interface/src/components/preferences-modal-section/index.js rename packages/{interface/src/components/preferences-modal-base-option => preferences/src/components/preference-base-option}/README.md (69%) rename packages/{interface/src/components/preferences-modal-base-option => preferences/src/components/preference-base-option}/index.js (86%) rename packages/{interface/src/components/preferences-modal-base-option => preferences/src/components/preference-base-option}/style.scss (75%) rename packages/{edit-site/src/components/preferences-modal/enable-feature.js => preferences/src/components/preference-toggle-control/index.js} (66%) rename packages/{interface => preferences}/src/components/preferences-modal-section/README.md (94%) create mode 100644 packages/preferences/src/components/preferences-modal-section/index.js rename packages/{interface => preferences}/src/components/preferences-modal-section/style.scss (50%) rename packages/{interface => preferences}/src/components/preferences-modal-tabs/README.md (100%) rename packages/{interface => preferences}/src/components/preferences-modal-tabs/index.js (93%) rename packages/{interface => preferences}/src/components/preferences-modal-tabs/style.scss (85%) rename packages/{interface => preferences}/src/components/preferences-modal/README.md (96%) rename packages/{interface => preferences}/src/components/preferences-modal/index.js (87%) rename packages/{interface => preferences}/src/components/preferences-modal/style.scss (94%) create mode 100644 packages/preferences/src/lock-unlock.js create mode 100644 packages/preferences/src/private-apis.js create mode 100644 packages/preferences/src/style.scss diff --git a/lib/client-assets.php b/lib/client-assets.php index c5b03b6833d030..717267a5e2a504 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -266,7 +266,7 @@ function gutenberg_register_packages_styles( $styles ) { $styles, 'wp-block-editor', gutenberg_url( 'build/block-editor/style.css' ), - array( 'wp-components' ), + array( 'wp-components', 'wp-preferences' ), $version ); $styles->add_data( 'wp-block-editor', 'rtl', 'replace' ); @@ -275,7 +275,7 @@ function gutenberg_register_packages_styles( $styles ) { $styles, 'wp-editor', gutenberg_url( 'build/editor/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-patterns', 'wp-reusable-blocks' ), + array( 'wp-components', 'wp-block-editor', 'wp-patterns', 'wp-reusable-blocks', 'wp-preferences' ), $version ); $styles->add_data( 'wp-editor', 'rtl', 'replace' ); @@ -284,7 +284,7 @@ function gutenberg_register_packages_styles( $styles ) { $styles, 'wp-edit-post', gutenberg_url( 'build/edit-post/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-commands' ), + array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-commands', 'wp-preferences' ), $version ); $styles->add_data( 'wp-edit-post', 'rtl', 'replace' ); @@ -409,7 +409,7 @@ function gutenberg_register_packages_styles( $styles ) { $styles, 'wp-edit-site', gutenberg_url( 'build/edit-site/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-commands' ), + array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-commands', 'wp-preferences' ), $version ); $styles->add_data( 'wp-edit-site', 'rtl', 'replace' ); @@ -418,7 +418,7 @@ function gutenberg_register_packages_styles( $styles ) { $styles, 'wp-edit-widgets', gutenberg_url( 'build/edit-widgets/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-patterns', 'wp-reusable-blocks', 'wp-widgets' ), + array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-patterns', 'wp-reusable-blocks', 'wp-widgets', 'wp-preferences' ), $version ); $styles->add_data( 'wp-edit-widgets', 'rtl', 'replace' ); @@ -436,7 +436,7 @@ function gutenberg_register_packages_styles( $styles ) { $styles, 'wp-customize-widgets', gutenberg_url( 'build/customize-widgets/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-widgets' ), + array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-widgets', 'wp-preferences' ), $version ); $styles->add_data( 'wp-customize-widgets', 'rtl', 'replace' ); @@ -466,6 +466,15 @@ function gutenberg_register_packages_styles( $styles ) { array( 'wp-components' ) ); $styles->add_data( 'wp-widgets', 'rtl', 'replace' ); + + gutenberg_override_style( + $styles, + 'wp-preferences', + gutenberg_url( 'build/preferences/style.css' ), + array( 'wp-components' ), + $version + ); + $styles->add_data( 'wp-preferences', 'rtl', 'replace' ); } add_action( 'wp_default_styles', 'gutenberg_register_packages_styles' ); diff --git a/package-lock.json b/package-lock.json index dc84ae2fba494e..626b31a3ee9f81 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55595,10 +55595,12 @@ "@babel/runtime": "^7.16.0", "@wordpress/a11y": "file:../a11y", "@wordpress/components": "file:../components", + "@wordpress/compose": "file:../compose", "@wordpress/data": "file:../data", "@wordpress/element": "file:../element", "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", + "@wordpress/private-apis": "file:../private-apis", "classnames": "^2.3.1" }, "engines": { @@ -70260,10 +70262,12 @@ "@babel/runtime": "^7.16.0", "@wordpress/a11y": "file:../a11y", "@wordpress/components": "file:../components", + "@wordpress/compose": "file:../compose", "@wordpress/data": "file:../data", "@wordpress/element": "file:../element", "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", + "@wordpress/private-apis": "file:../private-apis", "classnames": "^2.3.1" } }, diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index 36d01c843c1c73..e6d8d12769e701 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -161,9 +161,9 @@ $z-layers: ( ".components-resizable-box__corner-handle": 2, // Make sure block manager sticky category titles appear above the options - ".edit-post-block-manager__category-title": 1, + ".editor-block-manager__category-title": 1, // And block manager sticky disabled block count is higher still - ".edit-post-block-manager__disabled-blocks-count": 2, + ".editor-block-manager__disabled-blocks-count": 2, // Needs to appear below other color circular picker related UI elements. ".components-circular-option-picker__option-wrapper::before": -1, diff --git a/packages/edit-post/src/components/preferences-modal/options/enable-custom-fields.js b/packages/edit-post/src/components/preferences-modal/enable-custom-fields.js similarity index 87% rename from packages/edit-post/src/components/preferences-modal/options/enable-custom-fields.js rename to packages/edit-post/src/components/preferences-modal/enable-custom-fields.js index 15521b80b361b2..e3ba4a15684200 100644 --- a/packages/edit-post/src/components/preferences-modal/options/enable-custom-fields.js +++ b/packages/edit-post/src/components/preferences-modal/enable-custom-fields.js @@ -6,9 +6,16 @@ import { __ } from '@wordpress/i18n'; import { Button } from '@wordpress/components'; import { withSelect } from '@wordpress/data'; import { store as editorStore } from '@wordpress/editor'; -import { ___unstablePreferencesModalBaseOption as BaseOption } from '@wordpress/interface'; +import { privateApis as preferencesPrivateApis } from '@wordpress/preferences'; import { getPathAndQueryString } from '@wordpress/url'; +/** + * Internal dependencies + */ +import { unlock } from '../../lock-unlock'; + +const { PreferenceBaseOption } = unlock( preferencesPrivateApis ); + function submitCustomFieldsForm() { const customFieldsForm = document.getElementById( 'toggle-custom-fields-form' @@ -53,7 +60,7 @@ export function EnableCustomFieldsOption( { label, areCustomFieldsEnabled } ) { const [ isChecked, setIsChecked ] = useState( areCustomFieldsEnabled ); return ( - ) } - + ); } diff --git a/packages/edit-post/src/components/preferences-modal/options/enable-panel.js b/packages/edit-post/src/components/preferences-modal/enable-panel.js similarity index 72% rename from packages/edit-post/src/components/preferences-modal/options/enable-panel.js rename to packages/edit-post/src/components/preferences-modal/enable-panel.js index 6c9ea22b7f17dd..d698cdc360cae2 100644 --- a/packages/edit-post/src/components/preferences-modal/options/enable-panel.js +++ b/packages/edit-post/src/components/preferences-modal/enable-panel.js @@ -3,8 +3,15 @@ */ import { compose, ifCondition } from '@wordpress/compose'; import { withSelect, withDispatch } from '@wordpress/data'; -import { ___unstablePreferencesModalBaseOption as BaseOption } from '@wordpress/interface'; import { store as editorStore } from '@wordpress/editor'; +import { privateApis as preferencesPrivateApis } from '@wordpress/preferences'; + +/** + * Internal dependencies + */ +import { unlock } from '../../lock-unlock'; + +const { PreferenceBaseOption } = unlock( preferencesPrivateApis ); export default compose( withSelect( ( select, { panelName } ) => { @@ -20,4 +27,4 @@ export default compose( onChange: () => dispatch( editorStore ).toggleEditorPanelEnabled( panelName ), } ) ) -)( BaseOption ); +)( PreferenceBaseOption ); diff --git a/packages/edit-post/src/components/preferences-modal/options/enable-publish-sidebar.js b/packages/edit-post/src/components/preferences-modal/enable-publish-sidebar.js similarity index 75% rename from packages/edit-post/src/components/preferences-modal/options/enable-publish-sidebar.js rename to packages/edit-post/src/components/preferences-modal/enable-publish-sidebar.js index fa309bedf24616..84f4e72a946091 100644 --- a/packages/edit-post/src/components/preferences-modal/options/enable-publish-sidebar.js +++ b/packages/edit-post/src/components/preferences-modal/enable-publish-sidebar.js @@ -5,7 +5,14 @@ import { compose } from '@wordpress/compose'; import { withSelect, withDispatch } from '@wordpress/data'; import { ifViewportMatches } from '@wordpress/viewport'; import { store as editorStore } from '@wordpress/editor'; -import { ___unstablePreferencesModalBaseOption as BaseOption } from '@wordpress/interface'; +import { privateApis as preferencesPrivateApis } from '@wordpress/preferences'; + +/** + * Internal dependencies + */ +import { unlock } from '../../lock-unlock'; + +const { PreferenceBaseOption } = unlock( preferencesPrivateApis ); export default compose( withSelect( ( select ) => ( { @@ -22,4 +29,4 @@ export default compose( // In < medium viewports we override this option and always show the publish sidebar. // See the edit-post's header component for the specific logic. ifViewportMatches( 'medium' ) -)( BaseOption ); +)( PreferenceBaseOption ); diff --git a/packages/edit-post/src/components/preferences-modal/index.js b/packages/edit-post/src/components/preferences-modal/index.js index a422e4d0a207a2..b99be5cb34c384 100644 --- a/packages/edit-post/src/components/preferences-modal/index.js +++ b/packages/edit-post/src/components/preferences-modal/index.js @@ -5,294 +5,71 @@ import { __ } from '@wordpress/i18n'; import { useViewportMatch } from '@wordpress/compose'; import { useSelect, useDispatch } from '@wordpress/data'; -import { useMemo } from '@wordpress/element'; -import { - PostTaxonomies, - PostExcerptCheck, - PageAttributesCheck, - PostFeaturedImageCheck, - PostTypeSupportCheck, - store as editorStore, -} from '@wordpress/editor'; -import { - PreferencesModal, - PreferencesModalTabs, - PreferencesModalSection, - store as interfaceStore, -} from '@wordpress/interface'; -import { store as preferencesStore } from '@wordpress/preferences'; +import { store as interfaceStore } from '@wordpress/interface'; +import { privateApis as preferencesPrivateApis } from '@wordpress/preferences'; +import { privateApis as editorPrivateApis } from '@wordpress/editor'; /** * Internal dependencies */ - -import { - EnablePluginDocumentSettingPanelOption, - EnablePublishSidebarOption, - EnablePanelOption, - EnableFeature, -} from './options'; +import { unlock } from '../../lock-unlock'; import MetaBoxesSection from './meta-boxes-section'; -import { store as editPostStore } from '../../store'; -import BlockManager from '../block-manager'; +import EnablePublishSidebarOption from './enable-publish-sidebar'; + +const { PreferencesModalSection, PreferenceToggleControl } = unlock( + preferencesPrivateApis +); +const { PreferencesModal } = unlock( editorPrivateApis ); export const PREFERENCES_MODAL_NAME = 'edit-post/preferences'; export default function EditPostPreferencesModal() { const isLargeViewport = useViewportMatch( 'medium' ); const { closeModal } = useDispatch( interfaceStore ); - const [ isModalActive, showBlockBreadcrumbsOption ] = useSelect( - ( select ) => { - const { getEditorSettings } = select( editorStore ); - const { getEditorMode } = select( editPostStore ); - const { get } = select( preferencesStore ); - const modalActive = select( interfaceStore ).isModalActive( - PREFERENCES_MODAL_NAME - ); - const mode = getEditorMode(); - const isRichEditingEnabled = getEditorSettings().richEditingEnabled; - const isDistractionFreeEnabled = get( 'core', 'distractionFree' ); - return [ - modalActive, - ! isDistractionFreeEnabled && - isLargeViewport && - isRichEditingEnabled && - mode === 'visual', - isDistractionFreeEnabled, - ]; - }, - [ isLargeViewport ] - ); - - const { closeGeneralSidebar } = useDispatch( editPostStore ); - const { setIsListViewOpened, setIsInserterOpened } = - useDispatch( editorStore ); - const { set: setPreference } = useDispatch( preferencesStore ); - - const toggleDistractionFree = () => { - setPreference( 'core', 'fixedToolbar', true ); - setIsInserterOpened( false ); - setIsListViewOpened( false ); - closeGeneralSidebar(); - }; + const { isModalActive } = useSelect( ( select ) => { + const modalActive = select( interfaceStore ).isModalActive( + PREFERENCES_MODAL_NAME + ); + return { + isModalActive: modalActive, + }; + }, [] ); - const turnOffDistractionFree = () => { - setPreference( 'core', 'distractionFree', false ); - }; - - const sections = useMemo( - () => [ - { - name: 'general', - tabLabel: __( 'General' ), - content: ( - <> - { isLargeViewport && ( - - - - ) } - - - { showBlockBreadcrumbsOption && ( - - ) } - - - - - ( - - ) } - /> - - - - - - - - - - - - - - - - ), - }, - { - name: 'appearance', - tabLabel: __( 'Appearance' ), - content: ( - - + { isLargeViewport && ( + + - - - - ), - }, - { - name: 'accessibility', - tabLabel: __( 'Accessibility' ), - content: ( - <> - - - - - - - - ), - }, - { - name: 'blocks', - tabLabel: __( 'Blocks' ), - content: ( - <> - - - - - - - - ), - }, - ], - [ isLargeViewport, showBlockBreadcrumbsOption ] - ); + ) } + + + ), + appearance: ( + + ), + }; if ( ! isModalActive ) { return null; } return ( - - - + ); } diff --git a/packages/edit-post/src/components/preferences-modal/meta-boxes-section.js b/packages/edit-post/src/components/preferences-modal/meta-boxes-section.js index c160137cfa4518..2974e81547dbd6 100644 --- a/packages/edit-post/src/components/preferences-modal/meta-boxes-section.js +++ b/packages/edit-post/src/components/preferences-modal/meta-boxes-section.js @@ -4,13 +4,17 @@ import { __ } from '@wordpress/i18n'; import { withSelect } from '@wordpress/data'; import { store as editorStore } from '@wordpress/editor'; -import { PreferencesModalSection } from '@wordpress/interface'; +import { privateApis as preferencesPrivateApis } from '@wordpress/preferences'; /** * Internal dependencies */ -import { EnableCustomFieldsOption, EnablePanelOption } from './options'; +import EnableCustomFieldsOption from './enable-custom-fields'; +import EnablePanelOption from './enable-panel'; import { store as editPostStore } from '../../store'; +import { unlock } from '../../lock-unlock'; + +const { PreferencesModalSection } = unlock( preferencesPrivateApis ); export function MetaBoxesSection( { areCustomFieldsRegistered, diff --git a/packages/edit-post/src/components/preferences-modal/options/enable-feature.js b/packages/edit-post/src/components/preferences-modal/options/enable-feature.js deleted file mode 100644 index b3f3a4bbe69239..00000000000000 --- a/packages/edit-post/src/components/preferences-modal/options/enable-feature.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * WordPress dependencies - */ -import { useSelect, useDispatch } from '@wordpress/data'; -import { ___unstablePreferencesModalBaseOption as BaseOption } from '@wordpress/interface'; -import { store as preferencesStore } from '@wordpress/preferences'; - -export default function EnableFeature( props ) { - const { - scope = 'core/edit-post', - featureName, - onToggle = () => {}, - ...remainingProps - } = props; - const isChecked = useSelect( - ( select ) => !! select( preferencesStore ).get( scope, featureName ), - [ scope, featureName ] - ); - const { toggle } = useDispatch( preferencesStore ); - const onChange = () => { - onToggle(); - toggle( scope, featureName ); - }; - return ( - - ); -} diff --git a/packages/edit-post/src/components/preferences-modal/options/index.js b/packages/edit-post/src/components/preferences-modal/options/index.js deleted file mode 100644 index b5cb1c6c4fe1b7..00000000000000 --- a/packages/edit-post/src/components/preferences-modal/options/index.js +++ /dev/null @@ -1,5 +0,0 @@ -export { default as EnableCustomFieldsOption } from './enable-custom-fields'; -export { default as EnablePanelOption } from './enable-panel'; -export { default as EnablePluginDocumentSettingPanelOption } from './enable-plugin-document-setting-panel'; -export { default as EnablePublishSidebarOption } from './enable-publish-sidebar'; -export { default as EnableFeature } from './enable-feature'; diff --git a/packages/edit-post/src/components/preferences-modal/options/test/__snapshots__/enable-custom-fields.js.snap b/packages/edit-post/src/components/preferences-modal/test/__snapshots__/enable-custom-fields.js.snap similarity index 100% rename from packages/edit-post/src/components/preferences-modal/options/test/__snapshots__/enable-custom-fields.js.snap rename to packages/edit-post/src/components/preferences-modal/test/__snapshots__/enable-custom-fields.js.snap diff --git a/packages/edit-post/src/components/preferences-modal/options/test/enable-custom-fields.js b/packages/edit-post/src/components/preferences-modal/test/enable-custom-fields.js similarity index 100% rename from packages/edit-post/src/components/preferences-modal/options/test/enable-custom-fields.js rename to packages/edit-post/src/components/preferences-modal/test/enable-custom-fields.js diff --git a/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js index e77b1ce71160d2..09460b8d8624ed 100644 --- a/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js @@ -5,14 +5,18 @@ import { createSlotFill, PanelBody } from '@wordpress/components'; import { usePluginContext } from '@wordpress/plugins'; import { useDispatch, useSelect } from '@wordpress/data'; import warning from '@wordpress/warning'; -import { store as editorStore } from '@wordpress/editor'; +import { + store as editorStore, + privateApis as editorPrivateApis, +} from '@wordpress/editor'; /** * Internal dependencies */ -import { EnablePluginDocumentSettingPanelOption } from '../../preferences-modal/options'; +import { unlock } from '../../../lock-unlock'; const { Fill, Slot } = createSlotFill( 'PluginDocumentSettingPanel' ); +const { EnablePluginDocumentSettingPanelOption } = unlock( editorPrivateApis ); /** * Renders items below the Status & Availability panel in the Document Sidebar. diff --git a/packages/edit-post/src/editor.js b/packages/edit-post/src/editor.js index d1c7cdbade44f8..45bdd88318e499 100644 --- a/packages/edit-post/src/editor.js +++ b/packages/edit-post/src/editor.js @@ -1,7 +1,6 @@ /** * WordPress dependencies */ -import { store as blocksStore } from '@wordpress/blocks'; import { useSelect, useDispatch } from '@wordpress/data'; import { ErrorBoundary, @@ -38,68 +37,61 @@ function Editor( { initialPostType ); - const { - hasInlineToolbar, - post, - preferredStyleVariations, - hiddenBlockTypes, - blockTypes, - template, - } = useSelect( - ( select ) => { - const { - isFeatureActive, - getEditedPostTemplate, - getHiddenBlockTypes, - } = select( editPostStore ); - const { getEntityRecord, getPostType, getEntityRecords, canUser } = - select( coreStore ); - const { getEditorSettings } = select( editorStore ); - const { getBlockTypes } = select( blocksStore ); - const isTemplate = [ 'wp_template', 'wp_template_part' ].includes( - currentPost.postType - ); - // Ideally the initializeEditor function should be called using the ID of the REST endpoint. - // to avoid the special case. - let postObject; - if ( isTemplate ) { - const posts = getEntityRecords( - 'postType', - currentPost.postType, - { - wp_id: currentPost.postId, - } - ); - postObject = posts?.[ 0 ]; - } else { - postObject = getEntityRecord( - 'postType', - currentPost.postType, - currentPost.postId - ); - } - const supportsTemplateMode = - getEditorSettings().supportsTemplateMode; - const isViewable = - getPostType( currentPost.postType )?.viewable ?? false; - const canEditTemplate = canUser( 'create', 'templates' ); - return { - hasInlineToolbar: isFeatureActive( 'inlineToolbar' ), - preferredStyleVariations: select( preferencesStore ).get( - 'core/edit-post', - 'preferredStyleVariations' - ), - hiddenBlockTypes: getHiddenBlockTypes(), - blockTypes: getBlockTypes(), - template: - supportsTemplateMode && isViewable && canEditTemplate - ? getEditedPostTemplate() - : null, - post: postObject, - }; - }, - [ currentPost.postType, currentPost.postId ] - ); + const { hasInlineToolbar, post, preferredStyleVariations, template } = + useSelect( + ( select ) => { + const { isFeatureActive, getEditedPostTemplate } = + select( editPostStore ); + const { + getEntityRecord, + getPostType, + getEntityRecords, + canUser, + } = select( coreStore ); + const { getEditorSettings } = select( editorStore ); + const isTemplate = [ + 'wp_template', + 'wp_template_part', + ].includes( currentPost.postType ); + // Ideally the initializeEditor function should be called using the ID of the REST endpoint. + // to avoid the special case. + let postObject; + if ( isTemplate ) { + const posts = getEntityRecords( + 'postType', + currentPost.postType, + { + wp_id: currentPost.postId, + } + ); + postObject = posts?.[ 0 ]; + } else { + postObject = getEntityRecord( + 'postType', + currentPost.postType, + currentPost.postId + ); + } + const supportsTemplateMode = + getEditorSettings().supportsTemplateMode; + const isViewable = + getPostType( currentPost.postType )?.viewable ?? false; + const canEditTemplate = canUser( 'create', 'templates' ); + return { + hasInlineToolbar: isFeatureActive( 'inlineToolbar' ), + preferredStyleVariations: select( preferencesStore ).get( + 'core/edit-post', + 'preferredStyleVariations' + ), + template: + supportsTemplateMode && isViewable && canEditTemplate + ? getEditedPostTemplate() + : null, + post: postObject, + }; + }, + [ currentPost.postType, currentPost.postId ] + ); const { updatePreferredStyleVariations } = useDispatch( editPostStore ); @@ -113,33 +105,11 @@ function Editor( { onChange: updatePreferredStyleVariations, }, hasInlineToolbar, - - // Keep a reference of the `allowedBlockTypes` from the server to handle use cases - // where we need to differentiate if a block is disabled by the user or some plugin. - defaultAllowedBlockTypes: settings.allowedBlockTypes, }; - - // Omit hidden block types if exists and non-empty. - if ( hiddenBlockTypes.length > 0 ) { - // Defer to passed setting for `allowedBlockTypes` if provided as - // anything other than `true` (where `true` is equivalent to allow - // all block types). - const defaultAllowedBlockTypes = - true === settings.allowedBlockTypes - ? blockTypes.map( ( { name } ) => name ) - : settings.allowedBlockTypes || []; - - result.allowedBlockTypes = defaultAllowedBlockTypes.filter( - ( type ) => ! hiddenBlockTypes.includes( type ) - ); - } - return result; }, [ settings, hasInlineToolbar, - hiddenBlockTypes, - blockTypes, preferredStyleVariations, updatePreferredStyleVariations, getPostLinkProps, diff --git a/packages/edit-post/src/editor.native.js b/packages/edit-post/src/editor.native.js index 74d4299a2a1fd1..1e49673540e37e 100644 --- a/packages/edit-post/src/editor.native.js +++ b/packages/edit-post/src/editor.native.js @@ -10,7 +10,7 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler'; */ import { Component } from '@wordpress/element'; import { EditorProvider } from '@wordpress/editor'; -import { parse, serialize, store as blocksStore } from '@wordpress/blocks'; +import { parse, serialize } from '@wordpress/blocks'; import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { @@ -47,32 +47,12 @@ class Editor extends Component { this.setTitleRef = this.setTitleRef.bind( this ); } - getEditorSettings( settings, hiddenBlockTypes, blockTypes ) { + getEditorSettings( settings ) { settings = { ...settings, isRTL: I18nManager.isRTL, }; - // Omit hidden block types if exists and non-empty. - if ( hiddenBlockTypes.length > 0 ) { - if ( settings.allowedBlockTypes === undefined ) { - // If no specific flags for allowedBlockTypes are set, assume `true` - // meaning allow all block types. - settings.allowedBlockTypes = true; - } - // Defer to passed setting for `allowedBlockTypes` if provided as - // anything other than `true` (where `true` is equivalent to allow - // all block types). - const defaultAllowedBlockTypes = - true === settings.allowedBlockTypes - ? blockTypes.map( ( { name } ) => name ) - : settings.allowedBlockTypes || []; - - settings.allowedBlockTypes = defaultAllowedBlockTypes.filter( - ( type ) => ! hiddenBlockTypes.includes( type ) - ); - } - return settings; } @@ -127,8 +107,6 @@ class Editor extends Component { const { settings, initialEdits, - hiddenBlockTypes, - blockTypes, post, postId, postType, @@ -137,11 +115,7 @@ class Editor extends Component { ...props } = this.props; - const editorSettings = this.getEditorSettings( - settings, - hiddenBlockTypes, - blockTypes - ); + const editorSettings = this.getEditorSettings( settings ); const normalizedPost = post || { id: postId, @@ -180,13 +154,10 @@ class Editor extends Component { export default compose( [ withSelect( ( select ) => { - const { getEditorMode, getHiddenBlockTypes } = select( editPostStore ); - const { getBlockTypes } = select( blocksStore ); + const { getEditorMode } = select( editPostStore ); return { mode: getEditorMode(), - hiddenBlockTypes: getHiddenBlockTypes(), - blockTypes: getBlockTypes(), }; } ), withDispatch( ( dispatch ) => { diff --git a/packages/edit-post/src/index.js b/packages/edit-post/src/index.js index b9409f22f6ab33..78c79227c9d897 100644 --- a/packages/edit-post/src/index.js +++ b/packages/edit-post/src/index.js @@ -54,7 +54,6 @@ export function initializeEditor( dispatch( preferencesStore ).setDefaults( 'core/edit-post', { fullscreenMode: true, - hiddenBlockTypes: [], isPublishSidebarEnabled: true, preferredStyleVariations: {}, themeStyles: true, @@ -66,6 +65,7 @@ export function initializeEditor( allowRightClickOverrides: true, editorMode: 'visual', fixedToolbar: false, + hiddenBlockTypes: [], inactivePanels: [], openPanels: [ 'post-status' ], showBlockBreadcrumbs: true, diff --git a/packages/edit-post/src/index.native.js b/packages/edit-post/src/index.native.js index 974f617d609f23..c1b5126dba3b12 100644 --- a/packages/edit-post/src/index.native.js +++ b/packages/edit-post/src/index.native.js @@ -24,7 +24,6 @@ export function initializeEditor( id, postType, postId ) { dispatch( preferencesStore ).setDefaults( 'core/edit-post', { editorMode: 'visual', fullscreenMode: true, - hiddenBlockTypes: [], inactivePanels: [], isPublishSidebarEnabled: true, openPanels: [ 'post-status' ], @@ -32,6 +31,7 @@ export function initializeEditor( id, postType, postId ) { welcomeGuide: true, } ); dispatch( preferencesStore ).setDefaults( 'core', { + hiddenBlockTypes: [], inactivePanels: [], openPanels: [ 'post-status' ], } ); diff --git a/packages/edit-post/src/store/actions.js b/packages/edit-post/src/store/actions.js index 642640335d053d..ddbc3b120d0ebb 100644 --- a/packages/edit-post/src/store/actions.js +++ b/packages/edit-post/src/store/actions.js @@ -290,7 +290,7 @@ export const showBlockTypes = const existingBlockNames = registry .select( preferencesStore ) - .get( 'core/edit-post', 'hiddenBlockTypes' ) ?? []; + .get( 'core', 'hiddenBlockTypes' ) ?? []; const newBlockNames = existingBlockNames.filter( ( type ) => @@ -301,7 +301,7 @@ export const showBlockTypes = registry .dispatch( preferencesStore ) - .set( 'core/edit-post', 'hiddenBlockTypes', newBlockNames ); + .set( 'core', 'hiddenBlockTypes', newBlockNames ); }; /** @@ -315,7 +315,7 @@ export const hideBlockTypes = const existingBlockNames = registry .select( preferencesStore ) - .get( 'core/edit-post', 'hiddenBlockTypes' ) ?? []; + .get( 'core', 'hiddenBlockTypes' ) ?? []; const mergedBlockNames = new Set( [ ...existingBlockNames, @@ -324,9 +324,7 @@ export const hideBlockTypes = registry .dispatch( preferencesStore ) - .set( 'core/edit-post', 'hiddenBlockTypes', [ - ...mergedBlockNames, - ] ); + .set( 'core', 'hiddenBlockTypes', [ ...mergedBlockNames ] ); }; /** diff --git a/packages/edit-post/src/store/selectors.js b/packages/edit-post/src/store/selectors.js index 26f888999e9fbc..b6a54dfd0de2cb 100644 --- a/packages/edit-post/src/store/selectors.js +++ b/packages/edit-post/src/store/selectors.js @@ -164,21 +164,21 @@ export const getPreferences = createRegistrySelector( ( select ) => () => { // These preferences now exist in the preferences store. // Fetch them so that they can be merged into the post // editor preferences. - const preferences = [ - 'hiddenBlockTypes', - 'preferredStyleVariations', - ].reduce( ( accumulatedPrefs, preferenceKey ) => { - const value = select( preferencesStore ).get( - 'core/edit-post', - preferenceKey - ); + const preferences = [ 'preferredStyleVariations' ].reduce( + ( accumulatedPrefs, preferenceKey ) => { + const value = select( preferencesStore ).get( + 'core/edit-post', + preferenceKey + ); - return { - ...accumulatedPrefs, - [ preferenceKey ]: value, - }; - }, {} ); - const corePreferences = [ 'editorMode' ].reduce( + return { + ...accumulatedPrefs, + [ preferenceKey ]: value, + }; + }, + {} + ); + const corePreferences = [ 'editorMode', 'hiddenBlockTypes' ].reduce( ( accumulatedPrefs, preferenceKey ) => { const value = select( preferencesStore ).get( 'core', @@ -238,10 +238,8 @@ export function getPreference( state, preferenceKey, defaultValue ) { */ export const getHiddenBlockTypes = createRegistrySelector( ( select ) => () => { return ( - select( preferencesStore ).get( - 'core/edit-post', - 'hiddenBlockTypes' - ) ?? EMPTY_ARRAY + select( preferencesStore ).get( 'core', 'hiddenBlockTypes' ) ?? + EMPTY_ARRAY ); } ); diff --git a/packages/edit-post/src/style.scss b/packages/edit-post/src/style.scss index adfd7218c4c123..adb5e08da5e840 100644 --- a/packages/edit-post/src/style.scss +++ b/packages/edit-post/src/style.scss @@ -3,7 +3,6 @@ @import "./components/header/fullscreen-mode-close/style.scss"; @import "./components/keyboard-shortcut-help-modal/style.scss"; @import "./components/layout/style.scss"; -@import "./components/block-manager/style.scss"; @import "./components/meta-boxes/meta-boxes-area/style.scss"; @import "./components/sidebar/style.scss"; @import "./components/sidebar/post-format/style.scss"; diff --git a/packages/edit-site/src/components/preferences-modal/index.js b/packages/edit-site/src/components/preferences-modal/index.js index 8634e3e18b23ed..4d719fedad234f 100644 --- a/packages/edit-site/src/components/preferences-modal/index.js +++ b/packages/edit-site/src/components/preferences-modal/index.js @@ -1,30 +1,16 @@ /** * WordPress dependencies */ -import { - PreferencesModal, - PreferencesModalTabs, - PreferencesModalSection, - store as interfaceStore, -} from '@wordpress/interface'; -import { __ } from '@wordpress/i18n'; -import { useSelect, useDispatch, useRegistry } from '@wordpress/data'; -import { store as preferencesStore } from '@wordpress/preferences'; -import { - PostTaxonomies, - PostExcerptCheck, - PageAttributesCheck, - PostFeaturedImageCheck, - PostTypeSupportCheck, - store as editorStore, -} from '@wordpress/editor'; +import { store as interfaceStore } from '@wordpress/interface'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { privateApis as editorPrivateApis } from '@wordpress/editor'; /** * Internal dependencies */ -import EnableFeature from './enable-feature'; -import EnablePanelOption from './enable-panel-option'; -import { store as editSiteStore } from '../../store'; +import { unlock } from '../../lock-unlock'; + +const { PreferencesModal } = unlock( editorPrivateApis ); export const PREFERENCES_MODAL_NAME = 'edit-site/preferences'; @@ -32,201 +18,12 @@ export default function EditSitePreferencesModal() { const isModalActive = useSelect( ( select ) => select( interfaceStore ).isModalActive( PREFERENCES_MODAL_NAME ) ); - const { closeModal, openModal } = useDispatch( interfaceStore ); - const toggleModal = () => - isModalActive ? closeModal() : openModal( PREFERENCES_MODAL_NAME ); - const registry = useRegistry(); - const { closeGeneralSidebar } = useDispatch( editSiteStore ); - const { setIsListViewOpened, setIsInserterOpened } = - useDispatch( editorStore ); - - const { set: setPreference } = useDispatch( preferencesStore ); - const toggleDistractionFree = () => { - registry.batch( () => { - setPreference( 'core', 'fixedToolbar', true ); - setIsInserterOpened( false ); - setIsListViewOpened( false ); - closeGeneralSidebar(); - } ); - }; - - const turnOffDistractionFree = () => { - setPreference( 'core', 'distractionFree', false ); - }; + const { closeModal } = useDispatch( interfaceStore ); - const sections = [ - { - name: 'general', - tabLabel: __( 'General' ), - content: ( - <> - - - - - - - ( - - ) } - /> - - - - - - - - - - - - - - - ), - }, - { - name: 'appearance', - tabLabel: __( 'Appearance' ), - content: ( - - - - - - ), - }, - { - name: 'accessibility', - tabLabel: __( 'Accessibility' ), - content: ( - <> - - - - - - - - ), - }, - { - name: 'blocks', - tabLabel: __( 'Blocks' ), - content: ( - <> - - - - - ), - }, - ]; if ( ! isModalActive ) { return null; } return ( - - - + ); } diff --git a/packages/edit-post/src/components/block-manager/category.js b/packages/editor/src/components/block-manager/category.js similarity index 57% rename from packages/edit-post/src/components/block-manager/category.js rename to packages/editor/src/components/block-manager/category.js index 6a64563366d633..e7125fa151f72a 100644 --- a/packages/edit-post/src/components/block-manager/category.js +++ b/packages/editor/src/components/block-manager/category.js @@ -5,44 +5,46 @@ import { useMemo, useCallback } from '@wordpress/element'; import { useDispatch, useSelect } from '@wordpress/data'; import { useInstanceId } from '@wordpress/compose'; import { CheckboxControl } from '@wordpress/components'; -import { store as editorStore } from '@wordpress/editor'; +import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies */ import BlockTypesChecklist from './checklist'; -import { store as editPostStore } from '../../store'; +import { store as editorStore } from '../../store'; +import { unlock } from '../../lock-unlock'; function BlockManagerCategory( { title, blockTypes } ) { const instanceId = useInstanceId( BlockManagerCategory ); - const { defaultAllowedBlockTypes, hiddenBlockTypes } = useSelect( - ( select ) => { - const { getEditorSettings } = select( editorStore ); - const { getHiddenBlockTypes } = select( editPostStore ); - return { - defaultAllowedBlockTypes: - getEditorSettings().defaultAllowedBlockTypes, - hiddenBlockTypes: getHiddenBlockTypes(), - }; - }, - [] - ); + const { allowedBlockTypes, hiddenBlockTypes } = useSelect( ( select ) => { + const { getEditorSettings } = select( editorStore ); + const { get } = select( preferencesStore ); + return { + allowedBlockTypes: getEditorSettings().allowedBlockTypes, + hiddenBlockTypes: get( 'core', 'hiddenBlockTypes' ), + }; + }, [] ); const filteredBlockTypes = useMemo( () => { - if ( defaultAllowedBlockTypes === true ) { + if ( allowedBlockTypes === true ) { return blockTypes; } return blockTypes.filter( ( { name } ) => { - return defaultAllowedBlockTypes?.includes( name ); + return allowedBlockTypes?.includes( name ); } ); - }, [ defaultAllowedBlockTypes, blockTypes ] ); - const { showBlockTypes, hideBlockTypes } = useDispatch( editPostStore ); - const toggleVisible = useCallback( ( blockName, nextIsChecked ) => { - if ( nextIsChecked ) { - showBlockTypes( blockName ); - } else { - hideBlockTypes( blockName ); - } - }, [] ); + }, [ allowedBlockTypes, blockTypes ] ); + const { showBlockTypes, hideBlockTypes } = unlock( + useDispatch( editorStore ) + ); + const toggleVisible = useCallback( + ( blockName, nextIsChecked ) => { + if ( nextIsChecked ) { + showBlockTypes( blockName ); + } else { + hideBlockTypes( blockName ); + } + }, + [ showBlockTypes, hideBlockTypes ] + ); const toggleAllVisible = useCallback( ( nextIsChecked ) => { const blockNames = blockTypes.map( ( { name } ) => name ); @@ -52,7 +54,7 @@ function BlockManagerCategory( { title, blockTypes } ) { hideBlockTypes( blockNames ); } }, - [ blockTypes ] + [ blockTypes, showBlockTypes, hideBlockTypes ] ); if ( ! filteredBlockTypes.length ) { @@ -61,9 +63,9 @@ function BlockManagerCategory( { title, blockTypes } ) { const checkedBlockNames = filteredBlockTypes .map( ( { name } ) => name ) - .filter( ( type ) => ! hiddenBlockTypes.includes( type ) ); + .filter( ( type ) => ! ( hiddenBlockTypes ?? [] ).includes( type ) ); - const titleId = 'edit-post-block-manager__category-title-' + instanceId; + const titleId = 'editor-block-manager__category-title-' + instanceId; const isAllChecked = checkedBlockNames.length === filteredBlockTypes.length; const isIndeterminate = ! isAllChecked && checkedBlockNames.length > 0; @@ -72,13 +74,13 @@ function BlockManagerCategory( { title, blockTypes } ) {
{ title } } /> diff --git a/packages/edit-post/src/components/block-manager/checklist.js b/packages/editor/src/components/block-manager/checklist.js similarity index 85% rename from packages/edit-post/src/components/block-manager/checklist.js rename to packages/editor/src/components/block-manager/checklist.js index aa21fefb1c8180..01bd06abdeba86 100644 --- a/packages/edit-post/src/components/block-manager/checklist.js +++ b/packages/editor/src/components/block-manager/checklist.js @@ -6,11 +6,11 @@ import { CheckboxControl } from '@wordpress/components'; function BlockTypesChecklist( { blockTypes, value, onItemChange } ) { return ( -
    +
      { blockTypes.map( ( blockType ) => (
    • +
      { !! numberOfHiddenBlocks && ( -
      +
      { sprintf( /* translators: %d: number of blocks. */ _n( @@ -78,16 +79,16 @@ function BlockManager( { placeholder={ __( 'Search for a block' ) } value={ search } onChange={ ( nextSearch ) => setSearch( nextSearch ) } - className="edit-post-block-manager__search" + className="editor-block-manager__search" />
      { blockTypes.length === 0 && ( -

      +

      { __( 'No blocks found.' ) }

      ) } @@ -120,7 +121,7 @@ export default compose( [ hasBlockSupport, isMatchingSearchTerm, } = select( blocksStore ); - const { getHiddenBlockTypes } = select( editPostStore ); + const { get } = select( preferencesStore ); // Some hidden blocks become unregistered // by removing for instance the plugin that registered them, yet @@ -128,13 +129,13 @@ export default compose( [ // We consider "hidden", blocks which were hidden and // are still registered. const blockTypes = getBlockTypes(); - const hiddenBlockTypes = getHiddenBlockTypes().filter( - ( hiddenBlock ) => { - return blockTypes.some( - ( registeredBlock ) => registeredBlock.name === hiddenBlock - ); - } - ); + const hiddenBlockTypes = ( + get( 'core', 'hiddenBlockTypes' ) ?? [] + ).filter( ( hiddenBlock ) => { + return blockTypes.some( + ( registeredBlock ) => registeredBlock.name === hiddenBlock + ); + } ); const numberOfHiddenBlocks = Array.isArray( hiddenBlockTypes ) && hiddenBlockTypes.length; @@ -147,7 +148,7 @@ export default compose( [ }; } ), withDispatch( ( dispatch ) => { - const { showBlockTypes } = dispatch( editPostStore ); + const { showBlockTypes } = dispatch( editorStore ); return { enableAllBlockTypes: ( blockTypes ) => { const blockNames = blockTypes.map( ( { name } ) => name ); diff --git a/packages/edit-post/src/components/block-manager/style.scss b/packages/editor/src/components/block-manager/style.scss similarity index 66% rename from packages/edit-post/src/components/block-manager/style.scss rename to packages/editor/src/components/block-manager/style.scss index e1b92c7c4da430..62e5c9d60cb178 100644 --- a/packages/edit-post/src/components/block-manager/style.scss +++ b/packages/editor/src/components/block-manager/style.scss @@ -1,14 +1,14 @@ -.edit-post-block-manager__no-results { +.editor-block-manager__no-results { font-style: italic; padding: $grid-unit-30 0; text-align: center; } -.edit-post-block-manager__search { +.editor-block-manager__search { margin: $grid-unit-20 0; } -.edit-post-block-manager__disabled-blocks-count { +.editor-block-manager__disabled-blocks-count { border: 1px solid $gray-300; border-width: 1px 0; // Cover up horizontal areas off the sides of the box rectangle @@ -19,10 +19,10 @@ position: sticky; // When sticking, tuck the top border beneath the modal header border top: ($grid-unit-05 + 1) * -1; - z-index: z-index(".edit-post-block-manager__disabled-blocks-count"); + z-index: z-index(".editor-block-manager__disabled-blocks-count"); // Stick the category titles to the bottom - ~ .edit-post-block-manager__results .edit-post-block-manager__category-title { + ~ .editor-block-manager__results .editor-block-manager__category-title { top: $grid-unit-40 - 1; } .is-link { @@ -30,32 +30,32 @@ } } -.edit-post-block-manager__category { +.editor-block-manager__category { margin: 0 0 $grid-unit-30 0; } -.edit-post-block-manager__category-title { +.editor-block-manager__category-title { position: sticky; top: - $grid-unit-05; // Offsets the top padding on the modal content container padding: $grid-unit-20 0; background-color: $white; - z-index: z-index(".edit-post-block-manager__category-title"); + z-index: z-index(".editor-block-manager__category-title"); .components-checkbox-control__label { font-weight: 600; } } -.edit-post-block-manager__checklist { +.editor-block-manager__checklist { margin-top: 0; } -.edit-post-block-manager__category-title, -.edit-post-block-manager__checklist-item { +.editor-block-manager__category-title, +.editor-block-manager__checklist-item { border-bottom: 1px solid $gray-300; } -.edit-post-block-manager__checklist-item { +.editor-block-manager__checklist-item { display: flex; justify-content: space-between; align-items: center; @@ -72,11 +72,11 @@ } } -.edit-post-block-manager__results { +.editor-block-manager__results { border-top: $border-width solid $gray-300; } // Remove the top border from results when adjacent to the disabled block count -.edit-post-block-manager__disabled-blocks-count + .edit-post-block-manager__results { +.editor-block-manager__disabled-blocks-count + .editor-block-manager__results { border-top-width: 0; } diff --git a/packages/edit-site/src/components/preferences-modal/enable-panel-option.js b/packages/editor/src/components/preferences-modal/enable-panel.js similarity index 66% rename from packages/edit-site/src/components/preferences-modal/enable-panel-option.js rename to packages/editor/src/components/preferences-modal/enable-panel.js index 6c9ea22b7f17dd..66c91409434415 100644 --- a/packages/edit-site/src/components/preferences-modal/enable-panel-option.js +++ b/packages/editor/src/components/preferences-modal/enable-panel.js @@ -3,8 +3,15 @@ */ import { compose, ifCondition } from '@wordpress/compose'; import { withSelect, withDispatch } from '@wordpress/data'; -import { ___unstablePreferencesModalBaseOption as BaseOption } from '@wordpress/interface'; -import { store as editorStore } from '@wordpress/editor'; +import { privateApis as preferencesPrivateApis } from '@wordpress/preferences'; + +/** + * Internal dependencies + */ +import { unlock } from '../../lock-unlock'; +import { store as editorStore } from '../../store'; + +const { PreferenceBaseOption } = unlock( preferencesPrivateApis ); export default compose( withSelect( ( select, { panelName } ) => { @@ -20,4 +27,4 @@ export default compose( onChange: () => dispatch( editorStore ).toggleEditorPanelEnabled( panelName ), } ) ) -)( BaseOption ); +)( PreferenceBaseOption ); diff --git a/packages/edit-post/src/components/preferences-modal/options/enable-plugin-document-setting-panel.js b/packages/editor/src/components/preferences-modal/enable-plugin-document-setting-panel.js similarity index 90% rename from packages/edit-post/src/components/preferences-modal/options/enable-plugin-document-setting-panel.js rename to packages/editor/src/components/preferences-modal/enable-plugin-document-setting-panel.js index b18b0436579bcb..4dd2e55eba007b 100644 --- a/packages/edit-post/src/components/preferences-modal/options/enable-plugin-document-setting-panel.js +++ b/packages/editor/src/components/preferences-modal/enable-plugin-document-setting-panel.js @@ -6,7 +6,7 @@ import { createSlotFill } from '@wordpress/components'; /** * Internal dependencies */ -import { EnablePanelOption } from './index'; +import EnablePanelOption from './enable-panel'; const { Fill, Slot } = createSlotFill( 'EnablePluginDocumentSettingPanelOption' diff --git a/packages/editor/src/components/preferences-modal/index.js b/packages/editor/src/components/preferences-modal/index.js new file mode 100644 index 00000000000000..044c0eb426e222 --- /dev/null +++ b/packages/editor/src/components/preferences-modal/index.js @@ -0,0 +1,269 @@ +/** + * WordPress dependencies + */ + +import { __ } from '@wordpress/i18n'; +import { useViewportMatch } from '@wordpress/compose'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { useMemo } from '@wordpress/element'; +import { + store as preferencesStore, + privateApis as preferencesPrivateApis, +} from '@wordpress/preferences'; + +/** + * Internal dependencies + */ +import EnablePanelOption from './enable-panel'; +import EnablePluginDocumentSettingPanelOption from './enable-plugin-document-setting-panel'; +import BlockManager from '../block-manager'; +import PostTaxonomies from '../post-taxonomies'; +import PostFeaturedImageCheck from '../post-featured-image/check'; +import PostExcerptCheck from '../post-excerpt/check'; +import PageAttributesCheck from '../page-attributes/check'; +import PostTypeSupportCheck from '../post-type-support-check'; +import { store as editorStore } from '../../store'; +import { unlock } from '../../lock-unlock'; + +const { + PreferencesModal, + PreferencesModalTabs, + PreferencesModalSection, + PreferenceToggleControl, +} = unlock( preferencesPrivateApis ); + +export default function EditorPreferencesModal( { + extraSections = {}, + isActive, + onClose, +} ) { + const isLargeViewport = useViewportMatch( 'medium' ); + const { showBlockBreadcrumbsOption } = useSelect( + ( select ) => { + const { getEditorSettings } = select( editorStore ); + const { get } = select( preferencesStore ); + const isRichEditingEnabled = getEditorSettings().richEditingEnabled; + const isDistractionFreeEnabled = get( 'core', 'distractionFree' ); + return { + showBlockBreadcrumbsOption: + ! isDistractionFreeEnabled && + isLargeViewport && + isRichEditingEnabled, + }; + }, + [ isLargeViewport ] + ); + + const { setIsListViewOpened, setIsInserterOpened } = + useDispatch( editorStore ); + const { set: setPreference } = useDispatch( preferencesStore ); + + const toggleDistractionFree = () => { + setPreference( 'core', 'fixedToolbar', true ); + setIsInserterOpened( false ); + setIsListViewOpened( false ); + // Todo: Check sidebar when closing/opening distraction free. + }; + + const turnOffDistractionFree = () => { + setPreference( 'core', 'distractionFree', false ); + }; + + const sections = useMemo( + () => [ + { + name: 'general', + tabLabel: __( 'General' ), + content: ( + <> + + + { showBlockBreadcrumbsOption && ( + + ) } + + + + + ( + + ) } + /> + + + + + + + + + + + + + + { extraSections?.general } + + ), + }, + { + name: 'appearance', + tabLabel: __( 'Appearance' ), + content: ( + + + + + { extraSections?.appearance } + + ), + }, + { + name: 'accessibility', + tabLabel: __( 'Accessibility' ), + content: ( + <> + + + + + + + + ), + }, + { + name: 'blocks', + tabLabel: __( 'Blocks' ), + content: ( + <> + + + + + + + + ), + }, + ], + [ isLargeViewport, showBlockBreadcrumbsOption, extraSections ] + ); + + if ( ! isActive ) { + return null; + } + + return ( + + + + ); +} diff --git a/packages/editor/src/components/preferences-modal/test/__snapshots__/meta-boxes-section.js.snap b/packages/editor/src/components/preferences-modal/test/__snapshots__/meta-boxes-section.js.snap new file mode 100644 index 00000000000000..c39f90d4aa0e5d --- /dev/null +++ b/packages/editor/src/components/preferences-modal/test/__snapshots__/meta-boxes-section.js.snap @@ -0,0 +1,464 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`MetaBoxesSection renders a Custom Fields option 1`] = ` +.emotion-0 { + font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif; + font-size: 13px; + box-sizing: border-box; +} + +.emotion-0 *, +.emotion-0 *::before, +.emotion-0 *::after { + box-sizing: inherit; +} + +.components-panel__row .emotion-2 { + margin-bottom: inherit; +} + +.emotion-4 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + gap: calc(4px * 3); + -webkit-box-pack: start; + -ms-flex-pack: start; + -webkit-justify-content: flex-start; + justify-content: flex-start; + width: 100%; +} + +.emotion-4>* { + min-width: 0; +} + +.emotion-6 { + display: block; + max-height: 100%; + max-width: 100%; + min-height: 0; + min-width: 0; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; +} + +
      + +

      + Advanced panels +

      +
      +
      +
      +
      +
      +
      + + + + + + +
      +
      +
      +
      +
      +
      +`; + +exports[`MetaBoxesSection renders a Custom Fields option and meta box options 1`] = ` +.emotion-0 { + font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif; + font-size: 13px; + box-sizing: border-box; +} + +.emotion-0 *, +.emotion-0 *::before, +.emotion-0 *::after { + box-sizing: inherit; +} + +.components-panel__row .emotion-2 { + margin-bottom: inherit; +} + +.emotion-4 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + gap: calc(4px * 3); + -webkit-box-pack: start; + -ms-flex-pack: start; + -webkit-justify-content: flex-start; + justify-content: flex-start; + width: 100%; +} + +.emotion-4>* { + min-width: 0; +} + +.emotion-6 { + display: block; + max-height: 100%; + max-width: 100%; + min-height: 0; + min-width: 0; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; +} + +
      + +

      + Advanced panels +

      +
      +
      +
      +
      +
      +
      + + + + + + +
      +
      +
      +
      +
      +
      +
      +
      + + + + + + +
      +
      +
      +
      +
      +
      +
      +
      + + + + + + +
      +
      +
      +
      +
      +
      +`; + +exports[`MetaBoxesSection renders meta box options 1`] = ` +.emotion-0 { + font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif; + font-size: 13px; + box-sizing: border-box; +} + +.emotion-0 *, +.emotion-0 *::before, +.emotion-0 *::after { + box-sizing: inherit; +} + +.components-panel__row .emotion-2 { + margin-bottom: inherit; +} + +.emotion-4 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + gap: calc(4px * 3); + -webkit-box-pack: start; + -ms-flex-pack: start; + -webkit-justify-content: flex-start; + justify-content: flex-start; + width: 100%; +} + +.emotion-4>* { + min-width: 0; +} + +.emotion-6 { + display: block; + max-height: 100%; + max-width: 100%; + min-height: 0; + min-width: 0; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; +} + +
      + +

      + Advanced panels +

      +
      +
      +
      +
      +
      +
      + + + + + + +
      +
      +
      +
      +
      +
      +
      +
      + + + + + + +
      +
      +
      +
      +
      +
      +`; diff --git a/packages/editor/src/components/preferences-modal/test/index.js b/packages/editor/src/components/preferences-modal/test/index.js new file mode 100644 index 00000000000000..01ac1a88fbe7d8 --- /dev/null +++ b/packages/editor/src/components/preferences-modal/test/index.js @@ -0,0 +1,28 @@ +/** + * External dependencies + */ +import { render, screen } from '@testing-library/react'; + +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import EditPostPreferencesModal from '../'; + +// This allows us to tweak the returned value on each test. +jest.mock( '@wordpress/data/src/components/use-select', () => jest.fn() ); +jest.mock( '@wordpress/compose/src/hooks/use-viewport-match', () => jest.fn() ); + +describe( 'EditPostPreferencesModal', () => { + it( 'should not render when the modal is not active', () => { + useSelect.mockImplementation( () => [ false, false, false ] ); + render( ); + expect( + screen.queryByRole( 'dialog', { name: 'Preferences' } ) + ).not.toBeInTheDocument(); + } ); +} ); diff --git a/packages/editor/src/components/provider/use-block-editor-settings.js b/packages/editor/src/components/provider/use-block-editor-settings.js index eddc295766f8ce..c42d269b1e6d5c 100644 --- a/packages/editor/src/components/provider/use-block-editor-settings.js +++ b/packages/editor/src/components/provider/use-block-editor-settings.js @@ -11,6 +11,7 @@ import { import { __ } from '@wordpress/i18n'; import { store as preferencesStore } from '@wordpress/preferences'; import { useViewportMatch } from '@wordpress/compose'; +import { store as blocksStore } from '@wordpress/blocks'; /** * Internal dependencies @@ -29,7 +30,6 @@ const BLOCK_EDITOR_SETTINGS = [ '__experimentalPreferredStyleVariations', '__unstableGalleryWithImageBlocks', 'alignWide', - 'allowedBlockTypes', 'blockInspectorTabs', 'allowedMimeTypes', 'bodyPlaceholder', @@ -88,12 +88,14 @@ function useBlockEditorSettings( settings, postType, postId ) { const isLargeViewport = useViewportMatch( 'medium' ); const { allowRightClickOverrides, + blockTypes, focusMode, hasFixedToolbar, isDistractionFree, keepCaretInsideBlock, reusableBlocks, hasUploadPermissions, + hiddenBlockTypes, canUseUnfilteredHTML, userCanCreatePages, pageOnFront, @@ -114,7 +116,7 @@ function useBlockEditorSettings( settings, postType, postId ) { getBlockPatternCategories, } = select( coreStore ); const { get } = select( preferencesStore ); - + const { getBlockTypes } = select( blocksStore ); const siteSettings = canUser( 'read', 'settings' ) ? getEntityRecord( 'root', 'site' ) : undefined; @@ -124,6 +126,7 @@ function useBlockEditorSettings( settings, postType, postId ) { 'core', 'allowRightClickOverrides' ), + blockTypes: getBlockTypes(), canUseUnfilteredHTML: getRawEntityRecord( 'postType', postType, @@ -132,6 +135,7 @@ function useBlockEditorSettings( settings, postType, postId ) { focusMode: get( 'core', 'focusMode' ), hasFixedToolbar: get( 'core', 'fixedToolbar' ) || ! isLargeViewport, + hiddenBlockTypes: get( 'core', 'hiddenBlockTypes' ), isDistractionFree: get( 'core', 'distractionFree' ), keepCaretInsideBlock: get( 'core', 'keepCaretInsideBlock' ), reusableBlocks: isWeb @@ -215,6 +219,25 @@ function useBlockEditorSettings( settings, postType, postId ) { [ saveEntityRecord, userCanCreatePages ] ); + const allowedBlockTypes = useMemo( () => { + // Omit hidden block types if exists and non-empty. + if ( hiddenBlockTypes.length > 0 ) { + // Defer to passed setting for `allowedBlockTypes` if provided as + // anything other than `true` (where `true` is equivalent to allow + // all block types). + const defaultAllowedBlockTypes = + true === settings.allowedBlockTypes + ? blockTypes.map( ( { name } ) => name ) + : settings.allowedBlockTypes || []; + + return defaultAllowedBlockTypes.filter( + ( type ) => ! hiddenBlockTypes.includes( type ) + ); + } + + return settings.allowedBlockTypes; + }, [ settings.allowedBlockTypes, hiddenBlockTypes, blockTypes ] ); + const forceDisableFocusMode = settings.focusMode === false; return useMemo( @@ -224,6 +247,7 @@ function useBlockEditorSettings( settings, postType, postId ) { BLOCK_EDITOR_SETTINGS.includes( key ) ) ), + allowedBlockTypes, allowRightClickOverrides, focusMode: focusMode && ! forceDisableFocusMode, hasFixedToolbar, @@ -261,6 +285,7 @@ function useBlockEditorSettings( settings, postType, postId ) { __experimentalSetIsInserterOpened: setIsInserterOpened, } ), [ + allowedBlockTypes, allowRightClickOverrides, focusMode, forceDisableFocusMode, diff --git a/packages/editor/src/private-apis.js b/packages/editor/src/private-apis.js index 5f8fc7ccf73185..16c27b1b57c193 100644 --- a/packages/editor/src/private-apis.js +++ b/packages/editor/src/private-apis.js @@ -4,28 +4,32 @@ import EditorCanvas from './components/editor-canvas'; import { ExperimentalEditorProvider } from './components/provider'; import { lock } from './lock-unlock'; +import EnablePluginDocumentSettingPanelOption from './components/preferences-modal/enable-plugin-document-setting-panel'; import { EntitiesSavedStatesExtensible } from './components/entities-saved-states'; import useBlockEditorSettings from './components/provider/use-block-editor-settings'; import DocumentTools from './components/document-tools'; import InserterSidebar from './components/inserter-sidebar'; import ListViewSidebar from './components/list-view-sidebar'; +import PluginPostExcerpt from './components/post-excerpt/plugin'; import PostPanelRow from './components/post-panel-row'; import PostViewLink from './components/post-view-link'; import PreviewDropdown from './components/preview-dropdown'; -import PluginPostExcerpt from './components/post-excerpt/plugin'; +import PreferencesModal from './components/preferences-modal'; export const privateApis = {}; lock( privateApis, { DocumentTools, EditorCanvas, ExperimentalEditorProvider, + EnablePluginDocumentSettingPanelOption, EntitiesSavedStatesExtensible, InserterSidebar, ListViewSidebar, + PluginPostExcerpt, PostPanelRow, PostViewLink, PreviewDropdown, - PluginPostExcerpt, + PreferencesModal, // This is a temporary private API while we're updating the site editor to use EditorProvider. useBlockEditorSettings, diff --git a/packages/editor/src/store/private-actions.js b/packages/editor/src/store/private-actions.js index 7ddeab5f35734c..0d7c0a2186421b 100644 --- a/packages/editor/src/store/private-actions.js +++ b/packages/editor/src/store/private-actions.js @@ -4,6 +4,7 @@ import { store as coreStore } from '@wordpress/core-data'; import { __ } from '@wordpress/i18n'; import { store as noticesStore } from '@wordpress/notices'; +import { store as preferencesStore } from '@wordpress/preferences'; /** * Returns an action object used to set which template is currently being used/edited. @@ -59,3 +60,51 @@ export const createTemplate = } ); }; + +/** + * Update the provided block types to be visible. + * + * @param {string[]} blockNames Names of block types to show. + */ +export const showBlockTypes = + ( blockNames ) => + ( { registry } ) => { + const existingBlockNames = + registry + .select( preferencesStore ) + .get( 'core', 'hiddenBlockTypes' ) ?? []; + + const newBlockNames = existingBlockNames.filter( + ( type ) => + ! ( + Array.isArray( blockNames ) ? blockNames : [ blockNames ] + ).includes( type ) + ); + + registry + .dispatch( preferencesStore ) + .set( 'core', 'hiddenBlockTypes', newBlockNames ); + }; + +/** + * Update the provided block types to be hidden. + * + * @param {string[]} blockNames Names of block types to hide. + */ +export const hideBlockTypes = + ( blockNames ) => + ( { registry } ) => { + const existingBlockNames = + registry + .select( preferencesStore ) + .get( 'core', 'hiddenBlockTypes' ) ?? []; + + const mergedBlockNames = new Set( [ + ...existingBlockNames, + ...( Array.isArray( blockNames ) ? blockNames : [ blockNames ] ), + ] ); + + registry + .dispatch( preferencesStore ) + .set( 'core', 'hiddenBlockTypes', [ ...mergedBlockNames ] ); + }; diff --git a/packages/editor/src/style.scss b/packages/editor/src/style.scss index 09e50d1abed79a..450c61fd0bb7e6 100644 --- a/packages/editor/src/style.scss +++ b/packages/editor/src/style.scss @@ -1,4 +1,5 @@ @import "./components/autocompleters/style.scss"; +@import "./components/block-manager/style.scss"; @import "./components/document-bar/style.scss"; @import "./components/document-outline/style.scss"; @import "./components/document-tools/style.scss"; diff --git a/packages/interface/src/components/index.js b/packages/interface/src/components/index.js index c9c2d09b3b3ab0..6f986e138838e1 100644 --- a/packages/interface/src/components/index.js +++ b/packages/interface/src/components/index.js @@ -6,8 +6,4 @@ export { default as PinnedItems } from './pinned-items'; export { default as MoreMenuDropdown } from './more-menu-dropdown'; export { default as MoreMenuFeatureToggle } from './more-menu-feature-toggle'; export { default as ActionItem } from './action-item'; -export { default as PreferencesModal } from './preferences-modal'; -export { default as PreferencesModalTabs } from './preferences-modal-tabs'; -export { default as PreferencesModalSection } from './preferences-modal-section'; -export { default as ___unstablePreferencesModalBaseOption } from './preferences-modal-base-option'; export { default as NavigableRegion } from './navigable-region'; diff --git a/packages/interface/src/components/preferences-modal-section/index.js b/packages/interface/src/components/preferences-modal-section/index.js deleted file mode 100644 index 8ea2ca2652d6df..00000000000000 --- a/packages/interface/src/components/preferences-modal-section/index.js +++ /dev/null @@ -1,19 +0,0 @@ -const Section = ( { description, title, children } ) => ( -
      - -

      - { title } -

      - { description && ( -

      - { description } -

      - ) } -
      -
      - { children } -
      -
      -); - -export default Section; diff --git a/packages/interface/src/style.scss b/packages/interface/src/style.scss index be111640a0a796..e6950de411156a 100644 --- a/packages/interface/src/style.scss +++ b/packages/interface/src/style.scss @@ -4,7 +4,3 @@ @import "./components/interface-skeleton/style.scss"; @import "./components/more-menu-dropdown/style.scss"; @import "./components/pinned-items/style.scss"; -@import "./components/preferences-modal/style.scss"; -@import "./components/preferences-modal-tabs/style.scss"; -@import "./components/preferences-modal-section/style.scss"; -@import "./components/preferences-modal-base-option/style.scss"; diff --git a/packages/preferences-persistence/src/migrations/preferences-package-data/convert-editor-settings.js b/packages/preferences-persistence/src/migrations/preferences-package-data/convert-editor-settings.js index 5def03bb348fa5..01986803579b61 100644 --- a/packages/preferences-persistence/src/migrations/preferences-package-data/convert-editor-settings.js +++ b/packages/preferences-persistence/src/migrations/preferences-package-data/convert-editor-settings.js @@ -10,6 +10,7 @@ export default function convertEditorSettings( data ) { 'editorMode', 'fixedToolbar', 'focusMode', + 'hiddenBlockTypes', 'inactivePanels', 'keepCaretInsideBlock', 'mostUsedBlocks', diff --git a/packages/preferences/package.json b/packages/preferences/package.json index dc44878577aaf4..e1164a7a1306c9 100644 --- a/packages/preferences/package.json +++ b/packages/preferences/package.json @@ -31,10 +31,12 @@ "@babel/runtime": "^7.16.0", "@wordpress/a11y": "file:../a11y", "@wordpress/components": "file:../components", + "@wordpress/compose": "file:../compose", "@wordpress/data": "file:../data", "@wordpress/element": "file:../element", "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", + "@wordpress/private-apis": "file:../private-apis", "classnames": "^2.3.1" }, "peerDependencies": { diff --git a/packages/interface/src/components/preferences-modal-base-option/README.md b/packages/preferences/src/components/preference-base-option/README.md similarity index 69% rename from packages/interface/src/components/preferences-modal-base-option/README.md rename to packages/preferences/src/components/preference-base-option/README.md index 03c89960b6850c..8ff438ba322dc5 100644 --- a/packages/interface/src/components/preferences-modal-base-option/README.md +++ b/packages/preferences/src/components/preference-base-option/README.md @@ -1,17 +1,15 @@ -#__unstablePreferencesModalBaseOption +# PreferenceBaseOption -`__unstablePreferencesModalBaseOption` renders a toggle meant to be used with `PreferencesModal`. +`PreferenceBaseOption` renders a toggle meant to be used within `PreferencesModal`. This component implements a `ToggleControl` component from the `@wordpress/components` package. -**It is an unstable component so is subject to breaking changes at any moment. Use at own risk.** - ## Example ```jsx function MyEditorPreferencesOption() { return ( - <__unstablePreferencesModalBaseOption + ) } - + ) } ``` diff --git a/packages/interface/src/components/preferences-modal-base-option/index.js b/packages/preferences/src/components/preference-base-option/index.js similarity index 86% rename from packages/interface/src/components/preferences-modal-base-option/index.js rename to packages/preferences/src/components/preference-base-option/index.js index 92346630d98aa2..f2d1b4936c97f8 100644 --- a/packages/interface/src/components/preferences-modal-base-option/index.js +++ b/packages/preferences/src/components/preference-base-option/index.js @@ -5,7 +5,7 @@ import { ToggleControl } from '@wordpress/components'; function BaseOption( { help, label, isChecked, onChange, children } ) { return ( -
      +
      {}, ...remainingProps @@ -21,11 +25,14 @@ export default function EnableFeature( props ) { onToggle(); toggle( scope, featureName ); }; + return ( - ); } + +export default PreferenceToggleControl; diff --git a/packages/interface/src/components/preferences-modal-section/README.md b/packages/preferences/src/components/preferences-modal-section/README.md similarity index 94% rename from packages/interface/src/components/preferences-modal-section/README.md rename to packages/preferences/src/components/preferences-modal-section/README.md index 6e78ca05c0aa81..4b032b5db04975 100644 --- a/packages/interface/src/components/preferences-modal-section/README.md +++ b/packages/preferences/src/components/preferences-modal-section/README.md @@ -1,3 +1,4 @@ +# PreferencesModalSection `PreferencesModalSection` renders a section (as a fieldset) meant to be used with `PreferencesModal`. diff --git a/packages/preferences/src/components/preferences-modal-section/index.js b/packages/preferences/src/components/preferences-modal-section/index.js new file mode 100644 index 00000000000000..1a3f6f64ef4e75 --- /dev/null +++ b/packages/preferences/src/components/preferences-modal-section/index.js @@ -0,0 +1,15 @@ +const Section = ( { description, title, children } ) => ( +
      + +

      { title }

      + { description && ( +

      + { description } +

      + ) } +
      +
      { children }
      +
      +); + +export default Section; diff --git a/packages/interface/src/components/preferences-modal-section/style.scss b/packages/preferences/src/components/preferences-modal-section/style.scss similarity index 50% rename from packages/interface/src/components/preferences-modal-section/style.scss rename to packages/preferences/src/components/preferences-modal-section/style.scss index a1259af3430d56..2f6480dd71dab7 100644 --- a/packages/interface/src/components/preferences-modal-section/style.scss +++ b/packages/preferences/src/components/preferences-modal-section/style.scss @@ -1,4 +1,4 @@ -.interface-preferences-modal__section { +.preferences-modal__section { margin: 0 0 2.5rem 0; &:last-child { @@ -6,23 +6,23 @@ } } -.interface-preferences-modal__section-legend { +.preferences-modal__section-legend { margin-bottom: $grid-unit-10; } -.interface-preferences-modal__section-title { +.preferences-modal__section-title { font-size: 0.9rem; font-weight: 600; margin-top: 0; } -.interface-preferences-modal__section-description { +.preferences-modal__section-description { margin: -$grid-unit-10 0 $grid-unit-10 0; font-size: $helptext-font-size; font-style: normal; color: $gray-700; } -.interface-preferences-modal__section:has(.interface-preferences-modal__section-content:empty) { +.preferences-modal__section:has(.preferences-modal__section-content:empty) { display: none; } diff --git a/packages/interface/src/components/preferences-modal-tabs/README.md b/packages/preferences/src/components/preferences-modal-tabs/README.md similarity index 100% rename from packages/interface/src/components/preferences-modal-tabs/README.md rename to packages/preferences/src/components/preferences-modal-tabs/README.md diff --git a/packages/interface/src/components/preferences-modal-tabs/index.js b/packages/preferences/src/components/preferences-modal-tabs/index.js similarity index 93% rename from packages/interface/src/components/preferences-modal-tabs/index.js rename to packages/preferences/src/components/preferences-modal-tabs/index.js index 985d963227257f..4797b50985f03a 100644 --- a/packages/interface/src/components/preferences-modal-tabs/index.js +++ b/packages/preferences/src/components/preferences-modal-tabs/index.js @@ -25,7 +25,7 @@ import { isRTL, __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import { unlock } from '../../../lock-unlock'; +import { unlock } from '../../lock-unlock'; const { Tabs } = unlock( componentsPrivateApis ); @@ -64,7 +64,7 @@ export default function PreferencesModalTabs( { sections } ) { // We render different components based on the viewport size. if ( isLargeViewport ) { modalContent = ( -
      +
      - + { tabs.map( ( tab ) => ( { tab.title } @@ -87,7 +87,7 @@ export default function PreferencesModalTabs( { sections } ) { { sectionsContentMap[ tab.name ] || null } @@ -100,7 +100,7 @@ export default function PreferencesModalTabs( { sections } ) { modalContent = ( diff --git a/packages/interface/src/components/preferences-modal-tabs/style.scss b/packages/preferences/src/components/preferences-modal-tabs/style.scss similarity index 85% rename from packages/interface/src/components/preferences-modal-tabs/style.scss rename to packages/preferences/src/components/preferences-modal-tabs/style.scss index f598545d69c250..d3afd4174cd0cb 100644 --- a/packages/interface/src/components/preferences-modal-tabs/style.scss +++ b/packages/preferences/src/components/preferences-modal-tabs/style.scss @@ -1,6 +1,6 @@ $vertical-tabs-width: 160px; -.interface-preferences__tabs-tablist { +.preferences__tabs-tablist { position: absolute; top: $header-height + $grid-unit-30; // Aligns button text instead of button box. @@ -9,7 +9,7 @@ $vertical-tabs-width: 160px; } -.interface-preferences__tabs-tab { +.preferences__tabs-tab { border-radius: $radius-block-ui; font-weight: 400; @@ -34,7 +34,7 @@ $vertical-tabs-width: 160px; } } -.interface-preferences__tabs-tabpanel { +.preferences__tabs-tabpanel { padding-left: $grid-unit-30; margin-left: $vertical-tabs-width; } @@ -42,7 +42,7 @@ $vertical-tabs-width: 160px; @media (max-width: #{ ($break-medium - 1) }) { // Keep the navigator component from overflowing the modal content area // to ensure that sticky position elements stick where intended. - .interface-preferences__provider { + .preferences__provider { height: 100%; } } diff --git a/packages/interface/src/components/preferences-modal/README.md b/packages/preferences/src/components/preferences-modal/README.md similarity index 96% rename from packages/interface/src/components/preferences-modal/README.md rename to packages/preferences/src/components/preferences-modal/README.md index 4327a59a7905ae..4814fc12e5898a 100644 --- a/packages/interface/src/components/preferences-modal/README.md +++ b/packages/preferences/src/components/preferences-modal/README.md @@ -4,7 +4,7 @@ This component implements a `Modal` component from the `@wordpress/components` package. -Sections passed to this component should use `PreferencesModalSection` component from the `@wordpress/interface` package. +Sections passed to this component should use `PreferencesModalSection` component from the `@wordpress/preferences` package. ## Example diff --git a/packages/interface/src/components/preferences-modal/index.js b/packages/preferences/src/components/preferences-modal/index.js similarity index 87% rename from packages/interface/src/components/preferences-modal/index.js rename to packages/preferences/src/components/preferences-modal/index.js index 99bb9d3c25dcf4..8dc4f1020c036f 100644 --- a/packages/interface/src/components/preferences-modal/index.js +++ b/packages/preferences/src/components/preferences-modal/index.js @@ -7,7 +7,7 @@ import { __ } from '@wordpress/i18n'; export default function PreferencesModal( { closeModal, children } ) { return ( diff --git a/packages/interface/src/components/preferences-modal/style.scss b/packages/preferences/src/components/preferences-modal/style.scss similarity index 94% rename from packages/interface/src/components/preferences-modal/style.scss rename to packages/preferences/src/components/preferences-modal/style.scss index 4e70f9f817e644..ca185ac4258e0e 100644 --- a/packages/interface/src/components/preferences-modal/style.scss +++ b/packages/preferences/src/components/preferences-modal/style.scss @@ -1,4 +1,4 @@ -.interface-preferences-modal { +.preferences-modal { // To keep modal dimensions consistent as subsections are navigated, width // and height are used instead of max-(width/height). @include break-small() { diff --git a/packages/preferences/src/index.js b/packages/preferences/src/index.js index 72531a0824c178..856b93b21105d8 100644 --- a/packages/preferences/src/index.js +++ b/packages/preferences/src/index.js @@ -1,2 +1,3 @@ export * from './components'; export { store } from './store'; +export * from './private-apis'; diff --git a/packages/preferences/src/lock-unlock.js b/packages/preferences/src/lock-unlock.js new file mode 100644 index 00000000000000..981f244881ed03 --- /dev/null +++ b/packages/preferences/src/lock-unlock.js @@ -0,0 +1,9 @@ +/** + * WordPress dependencies + */ +import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis'; +export const { lock, unlock } = + __dangerousOptInToUnstableAPIsOnlyForCoreModules( + 'I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.', + '@wordpress/preferences' + ); diff --git a/packages/preferences/src/private-apis.js b/packages/preferences/src/private-apis.js new file mode 100644 index 00000000000000..110d134f86b822 --- /dev/null +++ b/packages/preferences/src/private-apis.js @@ -0,0 +1,18 @@ +/** + * Internal dependencies + */ +import PreferenceBaseOption from './components/preference-base-option'; +import PreferenceToggleControl from './components/preference-toggle-control'; +import PreferencesModal from './components/preferences-modal'; +import PreferencesModalSection from './components/preferences-modal-section'; +import PreferencesModalTabs from './components/preferences-modal-tabs'; +import { lock } from './lock-unlock'; + +export const privateApis = {}; +lock( privateApis, { + PreferenceBaseOption, + PreferenceToggleControl, + PreferencesModal, + PreferencesModalSection, + PreferencesModalTabs, +} ); diff --git a/packages/preferences/src/store/index.js b/packages/preferences/src/store/index.js index 0c2421966a0d79..7e57dac5e712ca 100644 --- a/packages/preferences/src/store/index.js +++ b/packages/preferences/src/store/index.js @@ -12,7 +12,7 @@ import * as selectors from './selectors'; import { STORE_NAME } from './constants'; /** - * Store definition for the interface namespace. + * Store definition for the preferences namespace. * * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore * diff --git a/packages/preferences/src/style.scss b/packages/preferences/src/style.scss new file mode 100644 index 00000000000000..c6769c44b00ba9 --- /dev/null +++ b/packages/preferences/src/style.scss @@ -0,0 +1,4 @@ +@import "./components/preference-base-option/style.scss"; +@import "./components/preferences-modal/style.scss"; +@import "./components/preferences-modal-tabs/style.scss"; +@import "./components/preferences-modal-section/style.scss"; diff --git a/packages/private-apis/src/implementation.js b/packages/private-apis/src/implementation.js index 4195991381d02c..a31fd91ce094dd 100644 --- a/packages/private-apis/src/implementation.js +++ b/packages/private-apis/src/implementation.js @@ -27,6 +27,7 @@ const CORE_MODULES_USING_PRIVATE_APIS = [ '@wordpress/format-library', '@wordpress/interface', '@wordpress/patterns', + '@wordpress/preferences', '@wordpress/reusable-blocks', '@wordpress/router', '@wordpress/dataviews', From 0b52b02cf92a690f5636fdb7c1530997e3212ba9 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 8 Jan 2024 12:49:49 +0100 Subject: [PATCH 2/4] Fix unit tests --- .../enable-custom-fields.js.snap | 8 +- .../__snapshots__/meta-boxes-section.js.snap | 36 +- packages/edit-post/src/store/actions.js | 31 +- packages/edit-post/src/store/test/actions.js | 18 +- .../__snapshots__/meta-boxes-section.js.snap | 464 ------------------ .../preferences-package-data/test/index.js | 8 +- 6 files changed, 38 insertions(+), 527 deletions(-) delete mode 100644 packages/editor/src/components/preferences-modal/test/__snapshots__/meta-boxes-section.js.snap diff --git a/packages/edit-post/src/components/preferences-modal/test/__snapshots__/enable-custom-fields.js.snap b/packages/edit-post/src/components/preferences-modal/test/__snapshots__/enable-custom-fields.js.snap index 781cff283f1646..1ecf664fa091f3 100644 --- a/packages/edit-post/src/components/preferences-modal/test/__snapshots__/enable-custom-fields.js.snap +++ b/packages/edit-post/src/components/preferences-modal/test/__snapshots__/enable-custom-fields.js.snap @@ -54,7 +54,7 @@ exports[`EnableCustomFieldsOption renders a checked checkbox and a confirmation

      Advanced panels

      Advanced panels

      Advanced panels

      ( { registry } ) => { - const existingBlockNames = - registry - .select( preferencesStore ) - .get( 'core', 'hiddenBlockTypes' ) ?? []; - - const newBlockNames = existingBlockNames.filter( - ( type ) => - ! ( - Array.isArray( blockNames ) ? blockNames : [ blockNames ] - ).includes( type ) - ); - - registry - .dispatch( preferencesStore ) - .set( 'core', 'hiddenBlockTypes', newBlockNames ); + unlock( registry.dispatch( editorStore ) ).showBlockTypes( blockNames ); }; /** @@ -312,19 +299,7 @@ export const showBlockTypes = export const hideBlockTypes = ( blockNames ) => ( { registry } ) => { - const existingBlockNames = - registry - .select( preferencesStore ) - .get( 'core', 'hiddenBlockTypes' ) ?? []; - - const mergedBlockNames = new Set( [ - ...existingBlockNames, - ...( Array.isArray( blockNames ) ? blockNames : [ blockNames ] ), - ] ); - - registry - .dispatch( preferencesStore ) - .set( 'core', 'hiddenBlockTypes', [ ...mergedBlockNames ] ); + unlock( registry.dispatch( editorStore ) ).hideBlockTypes( blockNames ); }; /** diff --git a/packages/edit-post/src/store/test/actions.js b/packages/edit-post/src/store/test/actions.js index f702d412d55dad..f1db11d26bafce 100644 --- a/packages/edit-post/src/store/test/actions.js +++ b/packages/edit-post/src/store/test/actions.js @@ -154,16 +154,13 @@ describe( 'actions', () => { expect( registry - .select( editPostStore ) - .getPreference( 'hiddenBlockTypes' ) + .select( preferencesStore ) + .get( 'core', 'hiddenBlockTypes' ) ).toEqual( expected ); expect( registry.select( editPostStore ).getHiddenBlockTypes() ).toEqual( expected ); - - // Expect a deprecation message for `getPreference`. - expect( console ).toHaveWarned(); } ); } ); @@ -177,8 +174,8 @@ describe( 'actions', () => { expect( registry - .select( editPostStore ) - .getPreference( 'hiddenBlockTypes' ) + .select( preferencesStore ) + .get( 'core', 'hiddenBlockTypes' ) ).toEqual( expectedA ); expect( @@ -193,8 +190,8 @@ describe( 'actions', () => { expect( registry - .select( editPostStore ) - .getPreference( 'hiddenBlockTypes' ) + .select( preferencesStore ) + .get( 'core', 'hiddenBlockTypes' ) ).toEqual( expectedB ); expect( @@ -220,6 +217,9 @@ describe( 'actions', () => { 'core/paragraph': 'fancy', 'core/quote': 'posh', } ); + + // Expect a deprecation message for `getPreference`. + expect( console ).toHaveWarned(); } ); it( 'removes a preferred style variation for a block when a style name is omitted', () => { diff --git a/packages/editor/src/components/preferences-modal/test/__snapshots__/meta-boxes-section.js.snap b/packages/editor/src/components/preferences-modal/test/__snapshots__/meta-boxes-section.js.snap deleted file mode 100644 index c39f90d4aa0e5d..00000000000000 --- a/packages/editor/src/components/preferences-modal/test/__snapshots__/meta-boxes-section.js.snap +++ /dev/null @@ -1,464 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`MetaBoxesSection renders a Custom Fields option 1`] = ` -.emotion-0 { - font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif; - font-size: 13px; - box-sizing: border-box; -} - -.emotion-0 *, -.emotion-0 *::before, -.emotion-0 *::after { - box-sizing: inherit; -} - -.components-panel__row .emotion-2 { - margin-bottom: inherit; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - gap: calc(4px * 3); - -webkit-box-pack: start; - -ms-flex-pack: start; - -webkit-justify-content: flex-start; - justify-content: flex-start; - width: 100%; -} - -.emotion-4>* { - min-width: 0; -} - -.emotion-6 { - display: block; - max-height: 100%; - max-width: 100%; - min-height: 0; - min-width: 0; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; -} - -
      - -

      - Advanced panels -

      -
      -
      -
      -
      -
      -
      - - - - - - -
      -
      -
      -
      -
      -
      -`; - -exports[`MetaBoxesSection renders a Custom Fields option and meta box options 1`] = ` -.emotion-0 { - font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif; - font-size: 13px; - box-sizing: border-box; -} - -.emotion-0 *, -.emotion-0 *::before, -.emotion-0 *::after { - box-sizing: inherit; -} - -.components-panel__row .emotion-2 { - margin-bottom: inherit; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - gap: calc(4px * 3); - -webkit-box-pack: start; - -ms-flex-pack: start; - -webkit-justify-content: flex-start; - justify-content: flex-start; - width: 100%; -} - -.emotion-4>* { - min-width: 0; -} - -.emotion-6 { - display: block; - max-height: 100%; - max-width: 100%; - min-height: 0; - min-width: 0; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; -} - -
      - -

      - Advanced panels -

      -
      -
      -
      -
      -
      -
      - - - - - - -
      -
      -
      -
      -
      -
      -
      -
      - - - - - - -
      -
      -
      -
      -
      -
      -
      -
      - - - - - - -
      -
      -
      -
      -
      -
      -`; - -exports[`MetaBoxesSection renders meta box options 1`] = ` -.emotion-0 { - font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif; - font-size: 13px; - box-sizing: border-box; -} - -.emotion-0 *, -.emotion-0 *::before, -.emotion-0 *::after { - box-sizing: inherit; -} - -.components-panel__row .emotion-2 { - margin-bottom: inherit; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - gap: calc(4px * 3); - -webkit-box-pack: start; - -ms-flex-pack: start; - -webkit-justify-content: flex-start; - justify-content: flex-start; - width: 100%; -} - -.emotion-4>* { - min-width: 0; -} - -.emotion-6 { - display: block; - max-height: 100%; - max-width: 100%; - min-height: 0; - min-width: 0; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; -} - -
      - -

      - Advanced panels -

      -
      -
      -
      -
      -
      -
      - - - - - - -
      -
      -
      -
      -
      -
      -
      -
      - - - - - - -
      -
      -
      -
      -
      -
      -`; diff --git a/packages/preferences-persistence/src/migrations/preferences-package-data/test/index.js b/packages/preferences-persistence/src/migrations/preferences-package-data/test/index.js index 5ea8cd45e06767..fefde528402ca9 100644 --- a/packages/preferences-persistence/src/migrations/preferences-package-data/test/index.js +++ b/packages/preferences-persistence/src/migrations/preferences-package-data/test/index.js @@ -45,6 +45,10 @@ describe( 'convertPreferencesPackageData', () => { "core": { "editorMode": "visual", "fixedToolbar": true, + "hiddenBlockTypes": [ + "core/audio", + "core/cover", + ], "inactivePanels": [], "openPanels": [ "post-status", @@ -56,10 +60,6 @@ describe( 'convertPreferencesPackageData', () => { }, "core/edit-post": { "fullscreenMode": false, - "hiddenBlockTypes": [ - "core/audio", - "core/cover", - ], "pinnedItems": { "my-sidebar-plugin/title-sidebar": false, }, From 85ccc0a4baee7606c246fd92a3117fab9b97bc84 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 8 Jan 2024 12:57:17 +0100 Subject: [PATCH 3/4] Fix e2e tests --- .../editor/src/components/provider/use-block-editor-settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/components/provider/use-block-editor-settings.js b/packages/editor/src/components/provider/use-block-editor-settings.js index c42d269b1e6d5c..5a9b3a82b1bdbb 100644 --- a/packages/editor/src/components/provider/use-block-editor-settings.js +++ b/packages/editor/src/components/provider/use-block-editor-settings.js @@ -221,7 +221,7 @@ function useBlockEditorSettings( settings, postType, postId ) { const allowedBlockTypes = useMemo( () => { // Omit hidden block types if exists and non-empty. - if ( hiddenBlockTypes.length > 0 ) { + if ( hiddenBlockTypes && hiddenBlockTypes.length > 0 ) { // Defer to passed setting for `allowedBlockTypes` if provided as // anything other than `true` (where `true` is equivalent to allow // all block types). From 0bfca080d3c3fdd80498d8524cc23a2ae59c24e2 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Mon, 8 Jan 2024 16:47:46 +0200 Subject: [PATCH 4/4] small fix --- packages/edit-post/src/components/preferences-modal/index.js | 2 +- packages/editor/src/components/block-manager/index.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/edit-post/src/components/preferences-modal/index.js b/packages/edit-post/src/components/preferences-modal/index.js index b99be5cb34c384..326677aeffc5a1 100644 --- a/packages/edit-post/src/components/preferences-modal/index.js +++ b/packages/edit-post/src/components/preferences-modal/index.js @@ -53,7 +53,7 @@ export default function EditPostPreferencesModal() { ), appearance: ( { - const { showBlockTypes } = dispatch( editorStore ); + const { showBlockTypes } = unlock( dispatch( editorStore ) ); return { enableAllBlockTypes: ( blockTypes ) => { const blockNames = blockTypes.map( ( { name } ) => name );