Skip to content

Instantly share code, notes, and snippets.

@m-e-h
Last active June 2, 2021 05:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save m-e-h/951b18d23ebf018e2f9f5a8ddadb1e19 to your computer and use it in GitHub Desktop.
Save m-e-h/951b18d23ebf018e2f9f5a8ddadb1e19 to your computer and use it in GitHub Desktop.
/**
* External Dependencies
*/
// import classnames from 'classnames';
/**
* WordPress Dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { Fragment } from '@wordpress/element';
import TokenList from '@wordpress/token-list';
import { PanelBody, SelectControl } from '@wordpress/components';
import { InspectorControls } from '@wordpress/block-editor';
import { createHigherOrderComponent } from '@wordpress/compose';
import {
hasBlockSupport
// parseWithAttributeSchema,
// getSaveContent,
} from '@wordpress/blocks';
// const TokenList = wp.tokenList;
// Restrict to specific block names
const allowedBlocks = [
'core/paragraph',
'core/heading',
'core/columns',
'core/column',
'core/cover',
'core/buttons',
'core/button',
'core/list',
'core/group',
'core/image',
'core/separator',
'meh-theme/action-call',
'meh-theme/wrapper',
'meh-theme/card'
];
/**
* Add controls on Advanced Block Panel.
*/
const withAdvancedControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
const { name, attributes, setAttributes, isSelected } = props;
const { padT, padR, padB, padL, marT, marR, marB, marL, maxX, shadowD } = attributes;
const pOptions = [
{ label: 'default', value: '' },
{ label: 'none', value: '0' },
{ label: '0.5rem', value: '05' },
{ label: '1rem', value: '1' },
{ label: 'Base (24px)', value: '-base' },
{ label: 'Gutter SM (40px)', value: '-gutter-sm' },
{ label: 'Gutter (48px)', value: '-gutter' },
{ label: 'Gutter L (64px)', value: '-lg' },
{ label: 'Gutter XL (80px)', value: '-xl' },
{ label: 'Gutter XXL (112px)', value: '-xxl' }
];
const mOptions = [
{ label: 'default', value: '' },
{ label: 'none', value: '0' },
{ label: 'auto', value: '-auto' },
{ label: '0.5rem', value: '05' },
{ label: '1rem', value: '1' },
{ label: 'Base (24px)', value: '-base' },
{ label: 'Gutter SM (40px)', value: '-gutter-sm' },
{ label: 'Gutter (48px)', value: '-gutter' },
{ label: 'Gutter L (64px)', value: '-lg' },
{ label: 'Gutter XL (80px)', value: '-xl' },
{ label: 'Gutter XXL (112px)', value: '-xxl' }
];
const maxXOptions = [
{ label: 'default', value: '' },
{ label: 'none', value: '0' },
{ label: 'Content 1/2 (475px)', value: '-md' },
{ label: 'Wide 1/2 (555px)', value: '-lg' },
{ label: 'Reading width (740px)', value: '-reading' },
{ label: 'Content width (950px)', value: '-content' },
{ label: 'Content wide (1110px)', value: '-wide' },
{ label: 'Full screen', value: '-screen' },
{ label: '100%', value: '-container' }
];
const shadowOptions = [
{ label: 'none', value: '' },
{ label: 'Minor', value: '-1' },
{ label: 'Major', value: '-2' }
];
return (
<Fragment>
<BlockEdit { ...props } />
{ isSelected && (
<InspectorControls>
<PanelBody
title="Design Settings"
className="block-p-selects"
initialOpen={ false }
>
<p className="block-padding-controls__label">Block Padding</p>
<div className="block-padding-controls">
<SelectControl
key="padT"
label="&uarr;"
className="block-p-select block-pt"
value={ padT }
options={ pOptions }
onChange={ (selected) => {
setAttributes({
padT: selected ? selected : undefined,
className: updateClass(
attributes.className,
selected ? 'u-pt' + selected : '',
padT ? 'u-pt' + padT : false
)
});
} }
/>
<SelectControl
key="padR"
label="&rarr;"
className="block-p-select block-pr"
value={ padR }
options={ pOptions }
onChange={ (selected) => {
setAttributes({
padR: selected ? selected : undefined,
className: updateClass(
attributes.className,
selected ? 'u-pr' + selected : '',
padR ? 'u-pr' + padR : false
)
});
} }
/>
<SelectControl
key="padB"
label="&darr;"
className="block-p-select block-pb"
value={ padB }
options={ pOptions }
onChange={ (selected) => {
setAttributes({
padB: selected ? selected : undefined,
className: updateClass(
attributes.className,
selected ? 'u-pb' + selected : '',
padB ? 'u-pb' + padB : false
)
});
} }
/>
<SelectControl
key="padL"
label="&larr;"
className="block-p-select block-pl"
value={ padL }
options={ pOptions }
onChange={ (selected) => {
setAttributes({
padL: selected ? selected : undefined,
className: updateClass(
attributes.className,
selected ? 'u-pl' + selected : '',
padL ? 'u-pl' + padL : false
)
});
} }
/>
</div>
<p className="block-margin-controls__label">Block Margin</p>
<div className="block-margin-controls">
<SelectControl
key="marT"
label="&uarr;"
className="block-m-select block-mt"
value={ marT }
options={ mOptions }
onChange={ (selected) => {
setAttributes({
marT: selected ? selected : undefined,
className: updateClass(
attributes.className,
selected ? 'u-mt' + selected : '',
marT ? 'u-mt' + marT : false
)
});
} }
/>
<SelectControl
key="marR"
label="&rarr;"
className="block-m-select block-mr"
value={ marR }
options={ mOptions }
onChange={ (selected) => {
setAttributes({
marR: selected ? selected : undefined,
className: updateClass(
attributes.className,
selected ? 'u-mr' + selected : '',
marR ? 'u-mr' + marR : false
)
});
} }
/>
<SelectControl
key="marB"
label="&darr;"
className="block-m-select block-mb"
value={ marB }
options={ mOptions }
onChange={ (selected) => {
setAttributes({
marB: selected ? selected : undefined,
className: updateClass(
attributes.className,
selected ? 'u-mb' + selected : '',
marB ? 'u-mb' + marB : false
)
});
} }
/>
<SelectControl
key="marL"
label="&larr;"
className="block-m-select block-ml"
value={ marL }
options={ mOptions }
onChange={ (selected) => {
setAttributes({
marL: selected ? selected : undefined,
className: updateClass(
attributes.className,
selected ? 'u-ml' + selected : '',
marL ? 'u-ml' + marL : false
)
});
} }
/>
</div>
<p className="block-dimension-controls__label">Block Dimensions</p>
<div className="block-dimension-controls">
<SelectControl
key="maxX"
label="Max Block Width"
className="block-min-x-select block-min-x"
value={ maxX }
options={ maxXOptions }
onChange={ (selected) => {
setAttributes({
maxX: selected ? selected : undefined,
className: updateClass(
attributes.className,
selected ? 'u-max-width' + selected : '',
maxX ? 'u-max-width' + maxX : false
)
});
} }
/>
<SelectControl
key="shadowD"
label="Drop Shadow Depth"
className="block-shadow-select block-shadow"
value={ shadowD }
options={ shadowOptions }
onChange={ (selected) => {
setAttributes({
shadowD: selected ? selected : undefined,
className: updateClass(
attributes.className,
selected ? 'u-shadow' + selected : false,
shadowD ? 'u-shadow' + shadowD : false
)
});
} }
/>
</div>
</PanelBody>
</InspectorControls>
) }
</Fragment>
);
};
}, 'withAdvancedControls');
/**
* Replaces the active style in the block's className.
*
* @param {string} className Class name.
* @param {Object} addNew The replacing style.
* @param {Object?} removeOld The replaced style.
*
* @return {string} The updated className.
*/
const updateClass = (className, addNew, removeOld) => {
const list = new TokenList(className);
if (list.contains(removeOld)) {
list.remove(removeOld);
}
// If there's a new class name, add it.
if (addNew) {
list.add(addNew);
}
// Return the class string.
if (list.value) {
return list.value;
}
};
const addAttributes = (settings) => {
if (hasBlockSupport(settings, 'customClassName', true)) {
// Gracefully handle if settings.attributes is undefined.
settings.attributes = {
...settings.attributes,
className: {
type: 'string'
},
padT: {
type: 'string'
},
padB: {
type: 'string'
},
padR: {
type: 'string'
},
padL: {
type: 'string'
},
marT: {
type: 'string'
},
marB: {
type: 'string'
},
marR: {
type: 'string'
},
marL: {
type: 'string'
},
maxX: {
type: 'string'
},
shadowD: {
type: 'string'
}
};
}
return settings;
};
addFilter('editor.BlockEdit', 'meh-theme/custom-advanced-control', withAdvancedControls);
addFilter('blocks.registerBlockType', 'meh-theme/block/register', addAttributes);
/**
* External Dependencies
*/
// import classnames from 'classnames';
/**
* WordPress Dependencies
*/
import classnames from 'classnames';
import { addFilter } from '@wordpress/hooks';
import { Fragment } from '@wordpress/element';
import { PanelBody, ToggleControl } from '@wordpress/components';
import { InspectorControls } from '@wordpress/block-editor';
import { createHigherOrderComponent } from '@wordpress/compose';
// Restrict to specific block names
const allowedBlocks = [
'core/paragraph',
'core/heading',
'core/columns',
'core/column',
'core/cover',
'core/buttons',
'core/button',
'core/list',
'core/group',
'core/image',
'core/separator',
'core/media-text',
'meh-theme/image-compare',
'meh-theme/action-call',
'meh-theme/wrapper',
'meh-theme/card'
];
/**
* Add controls on Advanced Block Panel.
*/
const withAdvancedControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
const { name, attributes, setAttributes, isSelected } = props;
const {
isTicksLeft,
isTicksRight,
isTicksLeftBottom,
isTicksRightBottom,
isTicksBottom
} = attributes;
return (
<Fragment>
<BlockEdit { ...props } />
{ isSelected && allowedBlocks.includes(name) && (
<InspectorControls>
<PanelBody
title="AIOSEO Accent Ticks"
className="block-meh-theme-toggles"
initialOpen={ false }
>
<p className="components-ticks-controls__label">
Tick Pattern Controls
</p>
<div className="components-ticks-left-controls">
<ToggleControl
label="Ticks Left"
className="components-ticks-left"
checked={ Boolean(isTicksLeft) }
onChange={ () =>
setAttributes({
isTicksLeft: !isTicksLeft
})
}
/>
</div>
<div className="components-ticks-right-controls">
<ToggleControl
label="Ticks Right"
className="components-ticks-right"
checked={ Boolean(isTicksRight) }
onChange={ () =>
setAttributes({
isTicksRight: !isTicksRight
})
}
/>
</div>
<div className="components-ticks-left-bottom-controls">
<ToggleControl
label="Ticks Left Bottom"
className="components-ticks-left-bottom"
checked={ Boolean(isTicksLeftBottom) }
onChange={ () =>
setAttributes({
isTicksLeftBottom: !isTicksLeftBottom
})
}
/>
</div>
<div className="components-ticks-right-bottom-controls">
<ToggleControl
label="Ticks Right Bottom"
className="components-ticks-right-bottom"
checked={ Boolean(isTicksRightBottom) }
onChange={ () =>
setAttributes({
isTicksRightBottom: !isTicksRightBottom
})
}
/>
</div>
<div className="components-ticks-right-bottom-controls">
<ToggleControl
label="Ticks Bottom"
className="components-ticks-bottom"
checked={ Boolean(isTicksBottom) }
onChange={ () =>
setAttributes({
isTicksBottom: !isTicksBottom
})
}
/>
</div>
</PanelBody>
</InspectorControls>
) }
</Fragment>
);
};
}, 'withAdvancedControls');
const addAttributes = (settings) => {
if (
'undefined' !== typeof settings.attributes &&
allowedBlocks.includes(settings.name)
) {
settings.attributes = {
...settings.attributes,
isTicksLeft: {
type: 'boolean',
default: false
},
isTicksRight: {
type: 'boolean',
default: false
},
isTicksLeftBottom: {
type: 'boolean',
default: false
},
isTicksRightBottom: {
type: 'boolean',
default: false
},
isTicksBottom: {
type: 'boolean',
default: false
}
};
}
return settings;
};
/**
* Add custom element class in save element.
*
* @param {Object} extraProps Block element.
* @param {Object} blockType Blocks object.
* @param {Object} attributes Blocks attributes.
*
* @return {Object} extraProps Modified block element.
*/
const applyExtraClass = (extraProps, blockType, attributes) => {
const {
isTicksLeft,
isTicksRight,
isTicksLeftBottom,
isTicksRightBottom,
isTicksBottom
} = attributes;
if (allowedBlocks.includes(blockType.name)) {
if ('undefined' !== typeof isTicksLeft && isTicksLeft) {
extraProps.className = classnames(extraProps.className, 'has-ticks-left');
}
if ('undefined' !== typeof isTicksRight && isTicksRight) {
extraProps.className = classnames(extraProps.className, 'has-ticks-right');
}
if ('undefined' !== typeof isTicksLeftBottom && isTicksLeftBottom) {
extraProps.className = classnames(extraProps.className, 'has-ticks-left-bottom');
}
if ('undefined' !== typeof isTicksRightBottom && isTicksRightBottom) {
extraProps.className = classnames(extraProps.className, 'has-ticks-right-bottom');
}
if ('undefined' !== typeof isTicksBottom && isTicksBottom) {
extraProps.className = classnames(extraProps.className, 'has-ticks-bottom');
}
}
return extraProps;
};
addFilter('editor.BlockEdit', 'meh-theme/custom-advanced-control', withAdvancedControls);
addFilter('blocks.registerBlockType', 'meh-theme/block/register', addAttributes);
addFilter('blocks.getSaveContent.extraProps', 'meh-theme/applyExtraClass', applyExtraClass);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment