[Brief and not-finished custom Gutenberg accordion block -- react]
I've got two -- one was actually functional, and created a simple single item accordion. I never got around to styling it.
The second was supposed to be an accordion block that held multiple accordion items. It was supposed to have buttons so you could add more accordion items -- like an ACF repeater field.
<?php
/**
* Plugin Name: Radicati Accordion
* Author: Meg and Jason
* Version: 1.0.0
* Description: A gutenberg accordion block to use with our custom theme
*/
function loadAccordionBlock()
{
wp_enqueue_script(
'radicati-accordion',
plugin_dir_url(__FILE__) . 'radicati-accordion.js',
['wp-blocks', 'wp-editor'],
true
);
}
add_action('enqueue_block_editor_assets', 'loadAccordionBlock');
/* This section of the code registers a new block, sets an icon and a category, and indicates what type of fields it'll include. */
wp.blocks.registerBlockType("rootid/radicati-accordion", {
title: "Accordion",
icon: "smiley",
category: "common",
attributes: {
header: { type: "string" },
body: { type: "string" },
button: { type: "button" }
},
/* Meg:
What fields does our accordion need on the backend?
- it needs a text field for the header
- it needs a text field for the expanded body
- it needs a button to add additional pairs of header/body fields
- it needs a button to remove header/body pairs
*/
/* This configures how the content and color fields will work, and sets up the necessary elements */
edit: function(props) {
function updateHeader(event) {
props.setAttributes({ header: event.target.value });
}
function updateBody(event) {
props.setAttributes({ body: event.target.value });
}
function addAccordion(event) {
alert("hello");
}
function removeAccordion(event) {
alert("goodbye");
}
return React.createElement(
"div",
{class: "accordion__wrapper"},
React.createElement(
"div",
{class: "accordion__set"},
React.createElement("input", {
type: "text",
value: props.attributes.header,
onChange: updateHeader
}),
React.createElement("input", {
type: "text",
value: props.attributes.body,
onChange: updateBody
}),
React.createElement("input", {
type: "button",
value: "Add",
onChange: addAccordion
}),
React.createElement("input", {
type: "button",
value: "Remove",
onChange: removeAccordion
})
)
);
},
save: function(props) {
return wp.element.createElement(
"div",
{class: "accordion__wrapper"},
// I need to stick a foreach loop here...
wp.element.createElement(
"div",
{class: "accordion__set"},
wp.element.createElement(
"div",
{class: "accordion__header"},
props.attributes.header
),
wp.element.createElement(
"div",
{class: "accordion__body"},
props.attributes.body
),
)
);
}
});
const path = require( 'path' );
const webpack = require( 'webpack' );
const ExtractTextPlugin = require( 'extract-text-webpack-plugin' );
// const BrowserSyncPlugin = require( 'browser-sync-webpack-plugin' );
// Set different CSS extraction for editor only and common block styles
const blocksCSSPlugin = new ExtractTextPlugin( {
filename: './blocks/css/blocks.style.css',
} );
const editBlocksCSSPlugin = new ExtractTextPlugin( {
filename: './blocks/css/blocks.editor.css',
} );
// Configuration for the ExtractTextPlugin.
const extractConfig = {
use: [
{ loader: 'raw-loader' },
{
loader: 'postcss-loader',
options: {
plugins: [ require( 'autoprefixer' ) ],
},
},
{
loader: 'sass-loader',
query: {
outputStyle:
'production' === process.env.NODE_ENV ? 'compressed' : 'nested',
},
},
],
};
module.exports = {
entry: {
'./blocks/js/editor.blocks' : './blocks/index.js',
// './assets/js/frontend.blocks' : './blocks/frontend.js',
},
output: {
path: path.resolve( __dirname ),
filename: '[name].js',
},
watch: true,
devtool: 'cheap-eval-source-map',
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
},
},
/*{
test: /style\.s?css$/,
use: blocksCSSPlugin.extract( extractConfig ),
},*/
{
test: /editor\.s?css$/,
use: editBlocksCSSPlugin.extract( extractConfig ),
},
],
},
plugins: [
blocksCSSPlugin,
editBlocksCSSPlugin,
// new BrowserSyncPlugin({
// // Load localhost:3333 to view proxied site
// host: 'localhost',
// port: '3333',
// // Change proxy to your local WordPress URL
// proxy: 'https://gutenberg.local'
// })
],
};
"babel-core": "^6.25.0",
"babel-eslint": "^8.1.2",
"babel-loader": "^7.1.1",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.1",
"browser-sync": "^2.18.13",
"browser-sync-webpack-plugin": "^1.2.0",
"classnames": "^2.2.5",
"cross-env": "^5.1.1",
"css-loader": "^0.28.7",
"eslint": "^4.14.0",
"eslint-config-prettier": "^2.9.0",
"eslint-config-wordpress": "^2.0.0",
"eslint-plugin-prettier": "^2.4.0",
"extract-text-webpack-plugin": "^3.0.2",
"node-sass": "^4.7.2",
"postcss-loader": "^2.0.9",
"raw-loader": "^0.5.1",
"sass-loader": "^6.0.6",
"style-loader": "^0.19.1",
"webpack": "^3.10.0",
"cgb-scripts": "1.9.2",
"create-react-class": "^15.6.2",
"react": "^16.2.0",
"react-dom": "^16.2.0",
<?php
/**
* Plugin Name: Radicati Accordion 2
* Author: Meg and Jason
* Version: 2.0.0
* Description: A gutenberg accordion block to use with our custom theme
*/
function loadAccordionBlock2()
{
wp_enqueue_script(
'radicati-accordion-2',
plugin_dir_url(__FILE__) . 'radicati-accordion.js',
['wp-blocks', 'wp-editor'],
true
);
}
add_action('enqueue_block_editor_assets', 'loadAccordionBlock2');
/* This section of the code registers a new block, sets an icon and a category, and indicates what type of fields it'll include. */
wp.blocks.registerBlockType("rootid/radicati-accordion-2", {
title: "Accordion 2",
icon: "admin-generic",
category: "common",
// ok, we need to store the data as an array, not as single strings
// that way it can expand and contract as needed
attributes: {
header: { type: "string" },
body: { type: "string" },
button: { type: "button" }
},
/* Meg:
What fields does our accordion need on the backend?
- it needs a text field for the header
- it needs a text field for the expanded body
- it needs a button to add additional pairs of header/body fields
- it needs a button to remove header/body pairs
*/
/* This configures how the content and color fields will work, and sets up the necessary elements */
edit: function(props) {
function updateHeader(event) {
props.setAttributes({ header: event.target.value });
}
function updateBody(event) {
props.setAttributes({ body: event.target.value });
}
function addAccordion(event) {
console.log("Here's the addAccordion event: ");
console.log(event);
console.log("Here's the addAccordion event target: ");
console.log(event.target);
}
function removeAccordion(event) {
alert("goodbye");
}
// here's where we create the form in react
var AccordionRow =
return React.createElement(
"div",
{class: "accordion__wrapper"},
// with a sub-div for each accordion set
// what I want to do is create additional children and insert them here...
// with some kind of array splicing in the background for the data???
React.createElement(
"div",
{class: "accordion__set"},
React.createElement("input", {
type: "text",
value: props.attributes.header,
onChange: updateHeader
}),
React.createElement("input", {
type: "text",
value: props.attributes.body,
onChange: updateBody
}),
React.createElement("input", {
type: "button",
value: "Add",
onClick: addAccordion
}),
React.createElement("input", {
type: "button",
value: "Remove",
onChange: removeAccordion
})
)
);
// // here's where we create the form in react
// return React.createElement(
// "div",
// {class: "accordion__wrapper"},
// // with a sub-div for each accordion set
// // what I want to do is create additional children and insert them here...
// // with some kind of array splicing in the background for the data???
// React.createElement(
// "div",
// {class: "accordion__set"},
// this.props.children
// )
// );
},
save: function(props) {
return wp.element.createElement(
"div",
{class: "accordion__wrapper"},
// I need to stick a foreach loop here...
wp.element.createElement(
"div",
{class: "accordion__set"},
wp.element.createElement(
"div",
{class: "accordion__header"},
props.attributes.header
),
wp.element.createElement(
"div",
{class: "accordion__body"},
props.attributes.body
),
)
);
}
});
const path = require( 'path' );
const webpack = require( 'webpack' );
const ExtractTextPlugin = require( 'extract-text-webpack-plugin' );
// const BrowserSyncPlugin = require( 'browser-sync-webpack-plugin' );
// Set different CSS extraction for editor only and common block styles
const blocksCSSPlugin = new ExtractTextPlugin( {
filename: './blocks/css/blocks.style.css',
} );
const editBlocksCSSPlugin = new ExtractTextPlugin( {
filename: './blocks/css/blocks.editor.css',
} );
// Configuration for the ExtractTextPlugin.
const extractConfig = {
use: [
{ loader: 'raw-loader' },
{
loader: 'postcss-loader',
options: {
plugins: [ require( 'autoprefixer' ) ],
},
},
{
loader: 'sass-loader',
query: {
outputStyle:
'production' === process.env.NODE_ENV ? 'compressed' : 'nested',
},
},
],
};
module.exports = {
entry: {
'./blocks/js/editor.blocks' : './blocks/index.js',
// './assets/js/frontend.blocks' : './blocks/frontend.js',
},
output: {
path: path.resolve( __dirname ),
filename: '[name].js',
},
watch: true,
devtool: 'cheap-eval-source-map',
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
},
},
/*{
test: /style\.s?css$/,
use: blocksCSSPlugin.extract( extractConfig ),
},*/
{
test: /editor\.s?css$/,
use: editBlocksCSSPlugin.extract( extractConfig ),
},
],
},
plugins: [
blocksCSSPlugin,
editBlocksCSSPlugin,
// new BrowserSyncPlugin({
// // Load localhost:3333 to view proxied site
// host: 'localhost',
// port: '3333',
// // Change proxy to your local WordPress URL
// proxy: 'https://gutenberg.local'
// })
],
};
"babel-core": "^6.25.0",
"babel-eslint": "^8.1.2",
"babel-loader": "^7.1.1",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.1",
"browser-sync": "^2.18.13",
"browser-sync-webpack-plugin": "^1.2.0",
"classnames": "^2.2.5",
"cross-env": "^5.1.1",
"css-loader": "^0.28.7",
"eslint": "^4.14.0",
"eslint-config-prettier": "^2.9.0",
"eslint-config-wordpress": "^2.0.0",
"eslint-plugin-prettier": "^2.4.0",
"extract-text-webpack-plugin": "^3.0.2",
"node-sass": "^4.7.2",
"postcss-loader": "^2.0.9",
"raw-loader": "^0.5.1",
"sass-loader": "^6.0.6",
"style-loader": "^0.19.1",
"webpack": "^3.10.0",
"cgb-scripts": "1.9.2",
"create-react-class": "^15.6.2",
"react": "^16.2.0",
"react-dom": "^16.2.0",