John67
(John Melody)
November 28, 2019, 10:05am
1
I have a application that used Vaadin 10 and changed the background color of a vaadin text field using the following in a my-text-field.html file.
<dom-module id="my-text-field" theme-for="vaadin-text-field">
<template>
<style include="vaadin-text-field-default-theme">
:host(.custom-style) [part="input-field"]
{
background-color: #909090 ;
}
:host(.ok) [part="input-field"]
{
background-color: #40bf80;
}
:host(.nok) [part="input-field"]
{
background-color: #ff0000;
}
:host(.init) [part="input-field"]
{
background-color: #909090;
}
:host(.view-toolbar__search-field) [part="input-field"]
{
background-color: #909090;
}
</style>
</template>
<!-- Polymer boilerplate to register the my-text-field element -->
<script>
class MyTextFieldElement extends Polymer.Element {
static get is() {
return 'my-text-field'
}
_isEmpty(array) {
return array.length == 0;
}
}
customElements.define(MyTextFieldElement.is, MyTextFieldElement);
</script>
</dom-module>
In the Java class that extended the PolymerTemplate I used a
@HtmlImport("frontend://src/views/paymentslist/my-text-field.html")
How do I do this with Vaadin 14 ?
I have tried the following for Vaadin 14 by creating a my-text-field.js file
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {html} from '@polymer/polymer/lib/utils/html-tag.js';
import '@vaadin/vaadin-text-field/vaadin-text-field.js';
//set your custom CSS rules for button.
//Use an unique id for the dom-module.
const $_documentContainer = html`
<dom-module id="my-text-field"
theme-for="vaadin-text-field">
<template>
<style include="vaadin-text-field-default-theme">
:host(.custom-style) [part="input-field"]
{
background-color: #909090 ;
}
:host(.ok) [part="input-field"]
{
background-color: #40bf80;
}
:host(.nok) [part="input-field"]
{
background-color: #ff0000;
}
:host(.init) [part="input-field"]
{
background-color: #909090;
}
:host(.view-toolbar__search-field) [part="input-field"]
{
background-color: #909090;
}
</style>
</template>
</dom-module>`;
document.head.appendChild($_documentContainer.content);
and used a @JsModule to import it in the Java class that extends the PolymerTemplate
@JsModule("./src/views/paymentslist/my-text-field.js")
However it doesn’t seem to work and I am not sure what I am doing wrong.
Grateful for any suggestions.
Thanks, John.
Jouni1
(Jouni Koivuviita)
November 28, 2019, 11:47am
2
Hi John!
If you are simply trying to add style customizations for the Vaadin Text Field component, here’s what you need:
A plain CSS file, for example /frontend/styles/text-field.css
:
:host(.custom-style) [part="input-field"]
{
background-color: #909090 ;
}
:host(.ok) [part="input-field"]
{
background-color: #40bf80;
}
:host(.nok) [part="input-field"]
{
background-color: #ff0000;
}
:host(.init) [part="input-field"]
{
background-color: #909090;
}
:host(.view-toolbar__search-field) [part="input-field"]
{
background-color: #909090;
}
Use the @CssImport
annotation, probably at the main class of your app:
@CssImport(value = "./styles/text-field.css", themeFor = "vaadin-text-field")
Jouni1
(Jouni Koivuviita)
November 28, 2019, 11:50am
3
Your previous solution seemed unnecessarily complex, by the way. You don’t need to extend a PolymerTemplate or Polymer.Element in the client-side to make style customizations, and you don’t need to re-include any additional style modules (like you did with “vaadin-text-field-default-theme”).
Before Vaadin 14 you only needed a single HTML file with a style module (i.e. dom-module with just a <style>
in the template) and the @HtmlImport
annotation like you had before (probably in the main class of your app):
<dom-module id="my-text-field" theme-for="vaadin-text-field">
<template>
<style>
:host(.custom-style) [part="input-field"]
{
background-color: #909090 ;
}
:host(.ok) [part="input-field"]
{
background-color: #40bf80;
}
:host(.nok) [part="input-field"]
{
background-color: #ff0000;
}
:host(.init) [part="input-field"]
{
background-color: #909090;
}
:host(.view-toolbar__search-field) [part="input-field"]
{
background-color: #909090;
}
</style>
</template>
</dom-module>
John67
(John Melody)
November 28, 2019, 5:26pm
4
Thanks, Jouni. That helped a lot and now works.
If I have my own element … example something like the vaadin example review list element
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {html} from '@polymer/polymer/lib/utils/html-tag.js';
import '@vaadin/vaadin-button/vaadin-button.js';
import '@vaadin/vaadin-text-field/vaadin-text-field.js';
import '@polymer/iron-icon/iron-icon.js';
class ReviewListElement extends PolymerElement {
static get template() {
return html`
<style include="lumo-color lumo-typography lumo-badge view-styles">
:host {
display: block;
}
#header {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: baseline;
}
.reviews__no-matches {
display: flex;
align-items: center;
justify-content: center;
height: 4em;
font-size: 22px;
color: var(--lumo-tertiary-text-color);
}
/* Small viewport styles */
@media (max-width: 500px) {
.review {
padding: var(--lumo-space-m);
padding-right: var(--lumo-space-s);
flex-wrap: wrap;
}
.review__date {
order: 1;
margin-left: 3.5em;
margin-top: 0.5em;
}
}
</style>
<div class="view-toolbar">
<vaadin-text-field id="search" class="view-toolbar__search-field" autocapitalize="off">
<iron-icon icon="lumo:search" slot="prefix"></iron-icon>
</vaadin-text-field>
<vaadin-button id="newReview" class="view-toolbar__button" theme="primary">
<iron-icon icon="lumo:plus" slot="prefix"></iron-icon>
<span>[[reviewButtonText]
]</span>
</vaadin-button>
</div>
<div class="view-container reviews">
<h2 id="header"></h2>
<template is="dom-if" if="{{!_isEmpty(reviews)}}">
<template is="dom-repeat" items="[[reviews]
]">
<div class="review">
<div class="review__rating">
<p class="review__score" data-score\$="[[item.score]
]">[[item.score]
]</p>
<p class="review__count">
[[item.count]
]
<span>times tasted</span>
</p>
</div>
<div class="review__details">
<h4 class="review__name">{{item.name}}</h4>
<template is="dom-if" if="[[item.category]
]">
<p class="review__category" theme="badge small" style\$="--category: [[item.category.id]
];">[[item.category.name]
]</p>
</template>
<template is="dom-if" if="[[!item.category]
]">
<p class="review__category" style="--category: -1;">Undefined</p>
</template>
</div>
<div class="review__date">
<h5>Last tasted</h5>
<p>[[item.date]
]</p>
</div>
<vaadin-button on-click="logClick" class="review__edit" theme="tertiary">
<iron-icon icon="lumo:edit"></iron-icon><span>[[editButtonText]
]</span>
</vaadin-button>
</div>
</template>
</template>
<template is="dom-if" if="{{_isEmpty(reviews)}}">
<div class="reviews__no-matches">No matches</div>
</template>
</div>
`;
}
static get is() {
return 'reviews-list'
}
logClick() {
console.log("Button clicked");
console.log(item.name)
}
_isEmpty(array) {
return array.length == 0;
}
}
customElements.define(ReviewListElement.is, ReviewListElement);
The styling is included in the element code using a tag.
Is that the right/best way to style an element you create or should you
create a reviews-list-style.css
and do a
@CssImport(value="./styles/reviews-list-style.css", themeFor="reviews-list")
I tried this but it doesn’t work for me. Whereas keeping the CSS in the element between the tags does.
Sami
(Sami Ekblad)
December 29, 2022, 5:53pm
5
In case someone is looking how to do this with Vaadin 14.
Java:
myField.addClassName("edited");
CSS that matches TextField, TextArea, DateField, Select, etc using Lumo theme:
.edited {
--field-border: inset 0 0 0 1px #CA9605;
--field-background: #FEF1CD;
}
.edited::part(checkbox) {
box-shadow: inset 0 0 0 1px #CA9605;
background-color: #FEF1CD;
}