From db4408ad3fb36a0ba690d6aaa129636b72bd1705 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Sun, 11 Apr 2021 12:54:03 +0100 Subject: [PATCH] fix: list rendering fixes for SanityContent * render lists correctly when they are first in a portable text array * render nested lists correctly closes #102 --- src/components/sanity-content.ts | 46 +++-- .../__snapshots__/sanity-content.test.ts.snap | 31 ++- test/unit/sanity-content.test.ts | 195 ++++++++++-------- 3 files changed, 170 insertions(+), 102 deletions(-) diff --git a/src/components/sanity-content.ts b/src/components/sanity-content.ts index 41ac1542..710fc966 100644 --- a/src/components/sanity-content.ts +++ b/src/components/sanity-content.ts @@ -199,6 +199,33 @@ function wrapMarks ( ) } +function walkList (blocks: Array, block: CustomBlock | Block | List) { + const { length } = blocks + + // Not a list item + if (!block.level) { + blocks.push(block) + return blocks + } + + const { _type, children, level } = blocks[length - 1] || {} + if (_type === 'list' && children) { + if (level === block.level) { + children.push(block) + } else { + walkList(children, block) + } + } else { + blocks.push({ + _type: 'list', + children: [block], + level: block.level, + } as List) + } + + return blocks +} + function renderBlocks ( h: CreateElement, blocks: Array, @@ -207,24 +234,7 @@ function renderBlocks ( ) { const nestedBlocks = nested ? blocks - : blocks.reduce((blocks, block) => { - const { length } = blocks - - if (block.level && length) { - const { _type, children } = blocks[length - 1] - if (_type === 'list' && children) { - children.push(block) - } else { - blocks.push({ - _type: 'list', - children: [block], - } as List) - } - } else { - blocks.push(block) - } - return blocks - }, [] as Array) + : blocks.reduce(walkList, [] as Array) return nestedBlocks.map((block) => { const node = wrapStyle( diff --git a/test/unit/__snapshots__/sanity-content.test.ts.snap b/test/unit/__snapshots__/sanity-content.test.ts.snap index d48fa949..061a6434 100644 --- a/test/unit/__snapshots__/sanity-content.test.ts.snap +++ b/test/unit/__snapshots__/sanity-content.test.ts.snap @@ -2,9 +2,11 @@ exports[`SanityContent should render exampleMarkDefs blocks 1`] = `
-
  • - Google Analytics: The Sites use Google Analytics. Further information is available at https://tools.google.com/dlpage/gaoptout/. -
  • +
    `; @@ -20,6 +22,29 @@ exports[`SanityContent should render link blocks 1`] = ` `; +exports[`SanityContent should render list blocks 1`] = ` +
    +
      +
    1. test
    2. +
    3. thing
    4. +
    +
    +`; + +exports[`SanityContent should render nestedList blocks 1`] = ` +
    +

    3. Providing your personal data to others

    +
      +
    1. test
    2. +
    3. thing
    4. +
        +
      • nested
      • +
      • list
      • +
      +
    +
    +`; + exports[`SanityContent should render with no props 1`] = `
    `; exports[`SanityContent should render with non-standard props 1`] = `
    `; diff --git a/test/unit/sanity-content.test.ts b/test/unit/sanity-content.test.ts index 97bb5508..45ce4c63 100644 --- a/test/unit/sanity-content.test.ts +++ b/test/unit/sanity-content.test.ts @@ -23,87 +23,120 @@ const exampleBlocks: Record = { markDefs: [], style: 'h3', }, - // TODO: test list length generation - // list: [ - // { - // _key: 'b1905c55df85', - // _type: 'block', - // children: [ - // { - // _key: 'b1905c55df850', - // _type: 'span', - // marks: [], - // text: '3. Providing your personal data to others', - // }, - // ], - // markDefs: [], - // style: 'h3', - // }, - // { - // _type: 'block', - // _key: 'a6cec1a2a738', - // style: 'normal', - // markDefs: [], - // children: [ - // { - // _type: 'span', - // _key: 'b39d8ec32f27', - // text: 'test', - // marks: [], - // }, - // ], - // level: 1, - // listItem: 'number', - // }, - // { - // _type: 'block', - // _key: '5917a3f6485d', - // style: 'normal', - // markDefs: [], - // children: [ - // { - // _type: 'span', - // _key: 'aaa0e0ab720a', - // text: 'thing', - // marks: [], - // }, - // ], - // level: 1, - // listItem: 'number', - // }, - // { - // _type: 'block', - // _key: 'ceaddc3e7d34', - // style: 'normal', - // markDefs: [], - // children: [ - // { - // _type: 'span', - // _key: '62d7844aaf8e', - // text: 'nested', - // marks: [], - // }, - // ], - // level: 2, - // listItem: 'number', - // }, - // { - // _type: 'block', - // _key: '415d8fb2fa1e', - // style: 'normal', - // markDefs: [], - // children: [ - // { - // _type: 'span', - // _key: 'a7705718303a', - // text: 'list', - // marks: [], - // }, - // ], - // level: 2, - // listItem: 'number', - // }, - // ], + list: [ + { + _type: 'block', + _key: 'a6cec1a2a738', + style: 'normal', + markDefs: [], + children: [ + { + _type: 'span', + _key: 'b39d8ec32f27', + text: 'test', + marks: [], + }, + ], + level: 1, + listItem: 'number', + }, + { + _type: 'block', + _key: '5917a3f6485d', + style: 'normal', + markDefs: [], + children: [ + { + _type: 'span', + _key: 'aaa0e0ab720a', + text: 'thing', + marks: [], + }, + ], + level: 1, + listItem: 'number', + }, + ], + nestedList: [ + { + _key: 'b1905c55df85', + _type: 'block', + children: [ + { + _key: 'b1905c55df850', + _type: 'span', + marks: [], + text: '3. Providing your personal data to others', + }, + ], + markDefs: [], + style: 'h3', + }, + { + _type: 'block', + _key: 'a6cec1a2a738', + style: 'normal', + markDefs: [], + children: [ + { + _type: 'span', + _key: 'b39d8ec32f27', + text: 'test', + marks: [], + }, + ], + level: 1, + listItem: 'number', + }, + { + _type: 'block', + _key: '5917a3f6485d', + style: 'normal', + markDefs: [], + children: [ + { + _type: 'span', + _key: 'aaa0e0ab720a', + text: 'thing', + marks: [], + }, + ], + level: 1, + listItem: 'number', + }, + { + _type: 'block', + _key: 'ceaddc3e7d34', + style: 'normal', + markDefs: [], + children: [ + { + _type: 'span', + _key: '62d7844aaf8e', + text: 'nested', + marks: [], + }, + ], + level: 2, + listItem: 'bullet', + }, + { + _type: 'block', + _key: '415d8fb2fa1e', + style: 'normal', + markDefs: [], + children: [ + { + _type: 'span', + _key: 'a7705718303a', + text: 'list', + marks: [], + }, + ], + level: 2, + listItem: 'bullet', + }, + ], exampleMarkDefs: { _key: '3522a2a863b9', _type: 'block',