日々の学びとか気づきについて書く

キャリアは日々のアウトプットの組み合わせ

ShopifyのPolarisによる Data Table Componentとスタイル編集法

はじめに

この記事はShpoifyの公式サイトにより提供されているNodeやReactでShopify アプリを構築するを完遂した方を対象としています。

まだ手をつけたことがない方は、まずそちらから目を通していただければと思います。

開発はNext×TypeScriptで行います。

TypeScriptのセットアップはこちらを参照してください。

UIコンポーネントとは

ReactやVue、Angularといったフロントエンドライブラリ(フレームワーク)が流行する以前は、開発者がなるべく早くそれなりのUIを実現するためにCSSフレームワーク(Bootstrapなど)が広く使われてきました。

昨今のようにフロントエンドにライブラリを導入する場面が多くなると、ライブラリ向けにサクッとそれなりのUIを実現するコンポーネントセットが出てきました。

コンポーネントセットから呼び出し、コードの中に読み込む事で使用するコンポーネントをUIコンポーネントと呼びます。

コンポーネントは部品といった意味のある英単語です。

WEBアプリケーションにおけるUIを実現する部品としてはボタンやフォームがすぐに思い浮かびます。

UIコンポーネントはいい感じのボタンをサクッと作るために使用できます。

Shopifyが提供しているコンポーネントセットはPolarisです。

これは開発者がアプリを開発するときに、Shopifyの管理画面と似たようなUIを実現するためのコンポーネントセットです。

Polarisを使用することで、アプリのユーザは管理画面との違和感が少ないUIを利用でき、開発者の工数も減らすことができるようになります。

Polarisのインストール

早速ShopifyアプリのプロジェクトにPolarisを導入してみましょう。

Polarisを使うには2つの方法があります。

  1. React のUI Componentとして使う
  2. CSSを読み込んで使う

今回は1に関して説明していきます。

まずは公式にしたがってパッケージをインストールします。

npmを使ってのインストールです。

npm install @shopify/polaris --save

yarnを使っている方はこちらのコマンドでインストールできます。

yarn add @shopify/polaris

これでインストールは完了です。 Polarisをプロジェクトで使用可能になりました!

Table Component を使ってみる

早速Polarisを使ってShopifyライクなUIを実装しましょう。 今回は Data Table Component を使ってみます。

ドキュメントに掲載されているサンプルコードを少しいじってみます。

index.tsx

import jaTranslations from '@shopify/polaris/locales/ja.json';
import '@shopify/polaris/dist/styles.css';
import { AppProvider, Card, DataTable, Page } from '@shopify/polaris';
import React from 'react';

const Index: React.FC = () => {
  const rows = [
    ['モニター', 13000, 140],
    ['キーボード', 15000, 183],
    ['マウス', 5000, 32],
  ];
  return (
    <AppProvider i18n={jaTranslations}>
      <Page>
        <Card>
          <DataTable
            columnContentTypes={[
              'text',
              'numeric',
              'numeric',
            ]}
            headings={[
              '商品名',
              '価格',
              '在庫数',
            ]}
            rows={rows}
          />
        </Card>
      </Page>
    </AppProvider>
  );
}

export default Index;

Polaris Data Table Example シンプルなコードでShopifyライクなUIを実装できましたね。

Polarisコンポーネントを使っても上手くスタイルが反映されない場合があります。 その場合は以下のコードが入っているか確認をしてください。

import '@shopify/polaris/dist/styles.css';

これをアプリケーションのルートに書いておけばどのファイルからでも Polaris コンポーネントが使えるようになります。

Data Table Component を使うためにはcolumnContentTypes headings rowsの3つの値が必須です。 ドキュメントを参照しながら3つの値について説明します。

columnContentTypes ("text" | "numeric")[] List of data types, which determines content alignment for each column. Data types are "text," which aligns left, or "numeric," which aligns right.

このプロパティにはテーブルのカラムのタイプを指定します。指定できる値の型はtext numericの2種類で、textを指定したカラム名は左揃えになり、numericを指定したカラムは右揃えになります。

先程のコードだと商品名にはtextを指定し、それ以外のカラムにはnumericを指定しました。それぞれのカラム名の位置に注目し、違いを確認してみてください。

headings React.ReactNode[] List of column headings.

このプロパティではカラム名をできます。型はReact.ReactNodeとなっておりあまり聞き馴染みがないかもしれません。この型は@types/reactの中で定義されており、その内容はこちらです。

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;

ReactNodeはunion型であることがわかります。また聞き馴染みのない型がたくさん出てきましたが、ReactChildを押さえておけば問題ありません。

type ReactText = string | number;
type ReactChild = ReactElement | ReactText;

この型も同様に@types/react内で定義されています。また合わせてReactTextも確認しておきましょう。ここまでみると、文字列と数値を許可していることがわかりますね。 先程のコードのように文字列でカラム名を指定できることがわかりました。

rows ((string | number | React.ReactNode)) Lists of data points which map to table body rows.

最後のプロパティです。ここにもReactNodeの型が出てきました。このプロパティでは二次元配列を指定しなければいけません。

これらを押さえておけば、Data Table Component を使用できます。

スタイルを編集してみる

最後に Data Table Component のスタイルを変更する方法を紹介します。 その前に現在のアプリの画面を再度確認してみましょう。

Polaris Data Table Example

何とも味気ない画面です。

工夫を加えるために在庫数が50以下の商品は赤文字で在庫数を表示させるようにしてみましょう。

ここで先程学習したrowsに指定できる型が活きてきます。

stringnumberではスタイルを加えることができません。そこでReactNodeを上手く使ってスタイルを埋め込んでいきます。

ReactNodeにはReactChildが指定でき、ReactChildにはReactElementが指定できると学びました。 この記事ではReactElementを明示できてに作成し、スタイルを埋め込んでいきます。

具体的には以下の関数を追加します。

  const createElement = (stock: number): number | ReactElement => {

    if (stock > 50) {
      return stock;
    } else {
      const style: React.CSSProperties = { color: 'red' };
      return React.createElement('span', { style }, stock);
    }
  }

React.createElementReactElement型のオブジェクトを返す関数です。DOMと思ってもらうとわかりやすいと思います。

第一引数にはHTML要素名、第二引数にオプション(省略可能)、第三引数に表示する文字列を入力します。

オプションではスタイルを指定できるので、スタイルを指定する変数を一つ作り、オプションとして渡しています。 CSSでの定義と同じように使えます。

この関数とrowsを組み合わせるとこのようになります。

  const rows = [
    ['モニター', 13000, createElement(140)],
    ['キーボード', 15000, createElement(183)],
    ['マウス', 5000, createElement(32)],
  ];

これで各配列の第三要素にはnumberもしくはReactElementが入るようになりました。 画面を確認してみましょう。

在庫数が32の項目だけ赤文字で表示されていますね。 最終的なコードは以下のようになりました。

import jaTranslations from '@shopify/polaris/locales/ja.json';
import '@shopify/polaris/dist/styles.css';
import { AppProvider, Card, DataTable, Page } from '@shopify/polaris';
import React, { ReactElement } from 'react';

const Index: React.FC = () => {
  const createElement = (stock: number): number | ReactElement => {

    if (stock > 50) {
      return stock;
    } else {
      const style: React.CSSProperties = { color: 'red' };
      return React.createElement('span', { style }, stock);
    }
  }

  const rows = [
    ['モニター', 13000, createElement(140)],
    ['キーボード', 15000, createElement(183)],
    ['マウス', 5000, createElement(32)],
  ];

  return (
    <AppProvider i18n={jaTranslations}>
      <Page>
        <Card>
          <DataTable
            columnContentTypes={[
              'text',
              'numeric',
              'numeric',
            ]}
            headings={[
              '商品名',
              '価格',
              '在庫数',
            ]}
            rows={rows}
          />
        </Card>
      </Page>
    </AppProvider>
  );
}

export default Index;

今回は Data Table Component を使いましたが、他のコンポーネントReactNodeが指定できるプロパティにも同様のことが行えると思います。 ぜひ参考にしてください。