vaadin-notification で通知パネルの背景色を動的に変更する
Vaadin Flow(1.0.0 Beta 3)で、通知パネルの色を動的に変更する方法を調べました。
通知コンポーネント vaadin-notification では、コンテンツ表示用のパネルに相当する部分は vaadin-notification-card コンポーネントで実装されています。
そのため、vaadin-notification-card コンポーネントに対して ThemableMixin でスタイルをあてるとパネルの背景色を変えられます。
<!-- src/theme/ex-notification-style.html --> <dom-module id="ex-notification-style" theme-for="vaadin-notification-card"> <template> <style> :host { --lumo-base-color: blue; /** 有効 */ } [part="overlay"] { color: white; background-color: red; /** 効かない。セレクタを div[part="overlay"]にすると有効になる */ } </style> </template> </dom-module>
<!-- 通知を利用するコンポーネントでは、通知コンポーネントのMixinスタイルをインポート --> <link rel="import" href="/frontend/src/theme/ex-notification-style.html"> <dom-module> ... </dom-module>
// Javaで通知を表示する Notification.show("Hello!", 5000, Position.TOP_STRETCH);
しかし、この方法では、Javaから通知パネルの背景色を動的に変更することができません。
vaadin-notification では、その内部で、通知パネルに相当する vaadin-notification-card コンポーネントのDOMを、body 配下に作成した vaadin-notification-container に移動させています。
そのため、vaadin-notification のスタイルクラスを動的に変えても、 vaadin-notification-card と親子関係がないので vaadin-notification-card に適用されるスタイルを変えることができません。
また、このDOM操作のためか vaadin-notification-card は、Javaから扱うことができませんでした。 (正確には何らかの手段があるのかもしれませんが...)
vaadin-notification-card に適用するスタイルを動的に変える手立てが見つけられないので、独自コンポーネントを作成して、Java側から背景色を指定できるように拡張します。
Javaでは、Notificationを継承し、プロパティ notificationType を指定できるようにします。
import com.vaadin.flow.component.Component; import com.vaadin.flow.component.PropertyDescriptor; import com.vaadin.flow.component.PropertyDescriptors; import com.vaadin.flow.component.Tag; import com.vaadin.flow.component.dependency.HtmlImport; import com.vaadin.flow.component.notification.Notification; @Tag("ex-notification") @HtmlImport("src/component/ex-notification.html") public class ExNotification extends Notification { private static PropertyDescriptor<String, String> NOTIFICATION_TYPE = PropertyDescriptors.propertyWithDefault("notificationType", ""); public ExNotification() {} public ExNotification(String text) { super(text); } public ExNotification(String text, int duration) { super(text, duration); } public ExNotification(String text, int duration, Position position) { super(text, duration, position); } public ExNotification(Component... components) { super(components); } public String getNotificationType() { return get(NOTIFICATION_TYPE); } public void setNotificationType(String notificationType) { set(NOTIFICATION_TYPE, notificationType); } public static ExNotification showAsInfo(String text, int duration, Position position) { ExNotification notification = new ExNotification(text, duration, position); notification.setNotificationType("info"); notification.open(); return notification; } public static ExNotification showAsError(String text, int duration, Position position) { ExNotification notification = new ExNotification(text, duration, position); notification.setNotificationType("error"); notification.open(); return notification; } }
HTMLでは、プロパティ notificationType を、vaadin-notification-card の属性に伝搬させます。
また、CSSで、notification-type属性に応じて背景色が切り替わるようにします。
<!-- src/component/ex-notification.html --> <link rel="import" href="/frontend/bower_components/vaadin-notification/vaadin-notification.html"/> <dom-module id="ex-notification-style" theme-for="vaadin-notification-card"> <template> <style> :host([notification-type="info"]) [part="overlay"] { color: white; background-color: blue; } :host([notification-type="error"]) [part="overlay"] { color: white; background-color: red; } </style> </template> </dom-module> <dom-module id="ex-notification"> <script> class ExNotification extends Vaadin.NotificationElement { static get is() { return 'ex-notification' } static get properties() { return {notificationType: {type: String, observer: '_changeNotificationType'}}; } _changeNotificationType(notificationType) { const card = this._card || this.$['vaadin-notification-card']; if(notificationType){ card.setAttribute('notification-type', notificationType); } else { card.removeAttribute('notification-type'); } } } customElements.define(ExNotification.is, ExNotification); </script> </dom-module>
このコンポーネントを利用すると以下のようなコードで、背景色を変えてメッセージを表示することができるようになりました。
ExNotification.showAsInfo("Info message!", 5000, Position.TOP_STRETCH); ExNotification.showAsError("Error message!", 5000, Position.TOP_STRETCH);
Vaddin Flow は、現時点ではまだβ版です。
ニーズが高く、不足している機能はいずれ提供されそうな気がしますが、今の所は、独自コンポーネントによる拡張で補うのが良さそうです。
なお、私自身は、Vaadin初学者で、まだドキュメントを読みながら試行錯誤している段階です。
もっと良いやり方があれば、提示頂けると大変助かります。