Comparing version 0.5.0 to 0.6.0
# Changelog | ||
## [0.6.0] - 2024-05-14 | ||
### Added | ||
- Button with icon style | ||
- Share button | ||
### Changed | ||
- **Breaking** Use `details` and `summary` instead of JavaScript for accordions | ||
## [0.5.0] - 2024-04-21 | ||
@@ -4,0 +15,0 @@ |
{ | ||
"name": "ratata", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"description": "HTML, CSS and JavaScript Boilerplate using just HTML, CSS and JavaScript.", | ||
@@ -28,3 +28,3 @@ "main": "src/css/ratata.css", | ||
"standard": "^17.1.0", | ||
"stylelint": "^16.3.1", | ||
"stylelint": "^16.5.0", | ||
"stylelint-config-standard": "^36.0.0" | ||
@@ -31,0 +31,0 @@ }, |
# Ratata | ||
More web standards, less bullshit. | ||
Ratata is a HTML, CSS and JavaScript Boilerplate using just HTML, CSS and JavaScript. It's main focus is on web standards, accessibility and performance. [Check it out on CodePen](https://codepen.io/deoostfrees/pen/XWGWbEy). | ||
@@ -87,2 +89,3 @@ | ||
- [David Bushell](https://dbushell.com)'s [CSS Button Styles You Might Not Know](https://dbushell.com/2024/03/10/css-button-styles-you-might-not-know/) | ||
- [Adrian Roselli](https://adrianroselli.com)'s [Progressively Enhanced HTML Accordion](https://adrianroselli.com/2023/08/progressively-enhanced-html-accordion.html) | ||
@@ -89,0 +92,0 @@ ## Browser Support |
export default function accordion () { | ||
// Select all accordion container that are not already marked as active | ||
const ACCORDIONS = document.querySelectorAll('.accordion:not(.accordion--active)') | ||
const BROWSER_WINDOW = window | ||
/** | ||
* Open accordion | ||
* | ||
* @param {HTMLElement} accordionItemTrigger | ||
*/ | ||
const openAccordion = (accordionItemTrigger) => { | ||
accordionItemTrigger.closest('.accordion__item').classList.add('accordion--open') | ||
accordionItemTrigger.setAttribute('aria-expanded', 'true') | ||
} | ||
const closeAllAccordions = () => { | ||
const OPEN_ACCORDION_ELS = document.querySelectorAll('details[open]') | ||
/** | ||
* Close accordion | ||
* | ||
* @param {HTMLElement} accordionItemTrigger | ||
*/ | ||
const closeAccordion = (accordionItemTrigger) => { | ||
accordionItemTrigger.closest('.accordion__item').classList.remove('accordion--open') | ||
accordionItemTrigger.setAttribute('aria-expanded', 'false') | ||
OPEN_ACCORDION_ELS.forEach((openAccordionEl) => { | ||
openAccordionEl.removeAttribute('open') | ||
}) | ||
} | ||
/** | ||
* Event handler for the click event | ||
* | ||
* @param {Event} event - The click event object | ||
*/ | ||
const clickHandler = (event) => { | ||
const { target } = event | ||
const openAllAccordions = () => { | ||
const OPEN_ACCORDION_ELS = document.querySelectorAll('details') | ||
if (target.classList.contains('accordion__item-trigger')) { | ||
if (target.getAttribute('aria-expanded') === 'false') { | ||
openAccordion(target) | ||
} else { | ||
closeAccordion(target) | ||
} | ||
event.preventDefault() | ||
} | ||
OPEN_ACCORDION_ELS.forEach((openAccordionEl) => { | ||
openAccordionEl.setAttribute('open', '') | ||
}) | ||
} | ||
/** | ||
* Event handler for the keydown event | ||
* Expand all accordions for printing, restore previously opened accordions | ||
* after printing | ||
* | ||
* @param {Event} event - The keydown event object | ||
*/ | ||
const keydownHandler = (event) => { | ||
const { target } = event | ||
let openAccordionEls | ||
// When focus is on an accordion header | ||
if (target.classList.contains('accordion__item-trigger')) { | ||
const ACCORDION_TRIGGER = Array.from(target.closest('.accordion').querySelectorAll('.accordion__item-trigger')) | ||
const ACCORDION_TRIGGER_LENGTH = ACCORDION_TRIGGER.length | ||
const CURRENT_INDEX = ACCORDION_TRIGGER.indexOf(target) | ||
let newIndex = CURRENT_INDEX | ||
BROWSER_WINDOW.addEventListener('beforeprint', () => { | ||
openAccordionEls = document.querySelectorAll('details[open]') | ||
// Moves focus to the previous/ next accordion header | ||
if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || (event.ctrlKey && (event.key === 'PageUp' || event.key === 'PageDown'))) { | ||
const DIRECTION = event.key === 'ArrowDown' || event.key === 'PageDown' ? 1 : -1 | ||
openAllAccordions() | ||
}) | ||
newIndex = (CURRENT_INDEX + ACCORDION_TRIGGER_LENGTH + DIRECTION) % ACCORDION_TRIGGER_LENGTH | ||
BROWSER_WINDOW.addEventListener('afterprint', () => { | ||
closeAllAccordions() | ||
event.preventDefault() | ||
// Go to first accordion when the HOME key is pressed | ||
} else if (event.key === 'Home') { | ||
newIndex = 0 | ||
event.preventDefault() | ||
// Go to last accordion when the END key is pressed | ||
} else if (event.key === 'End') { | ||
newIndex = ACCORDION_TRIGGER_LENGTH - 1 | ||
event.preventDefault() | ||
} | ||
if (newIndex !== CURRENT_INDEX) { | ||
ACCORDION_TRIGGER[newIndex].focus() | ||
} | ||
} | ||
} | ||
ACCORDIONS.forEach((accordion) => { | ||
accordion.addEventListener('click', clickHandler) | ||
accordion.addEventListener('keydown', keydownHandler) | ||
// Mark accordion container as active to prevent re-initialization | ||
accordion.classList.add('accordion--active') | ||
openAccordionEls.forEach((openAccordionEl) => { | ||
openAccordionEl.setAttribute('open', '') | ||
}) | ||
}) | ||
} |
@@ -22,1 +22,12 @@ /** | ||
} | ||
/** | ||
* Share button | ||
* | ||
*/ | ||
if (document.querySelector('.btn--share') !== null) { | ||
import('./libs/_share.js') | ||
.then(({ default: share }) => { | ||
share() | ||
}) | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
70768
49
94
1350