🐥

microCMS × Next.jsのブログでリッチエディタからリストの背景を指定する

2021/12/24に公開

やりたいこと

microCMSのリッチエディタからリストのスタイルを指定することを目指しました。例えば、画像のように背景が水色やグレーなどを自由に切り替えます。

繰り返しフィールドを使ってリストスタイルの情報をもたせる方法もありましたが、繰り返しフィールドを作るのが面倒なのと管理画面の文章が分断されるのが辛いので採用しませんでした。
https://zenn.dev/kmdisk/articles/microcms-custom-editor

方針

リストの一番最初にスタイルのテキストデータを記述し、そのデータをもとにパーサで変換する方法を取りました。これならテキストの記述だけで簡単にリストのスタイルを指定できます。

管理画面

コード

html-react-parserというパーサでコンポーネントに変換します。
https://www.npmjs.com/package/html-react-parser

ブログカードを作る際にも使ったので、具体的な使い方は以下の記事を見ると参考になるかと思います。
https://zenn.dev/hirokikameda/articles/2ecf83446eec8f

export default function BlogContents({ contents, cardDatas }) {
  const replace = (node) => {
    //ulタグで最初の要素に"//bg-blue"があったらblueの情報を持ったコンポーネントを返す
    if (
      node.name === "ul" &&
      node.children[0].children[0].data === "//bg-blue"
    ) {
      //liタグの最初の要素を削除
      node.children.shift();
      return (
        <ListBlogContents bgcolor="blue">
          {domToReact(node.children)}
        </ListBlogContents>
      );
    } else if ( //ulタグで最初の要素に"//bg-gray"があったらgrayの情報を持ったコンポーネントを返す
      node.name === "ul" &&
      node.children[0].children[0].data === "//bg-gray"
    ) {
      node.children.shift();
      return (
        <ListBlogContents bgcolor="gray">
          {domToReact(node.children)}
        </ListBlogContents>
      );
    }
    return null;
  };

  return (
    <div className={styles.postContents}>{parse(contents, { replace })}</div>
  );
}

コンポーネント側参考(MUI使用)

ListBlogContents.tsx
import React from "react";
import { styled } from "@mui/system";
import { Box, BoxProps } from "@mui/material";

type ListProps = {
  bgcolor: "blue" | "gray" | "yellow";
} & BoxProps;

const handleColorType = (bgcolor) => {
  switch (bgcolor) {
    case "blue":
      return "#E8F8FF";
    case "gray":
      return "#F6F6F6";
    case "yellow":
      return "#FFFBDC";
  }
};

const List = styled(Box)<ListProps>(({ theme, bgcolor }) => ({
  paddingLeft: "2.5em !important",
  backgroundColor: handleColorType(bgcolor),
  paddingTop: "1.5em",
  paddingBottom: "1.5em",
  borderRadius: "12px",
  paddingRight: "2em",
  [theme.breakpoints.up("md")]: {
    paddingLeft: "3em !important",
    borderRadius: "16px",  paddingTop: "1em",
    paddingBottom: "1em",
  },
}));

export default function ListBlogContents({ bgcolor, children }) {
  return (
    <List bgcolor={bgcolor} component="ul">
      {children}
    </List>
  );
}

注意点としては、判定に使っているテキストは通常使わないようなテキストが望ましいです。単にblueとかgrayだと通常のテキストと被る可能性があります。

まとめ

リッチエディタからでも柔軟にスタイルを指定できるようになりました。色々他にも使えそうなので、欲しいコンポーネントがあれば作って行きたいと思います。

Discussion