Last active
December 10, 2024 13:11
-
-
Save nextab/ac43f22db7f6f02822e84a01dfc98fcb to your computer and use it in GitHub Desktop.
Moved incorrect cursor: pointer to the correct element
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Variables | |
:root { | |
--toggle-bg-color: var(--color-bg2, #333); | |
--toggle-active-bg-color: var(--primary, #0a0); | |
--toggle-switch-color: var(--color-text, #fff); | |
--toggle-border-radius: 1rem; | |
--toggle-height: 1.5rem; | |
--toggle-width: 2.5rem; | |
--toggle-switch-width: 1.5rem; | |
--toggle-transition: 0.5s; | |
--toggle-box-shadow: inset 0 0.125rem 1rem rgba(0, 0, 0, 0.1), inset 0 0.125rem 0.5rem rgba(0, 0, 0, 0.1), inset 0 -0.25rem 0.25rem rgba(0, 0, 0, 0.05); | |
} | |
html:not(.dark-mode) { | |
--toggle-bg-color: var(--color-text, #ddd); | |
--toggle-switch-color: var(--color-bg, #000); | |
} | |
%toggle { | |
position: relative; | |
summary { | |
cursor: pointer; | |
&::before, &::after { | |
border-radius: var(--toggle-border-radius); | |
box-sizing: border-box; | |
content: ""; | |
height: var(--toggle-height); | |
top: 50%; | |
transform: translatey(-50%); | |
position: absolute; | |
} | |
&::before { | |
background-color: var(--toggle-bg-color); | |
box-shadow: var(--toggle-box-shadow); | |
outline: none; | |
pointer-events: none; | |
right: 0; | |
transition: var(--toggle-transition); | |
width: var(--toggle-width); | |
} | |
&::after { | |
background-color: var(--toggle-switch-color); | |
height: var(--toggle-switch-width); | |
right: calc(var(--toggle-width) - var(--toggle-switch-width)); | |
transition: all 500ms ease; | |
transform: translatey(-50%) scale(0.9); | |
width: var(--toggle-switch-width); | |
} | |
} | |
&[open] { | |
summary { | |
&::before { | |
background-color: var(--toggle-active-bg-color); | |
} | |
&::after { | |
right: 0; | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Accordion { | |
constructor(el) { | |
// Store the <details> element | |
this.el = el; | |
// Store the <summary> element | |
this.summary = el.querySelector('summary'); | |
// Store the <div class="content"> element | |
this.content = el.querySelector('.sub-menu, .wp-block-group'); | |
// Store the animation object (so we can cancel it if needed) | |
this.animation = null; | |
// Store if the element is closing | |
this.isClosing = false; | |
// Store if the element is expanding | |
this.isExpanding = false; | |
// Detect user clicks on the summary element | |
this.summary.addEventListener('click', (e) => this.onClick(e)); | |
// Add padding to account for border spacing | |
this.padding = 36; | |
this.paddingOpen = 55; | |
} | |
onClick(e) { | |
// Stop default behaviour from the browser | |
e.preventDefault(); | |
// Add an overflow on the <details> to avoid content overflowing | |
this.el.style.overflow = 'hidden'; | |
// Check if the element is being closed or is already closed | |
if (this.isClosing || !this.el.open) { | |
this.open(); | |
// Check if the element is being openned or is already open | |
} else if (this.isExpanding || this.el.open) { | |
this.shrink(); | |
} | |
} | |
shrink() { | |
// Set the element as "being closed" | |
this.isClosing = true; | |
const innerContent = this.el.querySelector('.wp-block-group'); | |
if (innerContent) { | |
innerContent.style.opacity = '0'; | |
innerContent.style.transition = 'opacity 0.1s'; | |
} | |
const startHeight = `${this.el.offsetHeight + this.padding}px`; | |
const endHeight = `${this.summary.offsetHeight + this.padding}px`; | |
// If there is already an animation running | |
if (this.animation) { | |
// Cancel the current animation | |
this.animation.cancel(); | |
} | |
// Start a WAAPI animation | |
this.animation = this.el.animate({ | |
// Set the keyframes from the startHeight to endHeight | |
height: [startHeight, endHeight] | |
}, { | |
duration: 400, | |
easing: 'ease-out' | |
}); | |
// When the animation is complete, call onAnimationFinish() | |
this.animation.onfinish = () => this.onAnimationFinish(false); | |
// If the animation is cancelled, isClosing variable is set to false | |
this.animation.oncancel = () => this.isClosing = false; | |
} | |
open() { | |
// Apply a fixed height on the element | |
this.el.style.height = `${this.el.offsetHeight}px`; | |
// Force the [open] attribute on the details element | |
this.el.open = true; | |
// Wait for the next frame to call the expand function | |
window.requestAnimationFrame(() => this.expand()); | |
} | |
expand() { | |
// Set the element as "being expanding" | |
this.isExpanding = true; | |
const innerContent = this.el.querySelector('.wp-block-group'); | |
if (innerContent) { | |
innerContent.style.opacity = '1'; | |
// innerContent.style.transition = 'opacity 0.1s'; | |
} | |
// Get the current fixed height of the element | |
const startHeight = `${this.el.offsetHeight}px`; | |
// Calculate the open height of the element (summary height + content height) | |
const endHeight = `${this.summary.offsetHeight + this.content.offsetHeight + this.paddingOpen}px`; | |
// If there is already an animation running | |
if (this.animation) { | |
// Cancel the current animation | |
this.animation.cancel(); | |
} | |
// Start a WAAPI animation | |
this.animation = this.el.animate({ | |
// Set the keyframes from the startHeight to endHeight | |
height: [startHeight, endHeight] | |
}, { | |
duration: 400, | |
easing: 'ease-out' | |
}); | |
// When the animation is complete, call onAnimationFinish() | |
this.animation.onfinish = () => this.onAnimationFinish(true); | |
// If the animation is cancelled, isExpanding variable is set to false | |
this.animation.oncancel = () => this.isExpanding = false; | |
} | |
onAnimationFinish(open) { | |
// Set the open attribute based on the parameter | |
this.el.open = open; | |
// Clear the stored animation | |
this.animation = null; | |
// Reset isClosing & isExpanding | |
this.isClosing = false; | |
this.isExpanding = false; | |
// Remove the overflow hidden and the fixed height | |
this.el.style.height = this.el.style.overflow = ''; | |
} | |
} | |
document.querySelectorAll('details').forEach((el) => { | |
new Accordion(el); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import 'toggle'; | |
details { | |
@extend %toggle; | |
border: 1px solid var(--primary); | |
border-radius: $input-border-radius; | |
padding: 1rem; | |
overflow: visible !important; | |
+ details { | |
margin-block-start: 4rem !important; | |
} | |
summary { | |
font-family: $header-font; | |
font-size: $larger; | |
font-weight: 700; | |
list-style: none; | |
padding-right: 2.25rem; | |
position: relative; | |
&::-webkit-details-marker { | |
display: none; | |
} | |
~ * { | |
animation: fadeInWithoutOpacity 700ms ease-in-out; | |
} | |
} | |
&[open] { | |
summary { | |
~ * { | |
animation: fadeIn 700ms ease-in-out; | |
} | |
} | |
} | |
/* #region width <= 550px */ | |
@media only screen and (width <= 550px) { | |
.wp-block-group { | |
padding-top: 0.75rem; | |
} | |
} | |
/* #endregion width <= 550px */ | |
} | |
@keyframes fadeIn { | |
from { | |
opacity: 0; | |
transform: translateY(0px); | |
} | |
to { | |
opacity: 1; | |
transform: translateY(10); | |
} | |
} | |
@keyframes fadeInWithoutOpacity { | |
from { | |
opacity: 0; | |
transform: translateY(0px); | |
} | |
50% { | |
opacity: 1; | |
transform: translateY(10px); | |
} | |
to { | |
opacity: 1; | |
transform: translateY(10px); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment