はじめに
この記事は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つの方法があります。
- React のUI Componentとして使う
- 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;
シンプルなコードで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 のスタイルを変更する方法を紹介します。 その前に現在のアプリの画面を再度確認してみましょう。
何とも味気ない画面です。
工夫を加えるために在庫数が50以下の商品は赤文字で在庫数を表示させるようにしてみましょう。
ここで先程学習したrows
に指定できる型が活きてきます。
string
やnumber
ではスタイルを加えることができません。そこで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.createElement
はReactElement
型のオブジェクトを返す関数です。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
が指定できるプロパティにも同様のことが行えると思います。
ぜひ参考にしてください。