Angular Material
前回までフレームワークをVue.jsにしようかAngularにしようか迷っていた筆者ですが、Angularを使う事にしました。UI部分ではAngular Materialを使うことにしました。
ここでは公式ページに従ってAngular Materialインストールと、Selectコンポーネントの導入をしてみたいと思います。
インストールと初期設定
公式:「getting-started」にしたがってインストールしていきます。インストールはngコマンドから可能です。ng new で作成したアプリケーションのフォルダに移動して次のようにコマンドを入力します。
このコマンドでは、「Angular Material」と一緒に「Component Dev Kit (CDK)」、「Angular Animations」、それとインストール中の質問によりいくつかのインストールをします。
- Choose a prebuilt theme name, or "custom" for a custom theme
デフォルトのテーマを提示された種類の中から選びます。
ここでの作業はCSSファイルの指定だけのようです。記述を変えたり、HTMLファイルで直接設定することもできるようです。次にあげるテーマ名と同じCSSファイルが用意されています。
- deeppurple-amber.css
- indigo-pink.css
- pink-bluegrey.css
- purple-green.css
- Set up global Angular Material typography styles?
typography(タイポグラフィ)とはテキストを読みやすくするためのハイライトの機能で、これをグローバルに設定するかを聞いています。
- Set up browser animations for Angular Material?
アニメーションを設定するかの設定です。
インストールの過程でsrcフォルダ内のindex.htmlに「Roboto font」と「Material Design icon」を利用するための記述が加えられます。
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<body class="mat-typography">
...
style.cssにも数行の記述が追加されます。
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
サンプルの作成
公式:「Components」に掲載されているSelectのサンプルを試しに構築していきたいと思います。
まずAngular Materialのモジュール群をまとめたmaterialモジュールを作成します。こうしておくことで管理や使いまわしが楽になります。
コマンドプロンプトから、src¥appフォルダに移動して次のようにngコマンドを入力します。
--flatオプションはフォルダを作らずトップレベルにモジュールを作成するものです。--module=appは登録先のモジュールをapp.moduleに指定しています。この作業によりmoduleが複数になりましたので、今後componentを新規作成する際には--module=appとしてapp.moduleに設定を追加するという明示的な指示が必要になります。
作成したmaterial.module.tsは次のようにします。ここでは、Angular Materialのモジュールをインポートしてそのままエクスポートしています。サンプルでは使っていないものが多数あります。実運用に合わせたラインナップにしてください。
material.module.ts
import {NgModule} from '@angular/core';
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {MatBadgeModule} from '@angular/material/badge';
import {MatBottomSheetModule} from '@angular/material/bottom-sheet';
import {MatButtonModule} from '@angular/material/button';
import {MatButtonToggleModule} from '@angular/material/button-toggle';
import {MatCardModule} from '@angular/material/card';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatChipsModule} from '@angular/material/chips';
import {MatStepperModule} from '@angular/material/stepper';
import {MatDatepickerModule} from '@angular/material/datepicker';
import {MatDialogModule} from '@angular/material/dialog';
import {MatDividerModule} from '@angular/material/divider';
import {MatExpansionModule} from '@angular/material/expansion';
import {MatGridListModule} from '@angular/material/grid-list';
import {MatIconModule} from '@angular/material/icon';
import {MatInputModule} from '@angular/material/input';
import {MatListModule} from '@angular/material/list';
import {MatMenuModule} from '@angular/material/menu';
import {MatNativeDateModule, MatRippleModule} from '@angular/material/core';
import {MatPaginatorModule} from '@angular/material/paginator';
import {MatProgressBarModule} from '@angular/material/progress-bar';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {MatRadioModule} from '@angular/material/radio';
import {MatSelectModule} from '@angular/material/select';
import {MatSidenavModule} from '@angular/material/sidenav';
import {MatSliderModule} from '@angular/material/slider';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {MatSnackBarModule} from '@angular/material/snack-bar';
import {MatSortModule} from '@angular/material/sort';
import {MatTableModule} from '@angular/material/table';
import {MatTabsModule} from '@angular/material/tabs';
import {MatToolbarModule} from '@angular/material/toolbar';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatTreeModule} from '@angular/material/tree';
@NgModule({
exports: [
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatTreeModule
]
})
export class MaterialModule {}
app.module.tsでは「FormsModule」と「ReactiveFormsModule」を読み込みます。先ほどの作業により「MaterialModule」の記述も自動的に追加されています。
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { CustomerEditComponent } from './customer-edit/customer-edit.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MaterialModule } from './material.module';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent,
CustomerEditComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
MaterialModule,
FormsModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
ここからはアプリのファイルになります。ここではapp.component.html、app.component.ts、app.component.cssとしています。
app.component.ts
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
toppings = new FormControl();
toppingList: string[] = ['チーズ増量', 'マッシュルーム', 'オニオン', 'ペパロニ', 'ソーセージ', 'トマト'];
}
app.component.html
<mat-form-field appearance="fill">
<mat-label>トッピング</mat-label>
<mat-select [formControl]="toppings" multiple>
<mat-select-trigger>
{{toppings.value ? toppings.value[0] : ''}}
<span *ngIf="toppings.value?.length > 1" class="example-additional-selection">
(+{{toppings.value.length - 1}} {{toppings.value?.length === 2 ? 'other' : 'others'}})
</span>
</mat-select-trigger>
<mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
</mat-select>
</mat-form-field>
app.component.css
.example-additional-selection {
opacity: 0.75;
font-size: 0.75em;
}
ここまでの設定で、トップ画像になっているようなSelectを作成することができました。