mjml-custom-component-decorator
TypeScript icon, indicating that this package has built-in type declarations

4.1.0 • Public • Published

mjml-custom-component-decorator

npm version Continuous Test, Build & Release Renovate Quality Gate Status Reliability Rating Maintainability Rating


TypeScript decorator for MJML custom components.

Features

  • Define custom MJML components with TypeScript decorator
  • Automatic discovery and registration on file load

Requirements

Installation

npm i --save mjml-custom-component-decorator

Usage

TypeScript

First of all, you will need to enable experimental decorators in your tsconfig:

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

Then you can use it as simple as this:

import {BodyComponent, registerComponent} from "mjml-core";
import {registerDependencies} from "mjml-validator";

import {MJMLCustomComponent} from "mjml-custom-component-decorator";

@MJMLCustomComponent({
    tag: "my-custom-component",
    attributes: {
        text: {
            type: 'string',
            default: 'Hello World'
        }
    },
    allowedParentTags: ["mj-column"],
})
export class MyCustomComponent extends BodyComponent {
    render() {
        return this.renderMJML(`
            <mj-text>
                Hello there, this is what you gave as text attribute: ${this.getAttribute("text")}
            </mj-text>`
        )
    }
}

Motivation

When you are developing custom components in mjml you will find yourself writing the same boilerplate code over and over again. It gets even worse, because you need to define some static properties without any kind of autocomplete.

This is where typescript and its decorator features come handy. You write the decorator, and the project simply intercepts the class and adds the required fields. To make it even easier, TypeScript enables you to use the autocomplete of your favourite IDE, isn't that awesome?!

Just for completeness without the decorator ...

... it looks like this:

import {registerDependencies} from "mjml-validator"
import {registerComponent} from "mjml-core";

export class MyCustomComponent extends BodyComponent {
    static allowedAttributes = {
        text: 'string'
    }

    static defaultAttributes = {
        'text': 'Hello World'
    }

    static endingTag = false

    render() {
        return this.renderMJML(`
            <mj-text>
                Hello there, this is what you gave as text attribute: ${this.getAttribute("text")}
            </mj-text>`
        )
    }
}

registerComponent(MyCustomComponent)
registerDependencies({
    'mj-column': ['my-custom-component'],
    'my-custom-component': []
})

You duplicate your attribute name twice and can't have some kind of defaults (excerpt using inheritance)

Contributing

I love your input! I want to make contributing to this project as easy and transparent as possible, whether it's:

  • Reporting a bug
  • Discussing the current state of the configuration
  • Submitting a fix
  • Proposing new features
  • Becoming a maintainer

To get started please read the Contribution Guidelines.

Development

Requirements

Test

npm run test

Build

npm run build

Readme

Keywords

none

Package Sidebar

Install

npm i mjml-custom-component-decorator

Weekly Downloads

61

Version

4.1.0

License

MIT

Unpacked Size

32.7 kB

Total Files

19

Last publish

Collaborators

  • timo-reymann