diff --git a/src/components/Divider.ts b/src/components/Divider.ts index d983b01..a24548e 100644 --- a/src/components/Divider.ts +++ b/src/components/Divider.ts @@ -17,6 +17,7 @@ export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPlugin draggable: componentsToQuery([typeColumn, typeHero]), droppable: false, 'style-default': { + 'align': 'center', 'width': '100%', 'border-width': '4px', 'border-style': 'solid', @@ -28,7 +29,7 @@ export default (editor: Editor, { coreMjmlModel, coreMjmlView }: ComponentPlugin }, stylable: [ 'padding', 'padding-top', 'padding-left', 'padding-right', 'padding-bottom', - 'width', 'container-background-color', + 'width', 'container-background-color', 'align', 'border-detached', 'border-width', 'border-style', 'border-color' ], void: false, diff --git a/tests/specs/divider.test.ts b/tests/specs/divider.test.ts new file mode 100644 index 0000000..9e51e5a --- /dev/null +++ b/tests/specs/divider.test.ts @@ -0,0 +1,69 @@ +import grapesjs, { Editor } from 'grapesjs'; +import grapesJSMJML from '../../src'; + +describe('Divider alignment', () => { + let editor: Editor; + + beforeEach((done) => { + document.body.innerHTML = '
'; + editor = grapesjs.init({ + container: '#gjs', + plugins: [grapesJSMJML], + storageManager: false, + }); + editor.onReady(() => { + jest.useFakeTimers(); + done(); + }); + }); + + afterEach(() => { + // Flush debounced selection/render work before destroying the editor. + jest.runOnlyPendingTimers(); + editor.destroy(); + jest.useRealTimers(); + }); + + function addDivider(attributes = '') { + editor.addComponents(` + + `); + const divider = editor.getWrapper()!.findType('mj-divider')[0]; + editor.select(divider); + jest.runOnlyPendingTimers(); + const sector = editor.StyleManager.getSectors().find((s) => s.getName() === 'Typography'); + return { divider, alignment: sector!.getProperty('align')! }; + } + + test('exposes the existing alignment control for dividers', () => { + const { alignment } = addDivider(); + expect(alignment.isVisible()).toBe(true); + }); + + test('uses the MJML center default without adding it to exported markup', () => { + const { divider, alignment } = addDivider(); + expect(alignment.getValue()).toBe('center'); + expect(divider.getStyle().align).toBe('center'); + expect(divider.toHTML()).not.toContain('align='); + }); + + test.each(['left', 'center', 'right'])('applies %s alignment through Style Manager', (align) => { + const { divider, alignment } = addDivider(); + alignment.upValue(align); + expect(divider.getAttributes().align).toBe(align); + const mjml = divider.toHTML(); + expect(mjml).toContain('width="50%"'); + if (align !== 'center') expect(mjml).toContain(`align="${align}"`); + const { errors, html } = editor.Commands.run('mjml-code-to-html'); + expect(errors).toHaveLength(0); + const document = new DOMParser().parseFromString(html, 'text/html'); + const line = document.querySelector('p')!; + expect(line.parentElement!.getAttribute('align')).toBe(align); + }); + + test.each(['left', 'right'])('preserves explicitly imported %s alignment', (align) => { + const { divider, alignment } = addDivider(`align="${align}"`); + expect(alignment.getValue()).toBe(align); + expect(divider.toHTML()).toContain(`align="${align}"`); + }); +});