見た目を変える
色、明暗、フォント、余白、角丸。
会社の色や情報密度は app.theme に書く。挙動は何も変わらない、見た目だけの指定。
app:
id: sales_admin
title: 販売管理
theme:
primaryColor: "#1B5E20"
secondaryColor: "#FF6F00"
brightness: light
density: compact
fontFamily: Noto Sans JP
radius: 8色は1つ書けばいい
primaryColor を種にして配色が作られる。secondaryColor は省略すれば主色から導かれるので、コーポレートカラーが1色決まっていれば書くのはそれだけ。
書き方は #RRGGBB か #AARRGGBB。色として読めない文字列を書くとパース時にエラーになる(黙って無視されると「書いたのに変わらない」で悩むことになるので、あえて落とす)。
業務画面では density: compact
| density | 行の高さ・余白 |
|---|---|
comfortable | 広い。タッチ操作が主な画面 |
standard | 既定 |
compact | 狭い。業務画面はこれ |
1画面にどれだけ情報が載るかが効率に直結するので、PC で使う業務システムなら compact から始めるのが良い。
brightness: system は端末に従う
light / dark / system の3つ。system にすると端末の設定に従う。社内システムで見た目を固定したいなら light を明示する。
ページごとには変えられない
theme は app にしか書けない。画面ごとに色を変えることはできない。「この画面だけ赤くしたい」という要求は、たいてい「危険な操作だと分からせたい」なので、テーマではなくアクションの danger: true で表現するほうが正しい。
Renderer が自分の流儀に落とす
theme は Material 固有の指定ではない。Material の Renderer なら ThemeData に、別の Renderer なら別の仕組みに翻訳される。だから書けるのは「意図」だけで、細かい見た目の作り込みはできない。
そこから先(影の付け方、特定のボタンの形)を変えたいなら、config に Renderer 固有の設定を渡すか、Renderer 側を差し替える。
theme:
primaryColor: "#1B5E20"
config: { logo: assets/logo.png }既存の Flutter アプリに混ぜるとき
自分で MaterialApp を組んでいる場合は、この theme から ThemeData を作る関数(materialThemeOf)が用意されている。定義で色を管理しつつ、アプリの組み立ては自分でやる、という使い方ができる。
書けるキー
| キー | 書く場所 | 型 | 必須 | 既定値 | 有効なページ種別 | 説明 |
|---|---|---|---|---|---|---|
theme | app | object → theme | 任意 | — | すべて | How the app looks: brand colour, brightness, density and shape. Renderer-neutral — a Material renderer maps this to a ThemeData, another renderer to its own equivalent. Nothing here changes behaviour. |
brightness | theme | string (light / dark / system) | 任意 | "light" | すべて | system follows the device setting. |
primaryColor | theme | string (#1B5E20 ほか) | 任意 | — | すべて | Brand colour as #RRGGBB (or #AARRGGBB). Used as the seed the rest of the palette is derived from. |
secondaryColor | theme | string | 任意 | — | すべて | Accent colour as #RRGGBB. Derived from the primary colour when omitted. |
fontFamily | theme | string | 任意 | — | すべて | Font family name; the renderer resolves it. |
density | theme | string (comfortable / standard / compact) | 任意 | "standard" | すべて | Row height and padding. Business screens usually want compact. |
radius | theme | number | 任意 | — | すべて | Corner radius in logical pixels. |
この表は spec/reference.json から生成している(JSON Schema が正)。手元では npx hatake reference <キー名> で同じものが引ける。
近い例
例は丸ごと写して直すのが一番速い。以下は CI で検証済み(そのまま動く形)。
| ファイル | 種別 | 画面 | どういうときに使うか |
|---|---|---|---|
sales_app.yaml | app | 販売管理 | 複数の画面をメニューで束ねて、1つのアプリにしたい。会社の色にもしたい |
よくある間違い
ページに theme を書く
なぜ駄目か 見た目はアプリ全体の性質なので app.theme にしかない。画面ごとに色が変わる業務システムは、ふつう作らない。
こう直す app: の直下に移す。1画面だけ違う見た目にしたいなら Renderer 側(Flutter なら Theme)で包む。
page:
type: search
id: order_search
title: 受注照会
repository: orderRepository
theme:
primaryColor: "#1B5E20"app:
id: sales_admin
title: 販売管理
theme:
primaryColor: "#1B5E20"
density: compact
pages:
- type: search
id: order_search
title: 受注照会
repository: orderRepositoryspec/pitfalls.json から生成。各項目は CI で検証済み(間違いは本当に落ち、正しい方は本当に通る)。手元では npx hatake pitfalls <キー名>。