Skip to content

Instantly share code, notes, and snippets.

@thisbit
Last active January 24, 2023 15:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thisbit/4c1d3f599d5b0b419bda3d3699b20e08 to your computer and use it in GitHub Desktop.
Save thisbit/4c1d3f599d5b0b419bda3d3699b20e08 to your computer and use it in GitHub Desktop.
GenerateBlocks Accordion
/*
* Toggle functionality
* Used in accordions and custom tables, etc.
* Depentds on @link /assets/js/apuri/scripts.js Toggle functionality section
*/
.site .click,
.editor-styles-wrapper .click {
cursor: pointer;
user-select: none;
}
.click + * {
opacity: 0;
height: 0;
overflow: hidden;
margin-bottom: 0 !important;
}
.click + .open{
opacity: 1;
}
/* the following code is just stylistic */
.accordion {
border-bottom: 1px solid var(--secondary-dark);
}
.accordion .gb-button-wrapper {
border-top: 1px solid var(--secondary-dark);
margin-left: 0;
padding-top: 0;
padding-left: .5em;
align-items: center;
}
.gb-button-wrapper:hover,
.gb-button-wrapper.toggled,
.gb-button-wrapper:focus {
color: var(--accent);
}
.site .accordion .gb-button-wrapper .gb-button,
.editor-styles-wrapper .accordion .gb-button-wrapper .gb-button {
padding-left: .5em;
}
.site .accordion .gb-button-wrapper .gb-button,
.editor-styles-wrapper .accordion .gb-button-wrapper .block-editor-inner-blocks,
.editor-styles-wrapper .accordion .gb-button-wrapper .wp-block,
.editor-styles-wrapper .accordion .gb-button-wrapper .gb-button {
/* flex: 1; */
line-height: unset;
text-transform: unset;
margin: 0;
border-radius: unset;
border: none;
justify-content: left;
}
/* the icon */
/* TODO: dodati has submenu opciju i di god bude jos trebalo */
.site .icon-plus::before,
.editor-styles-wrapper .icon-plus::before {
transform-origin: center;
padding-right: 0 !important;
transition: all 0.5s ease;
content: "";
width: 17px;
height: 17px;
display: inline-block;
background-repeat: no-repeat;
background-image: url("data:image/svg+xml,%3Csvg fill='none' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 17 17'%3E%3Cpath stroke='%23FF5E5E' d='M8.5 0v17M0 8.5h17'/%3E%3C/svg%3E");
}
/* TODO: dodati has submenu opciju i di god bude jos trebalo */
.site .icon-plus:hover::before,
.editor-styles-wrapper .icon-plus:hover::before,
.site .icon-plus:focus::before,
.editor-styles-wrapper .icon-plus:focus::before,
.site .icon-plus.toggled::before,
.editor-styles-wrapper .icon-plus.toggled::before {
transform: rotate(45deg);
}
/**
This gist goes with the youtube tutorial
*/
window.addEventListener("DOMContentLoaded", () => {
const buttons = Array.from(document.querySelectorAll(".click"));
buttons.forEach( element => element.nextElementSibling.setAttribute( 'data-collapsed', 'true' ) );
function toggle() {
const handleClick = (event) => {
event.preventDefault(); // dissable button/link behavior
event.currentTarget.classList.toggle("toggled"); // mark it as toggled
let currentPanel = event.currentTarget.nextElementSibling; // next content
currentPanel.classList.toggle("open"); // mark it as open
currentPanel.style.transition = 'ease all 0.25s'; // set the css transition
let panelHeight = currentPanel.scrollHeight; // get the DOM height
let openPanel = currentPanel.classList.contains('open'); // for conditions bellow
// if the pannel is open mek it heigh enough if not make it zero heigh
if ( openPanel ) {
currentPanel.style.height = panelHeight + 'px';
currentPanel.setAttribute( 'data-collapsed', 'false' );
} else {
currentPanel.style.height = '';
currentPanel.setAttribute( 'data-collapsed', 'true' );
}
};
// run the clicking
const clicker = buttons.forEach((element) => {
element.addEventListener("click", handleClick, false); // mouse
element.addEventListener("keyup", ( event ) => { // keyboard
if ( event.key === "Enter" ) {
handleClick();
}
}, false);
});
return clicker;
}
toggle(buttons);
});
<?php
/* either place this in functions.php or put it in mu-plugins, or include it in functions.php */
// for the public part of the site
function accprdion_front_scripts() {
if ( has_block( 'generateblocks/button' ) ) :
wp_enqueue_script( 'apuri-accordion', get_stylesheet_directory_uri() . '/assets/js/accordion.js', '', '1.0.0', true );
wp_enqueue_style( 'apuri-layout-use', get_stylesheet_directory_uri() . '/assets/css/accordion.css', false, '1.0.0', 'all');
endif;
}
add_action( 'wp_enqueue_scripts', 'accprdion_front_scripts', 9999 );
// for the editor
function accordion_styles_in_editor( ) {
wp_enqueue_style( 'apuri-layout-use', get_stylesheet_directory_uri() . '/assets/css/accordion.css', false, '1.0.0', 'all');
}
add_filter( 'admin_enqueue_scripts', 'accordion_styles_in_editor');
@gwmatthias
Copy link

gwmatthias commented Aug 4, 2022

Thanks so much for this inspiration.
I added a few tweaks to this:

Since you don't use "data-collapsed" -> i removed it.
Also i added the option to have a "autoClose" function which closes all inactive panels automaticly.

`
/**
This gist goes with the youtube tutorial
*/

window.addEventListener("DOMContentLoaded", () => {

function setUpAccordion() {

	const autoClose = true;

	const buttons = Array.from(document.querySelectorAll(".click"));
	const handleClick = (event) => {

		event.preventDefault(); // dissable button/link behavior

		if(autoClose){
			/*deactivate all*/
			let cur_button, cur_content;
			for (let i = 0; i < buttons.length; i++){
				cur_button = buttons[i];
				cur_button.classList.remove("toggled");
				cur_content = cur_button.nextElementSibling;
				cur_content.classList.remove("open");
				cur_content.style.height = '';
			}
		}

		event.currentTarget.classList.toggle("toggled"); // mark it as toggled

		let currentPanel = event.currentTarget.nextElementSibling; // next content
		currentPanel.classList.toggle("open"); // mark it as open
		currentPanel.style.transition = 'ease all 0.25s'; // set the css transition

		let panelHeight = currentPanel.scrollHeight; // get the DOM height
		let openPanel = currentPanel.classList.contains('open'); // for conditions bellow

		// if the pannel is open mek it heigh enough if not make it zero heigh
		if ( openPanel ) {
			currentPanel.style.height = panelHeight + 'px';
		} else {
			currentPanel.style.height = '';
		}
	};

	// run the clicking
	buttons.forEach((element) => {
		element.addEventListener("click", handleClick, false); // mouse
	});

  }

setUpAccordion();

});
`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment