From 7f869913ae71367f56b0e285b55a3e3536155649 Mon Sep 17 00:00:00 2001 From: Jason Crist Date: Fri, 12 Apr 2024 10:05:51 -0400 Subject: [PATCH] Big sweeping changes to UI workflow. Still WIP. --- src/editor-sidebar/create-panel.js | 45 ++-- src/editor-sidebar/create-variation-panel.js | 103 ++++++++ src/editor-sidebar/metadata-editor-modal.js | 198 +++++++++++++++ src/editor-sidebar/save-panel.js | 119 +++++++++ src/plugin-sidebar.js | 251 +++++++------------ 5 files changed, 532 insertions(+), 184 deletions(-) create mode 100644 src/editor-sidebar/create-variation-panel.js create mode 100644 src/editor-sidebar/metadata-editor-modal.js create mode 100644 src/editor-sidebar/save-panel.js diff --git a/src/editor-sidebar/create-panel.js b/src/editor-sidebar/create-panel.js index a294abaa..1dd5f60b 100644 --- a/src/editor-sidebar/create-panel.js +++ b/src/editor-sidebar/create-panel.js @@ -19,6 +19,7 @@ import { Button, TextControl, TextareaControl, + CheckboxControl, } from '@wordpress/components'; import { chevronLeft, addCard, download, copy } from '@wordpress/icons'; @@ -36,6 +37,7 @@ export const CreateThemePanel = ( { createType } ) => { useSelect( ( select ) => { const themeData = select( 'core' ).getCurrentTheme(); + if ( createType.includes( 'export') ) { setTheme( { name: themeData.name.raw, description: themeData.description.raw, @@ -50,6 +52,17 @@ export const CreateThemePanel = ( { createType } ) => { ) : '', } ); + } else { + setTheme( { + subfolder: + themeData.stylesheet.lastIndexOf( '/' ) > 1 + ? themeData.stylesheet.substring( + 0, + themeData.stylesheet.lastIndexOf( '/' ) + ) + : '', + } ); + } }, [] ); const handleExportClick = () => { @@ -236,18 +249,13 @@ export const CreateThemePanel = ( { createType } ) => { - { __( 'Create Theme', 'create-block-theme' ) } + { + __( 'Clone Theme', 'create-block-theme' ) + } - - { __( - 'Enter Metadata properties of the new theme.', - 'create-block-theme' - ) } - - { setTheme( { ...theme, name: value } ) } /> +
+ Theme MetaData + { 'create-block-theme' ) } /> - - setTheme( { ...theme, subfolder: value } ) - } - /> +
+
{ createType === 'createClone' && ( <> - - - { __( - 'Create a copy of this theme on the server and activate it. The user changes will be preserved in the new theme.', - 'create-block-theme' - ) } - ) } { createType === 'createChild' && ( diff --git a/src/editor-sidebar/create-variation-panel.js b/src/editor-sidebar/create-variation-panel.js new file mode 100644 index 00000000..9725f203 --- /dev/null +++ b/src/editor-sidebar/create-variation-panel.js @@ -0,0 +1,103 @@ +import { __ } from '@wordpress/i18n'; +import { useState } from '@wordpress/element'; +import { useDispatch, useSelect } from '@wordpress/data'; +import apiFetch from '@wordpress/api-fetch'; +import { downloadFile } from '../utils'; +import { store as noticesStore } from '@wordpress/notices'; +import { + // eslint-disable-next-line + __experimentalVStack as VStack, + // eslint-disable-next-line + __experimentalSpacer as Spacer, + // eslint-disable-next-line + __experimentalText as Text, + // eslint-disable-next-line + __experimentalHeading as Heading, + // eslint-disable-next-line + __experimentalNavigatorToParentButton as NavigatorToParentButton, + PanelBody, + Button, + TextControl, + TextareaControl, + CheckboxControl, +} from '@wordpress/components'; +import { chevronLeft, addCard, download, copy } from '@wordpress/icons'; + +export const CreateVariationPanel = ( { createType } ) => { + + const { createErrorNotice } = useDispatch( noticesStore ); + + const [ theme, setTheme ] = useState( { + name: '', + } ); + + const handleCreateVariationClick = () => { + apiFetch( { + path: '/create-block-theme/v1/create-variation', + method: 'POST', + data: theme, + headers: { + 'Content-Type': 'application/json', + }, + } ) + .then( () => { + // eslint-disable-next-line + alert( + __( + 'Theme variation created successfully. The editor will now reload.', + 'create-block-theme' + ) + ); + window.location.reload(); + } ) + .catch( ( error ) => { + const errorMessage = + error.message || + __( + 'An error occurred while attempting to create the theme variation.', + 'create-block-theme' + ); + createErrorNotice( errorMessage, { type: 'snackbar' } ); + } ); + }; + + return ( + + + + { + __( 'Create Variation', 'create-block-theme' ) + } + + + + + + { __( + 'Save the Global Styles changes as a theme variation.', + 'create-block-theme' + ) } + +
+ + setTheme( { ...theme, name: value } ) + } + /> +
+ +
+
+ ); +}; diff --git a/src/editor-sidebar/metadata-editor-modal.js b/src/editor-sidebar/metadata-editor-modal.js new file mode 100644 index 00000000..21282458 --- /dev/null +++ b/src/editor-sidebar/metadata-editor-modal.js @@ -0,0 +1,198 @@ +import { __ } from '@wordpress/i18n'; +import { useState, useEffect } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; +import CodeMirror from '@uiw/react-codemirror'; +import { json } from '@codemirror/lang-json'; +import { fetchThemeJson } from '../resolvers'; +import { + // eslint-disable-next-line + __experimentalVStack as VStack, + // eslint-disable-next-line + __experimentalSpacer as Spacer, + // eslint-disable-next-line + __experimentalText as Text, + // eslint-disable-next-line + __experimentalHeading as Heading, + // eslint-disable-next-line + __experimentalNavigatorToParentButton as NavigatorToParentButton, + PanelBody, + Modal, + Button, + TextControl, + TextareaControl, + ExternalLink, +} from '@wordpress/components'; + +export const ThemeMetadataEditorModal = ( { onRequestClose } ) => { + + const themeName = useSelect( ( select ) => + select( 'core' ).getCurrentTheme() + )?.name?.raw; + + const [ theme, setTheme ] = useState( { + name: '', + description: '', + uri: '', + version: '', + author: '', + author_uri: '', + tags_custom: '', + recommended_plugins: '', + } ); + + const handleUpdateClick = () => { + apiFetch( { + path: '/create-block-theme/v1/update', + method: 'POST', + data: theme, + headers: { + 'Content-Type': 'application/json', + }, + } ) + .then( () => { + // eslint-disable-next-line + alert( + __( + 'Theme updated successfully. The editor will now reload.', + 'create-block-theme' + ) + ); + window.location.reload(); + } ) + .catch( ( error ) => { + const errorMessage = + error.message || + __( + 'An error occurred while attempting to update the theme.', + 'create-block-theme' + ); + createErrorNotice( errorMessage, { type: 'snackbar' } ); + } ); + }; + return ( + + + + + { __( + 'Edit Metadata properties of the current theme.', + 'create-block-theme' + ) } + + + + + setTheme( { ...theme, description: value } ) + } + placeholder={ __( + 'A short description of the theme', + 'create-block-theme' + ) } + /> + + setTheme( { ...theme, uri: value } ) + } + placeholder={ __( + 'https://github.com/wordpress/twentytwentythree/', + 'create-block-theme' + ) } + /> + + setTheme( { ...theme, author: value } ) + } + placeholder={ __( + 'the WordPress team', + 'create-block-theme' + ) } + /> + + setTheme( { ...theme, author_uri: value } ) + } + placeholder={ __( + 'https://wordpress.org/', + 'create-block-theme' + ) } + /> + + setTheme( { ...theme, version: value } ) + } + placeholder={ __( + 'Version of the theme', + 'create-block-theme' + ) } + /> + + setTheme( { ...theme, tags_custom: value } ) + } + placeholder={ __( + 'A comma-separated collection of tags', + 'create-block-theme' + ) } + /> + + { __( + 'List the recommended plugins for this theme. e.g. contact forms, social media. Plugins must be from the WordPress.org plugin repository.', + 'create-block-theme' + ) } +
+ + { __( 'Read more.', 'create-block-theme' ) } + + + } + // eslint-disable-next-line @wordpress/i18n-no-collapsible-whitespace + placeholder={ __( + `Plugin Name +https://wordpress.org/plugins/plugin-name/ +Plugin Description`, + 'create-block-theme' + ) } + value={ theme.recommended_plugins } + onChange={ ( value ) => + setTheme( { ...theme, recommended_plugins: value } ) + } + /> + + setTheme( { ...theme, subfolder: value } ) + } + /> +
+ + +
+ ); +}; diff --git a/src/editor-sidebar/save-panel.js b/src/editor-sidebar/save-panel.js new file mode 100644 index 00000000..86661f11 --- /dev/null +++ b/src/editor-sidebar/save-panel.js @@ -0,0 +1,119 @@ +import { __ } from '@wordpress/i18n'; +import { useState } from '@wordpress/element'; +import { useDispatch, useSelect } from '@wordpress/data'; +import apiFetch from '@wordpress/api-fetch'; +import { downloadFile } from '../utils'; +import { store as noticesStore } from '@wordpress/notices'; +import { + // eslint-disable-next-line + __experimentalVStack as VStack, + // eslint-disable-next-line + __experimentalSpacer as Spacer, + // eslint-disable-next-line + __experimentalText as Text, + // eslint-disable-next-line + __experimentalHeading as Heading, + // eslint-disable-next-line + __experimentalNavigatorToParentButton as NavigatorToParentButton, + PanelBody, + Button, + TextControl, + TextareaControl, + CheckboxControl, +} from '@wordpress/components'; +import { chevronLeft, archive, addCard, download, copy } from '@wordpress/icons'; + + + +export const SaveThemePanel = ( ) => { + +const [ saveOptions, setSaveOptions ] = useState( { + saveStyle: true, + saveTemplates: true, + saveFonts: true, + removeNavRefs: true, + localizeText: true, +} ); + +const handleSaveClick = () => { + apiFetch( { + path: '/create-block-theme/v1/save', + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + } ) + .then( () => { + // eslint-disable-next-line + alert( + __( + 'Theme saved successfully. The editor will now reload.', + 'create-block-theme' + ) + ); + window.location.reload(); + } ) + .catch( ( error ) => { + const errorMessage = + error.message || + __( + 'An error occurred while attempting to save the theme.', + 'create-block-theme' + ); + createErrorNotice( errorMessage, { type: 'snackbar' } ); + } ); + }; + + return ( + + + + {__( 'Save Changes', 'create-block-theme' ) } + + + + + { setSaveOptions({ ...saveOptions, saveStyle: !saveOptions.saveStyle }) } } + /> + { setSaveOptions({ ...saveOptions, saveTemplates: !saveOptions.saveTemplates }) } } + /> + { setSaveOptions({ ...saveOptions, localizeText: !saveOptions.localizeText }) } } + /> + { setSaveOptions({ ...saveOptions, saveFonts: !saveOptions.saveFonts }) } } + /> + { setSaveOptions({ ...saveOptions, removeNavRefs: !saveOptions.removeNavRefs }) } } + /> + + + + ); +}; diff --git a/src/plugin-sidebar.js b/src/plugin-sidebar.js index a2daa9fb..9de50ab4 100644 --- a/src/plugin-sidebar.js +++ b/src/plugin-sidebar.js @@ -34,49 +34,28 @@ import { import { UpdateThemePanel } from './editor-sidebar/update-panel'; import { CreateThemePanel } from './editor-sidebar/create-panel'; import ThemeJsonEditorModal from './editor-sidebar/json-editor-modal'; +import { SaveThemePanel } from './editor-sidebar/save-panel'; +import { CreateVariationPanel } from './editor-sidebar/create-variation-panel'; import { tool, copy, download, edit, + code, chevronRight, chevronLeft, + addCard, + blockMeta, archive, } from '@wordpress/icons'; +import { ThemeMetadataEditorModal } from './editor-sidebar/metadata-editor-modal'; const CreateBlockThemePlugin = () => { const [ isEditorOpen, setIsEditorOpen ] = useState( false ); + const [ isMetadataEditorOpen, setIsMetadataEditorOpen ] = useState( false ); const { createErrorNotice } = useDispatch( noticesStore ); - const handleSaveClick = () => { - apiFetch( { - path: '/create-block-theme/v1/save', - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - } ) - .then( () => { - // eslint-disable-next-line - alert( - __( - 'Theme saved successfully. The editor will now reload.', - 'create-block-theme' - ) - ); - window.location.reload(); - } ) - .catch( ( error ) => { - const errorMessage = - error.message || - __( - 'An error occurred while attempting to save the theme.', - 'create-block-theme' - ); - createErrorNotice( errorMessage, { type: 'snackbar' } ); - } ); - }; const handleExportClick = () => { const fetchOptions = { @@ -132,44 +111,21 @@ const CreateBlockThemePlugin = () => { - - - { __( - 'Save user changes (including Templates and Global Styles) to the theme.', - 'create-block-theme' - ) } - -
- + { __( - 'Create Theme', + 'Save Changes to Theme', 'create-block-theme' ) } - - { __( - 'Create a new theme based on your current theme or create a new blank theme.', - 'create-block-theme' - ) } - -
@@ -182,116 +138,95 @@ const CreateBlockThemePlugin = () => { - + + +
- + { __( - 'Export Theme', + 'Create Blank Theme', 'create-block-theme' ) } - - { __( - 'Export your theme as a zip file.', - 'create-block-theme' - ) } - -
- + - + { __( - 'Theme Info', + 'Clone Theme', 'create-block-theme' ) } - - { __( - 'Edit Metadata properties of your current theme.', - 'create-block-theme' - ) } - -
- - - { __( - 'Open the theme.json file to inspect theme data.', - 'create-block-theme' - ) } -
- - - - - + { __( - 'Create Theme', + 'Clone Theme', 'create-block-theme' ) } - - - - - { __( - 'Create Blank Theme', - 'create-block-theme' - ) } - - - - - + { __( - 'Create a blank theme with no styles or templates.', + 'Would you like to make a Regular Theme or a Child Theme?', 'create-block-theme' ) }
{ __( - 'Clone Theme', + 'Create Regular Theme', 'create-block-theme' ) } @@ -300,13 +235,13 @@ const CreateBlockThemePlugin = () => { { __( - 'Create a copy of this theme on the server and activate it. The user changes will be preserved in the new theme.', + 'Create a clone of this theme with a new name. The user changes will be preserved in the new theme.', 'create-block-theme' ) }
@@ -322,100 +257,89 @@ const CreateBlockThemePlugin = () => { { __( - 'Create a child theme on the server and activate it. The user changes will be preserved in the new theme.', + 'Create a child theme that uses this theme as a parent. This theme will remain unchanged and the user changes will be preserved in the new child theme.', 'create-block-theme' ) }
- - - - - - - - - - - - - + + { __( - 'Export Theme', + 'Clone Theme', 'create-block-theme' ) } - - + { __( - 'Export your theme as a zip file. The user changes will NOT be preserved in the new theme. To include those save the theme first.', + 'Would you like to create the theme on your server or export it as a zip file?', 'create-block-theme' ) }
{ __( - 'Export Clone', + 'Create on Server', 'create-block-theme' ) } - - { __( - 'Export a copy of this theme with new MetaData as a .zip file. The user changes will be preserved in the new theme.', - 'create-block-theme' - ) } - + + { __( + 'Create the new theme on the server and activate it. The user changes will be preserved in the new theme.', + 'create-block-theme' + ) } +
{ __( - 'Export Child', + 'Export Zip', 'create-block-theme' ) } - - { __( - 'Export a child of this theme as a .zip file. The user changes will be preserved in the new theme.', - 'create-block-theme' - ) } - + + { __( + 'Export a copy of this theme as a .zip file. The user changes will be preserved in the new theme.', + 'create-block-theme' + ) } +
- - + + + + + - - + + + + + @@ -424,6 +348,11 @@ const CreateBlockThemePlugin = () => { onRequestClose={ () => setIsEditorOpen( false ) } /> ) } + { isMetadataEditorOpen && ( + setIsMetadataEditorOpen( false ) } + /> + ) } ); };