sanity-io / block-content-to-react

Deprecated in favor of @portabletext/react
https://github.com/portabletext/react-portabletext
MIT License
161 stars 25 forks source link

How to serialize list in block #33

Closed ghoshanjega closed 2 years ago

ghoshanjega commented 4 years ago

I cannot seem to figure out how to serialize for lists in block

Example ul block as _rawBody. image

This is my serializer.

const serializer = {
    types: {

      image: props => (
        <figure className="has-text-centered">
          <img
            src={urlFor(props.node.asset)
              .width(600)
              .url()}
            alt={props.node.alt}
            style={{ borderRadius: "5px" }}

          />

          <figcaption>{props.node.caption}</figcaption>
        </figure>
      ),
      block(props) {
        switch (props.node.style) {
          case 'h1':
            return <h1 className="">{props.children}</h1>

          case 'h2':
            return <h2 className="">{props.children}</h2>

          case 'h3':
            return <h3 className="">{props.children}</h3>

          case 'h4':
            return <h4 className="">{props.children}</h4>
          case 'li':
            return <h4 className="">{props.children}</h4>

          case 'blockquote':
            return <blockquote className="">{props.children}</blockquote>
          case 'normal':
            if (props.listItem) return <strong>{props.children}</strong>
            else return <p className="is-family-secondary is-size-5">{props.children}</p>
          default:
            return <p className="is-family-secondary">{props.children}</p>
        }
      }
    }
  };
hemantparashar commented 4 years ago

@ghoshanjega I was facing the same issue. After spending some time found out that the list and listItem overrides are supposed to be on the same level with types not nested inside it like this :

const serializer = {

  // use the list and listItem outside the types
  list: props => <div>{props.children}</div>,
  listItem: props => <strong>{props.children}</strong>,

  types: {
    image: props => (
      <figure className="has-text-centered">
        <img
          src={urlFor(props.node.asset).width(600).url()}
          alt={props.node.alt}
          style={{ borderRadius: "5px" }}
        />

        <figcaption>{props.node.caption}</figcaption>
      </figure>
    ),
    block(props) {
      switch (props.node.style) {
        case "h1":
          return <h1 className="">{props.children}</h1>

        case "h2":
          return <h2 className="">{props.children}</h2>

        case "h3":
          return <h3 className="">{props.children}</h3>

        case "h4":
          return <h4 className="">{props.children}</h4>
        case "li":
          return <h4 className="">{props.children}</h4>

        case "blockquote":
          return <blockquote className="">{props.children}</blockquote>

        case "normal":
          return  <p className="is-family-secondary is-size-5">{props.children}</p>

        default:
          return <p className="is-family-secondary">{props.children}</p>
      }
    },
  },
}
krisrobinson commented 4 years ago

Thanks for this. I also wanted to distinguish between ordered and unordered lists, this is how I did it, maybe it can be improved:

list: (props) => {
    const { type } = props;
    const bullet = type === 'bullet';
    if (bullet) {
      return <ul>{props.children}</ul>;
    }
    return <ol>{props.children}</ol>;
  },
listItem: (props) => <li>{props.children}</li>
logemann commented 3 years ago

Thanks for the reply regarding "list" and "listItem". Faced the same question. Searched for this in the docs to no avail. Would be nice to mention this somewhere because i think most of us try to style it in the block type..... :-)

rexxars commented 2 years ago

Thanks for raising this! We've improved the API of list/listItem overrides in the new @portabletext/react module - hopefully it should be easier to customize.