diff --git a/entry_types/scrolled/config/locales/new/info_table.de.yml b/entry_types/scrolled/config/locales/new/info_table.de.yml index 35a6491a0..0d3b2b87c 100644 --- a/entry_types/scrolled/config/locales/new/info_table.de.yml +++ b/entry_types/scrolled/config/locales/new/info_table.de.yml @@ -7,6 +7,21 @@ de: name: Info-Tabelle tabs: general: Info-Tabelle + attributes: + labelColumnAlign: + label: "Text-Ausrichtung (Erste Spalte) " + values: + auto: "(Automatisch)" + left: Linksbündig + center: Zentriert + right: Rechtsbündig + valueColumnAlign: + label: "Text-Ausrichtung (Zweite Spalte)" + values: + auto: "(Automatisch)" + left: Linksbündig + center: Zentriert + right: Rechtsbündig help_texts: shortcuts: |-
diff --git a/entry_types/scrolled/config/locales/new/info_table.en.yml b/entry_types/scrolled/config/locales/new/info_table.en.yml index 3899014e4..6b5f2d6ae 100644 --- a/entry_types/scrolled/config/locales/new/info_table.en.yml +++ b/entry_types/scrolled/config/locales/new/info_table.en.yml @@ -7,6 +7,21 @@ en: name: Info Table tabs: general: Info Table + attributes: + labelColumnAlign: + label: "Text align (First column)" + values: + auto: "(Auto)" + left: Left + center: Center + right: Right + valueColumnAlign: + label: "Text align (Second column)" + values: + auto: "(Auto)" + left: Left + center: Center + right: Right help_texts: shortcuts: |-
diff --git a/entry_types/scrolled/package/spec/frontend/EditableTable-spec.js b/entry_types/scrolled/package/spec/frontend/EditableTable-spec.js index 04f8cc852..252cf1d95 100644 --- a/entry_types/scrolled/package/spec/frontend/EditableTable-spec.js +++ b/entry_types/scrolled/package/spec/frontend/EditableTable-spec.js @@ -146,4 +146,49 @@ describe('EditableTable', () => { expect(container.querySelector('sup')).toHaveTextContent('3') expect(container.querySelector('sub')).toHaveTextContent('2') }); + + it('renders blank class on blank cells', () => { + const value = [ + { + type: 'row', + children: [ + { + type: 'label', + children: [ + {text: ''} + ] + }, + { + type: 'value', + children: [ + {text: 'Value'} + ] + } + ] + }, + { + type: 'row', + children: [ + { + type: 'label', + children: [ + {text: 'Label'} + ] + }, + { + type: 'value', + children: [ + {text: ''} + ] + } + ] + } + ]; + + render(); + + expect( + screen.queryAllByRole('cell').map(cell => cell.getAttribute('data-blank')) + ).toEqual(['', null, null, '']); + }); }); diff --git a/entry_types/scrolled/package/spec/frontend/inlineEditing/EditableTable/withFixedColumns-spec.js b/entry_types/scrolled/package/spec/frontend/inlineEditing/EditableTable/withFixedColumns-spec.js index 9844e90e1..838038e43 100644 --- a/entry_types/scrolled/package/spec/frontend/inlineEditing/EditableTable/withFixedColumns-spec.js +++ b/entry_types/scrolled/package/spec/frontend/inlineEditing/EditableTable/withFixedColumns-spec.js @@ -1862,6 +1862,61 @@ describe('handleTableNavigation', () => { }); }); + it('allows moving the cursor up inside multi line cell', () => { + const editor = withFixedColumns( + + + + Row 1, Col 2 + + + + + A{'\n'} + B + + + + ); + + const event = new KeyboardEvent('keydown', {key: 'ArrowUp'}); + handleTableNavigation(editor, event); + + expect(editor.selection).toEqual({ + anchor: {path: [1, 1, 0], offset: 3}, + focus: {path: [1, 1, 0], offset: 3} + }); + }); + + it('moves the cursor up to the last line of a multi line cell', () => { + const editor = withFixedColumns( + + + + + A{'\n'} + B{'\n'} + C + + + + + + Row 2, Col 2 + + + + ); + + const event = new KeyboardEvent('keydown', {key: 'ArrowUp'}); + handleTableNavigation(editor, event); + + expect(editor.selection).toEqual({ + anchor: {path: [0, 1, 0], offset: 4}, + focus: {path: [0, 1, 0], offset: 4} + }); + }); + it('moves the cursor to the cell below when pressing ArrowDown', () => { const editor = withFixedColumns( @@ -1886,4 +1941,30 @@ describe('handleTableNavigation', () => { focus: {path: [1, 1, 0], offset: 0} }); }); + + it('allows moving the cursor down inside multi line cell', () => { + const editor = withFixedColumns( + + + + + A{'\n'} + B + + + + + Row 2, Col 2 + + + ); + + const event = new KeyboardEvent('keydown', {key: 'ArrowDown'}); + handleTableNavigation(editor, event); + + expect(editor.selection).toEqual({ + anchor: {path: [0, 1, 0], offset: 1}, + focus: {path: [0, 1, 0], offset: 1} + }); + }); }); diff --git a/entry_types/scrolled/package/src/contentElements/infoTable/InfoTable.js b/entry_types/scrolled/package/src/contentElements/infoTable/InfoTable.js index 46c9cbdab..cd826e3c8 100644 --- a/entry_types/scrolled/package/src/contentElements/infoTable/InfoTable.js +++ b/entry_types/scrolled/package/src/contentElements/infoTable/InfoTable.js @@ -18,6 +18,8 @@ export function InfoTable({configuration, sectionProps}) { return ( + {children} @@ -87,7 +88,7 @@ export function createRenderElement({labelScaleCategory, valueScaleCategory}) { ); default: return ( - + {children} @@ -96,3 +97,7 @@ export function createRenderElement({labelScaleCategory, valueScaleCategory}) { } } } + +function cellAttributes(element) { + return utils.isBlankEditableTextValue([element]) ? {'data-blank': ''} : {}; +} diff --git a/entry_types/scrolled/package/src/frontend/inlineEditing/EditableTable/withFixedColumns/handleTableNavigation.js b/entry_types/scrolled/package/src/frontend/inlineEditing/EditableTable/withFixedColumns/handleTableNavigation.js index 8b3d6a3a4..8f66016ff 100644 --- a/entry_types/scrolled/package/src/frontend/inlineEditing/EditableTable/withFixedColumns/handleTableNavigation.js +++ b/entry_types/scrolled/package/src/frontend/inlineEditing/EditableTable/withFixedColumns/handleTableNavigation.js @@ -12,16 +12,19 @@ export function handleTableNavigation(editor, event) { const [, cellPath] = cellMatch; const rowPath = cellPath.slice(0, -1); - if (event.key === 'ArrowUp') { + if (event.key === 'ArrowUp' && Cell.inFirstLine(editor, selection.anchor)) { event.preventDefault(); if (rowPath[rowPath.length - 1] > 0) { const previousRowPath = Path.previous(rowPath); const targetPath = [...previousRowPath, cellPath[cellPath.length - 1]]; - Transforms.select(editor, Editor.start(editor, targetPath)); + Transforms.select( + editor, + Cell.getPointAtStartOfLastLine(editor, Editor.start(editor, targetPath).path) + ); } - } else if (event.key === 'ArrowDown') { + } else if (event.key === 'ArrowDown' && Cell.inLastLine(editor, selection.anchor)) { event.preventDefault(); const nextRowPath = Path.next(rowPath); diff --git a/entry_types/scrolled/package/src/frontend/inlineEditing/EditableTable/withFixedColumns/helpers.js b/entry_types/scrolled/package/src/frontend/inlineEditing/EditableTable/withFixedColumns/helpers.js index cc563e721..e68c4a3c5 100644 --- a/entry_types/scrolled/package/src/frontend/inlineEditing/EditableTable/withFixedColumns/helpers.js +++ b/entry_types/scrolled/package/src/frontend/inlineEditing/EditableTable/withFixedColumns/helpers.js @@ -1,4 +1,4 @@ -import {Editor} from 'slate'; +import {Editor, Node} from 'slate'; export const Row = { match(editor) { @@ -49,6 +49,34 @@ export const Cell = { }); return cellMatch; + }, + + inFirstLine(editor, point) { + const [node] = Editor.node(editor, point.path); + const text = Node.string(node); + + const firstLineBreak = text.indexOf('\n'); + + return firstLineBreak === -1 || point.offset <= firstLineBreak; + }, + + inLastLine(editor, point) { + const [node] = Editor.node(editor, point.path); + const text = Node.string(node); + + const lastLineBreak = text.lastIndexOf('\n'); + + return lastLineBreak === -1 || point.offset > lastLineBreak; + }, + + getPointAtStartOfLastLine(editor, cellPath) { + const [node] = Editor.node(editor, cellPath); + const text = Node.string(node); + + const lastLineBreak = text.lastIndexOf('\n'); + const offset = lastLineBreak === -1 ? 0 : lastLineBreak + 1; + + return {path: cellPath, offset}; } }