From 31574a0c993d78eaf486b2c7814b6854fa1573d5 Mon Sep 17 00:00:00 2001 From: z0al Date: Thu, 16 Sep 2021 10:08:20 +0200 Subject: [PATCH] feat(html+react): render Table header as --- .../src/__test__/documents/index.ts | 1 + .../src/__test__/documents/table-header.ts | 98 +++++++++++++++++++ .../src/__test__/index.test.ts | 15 ++- packages/rich-text-html-renderer/src/index.ts | 7 +- .../__snapshots__/index.test.tsx.snap | 81 ++++++++++----- .../src/__test__/documents/index.ts | 1 + .../src/__test__/documents/table-header.ts | 98 +++++++++++++++++++ .../src/__test__/index.test.tsx | 5 + .../rich-text-react-renderer/src/index.tsx | 3 +- 9 files changed, 278 insertions(+), 31 deletions(-) create mode 100644 packages/rich-text-html-renderer/src/__test__/documents/table-header.ts create mode 100644 packages/rich-text-react-renderer/src/__test__/documents/table-header.ts diff --git a/packages/rich-text-html-renderer/src/__test__/documents/index.ts b/packages/rich-text-html-renderer/src/__test__/documents/index.ts index 90c3af46..96f80960 100644 --- a/packages/rich-text-html-renderer/src/__test__/documents/index.ts +++ b/packages/rich-text-html-renderer/src/__test__/documents/index.ts @@ -10,3 +10,4 @@ export { default as olDoc } from './ol'; export { default as ulDoc } from './ul'; export { default as quoteDoc } from './quote'; export { default as tableDoc } from './table'; +export { default as tableWithHeaderDoc } from './table-header'; diff --git a/packages/rich-text-html-renderer/src/__test__/documents/table-header.ts b/packages/rich-text-html-renderer/src/__test__/documents/table-header.ts new file mode 100644 index 00000000..af7228cb --- /dev/null +++ b/packages/rich-text-html-renderer/src/__test__/documents/table-header.ts @@ -0,0 +1,98 @@ +import { Document, BLOCKS } from '@contentful/rich-text-types'; + +export default { + nodeType: BLOCKS.DOCUMENT, + data: {}, + content: [ + { + nodeType: BLOCKS.TABLE, + data: {}, + content: [ + { + nodeType: BLOCKS.TABLE_ROW, + data: {}, + content: [ + { + nodeType: BLOCKS.TABLE_HEADER_CELL, + data: {}, + content: [ + { + nodeType: BLOCKS.PARAGRAPH, + data: {}, + content: [ + { + nodeType: 'text', + data: {}, + marks: [], + value: 'A 1', + }, + ], + }, + ], + }, + { + nodeType: BLOCKS.TABLE_HEADER_CELL, + data: {}, + content: [ + { + nodeType: BLOCKS.PARAGRAPH, + data: {}, + content: [ + { + nodeType: 'text', + data: {}, + marks: [], + value: 'B 1', + }, + ], + }, + ], + }, + ], + }, + { + nodeType: BLOCKS.TABLE_ROW, + data: {}, + content: [ + { + nodeType: BLOCKS.TABLE_CELL, + data: {}, + content: [ + { + nodeType: BLOCKS.PARAGRAPH, + data: {}, + content: [ + { + nodeType: 'text', + data: {}, + marks: [], + value: 'A 2', + }, + ], + }, + ], + }, + { + nodeType: BLOCKS.TABLE_CELL, + data: {}, + content: [ + { + nodeType: BLOCKS.PARAGRAPH, + data: {}, + content: [ + { + nodeType: 'text', + data: {}, + marks: [], + value: 'B 2', + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], +} as Document; diff --git a/packages/rich-text-html-renderer/src/__test__/index.test.ts b/packages/rich-text-html-renderer/src/__test__/index.test.ts index 9d2519a9..06075fa7 100644 --- a/packages/rich-text-html-renderer/src/__test__/index.test.ts +++ b/packages/rich-text-html-renderer/src/__test__/index.test.ts @@ -14,6 +14,7 @@ import { tableDoc, quoteDoc, ulDoc, + tableWithHeaderDoc, } from './documents'; import inlineEntity from './documents/inline-entity'; @@ -205,14 +206,24 @@ describe('documentToHtmlString', () => { it('renders tables', () => { const document: Document = tableDoc; const expected = - '' + + '
' + '' + '' + - '

A 1

B 1

A 2

B 2

'; + ''; expect(documentToHtmlString(document)).toEqual(expected); }); + it('renders tables with header', () => { + const expected = + '' + + '' + + '' + + '

A 1

B 1

A 2

B 2

'; + + expect(documentToHtmlString(tableWithHeaderDoc)).toEqual(expected); + }); + it('does not crash with inline elements (e.g. hyperlink)', () => { const document: Document = hyperlinkDoc; diff --git a/packages/rich-text-html-renderer/src/index.ts b/packages/rich-text-html-renderer/src/index.ts index ef9b1e82..5069136d 100644 --- a/packages/rich-text-html-renderer/src/index.ts +++ b/packages/rich-text-html-renderer/src/index.ts @@ -27,8 +27,9 @@ const defaultNodeRenderers: RenderNode = { [BLOCKS.LIST_ITEM]: (node, next) => `
  • ${next(node.content)}
  • `, [BLOCKS.QUOTE]: (node, next) => `
    ${next(node.content)}
    `, [BLOCKS.HR]: () => '
    ', - [BLOCKS.TABLE]: (node, next) => `${next(node.content)}
    `, + [BLOCKS.TABLE]: (node, next) => `${next(node.content)}
    `, [BLOCKS.TABLE_ROW]: (node, next) => `${next(node.content)}`, + [BLOCKS.TABLE_HEADER_CELL]: (node, next) => `${next(node.content)}`, [BLOCKS.TABLE_CELL]: (node, next) => `${next(node.content)}`, [INLINES.ASSET_HYPERLINK]: node => defaultInline(INLINES.ASSET_HYPERLINK, node as Inline), [INLINES.ENTRY_HYPERLINK]: node => defaultInline(INLINES.ENTRY_HYPERLINK, node as Inline), @@ -102,7 +103,9 @@ export function documentToHtmlString( } function nodeListToHtmlString(nodes: CommonNode[], { renderNode, renderMark }: Options): string { - return nodes.map(node => nodeToHtmlString(node, { renderNode, renderMark })).join(''); + return nodes + .map(node => nodeToHtmlString(node, { renderNode, renderMark })) + .join(''); } function nodeToHtmlString(node: CommonNode, { renderNode, renderMark }: Options): string { diff --git a/packages/rich-text-react-renderer/src/__test__/__snapshots__/index.test.tsx.snap b/packages/rich-text-react-renderer/src/__test__/__snapshots__/index.test.tsx.snap index b6934485..77e766af 100644 --- a/packages/rich-text-react-renderer/src/__test__/__snapshots__/index.test.tsx.snap +++ b/packages/rich-text-react-renderer/src/__test__/__snapshots__/index.test.tsx.snap @@ -226,32 +226,61 @@ Array [ exports[`documentToReactComponents renders tables 1`] = ` Array [ - - - - - - - - - - + + + + + + + + +
    -

    - A 1 -

    -
    -

    - B 1 -

    -
    -

    - A 2 -

    -
    -

    - B 2 -

    -
    +

    + A 1 +

    +
    +

    + B 1 +

    +
    +

    + A 2 +

    +
    +

    + B 2 +

    +
    , +] +`; + +exports[`documentToReactComponents renders tables with header 1`] = ` +Array [ + + + + + + + + +
    +

    + A 1 +

    +
    +

    + B 1 +

    +
    +

    + A 2 +

    +
    +

    + B 2 +

    +
    , ] `; diff --git a/packages/rich-text-react-renderer/src/__test__/documents/index.ts b/packages/rich-text-react-renderer/src/__test__/documents/index.ts index 708845c9..0f04221f 100644 --- a/packages/rich-text-react-renderer/src/__test__/documents/index.ts +++ b/packages/rich-text-react-renderer/src/__test__/documents/index.ts @@ -12,3 +12,4 @@ export { default as olDoc } from './ol'; export { default as ulDoc } from './ul'; export { default as quoteDoc } from './quote'; export { default as tableDoc } from './table'; +export { default as tableWithHeaderDoc } from './table-header'; diff --git a/packages/rich-text-react-renderer/src/__test__/documents/table-header.ts b/packages/rich-text-react-renderer/src/__test__/documents/table-header.ts new file mode 100644 index 00000000..af7228cb --- /dev/null +++ b/packages/rich-text-react-renderer/src/__test__/documents/table-header.ts @@ -0,0 +1,98 @@ +import { Document, BLOCKS } from '@contentful/rich-text-types'; + +export default { + nodeType: BLOCKS.DOCUMENT, + data: {}, + content: [ + { + nodeType: BLOCKS.TABLE, + data: {}, + content: [ + { + nodeType: BLOCKS.TABLE_ROW, + data: {}, + content: [ + { + nodeType: BLOCKS.TABLE_HEADER_CELL, + data: {}, + content: [ + { + nodeType: BLOCKS.PARAGRAPH, + data: {}, + content: [ + { + nodeType: 'text', + data: {}, + marks: [], + value: 'A 1', + }, + ], + }, + ], + }, + { + nodeType: BLOCKS.TABLE_HEADER_CELL, + data: {}, + content: [ + { + nodeType: BLOCKS.PARAGRAPH, + data: {}, + content: [ + { + nodeType: 'text', + data: {}, + marks: [], + value: 'B 1', + }, + ], + }, + ], + }, + ], + }, + { + nodeType: BLOCKS.TABLE_ROW, + data: {}, + content: [ + { + nodeType: BLOCKS.TABLE_CELL, + data: {}, + content: [ + { + nodeType: BLOCKS.PARAGRAPH, + data: {}, + content: [ + { + nodeType: 'text', + data: {}, + marks: [], + value: 'A 2', + }, + ], + }, + ], + }, + { + nodeType: BLOCKS.TABLE_CELL, + data: {}, + content: [ + { + nodeType: BLOCKS.PARAGRAPH, + data: {}, + content: [ + { + nodeType: 'text', + data: {}, + marks: [], + value: 'B 2', + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], +} as Document; diff --git a/packages/rich-text-react-renderer/src/__test__/index.test.tsx b/packages/rich-text-react-renderer/src/__test__/index.test.tsx index 6ef2c9fe..208c4b38 100644 --- a/packages/rich-text-react-renderer/src/__test__/index.test.tsx +++ b/packages/rich-text-react-renderer/src/__test__/index.test.tsx @@ -18,6 +18,7 @@ import { quoteDoc, ulDoc, tableDoc, + tableWithHeaderDoc, } from './documents'; import DocumentWrapper from './components/Document'; import Paragraph from './components/Paragraph'; @@ -165,6 +166,10 @@ describe('documentToReactComponents', () => { expect(documentToReactComponents(document)).toMatchSnapshot(); }); + it('renders tables with header', () => { + expect(documentToReactComponents(tableWithHeaderDoc)).toMatchSnapshot(); + }); + it('does not crash with inline elements (e.g. hyperlink)', () => { const document: Document = hyperlinkDoc; diff --git a/packages/rich-text-react-renderer/src/index.tsx b/packages/rich-text-react-renderer/src/index.tsx index 861b0cb2..5c58ca64 100644 --- a/packages/rich-text-react-renderer/src/index.tsx +++ b/packages/rich-text-react-renderer/src/index.tsx @@ -17,8 +17,9 @@ const defaultNodeRenderers: RenderNode = { [BLOCKS.LIST_ITEM]: (node, children) =>
  • {children}
  • , [BLOCKS.QUOTE]: (node, children) =>
    {children}
    , [BLOCKS.HR]: () =>
    , - [BLOCKS.TABLE]: (node, children) => {children}
    , + [BLOCKS.TABLE]: (node, children) => {children}
    , [BLOCKS.TABLE_ROW]: (node, children) => {children}, + [BLOCKS.TABLE_HEADER_CELL]: (node, children) => {children}, [BLOCKS.TABLE_CELL]: (node, children) => {children}, [INLINES.ASSET_HYPERLINK]: node => defaultInline(INLINES.ASSET_HYPERLINK, node as Inline), [INLINES.ENTRY_HYPERLINK]: node => defaultInline(INLINES.ENTRY_HYPERLINK, node as Inline),