UNPKG

minsky-kit

Version:
89 lines (68 loc) 3.08 kB
// imports import { strToDom } from '../utils/dom'; import { svgIconString } from '../utils/svg'; import { strToCssClass } from '../utils/css'; // methods export function generateAccordionHtmlString (args, name = 'accordion') { args = args || {}; // set id const id = args.id ? args.id : (Date.now() * Math.round(Math.random() * 1000)).toString(32); // set default title wrapper tag const titleTag = args.titleTag || 'div'; // set classes const classes = [ strToCssClass(name), ...(args.classes || []).map((str) => strToCssClass(str)), ]; // set aria args.aria = args.aria || {}; const aria = { expanded: args.aria.expanded || false, titleId: `accordion-title-${id}`, contentId: `accordion-content-${id}`, }; // return element string return ` <div data-accordion-id="${id}" class="${classes.join(' ')}"> <div class="${strToCssClass(name, 'title-wrapper')}"> <${titleTag} class="${strToCssClass(name, 'title')}"> <button type="button" aria-expanded="${aria.expanded}" aria-controls="${aria.contentId}" class="${strToCssClass(name, 'trigger')}" id="${aria.titleId}">${args.title} <div class="${strToCssClass(name, 'icon')} ${strToCssClass(name, 'arrow')}">${svgIconString(args.arrowSvg || 'chevronDown', [strToCssClass(name, 'arrowSvg')])}</div></button> </${titleTag}> </div> <div id="${aria.contentId}" class="${strToCssClass(name, 'content-wrapper')}" role="region" aria-labelledby="${aria.titleId}" ${aria.expanded ? 'hidden' : ''}> <div class="${strToCssClass(name, 'content')}">${args.content || ''}</div> </div> </div> `.trim(); } export function generateAccordionElement (args, name = 'accordion') { // clone into new object so we can edit the properties without interfering with parent stack logic (shallow!) args = { ...args || {} }; // extract title & content in case these are elements const title = args.title; const content = args.content; // clear title & content args.title = ''; args.content = ''; // generate dom element const $el = strToDom(generateAccordionHtmlString(args, name)); // add title & content in case they were given if (title) $el.querySelector(`.${strToCssClass(name, 'trigger')}`).append(title); if (content) $el.querySelector(`.${strToCssClass(name, 'content')}`).append(content); // return el return $el; } export function removeAccordionElement (el, name = 'accordion') { // extract all content components const content = [...el.querySelectorAll(`.${strToCssClass(name, 'content')} > *`)]; // append every content before the accordion if (content.length) content.forEach((item) => { el.parentNode.insertBefore(item, el); }); // remove el el.remove(); return content.length && content.length === 1 ? content[0] : content; } export default { generateAccordionHtmlString, generateAccordionElement, removeAccordionElement, };