diff --git a/packages/block-editor/src/components/block-toolbar/shuffle.js b/packages/block-editor/src/components/block-toolbar/shuffle.js index e9101e76e6566..954c7ff22d68c 100644 --- a/packages/block-editor/src/components/block-toolbar/shuffle.js +++ b/packages/block-editor/src/components/block-toolbar/shuffle.js @@ -34,7 +34,14 @@ export default function Shuffle( { clientId, as = Container } ) { const _categories = attributes?.metadata?.categories || EMPTY_ARRAY; const _patternName = attributes?.metadata?.patternName; const rootBlock = getBlockRootClientId( clientId ); - const _patterns = __experimentalGetAllowedPatterns( rootBlock ); + + // Calling `__experimentalGetAllowedPatterns` is expensive. + // Checking if the block can be shuffled prevents unnecessary selector calls. + // See: https://github.com/WordPress/gutenberg/pull/64736. + const _patterns = + _categories.length > 0 + ? __experimentalGetAllowedPatterns( rootBlock ) + : EMPTY_ARRAY; return { categories: _categories, patterns: _patterns, @@ -45,12 +52,7 @@ export default function Shuffle( { clientId, as = Container } ) { ); const { replaceBlocks } = useDispatch( blockEditorStore ); const sameCategoryPatternsWithSingleWrapper = useMemo( () => { - if ( - ! categories || - categories.length === 0 || - ! patterns || - patterns.length === 0 - ) { + if ( categories.length === 0 || ! patterns || patterns.length === 0 ) { return EMPTY_ARRAY; } return patterns.filter( ( pattern ) => { diff --git a/packages/block-editor/src/utils/block-bindings.js b/packages/block-editor/src/utils/block-bindings.js index 4ba6e1a362958..b3daf4f4b36b4 100644 --- a/packages/block-editor/src/utils/block-bindings.js +++ b/packages/block-editor/src/utils/block-bindings.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { useDispatch, useSelect } from '@wordpress/data'; +import { useDispatch, useRegistry } from '@wordpress/data'; /** * Internal dependencies @@ -9,10 +9,14 @@ import { useDispatch, useSelect } from '@wordpress/data'; import { store as blockEditorStore } from '../store'; import { useBlockEditContext } from '../components/block-edit'; +function isObjectEmpty( object ) { + return ! object || Object.keys( object ).length === 0; +} + export function useBlockBindingsUtils() { const { clientId } = useBlockEditContext(); const { updateBlockAttributes } = useDispatch( blockEditorStore ); - const { getBlockAttributes } = useSelect( blockEditorStore ); + const { getBlockAttributes } = useRegistry().select( blockEditorStore ); /** * Updates the value of the bindings connected to block attributes. @@ -44,8 +48,10 @@ export function useBlockBindingsUtils() { * ``` */ const updateBlockBindings = ( bindings ) => { - const { metadata } = getBlockAttributes( clientId ); - const newBindings = { ...metadata?.bindings }; + const { metadata: { bindings: currentBindings, ...metadata } = {} } = + getBlockAttributes( clientId ); + const newBindings = { ...currentBindings }; + Object.entries( bindings ).forEach( ( [ attribute, binding ] ) => { if ( ! binding && newBindings[ attribute ] ) { delete newBindings[ attribute ]; @@ -59,15 +65,12 @@ export function useBlockBindingsUtils() { bindings: newBindings, }; - if ( Object.keys( newMetadata.bindings ).length === 0 ) { + if ( isObjectEmpty( newMetadata.bindings ) ) { delete newMetadata.bindings; } updateBlockAttributes( clientId, { - metadata: - Object.keys( newMetadata ).length === 0 - ? undefined - : newMetadata, + metadata: isObjectEmpty( newMetadata ) ? undefined : newMetadata, } ); }; @@ -83,14 +86,10 @@ export function useBlockBindingsUtils() { * ``` */ const removeAllBlockBindings = () => { - const { metadata } = getBlockAttributes( clientId ); - const newMetadata = { ...metadata }; - delete newMetadata.bindings; + const { metadata: { bindings, ...metadata } = {} } = + getBlockAttributes( clientId ); updateBlockAttributes( clientId, { - metadata: - Object.keys( newMetadata ).length === 0 - ? undefined - : newMetadata, + metadata: isObjectEmpty( metadata ) ? undefined : metadata, } ); }; diff --git a/packages/dataviews/src/components/dataviews-view-config/index.tsx b/packages/dataviews/src/components/dataviews-view-config/index.tsx index e396b1c68203c..fa17bd40893f6 100644 --- a/packages/dataviews/src/components/dataviews-view-config/index.tsx +++ b/packages/dataviews/src/components/dataviews-view-config/index.tsx @@ -143,6 +143,14 @@ function SortFieldControl() { function SortDirectionControl() { const { view, fields, onChangeView } = useContext( DataViewsContext ); + + const sortableFields = fields.filter( + ( field ) => field.enableSorting !== false + ); + if ( sortableFields.length === 0 ) { + return null; + } + let value = view.sort?.direction; if ( ! value && view.sort?.field ) { value = 'desc'; diff --git a/packages/dataviews/src/components/dataviews-view-config/style.scss b/packages/dataviews/src/components/dataviews-view-config/style.scss index 85e86722f7b61..00c1c6a9baf44 100644 --- a/packages/dataviews/src/components/dataviews-view-config/style.scss +++ b/packages/dataviews/src/components/dataviews-view-config/style.scss @@ -29,6 +29,10 @@ } } +.dataviews-settings-section:has(.dataviews-settings-section__content:empty) { + display: none; +} + /* stylelint-disable-next-line scss/at-rule-no-unknown -- '@container' not globally permitted */ @container (max-width: 500px) { .dataviews-settings-section.dataviews-settings-section { diff --git a/packages/dataviews/src/components/dataviews/stories/fixtures.js b/packages/dataviews/src/components/dataviews/stories/fixtures.js index 50401d97b026b..e061d0951ade7 100644 --- a/packages/dataviews/src/components/dataviews/stories/fixtures.js +++ b/packages/dataviews/src/components/dataviews/stories/fixtures.js @@ -191,6 +191,9 @@ export const fields = [ id: 'title', enableHiding: false, enableGlobalSearch: true, + render: ( { item } ) => { + return { item.title }; + }, }, { id: 'date', diff --git a/packages/dataviews/src/dataviews-layouts/list/style.scss b/packages/dataviews/src/dataviews-layouts/list/style.scss index 5b8f764d012a2..17d187c0c494a 100644 --- a/packages/dataviews/src/dataviews-layouts/list/style.scss +++ b/packages/dataviews/src/dataviews-layouts/list/style.scss @@ -100,6 +100,7 @@ } .dataviews-view-list__item { + box-sizing: border-box; padding: $grid-unit-20 $grid-unit-30; width: 100%; scroll-margin: $grid-unit-10 0; diff --git a/packages/dataviews/src/dataviews-layouts/table/style.scss b/packages/dataviews/src/dataviews-layouts/table/style.scss index 7bbd172c8c91b..dd091db4ec99f 100644 --- a/packages/dataviews/src/dataviews-layouts/table/style.scss +++ b/packages/dataviews/src/dataviews-layouts/table/style.scss @@ -7,11 +7,6 @@ color: $gray-700; margin-bottom: auto; - a { - text-decoration: none; - color: $gray-900; - font-weight: 500; - } th { text-align: left; color: $gray-900; diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index abc79853d222b..b9ca382e835d5 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Bug Fixes + +- Fix computeds without scope in Firefox ([#64825](https://github.com/WordPress/gutenberg/pull/64825)). + ## 6.6.0 (2024-08-21) ### Bug Fixes diff --git a/packages/interactivity/src/proxies/signals.ts b/packages/interactivity/src/proxies/signals.ts index 6a3f41c149e13..29bd58aaa4fce 100644 --- a/packages/interactivity/src/proxies/signals.ts +++ b/packages/interactivity/src/proxies/signals.ts @@ -20,7 +20,7 @@ import { withScope } from '../utils'; /** * Identifier for property computeds not associated to any scope. */ -const NO_SCOPE = Symbol(); +const NO_SCOPE = {}; /** * Structure that manages reactivity for a property in a state object. It uses