Skip to content

Commit

Permalink
Feat: add customComponent property to plugin options
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel Stencl committed Nov 25, 2023
1 parent abe0b22 commit ebac70c
Show file tree
Hide file tree
Showing 22 changed files with 101 additions and 25 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Supported MJML components (using default mjml-browser parser):
|`blocks`|Which blocks to add|(all)|
|`block`|Add custom block options, based on block id.|`(blockId) => ({})`|
|`codeViewerTheme`|Code viewer theme.|`hopscotch`|
|`customComponents`|List of components which will be added to default one |`[]` |
|`fonts`|Custom fonts on exported HTML header [more info](https://github.com/mjmlio/mjml#inside-nodejs)|`{}`|
|`importPlaceholder`|Placeholder MJML template for the import modal|`''`|
|`imagePlaceholderSrc`|Image placeholder source|`'https://via.placeholder.com/350x250/78c5d6/fff'`|
Expand Down Expand Up @@ -182,6 +183,39 @@ editor.on('load', () => {
});
```

### Using Independent mjml-browser Build

In case, you have your own version of MJML with custom or extended components, it is possible
to override default [mjml parser](https://github.com/mjmlio/mjml/tree/master/packages/mjml-browser)
with custom one and create custom grapesJS components.

For further info how to create MJML Component, you can
[visit components folder](https://github.com/GrapesJS/mjml/tree/master/src/components)
or you can go to [docs](https://grapesjs.com/docs/modules/Components.html#define-custom-component-type).

```ts
import 'grapesjs/dist/css/grapes.min.css'
import grapesJS from 'grapesjs'
import grapesJSMJML from 'grapesjs-mjml'
import customMjmlParser from 'custom-mjml-parser';

import customImage from 'custom/components/path'

grapesJS.init({
fromElement: true,
container: '#gjs',
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {
mjmlParser: customMjmlParser,
customComponents: [
customImage,
]
}
},
});
```

## Development

Clone the repository
Expand Down
3 changes: 2 additions & 1 deletion src/components/Body.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Specs: https://documentation.mjml.io/#mj-body
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { type as typeHero } from './Hero';
import { type as typeRaw } from './Raw';
import { type as typeSection } from './Section';
Expand All @@ -8,7 +9,7 @@ import { componentsToQuery, getName, isComponentType } from './utils';

export const type = 'mj-body';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
model: {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Button.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Specs: https://documentation.mjml.io/#mj-button
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeColumn } from './Column';
import { type as typeHero } from './Hero';

export const type = 'mj-button';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
extend: 'link',
Expand Down
4 changes: 3 additions & 1 deletion src/components/Column.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Specs: https://documentation.mjml.io/#mj-column
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType, mjmlConvert } from './utils';
import { type as typeSection } from './Section';


export const type = 'mj-column';

export default (editor: Editor, { opt, coreMjmlModel, coreMjmlView, sandboxEl }: any) => {
export default (editor: Editor, { opt, coreMjmlModel, coreMjmlView, sandboxEl }: ComponentPluginOptions) => {
const clmPadd = opt.columnsPadding;

editor.Components.addType(type, {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Divider.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Specs: https://documentation.mjml.io/#mj-divider
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeColumn } from './Column';
import { type as typeHero } from './Hero';

export const type = 'mj-divider';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
model: {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Font.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Specs: https://documentation.mjml.io/#mj-font
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, isComponentType, mjmlConvert } from './utils';
import { type as typeHead } from './Head';

export const type = 'mj-font';

export default (editor: Editor, { opt, coreMjmlModel, coreMjmlView, sandboxEl }: any) => {
export default (editor: Editor, { opt, coreMjmlModel, coreMjmlView, sandboxEl }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
model: {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Group.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Specs: https://documentation.mjml.io/#mj-group
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeSection } from './Section';
import { type as typeColumn } from './Column';

export const type = 'mj-group';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
model: {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Hero.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Specs: https://documentation.mjml.io/#mj-hero
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeBody } from './Body';
import { type as typeText } from './Text';
Expand All @@ -12,7 +13,7 @@ import { type as typeSpacer } from './Spacer';

export const type = 'mj-hero';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
model: {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Image.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// Specs: https://documentation.mjml.io/#mj-image
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeSection } from './Section';
import { type as typeColumn } from './Column';
import { type as typeHero } from './Hero';

export const type = 'mj-image';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
extend: 'image',
Expand Down
3 changes: 2 additions & 1 deletion src/components/NavBar.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// Specs https://documentation.mjml.io/#mj-navbar
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType, mjmlConvert } from './utils';
import { type as typeColumn } from './Column';
import { type as typeHero } from './Hero';
import { type as typeNavBarLink } from './NavBarLink';

export const type = 'mj-navbar';

export default (editor: Editor, { opt, coreMjmlModel, coreMjmlView, sandboxEl }: any) => {
export default (editor: Editor, { opt, coreMjmlModel, coreMjmlView, sandboxEl }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
model: {
Expand Down
3 changes: 2 additions & 1 deletion src/components/NavBarLink.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Specs: https://documentation.mjml.io/#mj-navbar-link
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeNavBar } from './NavBar';

export const type = 'mj-navbar-link';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
extend: 'link',
Expand Down
3 changes: 2 additions & 1 deletion src/components/Raw.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Specs: https://documentation.mjml.io/#mj-raw
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeBody } from './Body';
import { type as typeHead } from './Head';

export const type = 'mj-raw';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
model: {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Section.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Specs: https://documentation.mjml.io/#mj-section
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeBody } from './Body';
import { type as typeWrapper } from './Wrapper';
Expand All @@ -8,7 +9,7 @@ import { type as typeGroup } from './Group';

export const type = 'mj-section';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),

Expand Down
3 changes: 2 additions & 1 deletion src/components/Social.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// Specs: https://documentation.mjml.io/#mjml-social
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeColumn } from './Column';
import { type as typeHero } from './Hero';
import { type as typeSocialElement } from './SocialElement';

export const type = 'mj-social';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),

Expand Down
3 changes: 2 additions & 1 deletion src/components/SocialElement.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Specs: https://documentation.mjml.io/#mjml-social
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeSocial } from './Social';

export const type = 'mj-social-element';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),

Expand Down
3 changes: 2 additions & 1 deletion src/components/Spacer.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Specs: https://documentation.mjml.io/#mjml-spacer
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeColumn } from './Column';
import { type as typeHero } from './Hero';

export const type = 'mj-spacer';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),

Expand Down
3 changes: 2 additions & 1 deletion src/components/Style.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Specs: https://documentation.mjml.io/#mj-style
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, isComponentType, mjmlConvert } from './utils';
import { type as typeHead } from './Head';

export const type = 'mj-style';

export default (editor: Editor, { opt, coreMjmlModel, coreMjmlView, sandboxEl }: any) => {
export default (editor: Editor, { opt, coreMjmlModel, coreMjmlView, sandboxEl }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),

Expand Down
3 changes: 2 additions & 1 deletion src/components/Text.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Specs: https://documentation.mjml.io/#mjml-text
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeColumn } from './Column';
import { type as typeHero } from './Hero';

export const type = 'mj-text';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
extend: 'text',
extendFnView: ['onActive'],
Expand Down
3 changes: 2 additions & 1 deletion src/components/Wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Specs: https://documentation.mjml.io/#mjml-wrapper
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { componentsToQuery, getName, isComponentType } from './utils';
import { type as typeBody } from './Body';
import { type as typeSection } from './Section';

export const type = 'mj-wrapper';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),

Expand Down
22 changes: 18 additions & 4 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Editor } from 'grapesjs';
import { mjmlConvert, debounce } from './utils';
import type { Editor, PluginOptions } from 'grapesjs';
import { mjmlConvert, debounce, componentsToQuery } from './utils';
import loadMjml from './mjml';
import loadHead from './Head';
import loadStyle from './Style';
Expand All @@ -22,6 +22,20 @@ import loadHero from './Hero';
import loadRaw from './Raw';
import { RequiredPluginOptions } from '..';

export type ComponentPluginOptions = {
/**
* Core model, which can be extended
*/
coreMjmlModel: any;
/**
* Core view, which can be extended
*/
coreMjmlView: any;
opt: Required<PluginOptions>;
sandboxEl: HTMLDivElement;
componentsToQuery: typeof componentsToQuery,
}

export default (editor: Editor, opt: RequiredPluginOptions) => {
const { Components } = editor;
// @ts-ignore
Expand Down Expand Up @@ -266,9 +280,8 @@ export default (editor: Editor, opt: RequiredPluginOptions) => {
}
} as any;


// MJML Internal view (for elements inside mj-columns)
const compOpts = { coreMjmlModel, coreMjmlView, opt, sandboxEl };
const compOpts = { coreMjmlModel, coreMjmlView, opt, sandboxEl, componentsToQuery};

// Avoid the <body> tag from the default wrapper
editor.Components.addType('wrapper', {
Expand Down Expand Up @@ -303,6 +316,7 @@ export default (editor: Editor, opt: RequiredPluginOptions) => {
loadNavBarLink,
loadHero,
loadRaw,
...opt.customComponents,
]
.forEach(module => module(editor, compOpts));
};
3 changes: 2 additions & 1 deletion src/components/mjml.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Specs: https://documentation.mjml.io/#mjml
import type { Editor } from 'grapesjs';
import { ComponentPluginOptions } from '.';
import { isComponentType, componentsToQuery } from './utils';
import { type as typeHead } from './Head';
import { type as typeBody } from './Body';

export const type = 'mjml';

export default (editor: Editor, { coreMjmlModel, coreMjmlView }: any) => {
export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPluginOptions) => {
editor.Components.addType(type, {
isComponent: isComponentType(type),
model: {
Expand Down
Loading

0 comments on commit ebac70c

Please sign in to comment.