rdunk / sanity-blocks-vue-component

[DEPRECATED] Vue component for rendering block content from Sanity
MIT License
71 stars 10 forks source link

Provide an example for marks serializer #30

Open marekbrze opened 2 years ago

marekbrze commented 2 years ago

I think that documentation regarding marks needs to be updated or an example of the correct marks serializer usage should be provided. Right now it's not clear how exactly you should define and access marks props. It's really hard to find a correct answer anywhere in the web.

Current readme.md section:

When using custom Vue components as mark serializers, all properties of the block object will be passed via v-bind. To access the data, define the corresponding props in your component. You can use slots (e.g. this.$slots.default) to access the mark text or content.

eltorio commented 2 years ago

Hi @marekbrze , This is my serializer for Vuejs3, I added a mark highlight… Full code in my repo: https://github.com/eltorio/vue-highcanfly/blob/dev/src/components/Cards/CardSinglePost.vue This is ugly but it works

const postSerializers = {
  types: {
    image: defineComponent({
      props: ["asset"],
      setup(props) {
        return () => h("img", { src: props.asset.url, class: "inline" });
      },
    }),
  },
  marks: {
    mark: (props, children) => {
      //eslint-disable-line no-unused-vars
      return h("mark", children[0]);
    },
  },
  styles: {
    blockquote: (props,children) => {//eslint-disable-line no-unused-vars
      return h("blockquote", {}, children.slots.default()[0].children);
    },
  },
};

And my blockContent.js

/**
 * This is the schema definition for the rich text fields used for
 * for this blog studio. When you import it in schemas.js it can be
 * reused in other parts of the studio with:
 *  {
 *    name: 'someName',
 *    title: 'Some title',
 *    type: 'blockContent'
 *  }
 */
 import React from 'react';

 const markIcon = () => (
  <span style={{fontWeight: 'bold'}}>M</span>
  )
  const markRender = props => (
    <mark>{props.children}</mark>
  )

export default {
  title: 'Block Content',
  name: 'blockContent',
  type: 'array',
  of: [
    {
      title: 'Block',
      type: 'block',
      // Styles let you set what your user can mark up blocks with. These
      // correspond with HTML tags, but you can set any title or value
      // you want and decide how you want to deal with it where you want to
      // use your content.
      styles: [
        {title: 'Normal', value: 'normal'},
        {title: 'H1', value: 'h1'},
        {title: 'H2', value: 'h2'},
        {title: 'H3', value: 'h3'},
        {title: 'H4', value: 'h4'},
        {title: 'H5', value: 'h5'},
        {title: 'H6', value: 'h6'},
        {title: 'Quote', value: 'blockquote'},
      ],
      lists: [
        {title: 'Bullet', value: 'bullet'}
      ],
      // Marks let you mark up inline text in the block editor.
      marks: {
        // Decorators usually describe a single property – e.g. a typographic
        // preference or highlighting by editors.
        decorators: [
          {title: 'Strong', value: 'strong'},
          {title: 'Emphasis', value: 'em'},
          {title: 'Mark', value: 'mark', blockEditor: {
            icon: markIcon,
            render: markRender,
          } }
        ],
        // Annotations can be any object structure – e.g. a link or a footnote.
        annotations: [
          {
            title: 'URL',
            name: 'link',
            type: 'object',
            fields: [
              {
                title: 'URL',
                name: 'href',
                type: 'url',
              },
            ],
          },
        ],
      },
    },
    // You can add additional types here. Note that you can't use
    // primitive types such as 'string' and 'number' in the same array
    // as a block type.
    {
      type: 'image',
      options: {hotspot: true},
    },
  ],
}