Skip to content

Instantly share code, notes, and snippets.

@johnReeve
Last active December 27, 2018 18:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnReeve/35fdffb8fff2d16dd8325fc897fb4676 to your computer and use it in GitHub Desktop.
Save johnReeve/35fdffb8fff2d16dd8325fc897fb4676 to your computer and use it in GitHub Desktop.
// Import CSS.
import './style.scss';
import './editor.scss';
import {List_Item, List_Item_Edit} from './list_item.js';
const {__} = wp.i18n; // Import __() from wp.i18n
const {registerBlockType} = wp.blocks;
const {Component} = wp.element;
const {
Button,
TextControl
} = wp.components;
registerBlockType('mat/block-mat-gb-box-list', {
title: __('Materiell: Box List'),
icon: 'grid-view',
category: 'common',
keywords: [
__('Materiell'),
__('Box List'),
__('Custom'),
],
attributes: {
heading: {
type: 'array',
source: 'children',
selector: '.heading',
},
list_items: {
type: 'array',
source: 'query',
default: [],
selector: '.list-container .list-item',
query: {
index: {
type: 'string',
source: 'attribute',
attribute: 'value',
selector: '.index-holder',
},
title: {
type: 'string',
source: 'children',
selector: '.item-title',
},
copy: {
type: 'string',
source: 'children',
selector: '.item-copy',
},
url: {
type: 'string',
source: 'attribute',
selector: '.item-url',
attribute: 'href'
}
},
}
},
edit: class extends Component {
constructor(props) {
super(...arguments);
this.state = {
list_items: props.attributes.list_items
}
this.editListElement = this.editListElement.bind(this);
}
editListElement(list_item) {
const {setAttributes} = this.props;
let new_items = [];
if (list_item.delete_item) {
const old_items = [...this.state.list_items];
new_items = old_items.filter((item, j) => list_item.index !== item.index);
} else {
new_items = [...this.state.list_items];
new_items[list_item.index] = {
index: list_item.index,
title: list_item.title,
copy: list_item.copy,
url: list_item.url,
};
}
this.setState({list_items: new_items}, () => {
setAttributes({list_items: new_items});
});
}
render() {
const props = this.props;
const {
attributes: {heading, list_items},
className, setAttributes, isSelected
} = props;
return (
<div className={props.className}>
<section className="gb-layout-full-width-container">
<div className="contents">
<div className="gb-content-square-menu">
{isSelected ? (
<TextControl
label={__('Heading Text', 'materiell-plugins')}
help={__('Leave this field blank to omit the heading.', 'materiell-plugins')}
value={heading}
onChange={heading => setAttributes({heading})}
/>
) : (
<h2 className="heading">{heading}</h2>
)}
<ul className="list-container">
{isSelected ? (
this.state.list_items.map((ls, idx) => {
return (
<List_Item_Edit
title={ls.title}
copy={ls.copy}
url={ls.url}
index={ls.index}
key={ls.index}
onChange={this.editListElement}
/>
)
})
) : (
list_items.map((ls, idx) => {
return <List_Item
key={ls.index}
index={ls.index}
title={ls.title}
copy={ls.copy}
url={ls.url}
/>
})
)}
</ul>
</div>
</div>
</section>
{isSelected && (
<Button
className={"button button-large"}
onClick={() => {
const new_index = String(Number(this.state.list_items.slice(-1)[0].index) + 1);
const new_list_items = [...this.state.list_items, {
index: new_index,
title: __('New Title', 'materiell-plugins'),
copy: __('Add Copy', 'materiell-plugins'),
url: __('Add URL', 'materiell-plugins'),
}];
this.setState({list_items: new_list_items},
setAttributes({list_items: new_list_items})
);
}}
>
{__('Add List Item', 'materiell-plugins')}
</Button>
)}
</div>
);
}
},
save(props) {
const {
attributes: {heading, list_items}
} = props;
return (
<div>
<section className="gb-layout-full-width-container">
<div className="contents">
<div className="gb-content-square-menu">
<h2 className="heading">{heading}</h2>
<ul className="list-container">
{
list_items.map((ls, idx) => {
return <List_Item
key={ls.index}
index={ls.index}
title={ls.title}
copy={ls.copy}
url={ls.url}
/>
})
}
</ul>
</div>
</div>
</section>
</div>
);
},
});
const {__} = wp.i18n; // Import __() from wp.i18n
const {
Component
} = wp.element;
const {
Button,
TextControl,
} = wp.components;
export class List_Item extends Component {
render() {
const {
index,
title,
url,
copy
} = this.props;
return (
<li className="list-item">
<input type="hidden" className="index-holder" value={index} />
<a href={url} className="item-url">
<h3 className="item-title">{title}</h3>
<div className="item-copy">{copy}</div>
</a>
</li>
);
}
}
export class List_Item_Edit extends Component {
constructor(props) {
super(props);
const {
index,
title,
copy,
url,
} = this.props;
this.state = {
index: index,
title: title,
copy: copy,
url: url,
delete_item: false
};
}
render() {
const {onChange} = this.props;
return (
<li className="list-item">
<input type="hidden" className="index-holder" value={this.state.index}/>
<TextControl
className="item-title"
label={__('Title', 'materiell-plugins')}
value={this.state.title}
onChange={title => {
this.setState({title}, () => {onChange(this.state)});
}}
/>
<TextControl
className="item-copy"
label={__('Copy', 'materiell-plugins')}
value={this.state.copy}
onChange={copy => {
this.setState({copy}, () => {onChange(this.state)});
}}
/>
<TextControl
className="item-url"
label={__('URL', 'materiell-plugins')}
value={this.state.url}
onChange={url => {
this.setState({url}, () => {onChange(this.state)});
}}
/>
<Button
className={"button button-small"}
onClick={() => {
this.setState({delete_item: true}, () => {onChange(this.state)});
}}
>
{__('Remove List Item', 'materiell-plugins')}
</Button>
</li>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment