diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index ca5e414ae65769..b6517357e7b657 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -10,12 +10,14 @@ import { Button, __experimentalHStack as HStack, __experimentalTruncate as Truncate, + Tooltip, } from '@wordpress/components'; import { forwardRef } from '@wordpress/element'; -import { Icon, lockSmall as lock } from '@wordpress/icons'; +import { Icon, lockSmall as lock, pinSmall } from '@wordpress/icons'; import { SPACE, ENTER, BACKSPACE, DELETE } from '@wordpress/keycodes'; import { useSelect, useDispatch } from '@wordpress/data'; import { __unstableUseShortcutEventMatch as useShortcutEventMatch } from '@wordpress/keyboard-shortcuts'; +import { __, sprintf } from '@wordpress/i18n'; /** * Internal dependencies @@ -60,6 +62,15 @@ function ListViewBlockSelectButton( } = useSelect( blockEditorStore ); const { removeBlocks } = useDispatch( blockEditorStore ); const isMatch = useShortcutEventMatch(); + const isSticky = blockInformation?.positionType === 'sticky'; + + const positionLabel = blockInformation?.positionLabel + ? sprintf( + // translators: 1: Position of selected block, e.g. "Sticky" or "Fixed". + __( 'Position: %1$s' ), + blockInformation.positionLabel + ) + : ''; // The `href` attribute triggers the browser's native HTML drag operations. // When the link is dragged, the element's outerHTML is set in DataTransfer object as text/html. @@ -166,6 +177,13 @@ function ListViewBlockSelectButton( ) } + { positionLabel && isSticky && ( + + + + + + ) } { isLocked && ( diff --git a/packages/block-editor/src/components/list-view/style.scss b/packages/block-editor/src/components/list-view/style.scss index 082389f71d4a0e..4b3ba296d35bc8 100644 --- a/packages/block-editor/src/components/list-view/style.scss +++ b/packages/block-editor/src/components/list-view/style.scss @@ -335,7 +335,8 @@ background: rgba($black, 0.3); } - .block-editor-list-view-block-select-button__lock { + .block-editor-list-view-block-select-button__lock, + .block-editor-list-view-block-select-button__sticky { line-height: 0; } } diff --git a/packages/block-editor/src/components/use-block-display-information/index.js b/packages/block-editor/src/components/use-block-display-information/index.js index 950cb9c905b24c..87909cea45f637 100644 --- a/packages/block-editor/src/components/use-block-display-information/index.js +++ b/packages/block-editor/src/components/use-block-display-information/index.js @@ -7,6 +7,7 @@ import { isReusableBlock, isTemplatePart, } from '@wordpress/blocks'; +import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -27,6 +28,26 @@ import { store as blockEditorStore } from '../../store'; * @property {string} anchor HTML anchor. */ +/** + * Get the display label for a block's position type. + * + * @param {Object} attributes Block attributes. + * @return {string} The position type label. + */ +function getPositionTypeLabel( attributes ) { + const positionType = attributes?.style?.position?.type; + + if ( positionType === 'sticky' ) { + return __( 'Sticky' ); + } + + if ( positionType === 'fixed' ) { + return __( 'Fixed' ); + } + + return null; +} + /** * Hook used to try to find a matching block variation and return * the appropriate information for display reasons. In order to @@ -57,12 +78,15 @@ export default function useBlockDisplayInformation( clientId ) { const match = getActiveBlockVariation( blockName, attributes ); const isSynced = isReusableBlock( blockType ) || isTemplatePart( blockType ); + const positionLabel = getPositionTypeLabel( attributes ); const blockTypeInfo = { isSynced, title: blockType.title, icon: blockType.icon, description: blockType.description, anchor: attributes?.anchor, + positionLabel, + positionType: attributes?.style?.position?.type, }; if ( ! match ) return blockTypeInfo; @@ -72,6 +96,8 @@ export default function useBlockDisplayInformation( clientId ) { icon: match.icon || blockType.icon, description: match.description || blockType.description, anchor: attributes?.anchor, + positionLabel, + positionType: attributes?.style?.position?.type, }; }, [ clientId ] diff --git a/packages/icons/src/index.js b/packages/icons/src/index.js index cd8058425a8d68..903d6f9455a873 100644 --- a/packages/icons/src/index.js +++ b/packages/icons/src/index.js @@ -169,6 +169,7 @@ export { default as positionRight } from './library/position-right'; export { default as pencil } from './library/pencil'; export { default as people } from './library/people'; export { default as pin } from './library/pin'; +export { default as pinSmall } from './library/pin-small'; export { default as plugins } from './library/plugins'; export { default as plusCircleFilled } from './library/plus-circle-filled'; export { default as plusCircle } from './library/plus-circle'; diff --git a/packages/icons/src/library/pin-small.js b/packages/icons/src/library/pin-small.js new file mode 100644 index 00000000000000..7ed84e47949a23 --- /dev/null +++ b/packages/icons/src/library/pin-small.js @@ -0,0 +1,18 @@ +/** + * WordPress dependencies + */ +import { SVG, Path } from '@wordpress/primitives'; + +const pinSmall = ( + + + +); + +export default pinSmall;