From 9034196c71bab20b1cc38035f40f6404fc6dfc71 Mon Sep 17 00:00:00 2001 From: Bernie Reiter <96308+ockham@users.noreply.github.com> Date: Thu, 19 Dec 2024 13:29:03 +0100 Subject: [PATCH 01/13] Synced Patterns: Apply Block Hooks (#68058) Apply Block Hooks to synced patterns (i.e. `core/block` instances). Co-authored-by: ockham Co-authored-by: gziolo --- backport-changelog/6.8/8015.md | 3 +++ lib/compat/wordpress-6.8/blocks.php | 13 ++++++++++++- packages/block-library/src/block/index.php | 20 ++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 backport-changelog/6.8/8015.md diff --git a/backport-changelog/6.8/8015.md b/backport-changelog/6.8/8015.md new file mode 100644 index 0000000000000..214705518a0e7 --- /dev/null +++ b/backport-changelog/6.8/8015.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/8015 + +* https://github.com/WordPress/gutenberg/pull/68058 diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index 8e176e58c8d7f..dc8747c04aec2 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -170,7 +170,7 @@ function gutenberg_apply_block_hooks_to_post_content( $content ) { * @return WP_REST_Response The response object. */ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) { - if ( empty( $response->data['content']['raw'] ) || empty( $response->data['content']['rendered'] ) ) { + if ( empty( $response->data['content']['raw'] ) ) { return $response; } @@ -185,6 +185,8 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) { if ( 'wp_navigation' === $post->post_type ) { $wrapper_block_type = 'core/navigation'; + } elseif ( 'wp_block' === $post->post_type ) { + $wrapper_block_type = 'core/block'; } else { $wrapper_block_type = 'core/post-content'; } @@ -206,6 +208,11 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) { $response->data['content']['raw'] = $content; + // If the rendered content was previously empty, we leave it like that. + if ( empty( $response->data['content']['rendered'] ) ) { + return $response; + } + // No need to inject hooked blocks twice. $priority = has_filter( 'the_content', 'apply_block_hooks_to_content' ); if ( false !== $priority ) { @@ -224,6 +231,7 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) { } add_filter( 'rest_prepare_page', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 ); add_filter( 'rest_prepare_post', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 ); +add_filter( 'rest_prepare_wp_block', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 ); /** * Updates the wp_postmeta with the list of ignored hooked blocks @@ -272,6 +280,8 @@ function gutenberg_update_ignored_hooked_blocks_postmeta( $post ) { if ( 'wp_navigation' === $post->post_type ) { $wrapper_block_type = 'core/navigation'; + } elseif ( 'wp_block' === $post->post_type ) { + $wrapper_block_type = 'core/block'; } else { $wrapper_block_type = 'core/post-content'; } @@ -311,3 +321,4 @@ function gutenberg_update_ignored_hooked_blocks_postmeta( $post ) { } add_filter( 'rest_pre_insert_page', 'gutenberg_update_ignored_hooked_blocks_postmeta' ); add_filter( 'rest_pre_insert_post', 'gutenberg_update_ignored_hooked_blocks_postmeta' ); +add_filter( 'rest_pre_insert_wp_block', 'gutenberg_update_ignored_hooked_blocks_postmeta' ); diff --git a/packages/block-library/src/block/index.php b/packages/block-library/src/block/index.php index 8beef975fad6f..e8075115cabda 100644 --- a/packages/block-library/src/block/index.php +++ b/packages/block-library/src/block/index.php @@ -87,6 +87,26 @@ function render_block_core_block( $attributes ) { add_filter( 'render_block_context', $filter_block_context, 1 ); } + $ignored_hooked_blocks = get_post_meta( $attributes['ref'], '_wp_ignored_hooked_blocks', true ); + if ( ! empty( $ignored_hooked_blocks ) ) { + $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true ); + $attributes['metadata'] = array( + 'ignoredHookedBlocks' => $ignored_hooked_blocks, + ); + } + + // Wrap in "Block" block so the Block Hooks algorithm can insert blocks + // that are hooked as first or last child of `core/block`. + $content = get_comment_delimited_block_content( + 'core/block', + $attributes, + $content + ); + // Apply Block Hooks. + $content = apply_block_hooks_to_content( $content, $reusable_block ); + // Remove block wrapper. + $content = remove_serialized_parent_block( $content ); + $content = do_blocks( $content ); unset( $seen_refs[ $attributes['ref'] ] ); From c01cb99445c2261d2af1238b59104334fae91714 Mon Sep 17 00:00:00 2001 From: Bernie Reiter <96308+ockham@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:04:03 +0100 Subject: [PATCH 02/13] Assets: Add README.md about syncing (#68128) Add a README.md to the `assets/` directory, to document how it is synced to the plugin repository. Co-authored-by: ockham Co-authored-by: sirreal Co-authored-by: bph --- assets/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 assets/README.md diff --git a/assets/README.md b/assets/README.md new file mode 100644 index 0000000000000..e437ec744d380 --- /dev/null +++ b/assets/README.md @@ -0,0 +1,7 @@ +## Gutenberg Plugin Assets + +The contents of this directory are synced from the [`assets/` directory in the Gutenberg repository on GitHub](https://github.com/WordPress/gutenberg/tree/trunk/assets) to the [`assets/` directory of the Gutenberg WordPress.org plugin repository](https://plugins.trac.wordpress.org/browser/gutenberg/assets). **Any changes committed directly to the plugin repository on WordPress.org will be overwritten.** + +The sync is performed by a [GitHub Actions workflow](https://github.com/WordPress/gutenberg/actions/workflows/sync-assets-to-plugin-repo.yml) that is triggered whenever a file in this directory is changed. + +Since that workflow requires access to WP.org plugin repository credentials, it needs to be approved manually by a member of the Gutenberg Core team. If you don't have the necessary permissions, please ask someone in [#core-editor](https://wordpress.slack.com/archives/C02QB2JS7). From ec681ff31bce36aca02cc6a9128fa7ebdcae92ca Mon Sep 17 00:00:00 2001 From: Juan Aldasoro Date: Thu, 19 Dec 2024 16:13:21 +0100 Subject: [PATCH 03/13] Use Badge component in page markers (#68103) * Use Badge component in page markers * Remove redundant prop. * Remove import. * Fix the title alignment. Co-authored-by: juanfra Co-authored-by: tyxla Co-authored-by: jameskoster --- .../src/components/post-card-panel/index.js | 10 ++++++---- .../src/components/post-card-panel/style.scss | 17 ++++------------- .../fields/src/fields/page-title/style.scss | 10 ---------- packages/fields/src/fields/page-title/view.tsx | 7 +++++-- packages/fields/src/style.scss | 1 - 5 files changed, 15 insertions(+), 30 deletions(-) delete mode 100644 packages/fields/src/fields/page-title/style.scss diff --git a/packages/editor/src/components/post-card-panel/index.js b/packages/editor/src/components/post-card-panel/index.js index 7849f014ab49c..78f9522ba5f44 100644 --- a/packages/editor/src/components/post-card-panel/index.js +++ b/packages/editor/src/components/post-card-panel/index.js @@ -6,6 +6,7 @@ import { __experimentalHStack as HStack, __experimentalVStack as VStack, __experimentalText as Text, + privateApis as componentsPrivateApis, } from '@wordpress/components'; import { store as coreStore } from '@wordpress/core-data'; import { useSelect } from '@wordpress/data'; @@ -25,6 +26,7 @@ import { unlock } from '../../lock-unlock'; import PostActions from '../post-actions'; import usePageTypeBadge from '../../utils/pageTypeBadge'; import { getTemplateInfo } from '../../utils/get-template-info'; +const { Badge } = unlock( componentsPrivateApis ); /** * Renders a title of the post type and the available quick actions available within a 3-dot dropdown. @@ -109,11 +111,11 @@ export default function PostCardPanel( { className="editor-post-card-panel__title" as="h2" > - { title } + + { title } + { pageTypeBadge && postIds.length === 1 && ( - - { pageTypeBadge } - + { pageTypeBadge } ) } { @@ -27,11 +30,11 @@ export default function PageTitleView( { item }: { item: CommonPost } ) { return ( { [ frontPageId, postsPageId ].includes( item.id as number ) && ( - + { item.id === frontPageId ? __( 'Homepage' ) : __( 'Posts Page' ) } - + ) } ); diff --git a/packages/fields/src/style.scss b/packages/fields/src/style.scss index d9a571270fbb6..96b1f816de5b6 100644 --- a/packages/fields/src/style.scss +++ b/packages/fields/src/style.scss @@ -3,5 +3,4 @@ @import "./fields/featured-image/style.scss"; @import "./fields/template/style.scss"; @import "./fields/title/style.scss"; -@import "./fields/page-title/style.scss"; @import "./fields/pattern-title/style.scss"; From 505bbc8d285014ab3562e33f0a3919cff55e3f30 Mon Sep 17 00:00:00 2001 From: James Koster Date: Thu, 19 Dec 2024 15:37:30 +0000 Subject: [PATCH 04/13] Update active menu item appearance (#68147) Co-authored-by: jameskoster Co-authored-by: jasmussen --- .../edit-site/src/components/sidebar-navigation-item/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/edit-site/src/components/sidebar-navigation-item/style.scss b/packages/edit-site/src/components/sidebar-navigation-item/style.scss index 230967c4c7e0e..57b7e84bd57a8 100644 --- a/packages/edit-site/src/components/sidebar-navigation-item/style.scss +++ b/packages/edit-site/src/components/sidebar-navigation-item/style.scss @@ -18,6 +18,7 @@ &[aria-current="true"] { background: $gray-800; color: $white; + font-weight: $font-weight-medium; } // Make sure the focus style is drawn on top of the current item background. From afca7b5e11cbe3808c4333e18d522c5ea1b56ad2 Mon Sep 17 00:00:00 2001 From: Rinkal Pagdar <92097119+rinkalpagdar@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:46:25 +0530 Subject: [PATCH 05/13] Refactor "Settings" panel of Navigation Item block to use ToolsPanel instead of PanelBody (#67973) Co-authored-by: rinkalpagdar Co-authored-by: fabiankaegy Co-authored-by: getdave Co-authored-by: Mamaduka --- .../block-library/src/navigation-link/edit.js | 162 +++++++++++------- 1 file changed, 101 insertions(+), 61 deletions(-) diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index 39073b848d3ca..5966739aa61a6 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -9,7 +9,8 @@ import clsx from 'clsx'; import { createBlock } from '@wordpress/blocks'; import { useSelect, useDispatch } from '@wordpress/data'; import { - PanelBody, + __experimentalToolsPanel as ToolsPanel, + __experimentalToolsPanelItem as ToolsPanelItem, TextControl, TextareaControl, ToolbarButton, @@ -161,71 +162,110 @@ function getMissingText( type ) { function Controls( { attributes, setAttributes, setIsLabelFieldFocused } ) { const { label, url, description, title, rel } = attributes; return ( - - { - setAttributes( { label: labelValue } ); - } } + + !! label } label={ __( 'Text' ) } - autoComplete="off" - onFocus={ () => setIsLabelFieldFocused( true ) } - onBlur={ () => setIsLabelFieldFocused( false ) } - /> - { - updateAttributes( - { url: urlValue }, - setAttributes, - attributes - ); - } } + onDeselect={ () => setAttributes( { label: '' } ) } + isShownByDefault + > + { + setAttributes( { label: labelValue } ); + } } + autoComplete="off" + onFocus={ () => setIsLabelFieldFocused( true ) } + onBlur={ () => setIsLabelFieldFocused( false ) } + /> + + + !! url } label={ __( 'Link' ) } - autoComplete="off" - /> - { - setAttributes( { description: descriptionValue } ); - } } + onDeselect={ () => setAttributes( { url: '' } ) } + isShownByDefault + > + { + updateAttributes( + { url: urlValue }, + setAttributes, + attributes + ); + } } + autoComplete="off" + /> + + + !! description } label={ __( 'Description' ) } - help={ __( - 'The description will be displayed in the menu if the current theme supports it.' - ) } - /> - { - setAttributes( { title: titleValue } ); - } } + onDeselect={ () => setAttributes( { description: '' } ) } + isShownByDefault + > + { + setAttributes( { description: descriptionValue } ); + } } + help={ __( + 'The description will be displayed in the menu if the current theme supports it.' + ) } + /> + + + !! title } label={ __( 'Title attribute' ) } - autoComplete="off" - help={ __( - 'Additional information to help clarify the purpose of the link.' - ) } - /> - { - setAttributes( { rel: relValue } ); - } } + onDeselect={ () => setAttributes( { title: '' } ) } + isShownByDefault + > + { + setAttributes( { title: titleValue } ); + } } + autoComplete="off" + help={ __( + 'Additional information to help clarify the purpose of the link.' + ) } + /> + + + !! rel } label={ __( 'Rel attribute' ) } - autoComplete="off" - help={ __( - 'The relationship of the linked URL as space-separated link types.' - ) } - /> - + onDeselect={ () => setAttributes( { rel: '' } ) } + isShownByDefault + > + { + setAttributes( { rel: relValue } ); + } } + autoComplete="off" + help={ __( + 'The relationship of the linked URL as space-separated link types.' + ) } + /> + + ); } From 9b3e07f0ac02ad9fd4ea42450591070abef6122c Mon Sep 17 00:00:00 2001 From: Prasad Karmalkar Date: Thu, 19 Dec 2024 21:49:29 +0530 Subject: [PATCH 06/13] Refactor "Settings" panel of Spacer block to use ToolsPanel instead of PanelBody (#67981) Co-authored-by: prasadkarmalkar Co-authored-by: fabiankaegy --- packages/block-library/src/spacer/controls.js | 57 ++++++++++++++----- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/packages/block-library/src/spacer/controls.js b/packages/block-library/src/spacer/controls.js index 1e899e15aff0d..fde06d3ee8c33 100644 --- a/packages/block-library/src/spacer/controls.js +++ b/packages/block-library/src/spacer/controls.js @@ -10,10 +10,11 @@ import { privateApis as blockEditorPrivateApis, } from '@wordpress/block-editor'; import { - PanelBody, __experimentalUseCustomUnits as useCustomUnits, __experimentalUnitControl as UnitControl, __experimentalParseQuantityAndUnitFromRawValue as parseQuantityAndUnitFromRawValue, + __experimentalToolsPanel as ToolsPanel, + __experimentalToolsPanelItem as ToolsPanelItem, } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; import { View } from '@wordpress/primitives'; @@ -94,28 +95,54 @@ export default function SpacerControls( { } ) { return ( - + { + setAttributes( { + width: undefined, + height: '100px', + } ); + } } + > { orientation === 'horizontal' && ( - - setAttributes( { width: nextWidth } ) + isShownByDefault + hasValue={ () => width !== undefined } + onDeselect={ () => + setAttributes( { width: undefined } ) } - isResizing={ isResizing } - /> + > + + setAttributes( { width: nextWidth } ) + } + isResizing={ isResizing } + /> + ) } { orientation !== 'horizontal' && ( - - setAttributes( { height: nextHeight } ) + isShownByDefault + hasValue={ () => height !== '100px' } + onDeselect={ () => + setAttributes( { height: '100px' } ) } - isResizing={ isResizing } - /> + > + + setAttributes( { height: nextHeight } ) + } + isResizing={ isResizing } + /> + ) } - + ); } From dea955c5470d7fba505e40561b64cde9a17d3a46 Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Fri, 20 Dec 2024 04:00:53 +0900 Subject: [PATCH 07/13] Storybook: Make prop sort order consistent (#68152) Co-authored-by: mirka <0mirka00@git.wordpress.org> Co-authored-by: tyxla --- storybook/preview.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/storybook/preview.js b/storybook/preview.js index 8372103cd9944..b74640d9bcfbc 100644 --- a/storybook/preview.js +++ b/storybook/preview.js @@ -108,6 +108,9 @@ export const parameters = { sort: 'requiredFirst', }, docs: { + controls: { + sort: 'requiredFirst', + }, // Flips the order of the description and the primary component story // so the component is always visible before the fold. page: () => ( From ad073b08924d1c7c1c7d673bab951a1b05023257 Mon Sep 17 00:00:00 2001 From: Sainath Poojary <53347682+SainathPoojary@users.noreply.github.com> Date: Fri, 20 Dec 2024 08:25:57 +0530 Subject: [PATCH 08/13] Storybook: Add PlainText Storybook stories (#67341) * Storybook: Add PlainText Storybook stories - Add Default, LongText, and WithClassName stories - Configure meta for PlainText component * Refactor: `PlainText` stories and removed useEffect * Refactor: Remove comment from story * Storybook: improve `PlainText` JSDoc and storybook descriptions - Enhance prop descriptions - Fix import order in storybook. * Storybook: Unify value and onChange prop descriptions Co-authored-by: SainathPoojary Co-authored-by: t-hamano --- packages/block-editor/README.md | 40 ++++++++++ .../src/components/plain-text/README.md | 4 +- .../src/components/plain-text/index.js | 34 +++++++++ .../plain-text/stories/index.story.js | 75 +++++++++++++++++++ 4 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 packages/block-editor/src/components/plain-text/stories/index.story.js diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 13dffce114f59..8fe2c5f1179dc 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -713,10 +713,50 @@ Undocumented declaration. ### PlainText +Render an auto-growing textarea allow users to fill any textual content. + _Related_ - +_Usage_ + +```jsx +import { registerBlockType } from '@wordpress/blocks'; +import { PlainText } from '@wordpress/block-editor'; + +registerBlockType( 'my-plugin/example-block', { + // ... + + attributes: { + content: { + type: 'string', + }, + }, + + edit( { className, attributes, setAttributes } ) { + return ( + setAttributes( { content } ) } + /> + ); + }, +} ); +``` + +_Parameters_ + +- _props_ `Object`: Component props. +- _props.value_ `string`: String value of the textarea. +- _props.onChange_ `Function`: Function called when the text value changes. +- _props.ref_ `[Object]`: The component forwards the `ref` property to the `TextareaAutosize` component. + +_Returns_ + +- `Element`: Plain text component + ### privateApis Private @wordpress/block-editor APIs. diff --git a/packages/block-editor/src/components/plain-text/README.md b/packages/block-editor/src/components/plain-text/README.md index aa15758118afd..1e0a7888ed1e4 100644 --- a/packages/block-editor/src/components/plain-text/README.md +++ b/packages/block-editor/src/components/plain-text/README.md @@ -6,11 +6,11 @@ Render an auto-growing textarea allow users to fill any textual content. ### `value: string` -_Required._ String value of the textarea +_Required._ String value of the textarea. ### `onChange( value: string ): Function` -_Required._ Called when the value changes. +_Required._ Function called when the text value changes. You can also pass any extra prop to the textarea rendered by this component. diff --git a/packages/block-editor/src/components/plain-text/index.js b/packages/block-editor/src/components/plain-text/index.js index 4bd6681f4eb07..d28aabebf7a14 100644 --- a/packages/block-editor/src/components/plain-text/index.js +++ b/packages/block-editor/src/components/plain-text/index.js @@ -15,7 +15,41 @@ import { forwardRef } from '@wordpress/element'; import EditableText from '../editable-text'; /** + * Render an auto-growing textarea allow users to fill any textual content. + * * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/plain-text/README.md + * + * @example + * ```jsx + * import { registerBlockType } from '@wordpress/blocks'; + * import { PlainText } from '@wordpress/block-editor'; + * + * registerBlockType( 'my-plugin/example-block', { + * // ... + * + * attributes: { + * content: { + * type: 'string', + * }, + * }, + * + * edit( { className, attributes, setAttributes } ) { + * return ( + * <PlainText + * className={ className } + * value={ attributes.content } + * onChange={ ( content ) => setAttributes( { content } ) } + * /> + * ); + * }, + * } ); + * ```` + * + * @param {Object} props Component props. + * @param {string} props.value String value of the textarea. + * @param {Function} props.onChange Function called when the text value changes. + * @param {Object} [props.ref] The component forwards the `ref` property to the `TextareaAutosize` component. + * @return {Element} Plain text component */ const PlainText = forwardRef( ( { __experimentalVersion, ...props }, ref ) => { if ( __experimentalVersion === 2 ) { diff --git a/packages/block-editor/src/components/plain-text/stories/index.story.js b/packages/block-editor/src/components/plain-text/stories/index.story.js new file mode 100644 index 0000000000000..d1a6253c0870a --- /dev/null +++ b/packages/block-editor/src/components/plain-text/stories/index.story.js @@ -0,0 +1,75 @@ +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import PlainText from '..'; + +const meta = { + title: 'BlockEditor/PlainText', + component: PlainText, + parameters: { + docs: { + canvas: { sourceState: 'shown' }, + description: { + component: + 'PlainText renders an auto-growing textarea that allows users to enter any textual content.', + }, + }, + }, + argTypes: { + value: { + control: { + type: null, + }, + table: { + type: { + summary: 'string', + }, + }, + description: 'String value of the textarea.', + }, + onChange: { + action: 'onChange', + control: { + type: null, + }, + table: { + type: { + summary: 'function', + }, + }, + description: 'Function called when the text value changes.', + }, + className: { + control: 'text', + table: { + type: { + summary: 'string', + }, + }, + description: 'Additional class name for the PlainText.', + }, + }, +}; + +export default meta; + +export const Default = { + render: function Template( { onChange, ...args } ) { + const [ value, setValue ] = useState(); + return ( + <PlainText + { ...args } + onChange={ ( ...changeArgs ) => { + onChange( ...changeArgs ); + setValue( ...changeArgs ); + } } + value={ value } + /> + ); + }, +}; From 6dfea11802d846b062e46aa09031c71b7c81ab33 Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria <sukhendu.guria@rtcamp.com> Date: Fri, 20 Dec 2024 09:09:53 +0530 Subject: [PATCH 09/13] Site Title Block: Add dropdown menu props to ToolsPanel component (#68017) --- packages/block-library/src/site-title/edit.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/block-library/src/site-title/edit.js b/packages/block-library/src/site-title/edit.js index 644629a96fe4e..44b29173e06b0 100644 --- a/packages/block-library/src/site-title/edit.js +++ b/packages/block-library/src/site-title/edit.js @@ -25,6 +25,11 @@ import { import { createBlock, getDefaultBlockName } from '@wordpress/blocks'; import { decodeEntities } from '@wordpress/html-entities'; +/** + * Internal dependencies + */ +import { useToolsPanelDropdownMenuProps } from '../utils/hooks'; + export default function SiteTitleEdit( { attributes, setAttributes, @@ -47,6 +52,7 @@ export default function SiteTitleEdit( { }; }, [] ); const { editEntityRecord } = useDispatch( coreStore ); + const dropdownMenuProps = useToolsPanelDropdownMenuProps(); function setTitle( newTitle ) { editEntityRecord( 'root', 'site', undefined, { @@ -121,6 +127,7 @@ export default function SiteTitleEdit( { linkTarget: '_self', } ); } } + dropdownMenuProps={ dropdownMenuProps } > <ToolsPanelItem hasValue={ () => isLink !== false } From 8ad85f99f19525e5848565e409f0446fc7275f6a Mon Sep 17 00:00:00 2001 From: tellthemachines <tellthemachines@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:47:16 +1100 Subject: [PATCH 10/13] Fix uploading background images in stylebook view. (#68159) Co-authored-by: tellthemachines <isabel_brison@git.wordpress.org> Co-authored-by: ramonjd <ramonopoly@git.wordpress.org> --- package-lock.json | 1 + packages/edit-site/package.json | 1 + .../src/components/style-book/index.js | 18 ++++++++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index edfa7bfa80024..bd901baca24a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51237,6 +51237,7 @@ "@wordpress/icons": "*", "@wordpress/keyboard-shortcuts": "*", "@wordpress/keycodes": "*", + "@wordpress/media-utils": "5.14.0", "@wordpress/notices": "*", "@wordpress/patterns": "*", "@wordpress/plugins": "*", diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index 51045be503de3..299f0a67da9b7 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -56,6 +56,7 @@ "@wordpress/icons": "*", "@wordpress/keyboard-shortcuts": "*", "@wordpress/keycodes": "*", + "@wordpress/media-utils": "5.14.0", "@wordpress/notices": "*", "@wordpress/patterns": "*", "@wordpress/plugins": "*", diff --git a/packages/edit-site/src/components/style-book/index.js b/packages/edit-site/src/components/style-book/index.js index 4c93d2ed8db89..28a693e76958d 100644 --- a/packages/edit-site/src/components/style-book/index.js +++ b/packages/edit-site/src/components/style-book/index.js @@ -35,6 +35,8 @@ import { useEffect, } from '@wordpress/element'; import { ENTER, SPACE } from '@wordpress/keycodes'; +import { uploadMedia } from '@wordpress/media-utils'; +import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies @@ -361,10 +363,22 @@ export const StyleBookPreview = ( { userConfig = {}, isStatic = false } ) => { [] ); + const canUserUploadMedia = useSelect( + ( select ) => + select( coreStore ).canUser( 'create', { + kind: 'root', + name: 'media', + } ), + [] + ); + // Update block editor settings because useMultipleOriginColorsAndGradients fetch colours from there. useEffect( () => { - dispatch( blockEditorStore ).updateSettings( siteEditorSettings ); - }, [ siteEditorSettings ] ); + dispatch( blockEditorStore ).updateSettings( { + ...siteEditorSettings, + mediaUpload: canUserUploadMedia ? uploadMedia : undefined, + } ); + }, [ siteEditorSettings, canUserUploadMedia ] ); const [ section, onChangeSection ] = useSection(); From 910c38fc6b8c33ef45251bac2fba5170af43c9b9 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak <himanshu.pathak@rtcamp.com> Date: Fri, 20 Dec 2024 11:10:11 +0530 Subject: [PATCH 11/13] Storybook: Add stories for the TextDecorationControl component (#67337) * Storybook: Add stories for the text-decoration-control component * Storybook: Improve TextDecorationControl props table heading * Storybook: Update TextDecorationControl story to follow best practices and simplify the structure * Storybook: Simplify TextDecorationControl story * Storybook: Improve the structure of TextDecorationControl story Co-authored-by: himanshupathak95 <abcd95@git.wordpress.org> Co-authored-by: t-hamano <wildworks@git.wordpress.org> --- .../text-decoration-control/README.md | 1 - .../stories/index.story.js | 67 ++++++++++++++----- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/packages/block-editor/src/components/text-decoration-control/README.md b/packages/block-editor/src/components/text-decoration-control/README.md index a606140baa330..87fb6e89bd571 100644 --- a/packages/block-editor/src/components/text-decoration-control/README.md +++ b/packages/block-editor/src/components/text-decoration-control/README.md @@ -28,7 +28,6 @@ Then, you can use the component in your block editor UI: ### `value` - **Type:** `String` -- **Default:** `none` - **Options:** `none`, `underline`, `line-through` The current value of the Text Decoration setting. You may only choose from the `Options` listed above. diff --git a/packages/block-editor/src/components/text-decoration-control/stories/index.story.js b/packages/block-editor/src/components/text-decoration-control/stories/index.story.js index 2212b484185cd..d139b30a2bb4b 100644 --- a/packages/block-editor/src/components/text-decoration-control/stories/index.story.js +++ b/packages/block-editor/src/components/text-decoration-control/stories/index.story.js @@ -8,26 +8,61 @@ import { useState } from '@wordpress/element'; */ import TextDecorationControl from '../'; -export default { +const meta = { title: 'BlockEditor/TextDecorationControl', component: TextDecorationControl, + parameters: { + docs: { + canvas: { sourceState: 'shown' }, + description: { + component: 'Control to facilitate text decoration selections.', + }, + }, + }, argTypes: { - onChange: { action: 'onChange' }, + value: { + control: { type: null }, + description: 'Currently selected text decoration.', + table: { + type: { + summary: 'string', + }, + }, + }, + onChange: { + action: 'onChange', + control: { type: null }, + description: 'Handles change in text decoration selection.', + table: { + type: { + summary: 'function', + }, + }, + }, + className: { + control: 'text', + description: 'Additional class name to apply.', + table: { + type: { summary: 'string' }, + }, + }, }, }; -const Template = ( { onChange, ...args } ) => { - const [ value, setValue ] = useState(); - return ( - <TextDecorationControl - { ...args } - onChange={ ( ...changeArgs ) => { - onChange( ...changeArgs ); - setValue( ...changeArgs ); - } } - value={ value } - /> - ); -}; +export default meta; -export const Default = Template.bind( {} ); +export const Default = { + render: function Template( { onChange, ...args } ) { + const [ value, setValue ] = useState(); + return ( + <TextDecorationControl + { ...args } + onChange={ ( ...changeArgs ) => { + onChange( ...changeArgs ); + setValue( ...changeArgs ); + } } + value={ value } + /> + ); + }, +}; From 76d4652fd9f8369f70932631ba887a74b9c0c834 Mon Sep 17 00:00:00 2001 From: Eshaan Dabasiya <76681468+im3dabasia@users.noreply.github.com> Date: Fri, 20 Dec 2024 13:41:58 +0530 Subject: [PATCH 12/13] Storybook : Add TextTransformControl stories (#67365) * Add TextTransformControl stories * refactor: Removed the sample text, and extra stories and used story pattern * fix: Add options for the value prop and improve description * fix: Revert old template style code for render and updated argtypes * doc: Removed default value in props Co-authored-by: im3dabasia <im3dabasia1@git.wordpress.org> Co-authored-by: t-hamano <wildworks@git.wordpress.org> --- .../text-transform-control/README.md | 5 +- .../stories/index.story.js | 69 ++++++++++++++----- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/packages/block-editor/src/components/text-transform-control/README.md b/packages/block-editor/src/components/text-transform-control/README.md index 2d40cc16ba86f..3ed8f1da8cd6e 100644 --- a/packages/block-editor/src/components/text-transform-control/README.md +++ b/packages/block-editor/src/components/text-transform-control/README.md @@ -1,7 +1,7 @@ # TextTransformControl The `TextTransformControl` component is responsible for rendering a control element that allows users to select and apply text transformation options to blocks or elements in the Gutenberg editor. It provides an intuitive interface for changing the text appearance by applying different transformations such as `none`, `uppercase`, `lowercase`, `capitalize`. - + ![TextTransformConrol Element in Inspector Control](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/text-transform-component.png?raw=true) ## Development guidelines @@ -28,7 +28,6 @@ const MyTextTransformControlComponent = () => ( ### `value` - **Type:** `String` -- **Default:** `none` - **Options:** `none`, `uppercase`, `lowercase`, `capitalize` The current value of the Text Transform setting. You may only choose from the `Options` listed above. @@ -37,4 +36,4 @@ The current value of the Text Transform setting. You may only choose from the `O - **Type:** `Function` -A callback function invoked when the Text Transform value is changed via an interaction with any of the buttons. Called with the Text Transform value (`none`, `uppercase`, `lowercase`, `capitalize`) as the only argument. \ No newline at end of file +A callback function invoked when the Text Transform value is changed via an interaction with any of the buttons. Called with the Text Transform value (`none`, `uppercase`, `lowercase`, `capitalize`) as the only argument. diff --git a/packages/block-editor/src/components/text-transform-control/stories/index.story.js b/packages/block-editor/src/components/text-transform-control/stories/index.story.js index 96dd8ed479dc4..77dc550368da1 100644 --- a/packages/block-editor/src/components/text-transform-control/stories/index.story.js +++ b/packages/block-editor/src/components/text-transform-control/stories/index.story.js @@ -8,26 +8,63 @@ import { useState } from '@wordpress/element'; */ import TextTransformControl from '../'; -export default { +const meta = { title: 'BlockEditor/TextTransformControl', component: TextTransformControl, + parameters: { + docs: { + canvas: { sourceState: 'shown' }, + description: { + component: + 'Control to facilitate text transformation selections.', + }, + }, + }, argTypes: { - onChange: { action: 'onChange' }, + onChange: { + action: 'onChange', + control: { + type: null, + }, + description: 'Handles change in text transform selection.', + table: { + type: { + summary: 'function', + }, + }, + }, + className: { + control: { type: 'text' }, + description: 'Class name to add to the control.', + table: { + type: { summary: 'string' }, + }, + }, + value: { + control: { type: null }, + description: 'Currently selected text transform.', + table: { + type: { summary: 'string' }, + }, + }, }, }; -const Template = ( { onChange, ...args } ) => { - const [ value, setValue ] = useState(); - return ( - <TextTransformControl - { ...args } - onChange={ ( ...changeArgs ) => { - onChange( ...changeArgs ); - setValue( ...changeArgs ); - } } - value={ value } - /> - ); -}; +export default meta; + +export const Default = { + render: function Template( { onChange, ...args } ) { + const [ value, setValue ] = useState(); -export const Default = Template.bind( {} ); + return ( + <TextTransformControl + { ...args } + onChange={ ( ...changeArgs ) => { + onChange( ...changeArgs ); + setValue( ...changeArgs ); + } } + value={ value } + /> + ); + }, +}; From 9cb002ed3da642acf0826f63adb620537f3fc54b Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:51:50 +1000 Subject: [PATCH 13/13] Section Styles: Update block style variation docs (#68169) Co-authored-by: aaronrobertshaw <aaronrobertshaw@git.wordpress.org> Co-authored-by: ramonjd <ramonopoly@git.wordpress.org> --- .../themes/global-settings-and-styles.md | 101 +++++++++++++++++- 1 file changed, 97 insertions(+), 4 deletions(-) diff --git a/docs/how-to-guides/themes/global-settings-and-styles.md b/docs/how-to-guides/themes/global-settings-and-styles.md index f71bd67bfaf2e..205a3ee862ce6 100644 --- a/docs/how-to-guides/themes/global-settings-and-styles.md +++ b/docs/how-to-guides/themes/global-settings-and-styles.md @@ -1053,16 +1053,16 @@ Pseudo selectors `:hover`, `:focus`, `:visited`, `:active`, `:link`, `:any-link` #### Variations -A block can have a "style variation", as defined per the [block.json specification](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/#styles-optional). Theme authors can define the style attributes for an existing style variation using the theme.json file. Styles for unregistered style variations will be ignored. +A block can have a "style variation," as defined in the [block.json specification](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/#styles-optional). Theme authors can define the style attributes for an existing style variation using the `theme.json` file. Styles for unregistered style variations will be ignored. -Note that variations are a "block concept", they only exist bound to blocks. The `theme.json` specification respects that distinction by only allowing `variations` at the block-level but not at the top-level. It's also worth highlighting that only variations defined in the `block.json` file of the block are considered "registered": so far, the style variations added via `register_block_style` or in the client are ignored, see [this issue](https://github.com/WordPress/gutenberg/issues/49602) for more information. +Note that variations are a "block concept"—they only exist when bound to blocks. The `theme.json` specification respects this distinction by only allowing `variations` at the block level, not the top level. It’s also worth highlighting that only variations defined in the `block.json` file of the block or via `register_block_style` on the server are considered "registered" for `theme.json` styling purposes. For example, this is how to provide styles for the existing `plain` variation for the `core/quote` block: ```json { "version": 3, - "styles":{ + "styles": { "blocks": { "core/quote": { "variations": { @@ -1078,7 +1078,7 @@ For example, this is how to provide styles for the existing `plain` variation fo } ``` -The resulting CSS output is this: +The resulting CSS output is: ```css .wp-block-quote.is-style-plain { @@ -1086,6 +1086,99 @@ The resulting CSS output is this: } ``` +It is also possible for multiple block types to share the same variation styles. There are two recommended ways to define such shared styles: + +1. `theme.json` partial files +2. programmatically, using `register_block_style` + +##### Variation Theme.json Partials + +Like theme style variation partials, those for block style variations reside within a theme's `/styles` directory. However, they are differentiated from theme style variations by the introduction of a top-level property called `blockTypes`. The `blockTypes` property is an array of block types for which the block style variation has been registered. + +Additionally, a `slug` property is available to provide consistency between the different sources that may define block style variations and to decouple the `slug` from the translatable `title` property. + +The following is an example of a `theme.json` partial that defines styles for the "Variation A" block style for the Group, Columns, and Media & Text block types: + +```json +{ + "$schema": "https://schemas.wp.org/trunk/theme.json", + "version": 3, + "title": "Variation A", + "slug": "variation-a", + "blockTypes": [ "core/group", "core/columns", "core/media-text" ], + "styles": { + "color": { + "background": "#eed8d3", + "text": "#201819" + }, + "elements": { + "heading": { + "color": { + "text": "#201819" + } + } + }, + "blocks": { + "core/group": { + "color": { + "background": "#825f58", + "text": "#eed8d3" + }, + "elements": { + "heading": { + "color": { + "text": "#eed8d3" + } + } + } + } + } + } +} +``` + +##### Programmatically Registering Variation Styles + +As an alternative to `theme.json` partials, you can register variation styles at the same time as registering the variation itself through `register_block_style`. This is done by registering the block style for an array of block types while also passing a "style object" within the `style_data` option. + +The example below registers a "Green" variation for the Group and Columns blocks. Note that the style object passed via `style_data` follows the same shape as the `styles` property of a `theme.json` partial. + +```php +register_block_style( + array( 'core/group', 'core/columns' ), + array( + 'name' => 'green', + 'label' => __( 'Green' ), + 'style_data' => array( + 'color' => array( + 'background' => '#4f6f52', + 'text' => '#d2e3c8', + ), + 'blocks' => array( + 'core/group' => array( + 'color' => array( + 'background' => '#739072', + 'text' => '#e3eedd', + ), + ), + ), + 'elements' => array( + 'link' => array( + 'color' => array( + 'text' => '#ead196', + ), + ':hover' => array( + 'color' => array( + 'text' => '#ebd9b4', + ), + ), + ), + ), + ), + ) +); +``` + ### customTemplates <div class="callout callout-alert">Supported in WordPress from version 5.9.</div>