PhotoshopUXPのUIデザインについて
CEPの時はアプリケーションと合わせるためのデザインのためにtopcoatによるCSSがあったりアプリケーションの カラーと合わせるためのイベント、カラーもthemeManagerというメソッドがVsCodeのプラグインで生成されるテンプレートに デフォルトでありました。勿論UXPもこの辺のUI関係のシステムは揃っています。
Spectrum
UXPからSpectrumというAdobe独自のデザインシステムが標準で実装されています。これはUXP以外でも一般的に公開されていてReact,CSS,WebComponentsでも使えるようになっています。UXPに関しては最初からこういったシステムが埋め込まれているのです。(ただし仕様がやや異なったりする) いろんなパーツ類が揃っているので一から自分でフォームのカスタマイズなどしなくてもこれで統一感のあるUIが作れるというわけです。 色々こだわってゼロからデザインを構築したいという場合なまだしもある程度は既存のパーツを使いたい場合などはこういったパーツを使う方が 時間も節約できるでしょう。
使い方
公式サイトでも触れられていますがSpectrum UXP自体最初からUXPのシステムに埋め込まれているのでHTMLに該当のSpectrumパーツを記述するだけで そのまま使えます。細かい各パーツの仕様などは公式から参照できます。例えばsp-buttonならprimary、warningなどの属性の値を variantの属性に渡せてボタンの見た目を変えることができます。公式参照。しかしこのSpectrumのパーツの中身はいったいどうなっているのでしょうか?
WebComponentsとは
Spectrum UXPはWebComponentsと呼ばれるコンポーネントシステムをベースに作られています。これはJS上でコンポーネントの仕様を 定義してHTML上で使えるようになる代物なのです。ReactやVueのように特定のモジュールに依存したものではなくれっきとしたVanilla.jsで動く 標準のAPIです。詳細はMDNにありますが簡単に解説するとこれはclass構文を使用して独自のHTML要素が作成できます。
上記のコードですがHTML上のsimple-elmという要素がSpectrum UXPの実装とそっくりな感じでHTML上に配置されています。 WebComponentsは命名に当たりダッシュ文字(-)を使う必要があるみたいです。実際Adobe SpectrumおよびSpectrum UXPでも使われています。 (sp-button)これがWebComponentsです。実装時に専用の属性などを取得するようにすればテキスト文字の大きさ、色のような要素をユーザーに簡単にカスタムさせることができるようにすることも可能です。
ShadowDOM
しかしカスタムコンポーネントの中身を外部から切り離して複雑な要素から成り立ったカスタム要素自体一つの要素として扱いたい場合もあるでしょう。 その場合ShadowDOMを仕様してコンポーネントの中身に要素を隠してしますこともできます。
これで外部と切り離された状態でShadowRoot下にカスタム要素を加えました。shadowRootは通常JSからアクセスもできます。 しかし上記コードですがWebComponent作成時にmode: openをセットしているのがわかるでしょう。 open以外にもclosedというモードもありますこれをセットするとshadowRoot以下の要素は取得できずnullになります。 MDNでも解説されていますがclosedモードの場合基本は外からのアクセスはできません。
そしてSpectrum UXP
それでここからが本題のSpectrum UXPです。 上で触れた通りにWebComponentは複雑な要素の塊をまるで一つの要素のように扱うことができます。実装の際は特別な環境設定など必要無く、最初からUXPにのシステムに埋め込まれているので そのまま使うことができます。 Spectrum UXPでもそうなのですが公式ページでカスタム可能な属性なども基本は触れられています。 しかし中身はどうなっているのかというと実際調べたところほとんどのSpectrumのほとんどclosedモードとして実装されているのでshadowRoot以下の要素の仕様を確認できませんでした。 なので実際仕様がわからず問題が出てきた場合手探りで解決するくらいしか方法がなかったりします。 詳細は公式のドキュメントを参照。以下はaction buttonの実装例です。CSSは一切使ってません。
ちなみに公式より今後後述のSpectrum Web Componentへ以降するためSpectrum UXPの更新頻度は格段に下がると予告されています。
Web Spectrum Component
最初に触れた通りSpectrumというデザインシステム自体はUXP専用のシステムではなく一般的に公開されています。 このコンポーネントシステムのWeb Components版はSpectrum Web Component(通称SWC)と呼ばれUXPで使えるSpectrum UXPとは別物(紛らわしい)で公式サイトを見てもわかる通り 使えるコンポーネントの数がSpectrum UXPと比較にならないくらい多いです。UXP7.2よりこのSWCのサポートが始まっています。 現状使える種類がある程度限られていますがこれがさらに使えるようになれば今後Spectrum UXPよりも飛躍的に使えるコンポーネントの数が増えます。 尚、UXPにおけるSWCに関する詳細は公式ドキュメントを参照してください。ただ使用にあたって仕様がやや複雑なので以下実装の方法を載せます。
実装に必要な技術
実装にあたってwebpackとyarnが必要になります。yarnでなくてもnpmでもできるとは思いますが公式のサンプルがyarnを使っているのでyarnを使います。
対応バージョンと対応コンポーネントの確認
UXPですが最新のブラウザ環境とは異なるのでSWCのすべての最新のコンポーネントが使えるわけではありません。 まずは公式のドキュメントより対応のコンポーネントとバージョンを確認しましょう。例えばAction-Barなら0.5.9バージョン、その他Fixedのオプションに対応しています。 ただしインストールですが例えばsp-action-barのSWCのページでは@spectrum-web-components/action-barのパッケージのインストールを提示していますがUXPの場合これをそのまま使うことができません。 代わりにwrapperのパッケージをインストールします。例えばAction-Barなら以下のようになります。
spectrum-web-componentsの部分がそのままswc-uxp-wrappersに置き換わっています。その他パッケージも同様です。 しかしインストール前に依存パッケージのバージョン管理もしなければなりません。というわけで実際のパッケージのインストール前にバージョン管理をします。
resolutionsの部分が依存パッケージの管理にあたります。(npmだとoverridesがそれにあたるとは思いますが動作は確認していません) swc-uxp-wrappersの各種パッケージはUXP用にwrapperされたパッケージにすぎず、 おそらくコアの部分はspectrum-web-componentsのパッケージに依存しているのでしょう。 そのためこの依存パッケージ部分に関しては公式で言及されている通りの対応バージョンのパッケージをインストールしなければなりません。そこでこのresolutionsの部分にspectrum-web-componentsのパッケージの対応バージョンを書き込むとインストール時にresolutionsに沿ったバージョンがインストールされるようです。 詳しくはyarn公式サイトを参照。但しSWCの中でもicons, icons-workflow, icons-ui, theme, shared, base, stylesのコンポーネントはwrapperは必要ありません。 spectrum-web-componentsのパッケージを直接インストールしてください。 ともかくここまで用意してやっとSWCパッケージをインストールできます。
その他必要なパッケージ
webpackを使っていますのでwebpack, webpack-cli とインストールしています。 cssを読み込むためのcss-loaderと新しいCSSを古いUXPのシステム読み込めるようにpostcss-loaderももしかしたら必要かもしれません。(サンプルプラグインでは使用しているので私もインストールしました。) 以下必ず必要なパッケージです。
- webpack
- webpack-cli
- css-loader
- postcss-loader(多分)
- mini-css-extract-plugin CSSをバンドルしないで別途出力するためのパッケージ。おそらく必要。
- @spectrum-web-components/theme
- @swc-uxp-wrappers/utils
ここまで用意できました。manifest.jsonに以下の項目を追加してください。
webpack.configファイルの作成
ここまでやってもまだ実際のコーディングではありません。ここからwebpackの設定ファイルを作らなければなりません。 今回本番環境と開発環境で実行コードを分けたかったので三つのファイルに分けましたがサンプルプラグインでは一つのファイルにすべてまとめているのでお好きな方法で作成してください。
ここで重要なのが@swc-uxp-wrappers/utilsのaliasesです。これはこれからimportするSWCのコンポーネントのパスの問題を解決してくれるものでしょう。その他サンプルプラグインに倣ってCopyFilePluginでmanifest.jsonとindex.htmlを更新の度にコピーしてpluginフォルダーにまとめています。targetはおそらくwebが好ましいでしょう。externalsでUXPで扱うモジュール類を宣言してエラーが起きないようにしています。ここまでできたらやっと実際のコーディングに移れます。
コンポーネントをimportする
最後にSWCのベースとなるパッケージと必要なコンポーネントをJavaScript上で読み込みます。以下のようにimportするとWebComponentsが登録されてHTML上のSWCが表示されるようになります。
Spectrum、Componentのまとめ
この時点でコンポーネントとかSpectrumとか似たような名前が出て混乱すると思うので以下これまでの用語、種類をまとめます。
- Adobeのデザインシステム、Spectrum design systemがSpectrum
- UXPのみで使えるSpectrum UXP
- UXP以外でもブラウザなどでも使えるWeb Components SpectrumシステムSpectrum Web Components, SWC
- Reactで使える一般のweb向けのSpectrumシステムReact Spectrum
- CSS上で構築された一般のweb向けのSpectrumシステムSpectrum CSS
- Vanilla jsで使えるフレームワークに依存しないブラウザ上で構築できるコンポーネントシステムWeb Components
- Reactのコンポーネントは上記の物とは完全に別物のコンポーネントシステム。
UIカラー
Photoshopも含めてAdobeのアプリケーションのUIはライト、ダークといったUIのカラーを環境設定より選べます。CEPの時はこのUIカラーに合わせた パネルの色の変更できましたがUXPでも勿論できます。UXPではCSS変数が最初から埋め込まれているのでこれを使用してUIに合わせたカラーを実装できます。 この変数に合わせてUIを構築すればテキストが背景に溶けて見えないということもありません。ただしバグがあるので変化の際に妙な挙動を起こす可能性がありますので気をつけて使用してください。公式ドキュメントでも触れらていますが カラー以外にもフォントサイズも用意されています。以下、実際に使ったサンプルです。
JSでもUIカラーの変化を感知したい。
通常のイベントと同じく以下のようなコードで環境設定によるUIの変化を感知できます。
また、UIカラーの明るさを取得したい場合はbatchPlayで取得できます。
ちなみにSpectrum UXPのパーツはデフォルトでUIカラーの変化に対応しています。Spectrum Web Component(SWC)のパーツは通常そのままだとUIカラーに合わせて変化しません。 実際にUIのカラーに合わせて変化するイベントを自分で設定する必要があります。sp-themeのcolorにUIカラーを設定するとパーツを以下一括で簡単に変化させることができるでしょう。
参考サイト
- UXP 公式ドキュメント
- MDN Web Components
- Adobe Spectrum
- Spectrum web Componentsバージョン対応表など
- Photoshop サンプルプラグイン
- InDesign サンプルプラグイン