Skip to content

Instantly share code, notes, and snippets.

@kellymears
Created June 7, 2020 23:25
Show Gist options
  • Save kellymears/b65e6dad45800fbd31204626d2f7f6cf to your computer and use it in GitHub Desktop.
Save kellymears/b65e6dad45800fbd31204626d2f7f6cf to your computer and use it in GitHub Desktop.
/** @wordpress */
import {__} from '@wordpress/i18n'
import {RichText} from '@wordpress/block-editor'
/** Modules */
import PropTypes from 'prop-types'
/** Components */
import Buttons from '@blocks/ndn-page-header/components/Buttons'
/**
* Block skeleton
* @prop {string} className
* @prop {func} heading
* @prop {func} description
* @prop {func} buttons
*/
const Block = ({
className,
heading,
description,
buttons,
}) => {
return (
<div className={className}>
<div className="relative overflow-hidden">
<div className="relative top-0 bottom-0 left-0 right-0 z-10 w-full h-full py-0 py-10 bg-white-700 y-0 sm:py-12 md:py-16 lg:py-20 xl:py-28">
<div className="px-4 mx-auto sm:px-6">
{heading}
{description}
<div className="flex flex-row items-center justify-around max-w-md mx-auto mt-5">
{buttons}
</div>
</div>
</div>
</div>
</div>
)
}
export default Block
/** @wordpress */
import {__} from '@wordpress/i18n'
import {Button} from '@wordpress/components'
import {RichText, URLInput} from '@wordpress/block-editor'
/** Modules */
import classnames from 'classnames'
/** Components */
import classes from './classes'
/**
* Buttons
*/
const Buttons = ({buttons, setAttributes}) => {
const addButton = () => {
setAttributes({
buttons: [
...buttons,
{
label: 'Button',
url: '',
},
],
})
}
/**
* Remove an item from the buttons: array
*/
const removeButton = id => {
setAttributes({
buttons: buttons.filter((button, index) =>
index !== id
),
})
}
/**
* Set button attribute
*
* @param {number} id
* @param {string} key
* @param {string} value
*/
const setButton = (id, key, value) => {
const button = {...buttons[id], [`${key}`]: value}
setAttributes({
buttons: [
...buttons.slice(0, id),
button,
...buttons.slice(id + 1),
],
})
}
return buttons && buttons.length > 0
? (
<>
{buttons.map(({label, url}, id) => (
<div key={id} className="flex flex-col">
<div className={classes.buttonOuter}>
<div className={classnames(
classes.button,
'hover:border-teal-300',
id == 0 ? 'bg-primary text-white' : 'bg-white hover:border'
)}>
<Button
className={classnames(
'mx-1 text-current',
id == 0 ? 'focus:bg-white focus:text-primary' : 'focus:bg-white focus:text-primary'
)}
isTertiary
onClick={() => removeButton(id)}>
{__('X', 'tiny-pixel')}
</Button>
<RichText
className="border-transparent focus:border-teal-500 hover:border-teal-300 border-1"
value={label}
onChange={value => setButton(id, 'label', value)}
/>
</div>
</div>
<URLInput
value={url}
onChange={value => setButton(id, 'url', value)}
/>
</div>
))}
<div>
{buttons.length < 2 && (
<div className="align-center">
<Button
className="text-white bg-secondary"
onClick={addButton}>
{__('+', 'tiny-pixel')}
</Button>
</div>
)}
</div>
</>
) : (
<Button
className={`text-center`}
isSecondary
onClick={() => addButton()}>
{__('Add button', 'tiny-pixel')}
</Button>
)
}
export default Buttons
const classes = {
heading: 'text-4xl leading-10 tracking-tight text-center text-gray-900 uppercase font-feather sm:text-5xl sm:leading-none md:text-6xl',
description: 'max-w-4xl px-4 mx-auto mt-3 text-base text-center text-gray-800 sm:text-lg md:mt-5 md:text-xl blend-difference',
buttonOuter: 'w-full mx-1 rounded-md shadow',
button: 'border-1 border-transparent flex items-center justify-center px-8 py-3 font-sans text-base font-medium leading-6 transition duration-150 ease-in-out border border-transparent rounded-md scroll focus:outline-none focus:shadow-outline-primary',
}
export default classes
/** @wordpress */
import {__} from '@wordpress/i18n'
import {RichText} from '@wordpress/block-editor'
/** Modules */
import PropTypes from 'prop-types'
/** Components */
import Buttons from '@blocks/ndn-page-header/components/Buttons'
import Block from '@blocks/ndn-page-header/components/Block'
import classes from '@blocks/ndn-page-header/components/classes'
/**
* The edit function describes the structure of your block in the context of the editor.
* This represents what the editor will render when the block is used.
*
* @see https://git.io/JfZJD
*
* @prop {PropTypes.string} className
* @prop {PropTypes.bool} isSelected
* @prop {PropTypes.func} setAttributes
* @return {WPElement} Element to render.
*/
const edit = ({
attributes,
className,
isSelected,
setAttributes,
}) => {
const {buttons, heading, description} = attributes
/**
* Generic attribute handler.
*
* @param {string} attribute key
* @param {mixed} attribute value
* @return {void}
*/
const setAttribute = (attr, value) => {
setAttributes({[attr]: value})
}
/**
* Return the block contents for rendering.
*/
return (
<Block
className={className}
heading={
<RichText
className={classes.heading}
placeholder={__('placeholder heading', 'ndn-blocks')}
tagName={'h2'}
value={heading || ''}
style={{textShadow: '14px 3px 65px #FFFFFF'}}
onChange={value => setAttribute('heading', value)}
/>
}
description={
<RichText
className={classes.description}
placeholder={__('placeholder heading', 'ndn-blocks')}
tagName={'p'}
value={description || ''}
onChange={value => setAttribute('description', value)}
/>
}
buttons={
<Buttons
buttons={buttons}
setAttributes={setAttributes}
isSelected={isSelected}
/>
}
/>
)
}
edit.propTypes = {
attributes: PropTypes.shape({
heading: PropTypes.string,
description: PropTypes.string,
}),
className: PropTypes.string,
isSelected: PropTypes.bool,
setAttributes: PropTypes.func,
}
export {edit}
/** @wordpress */
import {getBlockDefaultClassName} from '@wordpress/blocks'
import {RichText} from '@wordpress/block-editor'
/** Modules */
import PropTypes from 'prop-types'
import classnames from 'classnames'
/** Components */
import Block from '@blocks/ndn-page-header/components/Block'
import classes from '@blocks/ndn-page-header/components/classes'
/**
* The save function defines the way in which the different attributes should be combined
* into the final markup, which is then serialized by the block editor into `post_content`.
*
* @see https://git.io/JfZJ9
*
* @return {WPElement} Element to render.
*/
const save = ({attributes}) => {
const className = getBlockDefaultClassName('ndn-blocks/ndn-page-header')
const {buttons, heading, description} = attributes
return (
<Block
className={className}
heading={
<RichText.Content
className={classes.heading}
tagName={'h2'}
value={heading || ''}
style={{textShadow: '14px 3px 65px #FFFFFF'}}
/>
}
description={
<RichText.Content
className={classes.description}
tagName={'p'}
value={description || ''}
/>
}
buttons={buttons.map(({label, url}, id) => (
<div key={id} className={classes.buttonOuter}>
<a href={url} className={classnames(
classes.button,
id == 0 ? 'bg-primary text-white' : 'bg-white text-primary-500',
)}>
<RichText.Content tagName="span" value={label} />
</a>
</div>
))}
/>
)
}
save.propTypes = {
attributes: PropTypes.shape({
buttons: PropTypes.array,
heading: PropTypes.string,
description: PropTypes.string,
}),
}
export {save}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment