From b4bbb609c00124aefd7a9851875711d02ff4badc Mon Sep 17 00:00:00 2001 From: Tim Fischbach Date: Wed, 27 Nov 2024 16:21:48 +0100 Subject: [PATCH] Support justified text align inside text blocks Per paragraph setting like color/typography variant. REDMINE-20877 --- .../config/locales/new/align_justified.de.yml | 11 ++ .../config/locales/new/align_justified.en.yml | 11 ++ .../spec/frontend/EditableText-spec.js | 30 +++++ .../inlineEditing/EditableText/blocks-spec.js | 114 ++++++++++++++++++ .../src/contentElements/textBlock/editor.js | 6 +- .../src/contentElements/textBlock/stories.js | 21 ++++ .../package/src/frontend/EditableText.js | 7 +- .../inlineEditing/EditableText/Selection.js | 3 +- .../inlineEditing/EditableText/blocks.js | 4 + .../inlineEditing/EditableText/index.js | 4 + 10 files changed, 206 insertions(+), 5 deletions(-) create mode 100644 entry_types/scrolled/config/locales/new/align_justified.de.yml create mode 100644 entry_types/scrolled/config/locales/new/align_justified.en.yml diff --git a/entry_types/scrolled/config/locales/new/align_justified.de.yml b/entry_types/scrolled/config/locales/new/align_justified.de.yml new file mode 100644 index 0000000000..0dde3efe26 --- /dev/null +++ b/entry_types/scrolled/config/locales/new/align_justified.de.yml @@ -0,0 +1,11 @@ +de: + pageflow_scrolled: + editor: + content_elements: + textBlock: + attributes: + textAlign: + label: "Textausrichtung" + values: + ragged: "Flattersatz" + justify: "Blocksatz" diff --git a/entry_types/scrolled/config/locales/new/align_justified.en.yml b/entry_types/scrolled/config/locales/new/align_justified.en.yml new file mode 100644 index 0000000000..dcdfa86de7 --- /dev/null +++ b/entry_types/scrolled/config/locales/new/align_justified.en.yml @@ -0,0 +1,11 @@ +en: + pageflow_scrolled: + editor: + content_elements: + textBlock: + attributes: + textAlign: + label: "Text align" + values: + ragged: "Ragged" + justify: "Justified" diff --git a/entry_types/scrolled/package/spec/frontend/EditableText-spec.js b/entry_types/scrolled/package/spec/frontend/EditableText-spec.js index b861e5a0f7..73017a381f 100644 --- a/entry_types/scrolled/package/spec/frontend/EditableText-spec.js +++ b/entry_types/scrolled/package/spec/frontend/EditableText-spec.js @@ -342,6 +342,36 @@ describe('EditableText', () => { 'color: rgb(0, 0, 0);'); }); + it('renders text align', () => { + const value = [{ + type: 'paragraph', + textAlign: 'justify', + children: [ + {text: 'Some text'} + ] + }]; + + const {container} = render(); + + expect(container.querySelector('p[style]')).toHaveStyle('text-align: justify;'); + }); + + it('can render both color and text align', () => { + const value = [{ + type: 'paragraph', + textAlign: 'justify', + color: '#000', + children: [ + {text: 'Some text'} + ] + }]; + + const {container} = render(); + + expect(container.querySelector('p[style]')).toHaveStyle('text-align: justify;'); + expect(container.querySelector('p[style]')).toHaveStyle('color: rgb(0, 0, 0);'); + }); + it('uses body scaleCategory by default', () => { const value = [{ type: 'paragraph', diff --git a/entry_types/scrolled/package/spec/frontend/inlineEditing/EditableText/blocks-spec.js b/entry_types/scrolled/package/spec/frontend/inlineEditing/EditableText/blocks-spec.js index 33a6417181..c21031a7dd 100644 --- a/entry_types/scrolled/package/spec/frontend/inlineEditing/EditableText/blocks-spec.js +++ b/entry_types/scrolled/package/spec/frontend/inlineEditing/EditableText/blocks-spec.js @@ -2,6 +2,7 @@ import { applyTypograpyhVariant, applyColor, + applyTextAlign, isBlockActive, toggleBlock, withBlockNormalization @@ -423,6 +424,119 @@ describe('applyColor', () => { }); }); +describe('applyTextAlign', () => { + it('sets color property deeply in lists', () => { + const editor = ( + + + + Item 1 + + + + Item 1 + + + + ); + + applyTextAlign(editor, 'justify'); + + const output = ( + + + + Item 1 + + + Item 1 + + + + ); + expect(editor.children).toEqual(output.children); + }); + + it('sets textAlign property of multiple elements', () => { + const editor = ( + + + + Text + + + More Text + + + + Other Text + + + ); + + applyTextAlign(editor, 'justify'); + + const output = ( + + + Text + + + More Text + + + Other Text + + + ); + expect(editor.children).toEqual(output.children); + }); + + it('unsets textAlign property if set to ragged', () => { + const editor = ( + + + + Text + + + ); + + applyTextAlign(editor, 'ragged'); + + const output = ( + + + Text + + + ); + expect(editor.children).toEqual(output.children); + }); + + it('unsets textAlign property if blank', () => { + const editor = ( + + + + Text + + + ); + + applyTextAlign(editor, undefined); + + const output = ( + + + Text + + + ); + expect(editor.children).toEqual(output.children); + }); +}); + describe('withBlockNormalization', () => { describe('with onlyParagraphs false', () => { it('is no-op by default', () => { diff --git a/entry_types/scrolled/package/src/contentElements/textBlock/editor.js b/entry_types/scrolled/package/src/contentElements/textBlock/editor.js index 0f2b1951ad..7cd42b1b03 100644 --- a/entry_types/scrolled/package/src/contentElements/textBlock/editor.js +++ b/entry_types/scrolled/package/src/contentElements/textBlock/editor.js @@ -2,7 +2,7 @@ import I18n from 'i18n-js'; import {utils} from 'pageflow-scrolled/frontend'; import {editor} from 'pageflow-scrolled/editor'; import {InfoBoxView} from 'pageflow/editor'; -import {SeparatorView} from 'pageflow/ui' +import {SeparatorView, SelectInputView} from 'pageflow/ui' import pictogram from './pictogram.svg'; @@ -51,6 +51,10 @@ editor.contentElementTypes.register('textBlock', { model: modelDelegator, propertyName: 'color' }); + this.input('textAlign', SelectInputView, { + model: contentElement.transientState, + values: ['ragged', 'justify'] + }); this.view(SeparatorView); diff --git a/entry_types/scrolled/package/src/contentElements/textBlock/stories.js b/entry_types/scrolled/package/src/contentElements/textBlock/stories.js index 1a23bb477f..aadf270651 100644 --- a/entry_types/scrolled/package/src/contentElements/textBlock/stories.js +++ b/entry_types/scrolled/package/src/contentElements/textBlock/stories.js @@ -137,6 +137,27 @@ storiesOfContentElement(module, { ] } }, + { + name: 'Text align justify', + configuration: { + value: [ + { + type: 'heading', + textAlign: 'justify', + children: [ + {text: 'Heading'} + ] + }, + { + type: 'paragraph', + textAlign: 'justify', + children: [ + {text: 'Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr.'}, + ] + } + ] + } + }, { name: 'With theme link color', configuration: linkExampleConfiguration, diff --git a/entry_types/scrolled/package/src/frontend/EditableText.js b/entry_types/scrolled/package/src/frontend/EditableText.js index 9099e42c07..683f1cb1f3 100644 --- a/entry_types/scrolled/package/src/frontend/EditableText.js +++ b/entry_types/scrolled/package/src/frontend/EditableText.js @@ -49,9 +49,10 @@ export function renderElement({attributes, children, element}) { ['typography-textBlock', camelize(element.type), element.variant].join('-'); - - const styles = element.color && - {color: paletteColor(element.color)}; + const styles = { + ...(element.color && {color: paletteColor(element.color)}), + ...(element.textAlign && {textAlign: element.textAlign}) + }; switch (element.type) { case 'block-quote': diff --git a/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/Selection.js b/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/Selection.js index 476e960845..b23b127a4b 100644 --- a/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/Selection.js +++ b/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/Selection.js @@ -86,7 +86,8 @@ export function Selection(props) { editableTextIsSingleBlock: editor.children.length <= 1, exampleNode: getUniformSelectedNode(editor, 'type'), typographyVariant: getUniformSelectedNode(editor, 'variant')?.variant, - color: getUniformSelectedNode(editor, 'color')?.color + color: getUniformSelectedNode(editor, 'color')?.color, + textAlign: getUniformSelectedNode(editor, 'textAlign')?.textAlign, }); boundsRef.current = {start, end}; diff --git a/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/blocks.js b/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/blocks.js index bd91762de0..f2aabefe35 100644 --- a/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/blocks.js +++ b/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/blocks.js @@ -42,6 +42,10 @@ export function applyColor(editor, color) { applyProperties(editor, {color}); } +export function applyTextAlign(editor, textAlign) { + applyProperties(editor, {textAlign: textAlign === 'justify' ? 'justify' : undefined}); +} + function applyProperties(editor, properties) { Transforms.setNodes(editor, properties, {mode: 'highest'}); applyPropertiesToListItems(editor, properties); diff --git a/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/index.js b/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/index.js index 6f5b8697db..d8f6d6170a 100644 --- a/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/index.js +++ b/entry_types/scrolled/package/src/frontend/inlineEditing/EditableText/index.js @@ -21,6 +21,7 @@ import {Selection} from './Selection'; import {DropTargets} from './DropTargets'; import {LinkTooltipProvider} from '../LinkTooltip'; import { + applyTextAlign, applyTypograpyhVariant, applyColor, withBlockNormalization @@ -99,6 +100,9 @@ export const EditableText = React.memo(function EditableText({ if ('color' in command.payload) { applyColor(editor, command.payload.color); } + if ('textAlign' in command.payload) { + applyTextAlign(editor, command.payload.textAlign); + } } });