Skip to content

見た目を変える

色、明暗、フォント、余白、角丸。

会社の色や情報密度は app.theme に書く。挙動は何も変わらない、見た目だけの指定。

yaml
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 を明示する。

ページごとには変えられない

themeapp にしか書けない。画面ごとに色を変えることはできない。「この画面だけ赤くしたい」という要求は、たいてい「危険な操作だと分からせたい」なので、テーマではなくアクションの danger: true で表現するほうが正しい。

Renderer が自分の流儀に落とす

theme は Material 固有の指定ではない。Material の Renderer なら ThemeData に、別の Renderer なら別の仕組みに翻訳される。だから書けるのは「意図」だけで、細かい見た目の作り込みはできない。

そこから先(影の付け方、特定のボタンの形)を変えたいなら、config に Renderer 固有の設定を渡すか、Renderer 側を差し替える。

yaml
theme:
  primaryColor: "#1B5E20"
  config: { logo: assets/logo.png }

既存の Flutter アプリに混ぜるとき

自分で MaterialApp を組んでいる場合は、この theme から ThemeData を作る関数(materialThemeOf)が用意されている。定義で色を管理しつつ、アプリの組み立ては自分でやる、という使い方ができる。

書けるキー

キー書く場所必須既定値有効なページ種別説明
themeappobjecttheme任意すべて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.
brightnessthemestringlight / dark / system任意"light"すべてsystem follows the device setting.
primaryColorthemestring#1B5E20 ほか)任意すべてBrand colour as #RRGGBB (or #AARRGGBB). Used as the seed the rest of the palette is derived from.
secondaryColorthemestring任意すべてAccent colour as #RRGGBB. Derived from the primary colour when omitted.
fontFamilythemestring任意すべてFont family name; the renderer resolves it.
densitythemestringcomfortable / standard / compact任意"standard"すべてRow height and padding. Business screens usually want compact.
radiusthemenumber任意すべてCorner radius in logical pixels.

この表は spec/reference.json から生成している(JSON Schema が正)。手元では npx hatake reference <キー名> で同じものが引ける。

近い例

例は丸ごと写して直すのが一番速い。以下は CI で検証済み(そのまま動く形)。

ファイル種別画面どういうときに使うか
sales_app.yamlapp販売管理複数の画面をメニューで束ねて、1つのアプリにしたい。会社の色にもしたい

よくある間違い

ページに theme を書く

なぜ駄目か 見た目はアプリ全体の性質なので app.theme にしかない。画面ごとに色が変わる業務システムは、ふつう作らない。

こう直す app: の直下に移す。1画面だけ違う見た目にしたいなら Renderer 側(Flutter なら Theme)で包む。

yaml
page:
  type: search
  id: order_search
  title: 受注照会
  repository: orderRepository
  theme:
    primaryColor: "#1B5E20"
yaml
app:
  id: sales_admin
  title: 販売管理
  theme:
    primaryColor: "#1B5E20"
    density: compact
  pages:
    - type: search
      id: order_search
      title: 受注照会
      repository: orderRepository

spec/pitfalls.json から生成。各項目は CI で検証済み(間違いは本当に落ち、正しい方は本当に通る)。手元では npx hatake pitfalls <キー名>