Ext JSのテーマ設定

テーマ設定はアプリケーションのビジュアルモチーフを定義します。テーマはビジュアル要素のセットで、これはベースカラー、フォントファミリ、ボーダー、背景などのCSSプロパティを含むアプリケーションの基本的な機能性に影響を及ぼすことなく簡単に切り替えられます。

テーマ設定は「スタイル化」とは異なり、スイッチ1つでテーマを変更できます。

Ext JS 5には、テーマ設定システムのオーバーホールが含まれ、アプリケーションの見た目や印象のカスタマイズをより簡単にしています。 Ext JSのテーマは、スタイルシートで変数とミックスインを使用できる SASSおよびCompassを利用しています。Ext JSコンポーネントのスタイルは、カラー、フォント、ボーダーおよび背景など、SASS 変数を変更するだけでほぼすべてがカスタマイズできるようになりました。

Ext JS にはデフォルトのテーマが含まれ、Ext JS アプリケーションで使用できる独自のカスタムテーマパッケージの作成にベースとして使用できます。

このチュートリアルでは、アプリケーション間で共有できるカスタムテーマの作成方法、アプリケーションでのテーマの使用方法、および共有しないアプリケーション固有のスタイルの作成方法について説明します。

必要条件

Sencha Cmd 5

Sencha Cmdはコマンドラインツールで、Ext JSおよびSencha Touchのアプリケーションをパッケージ化しデプロイするために使われます。Ext JS 5でテーマを構築するには、Sencha Cmd 5以上をお使いのコンピューターにインストールしなくてはなりません。Sencha Cmd 5ではこれ自体にバンドルされたバージョンを使用するため、 SASSとCompassをコンピューターにインストールする必要がなくなりました。

Sencha Cmdのインストールと使用の準備については、Sencha Cmdの導入にあたってをご覧ください。

Ruby

Rubyはオープンソースのプログラム言語で、Sencha Cmdの実行に必要です。Rubyのインストール方法については、Sencha Cmdの導入にあたってをご覧ください。

Ext JS

カスタムテーマはExt JS SDKに含まれるデフォルトのテーマをベースにします。

Sencha CmdではExt JSをダウンロードする必要はなくなりました。generateコマンドで“-ext”フラグを使用できるようになりました。これによって、最新バージョンの Ext JS 5を自動的にダウンロードできます。Sencha Cmdはこれを使用してアプリケーションを生成します。

ただし、引き続きExt JSをダウンロードすることもできます。Ext JS 開発キット(SDK)を任意の場所に解凍するだけです。

このチュートリアルでは、“-ext”フラグを使用してワークスペースを生成していることを前提にしています。

カスタムテーマの構築

テーマ構築に上記の必要なアプリケーションをインストールしたら、完全カスタマイズテーマを作成できます。

ワークスペースのセットアップ

カスタムテーマを構築する最初のステップは、Sencha Cmdを使ってワークスペースをセットアップすることです。

sencha generate workspace -ext my-workspace

SDKの既存のローカルコピーを使用する場合、以下をコマンドラインから実行します。 "~/sencha-5.0.0/"をExt JS SDKを解凍する場所のパスに置き換えるだけです。

sencha -sdk ~/sencha-5.0.0 generate workspace my-workspace

‘generate workspace’はSenchaワークスペースのアプリの雛形をターゲットディレクトリ"my-workspace"に作成します。このワークスペースはカスタムテーマパッケージを作成する場所です。また、新しいカスタムテーマを使用するアプリケーションをここに作成します。このコマンドはExt JS SDKおよびパッケージをワークスペースにコピーし、テーマとアプリケーションが必要な依存関係を見つけられるようにします。 テーマとアプリケーションを生成するコマンドはワークスペースディレクトリの内部から実行する必要があります。つまり、新しい"my-workspace"ディレクトリに作業ディレクトリを変更する必要があります。

cd my-workspace

今、ワークスペース内に2つのディレクトリがあります。

  • "ext" – Ext JS SDKを含みます。
  • "packages" – Ext JSのロケールおよびテーマパッケージを含みます。

テーマをテストするアプリケーションの作成

カスタムテーマを作成する前に、テーマをテストする方法を作っておく必要があります。 テーマをテストする一番良い方法は、アプリケーションでそれを使うことです。 以下の"my-workspace"ディレクトリからコマンドを使用してスケルトンExt JSアプリケーションを生成します。

sencha -sdk ext generate app ThemeDemoApp theme-demo-app

Sencha CmdはThemeDemoAppと名付けられたアプリケーションを"theme-demo-app"と名付けられたサブディレクトリに生成します。生成されたアプリケーションは‘ext’ディレクトリのコンテンツをExt JS SDKのソースとして使用します。このディレクトリは“my-workspace”ディレクトリに作成され、ワークスペースが生成されるとフレームワークがそこにコピーされます。

cd theme-demo-app
sencha app watch

アプリを実行するには2つの方法があります。

1.開発モード

アプリケーションを開発モードで表示するには、次を開きます。

`"my-workspace/theme-demo-app/index.html"`

このチュートリアルでは、デバッグを簡単にするため縮小していないソースファイルを使うので、開発モードを使います。

2.本番モード

アプリケーションを本番モードで表示するには、アプリケーションを下記で構築する必要があります。

sencha app build

構築されるとアプリケーションは以下で見つけることができます。

ブラウザの"my-workspace/build/production/ThemeDemoApp/index.html"

本番モードは、容量を抑えアプリケーションのパフォーマンスを向上するため、縮小したソースファイルを使用します。

カスタムテーマパッケージとファイル構造の生成

Sencha Cmdはカスタムテーマに必要なすべてのファイルを含むテーマパッケージを生成することによって、カスタムテーマの作成プロセスを簡略化します。theme-demo-appディレクトリから次のコマンドを実行します。

sencha generate theme my-custom-theme

これはSencha Cmdに対し、現在のワークスペース内に"my-custom-theme"という名前のパッケージを作成するよう伝えます。 ワークスペースの“packages”ディレクトリに"my-custom-theme"という名前のディレクトリが新しく作成されます。 これがテーマパッケージです。主な内容を見てみましょう。

  • "package.json" - パッケージのプロパティファイルです。それがSencha Cmdに対し、名前、バージョン、依存関係(それが必要とする他のパッケージ)などのパッケージに関する事柄を伝えます。
  • "sass/" - このディレクトリにテーマのSASSファイルがすべて含まれます。SASSファイルは3つのセクションに分かれています。
    • "sass/etc/" - 追加のユーティリティ関数またはミックスインが含まれます。
    • "sass/src/" - “sass/var/”で定義された変数を使用できるSASSルールとUIミックスイン呼び出しが含まれます。
    • "sass/var/" - SASS変数が含まれます。"sass/var/"および"sass/src"内のファイルは、スタイル設定しているコンポーネントのクラスパスに一致するよう構成します。例えば、Ext.panel.Panelの見た目を変更する変数は"sass/var/panel/Panel.scss"という名前のファイルに配置します。
  • "resources/" - テーマに必要な画像とその他の静的リソースが含まれます。

  • "overrides/" - コンポーネントのテーマ設定に必要となる可能性のあるExt JSコンポーネントクラスへのJavaScriptのオーバーライドが含まれます。

テーマの継承の設定

Senchaのテーマパッケージはすべて、より大きなテーマ階層の一部であり、各テーマパッケージはベーステーマを継承していなくてはなりません。カスタムテーマ作成の次のステップは、継承するテーマを決めることです。ワークスペースのパッケージディレクトリに、次のテーマパッケージがあります。

  • "ext-theme-base" - このパッケージは他のすべてのテーマのベーステーマで、親テーマを持たない唯一のテーマパッケージです。Ext JSコンポーネントおよびレイアウトが正しく動作するために必要な最小限のCSSルールのみを含みます。"ext-theme-base"内のスタイルルールは派生テーマで設定変更できず、このテーマにより作成されるスタイルルールはいずれもオーバーライドしないようにする必要があります。

  • "ext-theme-neutral" - このニュートラルテーマは"ext-theme-base"を継承し、設定可能なスタイルルールの大半を含みます。Ext JSコンポーネントの外観の設定に利用できる変数のほとんどは、"ext-theme-neutral"で定義されています。これらはカスタムテーマでオーバーライドできる変数です。

  • "ext-theme-neptune" - モダンなボーダレステーマです。"ext-theme-neutral"を継承します。

  • "ext-theme-crisp-touch" - NeptuneベースのTouchテーマです。"ext-theme-neptune"を継承します。
    • このテーマには"touch-sizing"パッケージが含まれます。
  • "ext-theme-crisp" - 最小構成のテーマです。"ext-theme-neptune"を継承します。
  • "ext-theme-crisp-touch" - CrispベースのTouchテーマです。"ext-theme-crisp"を継承します。
  • "ext-theme-classic" - クラシックブルーのExt JSテーマです。"ext-theme-neutral"を継承します。
  • "ext-theme-gray" - グレーのテーマです。"ext-theme-classic"を継承します。
  • "ext-theme-aria" - アクセシビリティのテーマです。"ext-theme-neptune"を継承します。
    • このテーマには"ext-aria"パッケージが含まれます。

このチャートはExt JS 5でテーマの継承がどのように行われるかを分かりやすく説明しています。

ではどのカスタムテーマを継承すべきでしょうか。カスタムテーマの開始点としては、"ext-theme-neptune"または"ext-theme-classic"がお勧めです。なぜなら、これらのテーマはすぐに使える魅力的なテーマの作成に必要なコードをすべて含んでいるからです。neutralテーマは非常に抽象的なテーマと考えるべきで、通常は直接継承する必要はありません。"ext-theme-neutral"をオーバーライドしてカスタムテーマを作成するには、数百の変数のオーバーライドと長時間の作業が必要であり、非常に高度なテーマ開発者のみが行う必要があります。ただし、Neptuneまたはclassicテーマから派生するカスタムテーマは、変数をいくつか変えるだけで数分で稼働可能な状態になります。 さらに、カスタムテーマにふさわしい開始点を得られる場合は"ext-theme-gray"または"ext-theme-aria"をオーバーライドすることができます。

このチュートリアルでは、Neptuneテーマを継承するカスタムテーマを作成します。最初に、継承するテーマの名前でカスタムテーマを設定します。 ここに示すように、“packages/my-custom-theme/package.json”で‘extend’プロパティをデフォルト値から変更することによって行うことができます。

"extend": "ext-theme-classic"

変更後:

"extend": "ext-theme-neptune"

ここでアプリケーションを更新する必要があります。これにより、正しいテーマのJavaScriptファイルがアプリケーションの“bootstrap.js”ファイルに含まれ、アプリケーションが開発モードで実行できるようになります。“theme-demo-app”ディレクトリから次のコマンドを実行します。

sencha app refresh

これでNeptuneテーマをベースとして使用するカスタムテーマが設定できました。ただし、Neptuneと同じように、独自の変更を加える必要があります。これでテーマにカスタムテーマを追加できます。

グローバルテーマ変数の設定

まず、多くのExt JSコンポーネントの色が派生するベースカラーの変更から始めます。"my-custom-theme/sass/var/"にComponent.scssと呼ばれるファイルを作成します。 Component.scssファイルに次のコードを追加します。

$base-color: #317040 !default;

カスタムテーマを継承可能にしたければ、すべての変数割り当ての最後に必ず!defaultを含めてください。Sencha Cmdは変数ファイルを「逆」の順、つまり末端の派生テーマが先でベーステーマが最後になるよう含むため、!defaultがないと、派生テーマでその変数をオーバーライドできません。!defaultの使い方については変数のデフォルト値をご覧ください。

$base-color値は有効なHTMLカラーコードでなくてはなりません。HTMLカラーコードのWebページをご覧ください。

Ext JSグローバルSASS変数の完全なリストについては、 Global_CSSをご覧ください。

パッケージの構築

これでテーマのベースカラーを変更したので、テーマのすべてのスタイルルールを含む更新バージョンのテーマcssファイルを構築する必要があります。"packages/my-custom-theme/"ディレクトリから次のコマンドを実行します。

sencha package build

パッケージを構築すると、テーマパッケージディレクトリに“build”ディレクトリが作成されます。 "my-custom-theme/build/resources"の内部に、my-custom-theme-all.cssという名前のファイルができます。 このファイルには、テーマのすべてのExt JSコンポーネントのスタイルルールが含まれます。このファイルにはアプリから直接リンクすることができますが、これはお勧めしません。なぜなら、"all"ファイルが各Ext JSコンポーネントのすべてのスタイルを含み、ほとんどのアプリはExt JSコンポーネントのサブセットしか使用しないからです。Sencha Cmdはアプリ構築時に不使用のCSSスタイルルールをフィルタリングで除去することができますが、まずカスタムテーマを使うテストアプリを設定する必要があります。

アプリケーションでのテーマの使用

この時点で、sencha app watchをアプリケーションのディレクトリから開始できます。

これはアプリケーションに変更があるか監視し、自動的にアプリケーションを再構築して更新します。sencha app watchは現時点ではパッケージは監視しません。

カスタムテーマを使用するテストアプリケーションを設定するには、theme-demo-app/app.jsonで次の行を見つけます。

/**
 * このアプリケーションのテーマの名前。
 */
"theme": "ext-theme-neptune",

そして、次のように書き換えます。

/**
 * このアプリケーションのテーマの名前。
 */
"theme": "my-custom-theme",

sencha app watchが変更処理を完了したら、ブラウザで"theme-demo-app/index.html"を更新します。画面のコンポーネントに適用する$base-colorとして以前に指定した緑色になります。

コンポーネントの変数の設定

各Ext JSコンポーネントは、外観の設定に使用できるグローバル変数のリストを持っています。"my-custom-theme"のパネルヘッダーのfont-familyを変更してみましょう。"packages/my-custom-theme/sass/var/panel/Panel.scss"という名前のファイルを作成し、次のコードを追加します。

$panel-header-font-family: Times New Roman !default;

そして、"theme-demo-app"ディレクトリから以下のコマンドを実行してアプリを構築します。

sencha app build

"theme-demo-app/index.html"をWebブラウザで開くと、 パネルヘッダーが「Times New Roman」フォントを使用していることを確認できます。

各コンポーネントのSASS変数の完全なリストは、APIドキュメント各ページの「CSS変数」セクションで見ることができます。 例えば、Ext.panel.Panelで「CSS変数」というタイトルのセクションにスクロールダウンします。

カスタムコンポーネントUIの作成

Ext JSフレームワークの各コンポーネントにはユーザーインターフェイス(UI)設定があります。(デフォルトはdefault)。このプロパティは個々のコンポーネントインスタンスに設定し、同じタイプのコンポーネントインスタンスとは異なる外観にすることができます。 これをNeptuneテーマに使い、様々なタイプの パネルボタンを作成します。例えば、‘default’のUIのパネルにはダークブルーのヘッダーがあり、‘light’のUIのパネルにはライトブルーのヘッダーがあります。ボタンはUIを使って、通常のボタンとは異なる見た目をツールバーボタンに与えます。

ext-theme-neutralテーマには、多くの異なるExt JSコンポーネント用のSASSミックスインが含まれます。 これらのミックスインは、コンポーネント用の新しいUIを作成します。各コンポーネントで使用できるミックスインは、APIドキュメントにリストがあります。例えば、Ext.panel.Panelで「CSS Mixins」セクションにスクロールダウンし、Panel UIミックスインが受け入れるパラメータを確認できます。このミックスインを使ってカスタムパネルUIを作成してみましょう。"packages/my-custom-theme/sass/src/panel/Panel.scss"という名前のファイルを作成し、次のコードを追加します。

@include extjs-panel-ui(
    $ui-label: 'highlight-framed',
    $ui-header-background-color: red,
    $ui-border-color: red,
    $ui-header-border-color: red,
    $ui-body-border-color: red,
    $ui-border-width: 5px,
    $ui-border-radius: 5px
);

このミックスイン呼び出しは「highlight-framed」という名前の新しいパネルUIを生成します。これは赤のヘッダー背景、赤のボーダー、5pxのボーダーライン、5pxのボーダー径を持っています。このUIは、「highlight」を持つパネルをその「ui」プロパティとして設定するだけで使えます(frameコンフィグをtrueに設定すると、パネルのUIに接尾辞「-framed」が追加されます)。"theme-demo-app/app/view/Main.js"を開いて、アイテム配列を次と置き換えます。

items: [{
    // custom "highlight" UI        
    xtype: 'panel',
    ui: 'highlight-framed',
    frame: true, // Make sure to add this config to see the frame highlight changes
    bind: {
        title: '{name}'
    },
    region: 'west',
    html: '<ul><li>This area is used for navigation, for example, using a "tree" component.</li></ul>',
    width: 250,
    split: true,
    tbar: [{
        text: 'Button',
        handler: 'onClickButton'
    }]
},{    
    region: 'center',
    xtype: 'tabpanel',
    items:[{
        title: 'Tab 1',
        html: '<h2>Content appropriate for the current navigation.</h2>'
    }]
}]

sencha app watchが実行中の場合、Main.jsへの変更はピックアップされているはずです。

"theme-demo-app/index.html"をウェブブラウザで開くと、westリージョンに赤の「highlight」パネルが表示されます。

UIミックスインはコンポーネントに複数の見た目を手軽に設定できますが、使いすぎてはいけません。UIミックスインを呼び出すごとにCSSルールが生成されて追加されます。 必要に応じてUIミックスインを呼び出すと、非常に大規模なCSSファイルを生成できます。

UIミックスインの呼び出し時に注意すべきもう1つの点は、ミックスインを、パラメータ値の順序リストではなく、その名前のついたパラメータを渡して呼び出すということです。SASSは両方の形式をサポートしていますが、次の形式を使うのが最良です。

@include extjs-component-ui(
    $ui-foo: foo,
    $ui-bar: bar
);

次の形式は避けてください。

@include extjs-component-ui(foo, bar);

これは、ミックスインパラメータは複雑で多数あるため、新しいパラメータが追加されたり非推奨のパラメータが削除されたりした場合に順序が同じままとなるよう保証できません。そのため、UIミックスインの呼び出し時には、順序ではなく常に名称でパラメータを指定することが安全です。

画像アセットの変更

必要な画像アセットは、デフォルトではすべて親テーマから継承されますが、場合によっては画像をオーバーライドする必要があります。これは"my-custom-theme/resources/images/"内にその画像を配置し、オーバーライドする画像と同じ名前をつけることで簡単に実行できます。例えば、MessageBoxコンポーネントの情報アイコンを変更してみます。 次の画像を"packages/my-custom-theme/resources/images/shared/icon-info.png"として保存します。

次に、そのカスタムアイコンを使用するMessageBoxを表示させるため、テストアプリケーションを変更します。アプリケーションの"theme-demo-app/app/view/Main.js"にあるhighlight パネルに次のアイテム配列を追加します。

...
tbar: [{
    text: 'Button',
    handler: 'onClickButton'
}],
items: [{
    xtype: 'button',
    text: 'Show Message',
    handler: function() {
        Ext.Msg.show({
            title: 'Info',
            msg: 'Message Box with custom icon',
            buttons: Ext.MessageBox.OK,
            icon: Ext.MessageBox.INFO
        });
    }
}]
...

そして、"theme-demo-app"ディレクトリから以下のコマンドを実行してアプリを構築します。

sencha app build

次にブラウザでアプリを表示します。ボタンをクリックしたらMessageBoxに親しみやすい顔があるのが分かります。

IEのCSS3エフェクト用に画像をスライス

新しいUIの作成時には多くの場合、背景のグラデーションや丸みのあるコーナーを含めたいことがあります。残念ながら、従来のブラウザはこれらのエフェクトのCSS3プロパティをサポートしていないので、代わりに画像を使わなくてはなりません。Sencha Cmdにはこうした画像を自動的にスライスする機能があります。これを行うためには、Sencha Cmdに、スライスが必要なコンポーネントを伝える必要があります。スライス設定を含むファイルは、テーマの"sass/example/"ディレクトリに含まれます。これらのファイルがどのようなものか、ワークスペースの"packages/ext-theme-base/sass/example/"ディレクトリを見てみましょう。

  • "shortcuts.js" - このファイルには、スライスできるコンポーネントタイプのベース設定が含まれます。ほとんどのカスタムテーマは"shortcuts.js"ファイルを含む必要はなく、テーマがカスタムコンポーネントのスタイル設定を含む場合のみ必要になります。 テーマはベーステーマに定義されているショートカットをすべて継承し、必要な場合はテーマの"shortcuts.js"ファイル内のExt.theme.addShortcuts()を呼び出して、さらにショートカットを追加できます。

  • "manifest.js" - このファイルには、テーマを構築するときにスライス画像が生成されるコンポーネントUIのリストが含まれます。テーマは親テーマからマニフェストエントリをすべて継承し、自身の"manifest.js"ファイル内のExt.theme.addManifest()関数を呼び出すことにより、自身のマニフェストエントリを追加できます。

  • "theme.html" - これは、"manifest.js"ファイル内に定義されたコンポーネントを描画するファイルです。Sencha Cmdは、ヘッドレスのWebKitブラウザに"theme.html"を描画し、そのページのスクリーンショットを取得します。 それからこのスクリーンショットを使って、IEに丸みのあるコーナーやグラデーションを表示するために必要な画像をスライスします。

このチュートリアルの前の方で作成した「highlight」パネルUIの丸みのあるコーナーのスライスを作成するため、"packages/my-custom-theme/sass/example/manifest.js"という名前のファイルを作成し、それに次のコードを追加します。

Ext.theme.addManifest(
    {
        xtype: 'panel',
        ui: 'highlight'
    }
);

次に"packages/my-custom-theme/sass/example/theme.html"を編集し、次のスクリプトタグを追加します。

<!-- Required because Sencha Cmd doesn't currently add manifest.js from parent themes -->
<script src="../../../ext-theme-neptune/sass/example/manifest.js"></script>
<!-- Your theme's manifest.js file -->
<script src="manifest.js"></script>

これにより、sencha package buildを使ってmy-custom-theme パッケージを作成すると、ext-theme-neptuneおよびmy-custom-themeで定義されたUIが正しくスライスされます。 これら2つのタグはまた、"theme-demo-app/sass/example/theme.html"に追加しなくてはなりません。それにより、sencha app buildを使ってアプリを構築するときにUIがスライスされます。

<script type="text/javascript" src="../../../../ext/packages/ext-theme-neptune/sass/example/manifest.js"></script>
<script type="text/javascript" src="../../../../ext/packages/my-custom-theme/sass/example/manifest.js"></script>

将来的には、手動で"theme.html"を変更する必要はほとんどなくなりますが、Sencha Cmd 5.0スクリプトタグでは"shortcuts.js"および"manifest.js"は自動的に追加されません。

ただこれだけです。では再びデモアプリを構築し、IE8以降で実行します。 最新のブラウザでアプリを実行すると、「highlight」パネル上に、CSS3で作成したような丸みのあるコーナーが現れます。

テーマJSオーバーライド

テーマは時々、JavaScriptだけで設定できるコンポーネントの外観を変える必要があります。これは、JavaScriptオーバーライドをテーマパッケージに加えることで簡単に実行できます。これがどのように実行されるかデモンストレーションするために、カスタムテーマのパネルのtitleAlignコンフィグを変更してみましょう。 "packages/my-custom-theme/overrides/panel/Panel.js"という名前のファイルを作成し、次のコードを追加します。

Ext.define('MyCustomTheme.panel.Panel', {
    override: 'Ext.panel.Panel',
    titleAlign: 'center'
});

次にテーマパッケージを構築し、"packages/my-custom-theme/build/my-custom-theme.js"が新しいオーバーライドを含むようにします。"packages/my-custom-theme/"ディレクトリから次を実行します。

sencha package build

アプリケーションを更新し、開発モードでアプリケーションを実行したときにテーマのJSオーバーライドが含まれるようにします。"theme-demo-app"ディレクトリから次のコマンドを実行します。

sencha app refresh

次に、theme-demo-appディレクトリからアプリを構築します。

sencha app build

それからブラウザで"theme-demo-app/index.html"を開きます。すべてのパネルヘッダーが中央揃えのタイトルを持っていることを確認します。

Ext JSコンポーネントコンフィグはこの方法でオーバーライドできますが、一番良いのは、テーマオーバーライドだけを使って、コンポーネントの外観に直接影響があるコンフィグを変更することです。

SASS名前空間

上述のように、Sencha Cmdは、JavaScriptクラスと一致する"sass/var"および"sass/src"でファイルを探します。デフォルトでは、Ext名前空間はトップレベルの名前空間と想定されるため、テーマはExt.panel.Panelに対応する"sass/src/panel/Panel.scss"ファイルを持つことになります。

Ext名前空間外に適用するテーマは、".sencha/package/app.json"package.sass.namespaceと呼ばれるコンフィグプロパティを変更しなくてはなりません。テーマですべてのコンポーネントにスタイル設定できるようにするには、これをブランクに設定する必要があります。

/**
 * Sass設定プロパティ。
 */
"sass": {
    /**
     * *.scssファイルを
     * sass/srcディレクトリとsass/varディレクトリのクラスにマップする際に使用するルート名前空間。例えば、"MyApp.view.Foo"は
     * "sass/src/view/Foo.scss"にマップします。これを"MyApp.view"に変更すると、
     * "sass/src/Foo.scss"にマップします。アプリのルート名前空間外のクラスにスタイルを設定するには、
     * これを""に変更します。これを行うと、
     * "MyApp.view.Foo"へのマッピングを"sass/src/MyApp/view/Foo.scss"に変更します。
     */
    "namespace": ""
},

これを設定すると、Ext.panel.Panelに対応させるために作成する必要があるファイルは"sass/src/Ext/panel/Panel.scss"です。

カスタムユーティリティのSASSを追加する

コンポーネントのスタイル設定とは関係ないSASS関数またはミックスイン(ユーティリティなど)をテーマが必要とする場合は、これらはテーマの"sass/etc"ディレクトリに配置する必要があります。このディレクトリ内では好きなようにファイルを整理できますが、Sencha Cmdがビルドに含む唯一のファイルは"sass/etc/all.scss"です。 他のファイルはすべて、"all.scss"ファイルによりインポートしなくてはなりません。 このパターンに従う例として、"packages/ext-theme-base/sass/etc/"をご覧ください。

Ext JS 4.1以前からテーマを移行する

Ext 4.1では、テーマ設定はまったく別の方法で行われていました。通常、SASS変数はすべて1つの"all.scss"ファイルに設置されることになり、ファイルの最後にベーステーマの“all.scss”ファイルがインポートされます。 既存のテーマから移行するのに最適な開始点は、そのテーマ内の旧SASS変数をすべて"sass/etc/all.scss"ファイルに入れることです。古いテーマが持っていたSASSルールはいずれも、"sass/src/Component.scss"に入れます。それから上述のように、そのテーマを使用するテーマまたはアプリを構築してみます。最終的に、スタイル設定されているコンポーネントに対応するファイルに変数やルールを移す場合もあります。

アプリケーションのスタイル設定

アプリケーション間で共有されないスタイル設定は、テーマではなくアプリケーション自体に属します。Sencha Cmdは、テーマのスタイル設定と同じパターンに従い、簡単にアプリケーションレベルのスタイル設定を追加する方法を提供しています。アプリケーションはテーマ階層の最終レベルとして動作します。アプリケーションはテーマ変数を変更でき、アプリケーションのビューのスタイル設定用にカスタムの変数とルールを追加できます。

アプリケーションのテーマ変数を変更する

引き続き上で作成した"theme-demo-app"アプリケーションを使って、アプリケーションのテーマの$base-colorをオーバーライドしてみましょう。 "theme-demo-app/sass/var/view/main/Main.scss"という名前のファイルを作成し、次のコードを追加します。

$base-color: #333;

そして、"theme-demo-app"ディレクトリから以下のコマンドを実行してアプリを構築します。

sencha app build

ブラウザでアプリケーションの"index.html"ページを開くと、色がグレーに変わっています。

$base-color変数を設定するときに!defaultを使わなかったことにお気づきでしょうか。!defaultはテーマ内の変数設定に使用します。そうしたテーマ変数は、派生テーマまたはアプリケーションでオーバーライドする場合があるからです。ここでは、アプリケーションがテーマの継承ツリーの最後であるため、!defaultは必要ありません。

また、テーマの$base-colorを変更したときのように"Component.scss"ではなく、"Main.scss"$base-colorを設定したことを不思議に思われているかもしれません。 これは、scssファイル名の解決にSencha Cmdが使用する名前空間が、アプリケーションの名前空間だからです。 アプリケーションの各クラスについて、Sencha Cmdは対応するscssファイルを、変数は"sass/var/"、ルールは"sass/src/"で確認します。 アプリケーションがThemeDemoApp.view.Mainという名前のクラスを持つため、"sass/var/view/main/Main.scss"ファイルがビルドに含まれます。 アプリケーションが“ThemeDemoApp.Component”という名前のクラスを持たない場合、"sass/var/Componenent.scss"は含まれません。

アプリケーションのビューのスタイル設定

アプリケーションのビューのCSSスタイルルールは、スタイル設定しているビューと同じパスおよび名前を持つscssファイル内のアプリケーションの"sass/src/"ディレクトリに入れる必要があります。ThemeDemoAppアプリケーションのセンターパネルをスタイリングしましょう。そのパネルがThemeDemoApp.view.Mainに定義されているため、それをスタイル設定するCSSルールは"sass/src/view/Main.scss"に入ります。

.content-panel-body {
    background-color: #ccc;
}

アプリケーションのMain.jsファイルのセンターパネルのボディに、「content-panel-body」CSSクラスを追加します。

...
xtype: 'panel',
ui: 'highlight',
bodyCls: 'content-panel-body',
frame: true,
...

センタータブパネルのボディがグレーの背景色になっているはずです。

SASS名前空間

テーマと同様に、アプリケーションには"sass/var"および"sass/src"フォルダがあり、これらもまたJavaScriptクラス階層に対応しています。アプリケーションでは、最上位の名前空間は"app.json"nameで指定されています。デフォルトではこの値がアプリケーションの名前空間です。

このデフォルト設定は、アプリケーションのビューが多くの場合アプリケーションの名前空間にあるため、そのスタイル設定に最も便利です。アプリケーションの名前空間外のコンポーネントをスタイリングするために、app.sass.namespaceを変更できますが、代わりにテーマを作成した方が良いかもしれません。

作成したSASSの整理

上述のようにテーマを使う場合、テーマ、アプリケーションおよび必要なパッケージ(Sencha Cmdパッケージ参照)からのSASSは、"app-all.scss"ファイルに結合され、それからCompassでコンパイルされます。テーマまたは必要なパッケージから、何をいつ使用できるかを知るために、このファイル構造を理解することが重要です。

アプリケーション用に作成された"all.scss"ファイルの構造はこのようになります。

+---------------------------------------+
| inclusion flags                       |
+-----------+-----------+---------------+
|           |           | base          |
|           | theme     +---------------+
|           |           | derived       |
|           +-----------+---------------+
|           |                           |
|    etc    | packages (dep order)      |
|           |                           |
|           +---------------------------+
|           |                           |
|           | application               |
|           |                           |
+-----------+---------------------------+
|           |                           |
|           | application               |
|           |                           |
|           +-----------+---------------+
|           |           | derived       |
|    var    | theme     +---------------+
|           |           | base          |
|           +-----------+---------------+
|           |                           |
|           | packages (dep order)      |
|           |                           |
+-----------+-----------+---------------+
|           |           | base          |
|           | theme     +---------------+
|           |           | derived       |
|           +-----------+---------------+
|           |                           |
|    src    | packages (dep order)      |
|           |                           |
|           +---------------------------+
|           |                           |
|           | application               |
|           |                           |
+-----------+---------------------------+

"sass/var"および"sass/src"用の“bands”の内部で、任意のテーマ、パッケージおよびアプリケーションの個々の".scss"ファイルが、常にJavaScriptクラス階層に一致する順に並んでいます。例えば、“base”テーマがその"sass/var"フォルダにExt.window.WindowおよびExt.panel.Panel".scss"ファイルを持つ場合、Ext.panel.PanelのファイルはExt.panel.Panelを継承するため、Ext.window.Windowのファイルの前に含まれることになります。

この特有な構造の目的と理由は次のとおりです。

  • "sass/etc"スペースでは、ベーステーマからのユーティリティなどが派生テーマで使用できる必要があります。
  • パッケージは現在のテーマにより提供された機能を使用できる必要があります。
  • アプリケーションは自身のテーマや必要なパッケージを使用できる必要があります。
  • "sass/var"スペースでは、変数管理と派生計算が問題です。
  • アプリケーションはすべての変数を管理てきなくてはならないため、そのvarsが最初にきます。
  • テーマが次にきて、アプリケーションの変数値を拾いますが、ベースとするほとんどの派生テーマからは「逆」順できます。これにより、アプリケーションやさらに派生したテーマがまだ設定していない任意の変数を、派生テーマが設定できるようになります。
  • パッケージ変数は、パッケージの依存関係順に取り入れられます。これによりパッケージ変数は、現在のテーマから(最も重要なのはbase-colorから)値を導くことができます。
  • "sass/src"セクションでは、順序が"sass/etc"と同じです。 これによりルールの適切なカスケードを提供し、派生テーマのルールをベーステーマからのルールより優先させることが簡単になります。

  • アプリケーションは、そのルールが常に最終権限を持つため、カスケードの最後にきます。

インクルードフラグ

「インクルードフラグ」セクションは、含まれる*かもしれない*各JavaScriptクラスに対し、trueまたはfalseとなるよう定義される変数セットです。そのクラスが含まれている場合、この変数の値はtrueです。例えば、ビルドがExt.grid.Panelを使う場合、このセクションにはこの行があります。

$include-ext-grid-panel: true;

ビルドがExt.menu.ColorPickerを含まない場合、この行があります。

$include-ext-menu-colorpicker: false;

アプリケーション間でテーマを共有する

2つ目のアプリケーションで構築したテーマを共有するのは簡単です。「my-workspace」ディレクトリに行き、次のコマンドを実行します。

sencha -sdk ext generate app AnotherApp another-app

これにより、「AnotherApp」という名前の「another-app」ディレクトリにアプリを作成し、作成した1つ目のアプリと同じExt JS SDKを使うようSencha Cmdに伝えられます。

次のステップは、アプリにカスタムテーマを使うよう伝えることです。「another-app/app.json」を編集し、次の行を置き換えます。

/**
 * このアプリケーションのテーマの名前。
 */
"theme": "ext-theme-neptune",

を次に置き換えます。

/**
 * このアプリケーションのテーマの名前。
 */
"theme": "my-custom-theme",

ではアプリを構築しましょう。「"another-app」ディレクトリから次を実行します。

sencha app build

次に、ブラウザで「another-app/index.html」ページを開きます。ThemeDemoAppと同じカスタムテーマを使用するスターターアプリが表示されます。

Last updated