はじめに

このドキュメントでは、Orizmデザインエディターを使用してコンポーネントを定義し、エディターを表示する方法、さらにWebサイト側でのコンポーネント実装やプレビュー機能の設定方法を説明します。以下の手順に従うことで、デザインエディターを活用した効率的な開発が可能になります。

コンポーネントの定義

デザインエディターで使用するコンポーネントの名前やプロパティを定義します。この定義に基づき、エディターの編集UIが生成され、Webサイト側でコンポーネントの状態が認識されます。

以下は、Buttonコンポーネントを定義する例です。このコンポーネントには、以下の4つのプロパティがあります。

  • text: ボタンのテキスト
  • href: リンク先URL
  • variant: デザインの種類
  • size: サイズ
import * as orizm from "@orizm-private/orizm-editor/schema";
 
export const componentSchema = orizm.defineComponentSchema({
  Button: orizm.component({
    displayName: "ボタン",
    category: "アイテム",
    props: orizm.props({
      text: orizm.string({
        displayName: "テキスト",
        default: "ボタン",
      }),
      href: orizm.string({
        displayName: "リンク先URL",
        default: "https://www.google.com",
      }),
      variant: orizm.picklist({
        displayName: "デザイン",
        options: {
          default: { displayName: "デフォルト" },
          secondary: { displayName: "セカンダリ" },
          black: { displayName: "黒" },
          white: { displayName: "白" },
        },
        default: "default",
      }),
      size: orizm.picklist({
        displayName: "サイズ",
        options: {
          sm: { displayName: "小" },
          md: { displayName: "中" },
          lg: { displayName: "大" },
        },
        default: "md",
      }),
    }),
  }),
});

複数のコンポーネントを定義する場合は、orizm.defineComponentSchema関数に渡すorizm.componentを増やしてください。必要に応じてコンポーネントを追加します。

エディターの表示

デザインエディターをCMSで表示するには、OrizmEditorComposerOrizmEditorを使用します。

以下は、エディターを表示するReactコンポーネントの例です。

import "@orizm-private/orizm-editor/editor.css";
import { Block } from "@orizm-private/orizm-editor/common";
import {
  OrizmEditor,
  OrizmEditorComposer,
} from "@orizm-private/orizm-editor/editor";
import { componentSchema } from "@repo/design-editor/component-schema";
import { useState } from "react";
import { ImageUpload } from "../image-upload";
 
export const StaticPageEditor: React.FC = () => {
  const [blocks, setBlocks] = useState<Block[]>([]);
 
  return (
    <OrizmEditorComposer
      componentSchema={componentSchema}
      initialBlocks={blocks}
      onChange={setBlocks}
      pageSlug="/my-page"
      pageTitle="My Page"
      previewSiteURL="http://localhost:3001"
      customPropEditors={{
        Image: {
          image: ImageUpload,
        },
      }}
    >
      <OrizmEditor />
    </OrizmEditorComposer>
  );
};

主なプロパティ

  • componentSchema: 定義したコンポーネントスキーマを指定します。
  • initialBlocks: 初期状態のブロックを指定します。
  • onChange: ブロックが変更された際に呼び出されるコールバック関数です。
  • previewSiteURL: プレビュー用のWebサイトURLを指定します。
  • customPropEditors: 独自の編集UIをReactコンポーネントとして指定します。

これにより、エディターで編集したデータをblocksステートに反映させ、データベースなどに保存できます。

Webサイト側でのコンポーネント実装

定義したスキーマに基づき、Webサイト側でコンポーネントを実装します。以下は、Buttonコンポーネントの実装例です。

import {
  ComponentMarker,
  type ComponentRenderers,
} from "@orizm-private/orizm-editor/renderer";
import { buttonVariants } from "@repo/ui";
import Link from "next/link";
import { cn } from "../../../ui/src/lib/utils";
import type { componentSchema } from "../component-schema";
 
type ButtonFC = ComponentRenderers<typeof componentSchema>["Button"];
 
export const Button: ButtonFC = ({
  text,
  href = "#",
  variant,
  size,
  width,
  marginTop,
  marginBottom,
  isThumbnail,
}) => {
  return (
    <ComponentMarker>
      <Link
        href={href}
        data-orizm-text-property="text"
        className={cn(
          buttonVariants({
            variant,
            size,
            marginTop,
            marginBottom,
          }),
          width && "w-full",
        )}
      >
        {isThumbnail ? "プレビュー中" : text}
      </Link>
    </ComponentMarker>
  );
};

実装のポイント

  • ComponentMarkerをルートに設置することで、エディターがコンポーネントを認識します。
  • スキーマで定義したプロパティがReactコンポーネントのpropsとして渡されます。
  • isThumbnailはサムネイル撮影中かどうかを示す予約済みのpropsです。

本番用ページの表示

本番用ページでは、PageRendererを使用してコンテンツデータを表示します。

import { Block } from "@orizm-private/orizm-editor/common";
import { PageRenderer } from "@orizm-private/orizm-editor/renderer";
import { componentSchema } from "../component-schema";
import { components } from "../components";
 
const Page: React.FC = async () => {
  const blocks: Block[] = await fetchBlocksFromCMS();
 
  return (
    <PageRenderer
      blocks={blocks}
      components={components}
      componentSchema={componentSchema}
    />
  );
};
 
export default Page;

必要なプロパティ

  • blocks: CMSから取得したコンテンツデータ。
  • components: 実装したコンポーネントのオブジェクト。
  • componentSchema: 定義したスキーマ。

プレビュー用ページの表示

エディターからiframe経由で表示するプレビュー用ページを実装します。

"use client";
 
import { PreviewRenderer } from "@orizm-private/orizm-editor/preview";
import { componentSchema } from "./component-schema";
import { components } from "./components";
import { PageRenderer } from "@orizm-private/orizm-editor/renderer";
 
const Page: React.FC = () => {
  return (
    <PreviewRenderer
      initialBlocks={[]}
      componentSchema={componentSchema}
      editorOrigin={
        process.env.NODE_ENV === "development"
          ? "http://localhost:3000"
          : "https://design-editor-demo-cms.vercel.app"
      }
      renderPage={(blocks, isThumbnail) => (
        <PageRenderer
          blocks={blocks}
          components={components}
          componentSchema={componentSchema}
          isThumbnail={isThumbnail}
        />
      )}
    />
  );
};
 
export default Page;

実装のポイント

  • PreviewRendererはエディターから受信したステートをPageRendererに渡します。
  • editorOriginにはエディターが動作するURLを指定します。
  • 初期状態のステートがある場合はinitialBlocksに渡します。

起動方法

  1. CMS側とWebサイト側の開発サーバーを起動します。
  2. CMS側のエディターを開き、Webページを編集します。