UNPKG

@wordpress/editor

Version:
8 lines (7 loc) 27.2 kB
{ "version": 3, "sources": ["../../../src/hooks/push-changes-to-global-styles/index.js"], "sourcesContent": ["import { addFilter } from '@wordpress/hooks';\nimport { createHigherOrderComponent } from '@wordpress/compose';\nimport {\n\tInspectorAdvancedControls,\n\tstore as blockEditorStore,\n\tprivateApis as blockEditorPrivateApis,\n\tuseBlockEditingMode,\n} from '@wordpress/block-editor';\nimport { BaseControl, Button } from '@wordpress/components';\nimport { __, sprintf } from '@wordpress/i18n';\nimport {\n\t__EXPERIMENTAL_STYLE_PROPERTY,\n\tgetBlockType,\n\thasBlockSupport,\n\tstore as blocksStore,\n} from '@wordpress/blocks';\nimport { useMemo, useCallback, useState } from '@wordpress/element';\nimport { useDispatch, useSelect } from '@wordpress/data';\nimport { store as noticesStore } from '@wordpress/notices';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { unlock } from '../../lock-unlock';\nimport setNestedValue from '../../utils/set-nested-value';\nimport { useGlobalStyles } from '../../components/global-styles/hooks';\nimport ApplyGloballyModal from './apply-globally-modal';\n\nconst { cleanEmptyObject } = unlock( blockEditorPrivateApis );\n\n// Block Gap is a special case and isn't defined within the blocks\n// style properties config. We'll add it here to allow it to be pushed\n// to global styles as well.\nconst STYLE_PROPERTY = {\n\t...__EXPERIMENTAL_STYLE_PROPERTY,\n\tblockGap: { value: [ 'spacing', 'blockGap' ] },\n};\n\n// TODO: Temporary duplication of constant in @wordpress/block-editor. Can be\n// removed by moving PushChangesToGlobalStylesControl to\n// @wordpress/block-editor.\nconst STYLE_PATH_TO_CSS_VAR_INFIX = {\n\t'border.color': 'color',\n\t'color.background': 'color',\n\t'color.text': 'color',\n\t'elements.link.color.text': 'color',\n\t'elements.link.:hover.color.text': 'color',\n\t'elements.link.typography.fontFamily': 'font-family',\n\t'elements.link.typography.fontSize': 'font-size',\n\t'elements.button.color.text': 'color',\n\t'elements.button.color.background': 'color',\n\t'elements.button.typography.fontFamily': 'font-family',\n\t'elements.button.typography.fontSize': 'font-size',\n\t'elements.caption.color.text': 'color',\n\t'elements.heading.color': 'color',\n\t'elements.heading.color.background': 'color',\n\t'elements.heading.typography.fontFamily': 'font-family',\n\t'elements.heading.gradient': 'gradient',\n\t'elements.heading.color.gradient': 'gradient',\n\t'elements.h1.color': 'color',\n\t'elements.h1.color.background': 'color',\n\t'elements.h1.typography.fontFamily': 'font-family',\n\t'elements.h1.color.gradient': 'gradient',\n\t'elements.h2.color': 'color',\n\t'elements.h2.color.background': 'color',\n\t'elements.h2.typography.fontFamily': 'font-family',\n\t'elements.h2.color.gradient': 'gradient',\n\t'elements.h3.color': 'color',\n\t'elements.h3.color.background': 'color',\n\t'elements.h3.typography.fontFamily': 'font-family',\n\t'elements.h3.color.gradient': 'gradient',\n\t'elements.h4.color': 'color',\n\t'elements.h4.color.background': 'color',\n\t'elements.h4.typography.fontFamily': 'font-family',\n\t'elements.h4.color.gradient': 'gradient',\n\t'elements.h5.color': 'color',\n\t'elements.h5.color.background': 'color',\n\t'elements.h5.typography.fontFamily': 'font-family',\n\t'elements.h5.color.gradient': 'gradient',\n\t'elements.h6.color': 'color',\n\t'elements.h6.color.background': 'color',\n\t'elements.h6.typography.fontFamily': 'font-family',\n\t'elements.h6.color.gradient': 'gradient',\n\t'color.gradient': 'gradient',\n\tblockGap: 'spacing',\n\t'typography.fontSize': 'font-size',\n\t'typography.fontFamily': 'font-family',\n};\n\n// TODO: Temporary duplication of constant in @wordpress/block-editor. Can be\n// removed by moving PushChangesToGlobalStylesControl to\n// @wordpress/block-editor.\nconst STYLE_PATH_TO_PRESET_BLOCK_ATTRIBUTE = {\n\t'border.color': 'borderColor',\n\t'color.background': 'backgroundColor',\n\t'color.text': 'textColor',\n\t'color.gradient': 'gradient',\n\t'typography.fontSize': 'fontSize',\n\t'typography.fontFamily': 'fontFamily',\n};\n\nconst SUPPORTED_STYLES = [ 'border', 'color', 'spacing', 'typography' ];\n\nconst getValueFromObjectPath = ( object, path ) => {\n\tlet value = object;\n\tpath.forEach( ( fieldName ) => {\n\t\tvalue = value?.[ fieldName ];\n\t} );\n\treturn value;\n};\n\nconst sides = [ 'top', 'right', 'bottom', 'left' ];\n\n/**\n * One style change shown as a single row. It holds every `{ path, value }` pair\n * the change covers so they all get pushed together.\n *\n * @typedef {Object} ChangeRow\n * @property {string} id Unique row id.\n * @property {string[]} primaryPath Path used to look up the current value.\n * @property {Array<{path: string[], value: *}>} paths The path/value pairs to push.\n * @property {string[]} presetAttributes Preset block attributes to clear when pushed.\n * @property {*} newValue Value shown in the \"New\" column.\n * @property {string} [format] How to display the value (`border`, `borderRadius`, `spacing`).\n */\n\n// Builds the border rows, grouped so each one reads as a single CSS `border`\n// value (all sides, one side, and radius) instead of a row per property.\nfunction getBorderRows( supports, attributes, blockUserConfig ) {\n\tconst rows = [];\n\tconst border = attributes.style?.border;\n\tconst userBorder = blockUserConfig?.border;\n\n\tconst colorSupported = supports.includes( 'borderColor' );\n\tconst widthSupported = supports.includes( 'borderWidth' );\n\tconst styleSupported = supports.includes( 'borderStyle' );\n\n\t// The all-sides border. A preset border color lives in a block attribute\n\t// and is pushed as a preset value.\n\tconst presetBorderColor = attributes.borderColor;\n\tconst flatColor = presetBorderColor\n\t\t? `var:preset|color|${ presetBorderColor }`\n\t\t: border?.color;\n\tconst flatRow = buildBorderScopeRow( {\n\t\tid: 'border',\n\t\tprimaryPath: [ 'border' ],\n\t\tside: null,\n\t\tcolor: colorSupported ? flatColor : undefined,\n\t\twidth: widthSupported ? border?.width : undefined,\n\t\tstyle: styleSupported ? border?.style : undefined,\n\t\tuserBorder,\n\t\tpresetAttributes: presetBorderColor ? [ 'borderColor' ] : [],\n\t} );\n\tif ( flatRow ) {\n\t\trows.push( flatRow );\n\t}\n\n\tsides.forEach( ( side ) => {\n\t\tconst sideBorder = border?.[ side ];\n\t\tconst sideRow = buildBorderScopeRow( {\n\t\t\tid: `border.${ side }`,\n\t\t\tprimaryPath: [ 'border', side ],\n\t\t\tside,\n\t\t\tcolor: colorSupported ? sideBorder?.color : undefined,\n\t\t\twidth: widthSupported ? sideBorder?.width : undefined,\n\t\t\tstyle: styleSupported ? sideBorder?.style : undefined,\n\t\t\tuserBorder,\n\t\t\tpresetAttributes: [],\n\t\t} );\n\t\tif ( sideRow ) {\n\t\t\trows.push( sideRow );\n\t\t}\n\t} );\n\n\t// Border radius, pushed as-is (a string or an object per corner) since\n\t// Global Styles takes either.\n\tif (\n\t\tsupports.includes( 'borderRadius' ) &&\n\t\tborder?.radius !== undefined &&\n\t\tborder?.radius !== ''\n\t) {\n\t\trows.push( {\n\t\t\tid: 'border.radius',\n\t\t\tprimaryPath: [ 'border', 'radius' ],\n\t\t\tpaths: [ { path: [ 'border', 'radius' ], value: border.radius } ],\n\t\t\tpresetAttributes: [],\n\t\t\tnewValue: border.radius,\n\t\t\tformat: 'borderRadius',\n\t\t} );\n\t}\n\n\treturn rows;\n}\n\n// Builds one border row (all sides or a single side) that pushes its color,\n// width and style together and shows them as one CSS value. Returns `null`\n// when there's nothing set.\nfunction buildBorderScopeRow( {\n\tid,\n\tprimaryPath,\n\tside,\n\tcolor,\n\twidth,\n\tstyle,\n\tuserBorder,\n\tpresetAttributes,\n} ) {\n\tif ( ! color && ! width && ! style ) {\n\t\treturn null;\n\t}\n\n\tconst paths = [];\n\t// The all-sides value is also written to each side so it can override any\n\t// per-side values from theme.json.\n\tconst targetSides = side ? [ side ] : sides;\n\n\tconst addChange = ( property, value ) => {\n\t\tif ( value === undefined ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( ! side ) {\n\t\t\tpaths.push( { path: [ 'border', property ], value } );\n\t\t}\n\t\ttargetSides.forEach( ( targetSide ) => {\n\t\t\tpaths.push( { path: [ 'border', targetSide, property ], value } );\n\t\t} );\n\t};\n\n\taddChange( 'color', color );\n\taddChange( 'width', width );\n\taddChange( 'style', style );\n\n\t// A border only shows with a style, so use `solid` when a color or width\n\t// is set without one (unless Global Styles already sets a style for that\n\t// side, which is kept).\n\tlet effectiveStyle = style;\n\tif ( ! style && ( color || width ) ) {\n\t\tconst sideStyles = targetSides.map(\n\t\t\t( targetSide ) => userBorder?.[ targetSide ]?.style\n\t\t);\n\t\ttargetSides.forEach( ( targetSide, index ) => {\n\t\t\tif ( ! sideStyles[ index ] ) {\n\t\t\t\tpaths.push( {\n\t\t\t\t\tpath: [ 'border', targetSide, 'style' ],\n\t\t\t\t\tvalue: 'solid',\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t\t// Show the style the border will actually have after Apply: the shared\n\t\t// Global Styles style when every side agrees on one, else `solid`.\n\t\tconst sharedStyle = sideStyles.every(\n\t\t\t( sideStyle ) => sideStyle === sideStyles[ 0 ]\n\t\t)\n\t\t\t? sideStyles[ 0 ]\n\t\t\t: undefined;\n\t\teffectiveStyle = sharedStyle || 'solid';\n\t}\n\n\treturn {\n\t\tid,\n\t\tprimaryPath,\n\t\tpaths,\n\t\tpresetAttributes,\n\t\tnewValue: { color, width, style: effectiveStyle },\n\t\tformat: 'border',\n\t};\n}\n\n/**\n * Works out which of the block's style changes can be pushed to Global Styles,\n * grouped into rows (see `ChangeRow`).\n *\n * @param {Array} supports Supported style keys for the block.\n * @param {Object} attributes Block attributes.\n * @param {Object} blockUserConfig The block's user Global Styles config.\n *\n * @return {ChangeRow[]} The changes, grouped into rows.\n */\nexport function getChangesToPush( supports, attributes, blockUserConfig ) {\n\tconst rows = [];\n\n\tsupports.forEach( ( key ) => {\n\t\tif ( ! STYLE_PROPERTY[ key ] ) {\n\t\t\treturn;\n\t\t}\n\t\t// Border styles are grouped and handled separately below.\n\t\tif ( key.startsWith( 'border' ) ) {\n\t\t\treturn;\n\t\t}\n\t\t// Root-only properties (e.g. `--wp--style--root--padding`) repeat their\n\t\t// normal version (`padding`) and only apply to the root, so skip them.\n\t\tif ( STYLE_PROPERTY[ key ].rootOnly ) {\n\t\t\treturn;\n\t\t}\n\t\tconst { value: path } = STYLE_PROPERTY[ key ];\n\t\tconst presetAttributeKey = path.join( '.' );\n\t\tconst presetAttributeName =\n\t\t\tSTYLE_PATH_TO_PRESET_BLOCK_ATTRIBUTE[ presetAttributeKey ];\n\t\tconst presetAttributeValue = presetAttributeName\n\t\t\t? attributes[ presetAttributeName ]\n\t\t\t: undefined;\n\t\tconst value = presetAttributeValue\n\t\t\t? `var:preset|${ STYLE_PATH_TO_CSS_VAR_INFIX[ presetAttributeKey ] }|${ presetAttributeValue }`\n\t\t\t: getValueFromObjectPath( attributes.style, path );\n\n\t\t// A preset attribute is only removed from the block when its row is\n\t\t// pushed (see `getStylesUpdate`).\n\t\tconst presetAttributes = presetAttributeValue\n\t\t\t? [ presetAttributeName ]\n\t\t\t: [];\n\n\t\t// Links have a single support but two styles: color and hover color.\n\t\t// Add the hover color to the changes when it's set.\n\t\tif ( key === 'linkColor' ) {\n\t\t\tconst paths = value ? [ { path, value } ] : [];\n\t\t\tconst hoverPath = [ 'elements', 'link', ':hover', 'color', 'text' ];\n\t\t\tconst hoverValue = getValueFromObjectPath(\n\t\t\t\tattributes.style,\n\t\t\t\thoverPath\n\t\t\t);\n\n\t\t\tif ( hoverValue ) {\n\t\t\t\tpaths.push( { path: hoverPath, value: hoverValue } );\n\t\t\t}\n\n\t\t\tif ( paths.length === 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\trows.push( {\n\t\t\t\tid: presetAttributeKey,\n\t\t\t\tprimaryPath: path,\n\t\t\t\tpaths,\n\t\t\t\tpresetAttributes,\n\t\t\t\tnewValue: value ?? hoverValue,\n\t\t\t} );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( value ) {\n\t\t\t// Padding and margin can be axial or per-side objects. The format\n\t\t\t// hint lets them show as one CSS value instead of a row per side\n\t\t\t// or a raw object. Block gap can be an axial `{ top, left }` object.\n\t\t\tlet format;\n\t\t\tif ( key === 'padding' || key === 'margin' ) {\n\t\t\t\tformat = 'spacing';\n\t\t\t} else if ( key === 'blockGap' ) {\n\t\t\t\tformat = 'blockGap';\n\t\t\t}\n\t\t\trows.push( {\n\t\t\t\tid: presetAttributeKey,\n\t\t\t\tprimaryPath: path,\n\t\t\t\tpaths: [ { path, value } ],\n\t\t\t\tpresetAttributes,\n\t\t\t\tnewValue: value,\n\t\t\t\tformat,\n\t\t\t} );\n\t\t}\n\t} );\n\n\trows.push( ...getBorderRows( supports, attributes, blockUserConfig ) );\n\n\treturn rows;\n}\n\nfunction useChangesToPush( name, attributes, userConfig ) {\n\tconst supports = useSelect(\n\t\t( select ) => {\n\t\t\treturn unlock( select( blocksStore ) ).getSupportedStyles( name );\n\t\t},\n\t\t[ name ]\n\t);\n\tconst blockUserConfig = userConfig?.styles?.blocks?.[ name ];\n\n\treturn useMemo(\n\t\t() => getChangesToPush( supports, attributes, blockUserConfig ),\n\t\t[ supports, attributes, blockUserConfig ]\n\t);\n}\n\n/**\n * Works out the block attribute and user Global Styles updates for the chosen\n * rows, without applying them. Returns `null` when there's nothing to push.\n *\n * @param {Object} options Options.\n * @param {Array} options.rowsToPush The rows to push.\n * @param {Object} options.attributes Current block attributes.\n * @param {Object} options.userConfig Current user Global Styles config.\n * @param {string} options.name Block name.\n *\n * @return {?{newBlockAttributes: Object, newUserConfig: Object}} The updates,\n * or `null` when no rows were chosen.\n */\nexport function getStylesUpdate( {\n\trowsToPush,\n\tattributes,\n\tuserConfig,\n\tname,\n} ) {\n\tif ( ! rowsToPush || rowsToPush.length === 0 ) {\n\t\treturn null;\n\t}\n\n\tconst selectedChanges = rowsToPush.flatMap( ( row ) => row.paths );\n\n\tif ( selectedChanges.length === 0 ) {\n\t\treturn null;\n\t}\n\n\tconst { style: blockStyles } = attributes;\n\n\tconst newBlockStyles = structuredClone( blockStyles );\n\tconst newUserConfig = structuredClone( userConfig );\n\n\tfor ( const { path, value } of selectedChanges ) {\n\t\tsetNestedValue( newBlockStyles, path, undefined );\n\t\tsetNestedValue(\n\t\t\tnewUserConfig,\n\t\t\t[ 'styles', 'blocks', name, ...path ],\n\t\t\tvalue\n\t\t);\n\t}\n\n\t// Only clear the preset attributes from the rows being pushed. Clearing\n\t// them all would wipe unselected preset styles from the block without\n\t// pushing them to Global Styles.\n\tconst newBlockAttributes = {\n\t\tstyle: cleanEmptyObject( newBlockStyles ),\n\t};\n\tfor ( const presetAttribute of rowsToPush.flatMap(\n\t\t( row ) => row.presetAttributes\n\t) ) {\n\t\tnewBlockAttributes[ presetAttribute ] = undefined;\n\t}\n\n\treturn { newBlockAttributes, newUserConfig };\n}\n\nfunction PushChangesToGlobalStylesControl( {\n\tname,\n\tattributes,\n\tsetAttributes,\n} ) {\n\tconst { user: userConfig, setUser: setUserConfig } = useGlobalStyles();\n\n\tconst rows = useChangesToPush( name, attributes, userConfig );\n\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\n\tconst { __unstableMarkNextChangeAsNotPersistent } =\n\t\tuseDispatch( blockEditorStore );\n\tconst { createSuccessNotice } = useDispatch( noticesStore );\n\n\tconst pushChanges = useCallback(\n\t\t( rowsToPush ) => {\n\t\t\tconst update = getStylesUpdate( {\n\t\t\t\trowsToPush,\n\t\t\t\tattributes,\n\t\t\t\tuserConfig,\n\t\t\t\tname,\n\t\t\t} );\n\n\t\t\tif ( ! update ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { newBlockAttributes, newUserConfig } = update;\n\n\t\t\t// @wordpress/core-data doesn't support editing multiple entity types in\n\t\t\t// a single undo level. So for now, we disable @wordpress/core-data undo\n\t\t\t// tracking and implement our own Undo button in the snackbar\n\t\t\t// notification.\n\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\tsetAttributes( newBlockAttributes );\n\t\t\tsetUserConfig( newUserConfig, { undoIgnore: true } );\n\t\t\tcreateSuccessNotice(\n\t\t\t\tsprintf(\n\t\t\t\t\t// translators: %s: Title of the block e.g. 'Heading'.\n\t\t\t\t\t__( '%s styles applied.' ),\n\t\t\t\t\tgetBlockType( name ).title\n\t\t\t\t),\n\t\t\t\t{\n\t\t\t\t\ttype: 'snackbar',\n\t\t\t\t\tactions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: __( 'Undo' ),\n\t\t\t\t\t\t\tonClick() {\n\t\t\t\t\t\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\t\t\t\t\t\tsetAttributes( attributes );\n\t\t\t\t\t\t\t\tsetUserConfig( userConfig, {\n\t\t\t\t\t\t\t\t\tundoIgnore: true,\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}\n\t\t\t);\n\t\t},\n\t\t[\n\t\t\t__unstableMarkNextChangeAsNotPersistent,\n\t\t\tattributes,\n\t\t\tcreateSuccessNotice,\n\t\t\tname,\n\t\t\tsetAttributes,\n\t\t\tsetUserConfig,\n\t\t\tuserConfig,\n\t\t]\n\t);\n\n\treturn (\n\t\t<BaseControl\n\t\t\tclassName=\"editor-push-changes-to-global-styles-control\"\n\t\t\thelp={ sprintf(\n\t\t\t\t// translators: %s: Title of the block e.g. 'Heading'.\n\t\t\t\t__(\n\t\t\t\t\t'Review and apply this block’s typography, spacing, dimensions, and color styles to all %s blocks.'\n\t\t\t\t),\n\t\t\t\tgetBlockType( name ).title\n\t\t\t) }\n\t\t>\n\t\t\t<BaseControl.VisualLabel>\n\t\t\t\t{ __( 'Styles' ) }\n\t\t\t</BaseControl.VisualLabel>\n\t\t\t<Button\n\t\t\t\t__next40pxDefaultSize\n\t\t\t\tvariant=\"secondary\"\n\t\t\t\taccessibleWhenDisabled\n\t\t\t\tdisabled={ rows.length === 0 }\n\t\t\t\tonClick={ () => setIsModalOpen( true ) }\n\t\t\t>\n\t\t\t\t{ __( 'Apply globally' ) }\n\t\t\t</Button>\n\t\t\t{ isModalOpen && (\n\t\t\t\t<ApplyGloballyModal\n\t\t\t\t\tname={ name }\n\t\t\t\t\trows={ rows }\n\t\t\t\t\tonApply={ pushChanges }\n\t\t\t\t\tonRequestClose={ () => setIsModalOpen( false ) }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</BaseControl>\n\t);\n}\n\nfunction PushChangesToGlobalStyles( props ) {\n\tconst blockEditingMode = useBlockEditingMode();\n\tconst isBlockBasedTheme = useSelect(\n\t\t( select ) => select( coreStore ).getCurrentTheme()?.is_block_theme,\n\t\t[]\n\t);\n\tconst supportsStyles = SUPPORTED_STYLES.some( ( feature ) =>\n\t\thasBlockSupport( props.name, feature )\n\t);\n\tconst isDisplayed =\n\t\tblockEditingMode === 'default' && supportsStyles && isBlockBasedTheme;\n\n\tif ( ! isDisplayed ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<InspectorAdvancedControls>\n\t\t\t<PushChangesToGlobalStylesControl { ...props } />\n\t\t</InspectorAdvancedControls>\n\t);\n}\n\nconst withPushChangesToGlobalStyles = createHigherOrderComponent(\n\t( BlockEdit ) => ( props ) => (\n\t\t<>\n\t\t\t<BlockEdit key=\"edit\" { ...props } />\n\t\t\t{ props.isSelected && <PushChangesToGlobalStyles { ...props } /> }\n\t\t</>\n\t)\n);\n\naddFilter(\n\t'editor.BlockEdit',\n\t'core/editor/push-changes-to-global-styles',\n\twithPushChangesToGlobalStyles\n);\n"], "mappings": "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", "names": [] }