Lägg till klass och attribut på heading för att t.ex. göra en horisontell linje efter en rubrik

I JS nedan skapar vi en checkruta på headingblocken som i sin tur lägger på en klass på elementet om ibockad. Längst ner hittar vi ipmAddExtraProps där vi lägger till den inmatade texten som data-attribut på elementet. På så vis kan vi använda samma text i en ::before-deklaration. Väldigt omständigt men det är ett sätt att göra det på om man inte kan injecta <span> och grejer runt texten.

import assign from 'lodash.assign';
import { appendClassNames } from './helpers/appendClassNames';

const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody, SelectControl, CheckboxControl } = wp.components;
const { addFilter } = wp.hooks;
const { __, _x } = wp.i18n;


/**
 * Add spacing control attribute to block.
 *
 * @param {object} settings Current block settings.
 * @param {string} name Name of block.
 *
 * @returns {object} Modified block settings.
 */
const addControlAttributes = (settings, name) => {

	// Do nothing if it's another block than our defined ones.
	if (name !== 'core/heading') {
		return settings;
	}

	// Use Lodash's assign to gracefully handle if attributes are undefined
	settings.attributes = assign(settings.attributes, {
		headingline: {
			type: 'boolean',
			default: false
		}
	});

	return settings;
};



/**
 * Create HOC to add spacing control to inspector controls of block.
 */
const additionalSettings = createHigherOrderComponent((BlockEdit) => {
	return (props) => {

		// Do nothing if it's another block than our defined ones.
		if (props.name !== 'core/heading') {
			return (
				<BlockEdit {...props} />
			);
		}

		const { headingline } = props.attributes;

		return (
			<Fragment>
				<BlockEdit {...props} />
				<InspectorControls>
					<PanelBody
						title={_x('Heading settings','heading line label', 'ipm-gef')}
						initialOpen={false}
					>
						<CheckboxControl
							label={_x('Line', 'heading line label', 'ipm-gef')}
							checked={ headingline }
							onChange={(selectedLineOption) => {
								props.attributes.className = appendClassNames(props.attributes.className, 'has-heading-line', headingline, selectedLineOption)
								props.setAttributes({
									headingline: selectedLineOption,
								});
							}}
						/>

					</PanelBody>
				</InspectorControls>
			</Fragment>
		);
	};
}, 'additionalSettings');

addFilter('blocks.registerBlockType', 'ipm/settings/heading-attributes', addControlAttributes);
addFilter('editor.BlockEdit', 'ipm/settings/heading-controls', additionalSettings);



function ipmAddExtraProps(extraProps, blockType, attributes) {
	if (blockType.name === 'core/heading' && attributes.headingline === true) {

		return {
			...extraProps,
			'data-heading-content': attributes.content,
		};
	}

	return extraProps;
}
addFilter('blocks.getSaveContent.extraProps', 'ipm/add-extra-props', ipmAddExtraProps);
&.has-heading-line {
		background-color: var(--color-white);
		padding-right: 1rem;
		position: relative;
		display: flex;

		&::before {
			background: var(--color-gray--darkest);
			content: "";
			display: inline-block;
			width: calc(100%);
			height: 1px;
			position: absolute;
			right: 0;
			top: 50%;
			transform: translateY(-50%);
		}

		&::after {
			content: attr(data-heading-content);
			position: absolute;
			background: #fff;
			display: block;
			padding-right: 1rem;
		}
	}

Men, det finns en stor nackdel med detta och det är att text i pseudoelement inte är markerbar.

CSS Grid to the rescue:

&.has-heading-line {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr);
		align-items: center;
		grid-gap: 1rem;

		&::after {
			content: '';
			border-top: 1px solid var(--color-gray--darkest);
		}
}

Författare: Erik

Erik har jobbat med webb professionellt sedan 2008. Från 2005 till 2008 studerades webb på ING/JTH och dessförinnan skapades webb på all fritid. Första sajten byggdes någon gång mellan 1996-1998.