Interactive MJML component to stack content in tabs for email templates
npx @tessl/cli install tessl/npm-mjml-accordion@4.15.0MJML Accordion is an interactive MJML component library that provides collapsible content sections for HTML email templates. It enables developers to create space-efficient, mobile-friendly email experiences by allowing content to be collapsed into clickable tabs that expand to reveal additional information.
npm install mjml-accordionconst { Accordion, AccordionElement, AccordionText, AccordionTitle } = require("mjml-accordion");For ES6 modules:
import { Accordion, AccordionElement, AccordionText, AccordionTitle } from "mjml-accordion";Note: These are default exports from the main index file, not named exports.
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-accordion border="2px solid black" padding="10px 25px">
<mj-accordion-element>
<mj-accordion-title font-size="16px" padding="16px">
Why use accordions in emails?
</mj-accordion-title>
<mj-accordion-text font-size="14px" padding="16px">
Accordions help deliver lots of information in a mobile-friendly format
by allowing users to expand only the content they're interested in.
</mj-accordion-text>
</mj-accordion-element>
<mj-accordion-element>
<mj-accordion-title>How it works</mj-accordion-title>
<mj-accordion-text>
Content is stacked into tabs. On mobile devices with responsive support,
users can click to expand. On desktop clients without responsive support,
all content is expanded by default.
</mj-accordion-text>
</mj-accordion-element>
</mj-accordion>
</mj-column>
</mj-section>
</mj-body>
</mjml>MJML Accordion is built around four main components that work together:
mj-accordion provides the overall structure and styling contextmj-accordion-element represents individual collapsible sectionsmj-accordion-title creates clickable headers with expand/collapse iconsmj-accordion-text contains the collapsible content that shows/hidesEach component extends the BodyComponent base class from mjml-core and includes comprehensive attribute validation, default styling, and responsive email client compatibility through conditional CSS.
Main container component that wraps accordion elements and provides global styling context including borders, fonts, and icon configuration.
import { BodyComponent } from 'mjml-core'class MjAccordion extends BodyComponent {
static componentName = 'mj-accordion';
static allowedAttributes = {
'container-background-color': 'color',
'border': 'string',
'font-family': 'string',
'icon-align': 'enum(top,middle,bottom)',
'icon-width': 'unit(px,%)',
'icon-height': 'unit(px,%)',
'icon-wrapped-url': 'string',
'icon-wrapped-alt': 'string',
'icon-unwrapped-url': 'string',
'icon-unwrapped-alt': 'string',
'icon-position': 'enum(left,right)',
'padding-bottom': 'unit(px,%)',
'padding-left': 'unit(px,%)',
'padding-right': 'unit(px,%)',
'padding-top': 'unit(px,%)',
'padding': 'unit(px,%){1,4}',
};
static defaultAttributes = {
'border': '2px solid black',
'font-family': 'Ubuntu, Helvetica, Arial, sans-serif',
'icon-align': 'middle',
'icon-wrapped-url': 'https://i.imgur.com/bIXv1bk.png',
'icon-wrapped-alt': '+',
'icon-unwrapped-url': 'https://i.imgur.com/w4uTygT.png',
'icon-unwrapped-alt': '-',
'icon-position': 'right',
'icon-height': '32px',
'icon-width': '32px',
'padding': '10px 25px',
};
headStyle() { /* returns CSS string for <head> */ }
getStyles() { /* returns style object */ }
render() { /* returns HTML string */ }
}Individual accordion section containing a title/text pair. Automatically creates missing title or text components if not explicitly provided.
import { BodyComponent } from 'mjml-core'
import { find } from 'lodash'
import conditionalTag from 'mjml-core/lib/helpers/conditionalTag'class MjAccordionElement extends BodyComponent {
static componentName = 'mj-accordion-element';
static allowedAttributes = {
'background-color': 'color',
'border': 'string',
'font-family': 'string',
'icon-align': 'enum(top,middle,bottom)',
'icon-width': 'unit(px,%)',
'icon-height': 'unit(px,%)',
'icon-wrapped-url': 'string',
'icon-wrapped-alt': 'string',
'icon-unwrapped-url': 'string',
'icon-unwrapped-alt': 'string',
'icon-position': 'enum(left,right)',
};
static defaultAttributes = {
title: {
img: {
width: '32px',
height: '32px',
},
},
};
getStyles() { /* returns style objects */ }
handleMissingChildren() { /* creates missing title/text components */ }
render() { /* returns HTML string */ }
}Clickable title component that displays the accordion header with expand/collapse icons. Supports HTML content as it is an ending tag component.
import { BodyComponent } from 'mjml-core'
import conditionalTag from 'mjml-core/lib/helpers/conditionalTag'class MjAccordionTitle extends BodyComponent {
static componentName = 'mj-accordion-title';
static endingTag = true;
static allowedAttributes = {
'background-color': 'color',
'color': 'color',
'font-size': 'unit(px)',
'font-family': 'string',
'padding-bottom': 'unit(px,%)',
'padding-left': 'unit(px,%)',
'padding-right': 'unit(px,%)',
'padding-top': 'unit(px,%)',
'padding': 'unit(px,%){1,4}',
};
static defaultAttributes = {
'font-size': '13px',
'padding': '16px',
};
getStyles() { /* returns style objects */ }
renderTitle() { /* renders title cell */ }
renderIcons() { /* renders expand/collapse icons */ }
render() { /* returns HTML string */ }
}Collapsible text content component that contains the hidden/shown content. Supports HTML content as it is an ending tag component.
import { BodyComponent } from 'mjml-core'class MjAccordionText extends BodyComponent {
static componentName = 'mj-accordion-text';
static endingTag = true;
static allowedAttributes = {
'background-color': 'color',
'font-size': 'unit(px)',
'font-family': 'string',
'font-weight': 'string',
'letter-spacing': 'unitWithNegative(px,em)',
'line-height': 'unit(px,%,)',
'color': 'color',
'padding-bottom': 'unit(px,%)',
'padding-left': 'unit(px,%)',
'padding-right': 'unit(px,%)',
'padding-top': 'unit(px,%)',
'padding': 'unit(px,%){1,4}',
};
static defaultAttributes = {
'font-size': '13px',
'line-height': '1',
'padding': '16px',
};
getStyles() { /* returns style objects */ }
renderContent() { /* renders content cell */ }
render() { /* returns HTML string */ }
}// Base class from mjml-core - all accordion components extend this
class BodyComponent {
constructor(initialDatas) { /* component initialization */ }
getAttribute(name) { /* get attribute value */ }
getChildContext() { /* get component context */ }
htmlAttributes(attributes) { /* format HTML attributes */ }
renderChildren(children, options) { /* render child components */ }
getContent() { /* get component inner content */ }
}
// Utility functions from dependencies
const { find } = require('lodash'); // Used in AccordionElement
const conditionalTag = require('mjml-core/lib/helpers/conditionalTag'); // Used for conditional HTML outputThe accordion components include sophisticated CSS that provides different behaviors across email clients:
The component automatically handles cross-client compatibility without requiring additional configuration.