I have a Button with an Icon
Button logoutButton = new Button("Logout", VaadinIcon.SIGN_OUT.create());
How can i define, where the icon should be?
Per default it is left of the text.
But i want it on top of the text.
I have a Button with an Icon
Button logoutButton = new Button("Logout", VaadinIcon.SIGN_OUT.create());
How can i define, where the icon should be?
Per default it is left of the text.
But i want it on top of the text.
I may have missed it, but last time I checked (this was in June) I couldn’t find a way to get the icon on the top.
I ended up writing a simple icon button with a polymer template:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">
<link rel="import" href="../../bower_components/vaadin-icons/vaadin-icons.html">
<dom-module id="icon-button">
<template>
<style>
:host {
width: 80px;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
color: var(--lumo-contrast-60pct);
}
:host(:hover:not([disabled]
)), :host([focus-ring]
:not([disabled]
)) {
color: var(--lumo-body-text-color);
}
:host([disabled]
) {
color: var(--lumo-contrast-30pct);
pointer-events: none;
}
label {
display: block;
cursor: pointer;
margin-top: .5em;
}
iron-icon {
display: block;
margin: 0 auto;
cursor: pointer;
font-size: 2em;
}
</style>
<div class="box box2">
<iron-icon id="iconx" icon="vaadin:plus"></iron-icon>
<label id="label">Label</label>
</div>
</template>
<script>
class IconButton extends Polymer.Element {
static get is() {
return 'icon-button';
}
static get properties() {
return {
// Declare your properties here.
};
}
}
customElements.define(IconButton.is, IconButton);
</script>
</dom-module>
And
package bc.ui.components;
import com.vaadin.flow.component.ClickEvent;
import com.vaadin.flow.component.ComponentEventListener;
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.html.Label;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.polymertemplate.Id;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
import com.vaadin.flow.shared.Registration;
import com.vaadin.flow.templatemodel.TemplateModel;
/**
* A Designer generated component for the icon-button.html template.
*
* Designer will add and remove fields with @Id mappings but does not overwrite
* or otherwise change this file.
*/
@Tag("icon-button")
@HtmlImport("src/components/icon-button.html")
public class IconButton extends PolymerTemplate<IconButton.IconButtonModel> {
@Id("iconx")
private Icon icon;
@Id("label")
private Label label;
private boolean disabled;
private static PropertyDescriptor<String, String> VALUE = PropertyDescriptors.propertyWithDefault("value", "");
public String getValue() {
return get(VALUE);
}
public void setValue(String value) {
set(VALUE, value);
}
/**
* Creates a new IconButton.
*/
public IconButton() {
// You can initialise any data required for the connected UI components
// here.
}
public IconButton(String label, VaadinIcon icon) {
setLabel(label);
setIcon(icon);
}
public IconButton(String label, VaadinIcon icon, boolean enabled) {
setLabel(label);
setIcon(icon);
setDisabled(!enabled);
}
public IconButton(String label, VaadinIcon icon, boolean enabled, ComponentEventListener listener) {
setLabel(label);
setIcon(icon);
setDisabled(!enabled);
addClickListener(listener);
}
public IconButton(String label, String icon, boolean enabled, ComponentEventListener listener) {
this(label, VaadinIcon.valueOf(icon), enabled, listener);
}
/**
* This model binds properties between IconButton and icon-button.html
*/
public interface IconButtonModel extends TemplateModel {
// Add setters and getters for template properties here.
}
public void setIcon(VaadinIcon icon) {
this.icon.getElement().setAttribute("icon", "vaadin:" + icon.name().toLowerCase().replace('_', '-'));
}
public void setLabel(String text) {
this.label.setText(text);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public Registration addClickListener(ComponentEventListener listener) {
return this.addListener(ClickEvent.class, listener);
}
public boolean isDisabled() {
return disabled;
}
public void setDisabled(boolean disabled) {
if (this.disabled == disabled)
return;
this.getElement().setAttribute("disabled", "true");
this.disabled = disabled;
}
}
Hi hans-georg!
This should do it:
Button rightButton = new Button("Right",
new Icon(VaadinIcon.ARROW_RIGHT));
rightButton.setIconAfterText(true);
Found the example from https://vaadin.com/components/button/java-examples
Hey Martin!
You should really avoid recreating existing components like this. Now your button is missing basic accessibility features like keyboard navigation and screen reader support.
I can suggest two better alternatives, reusing the existing Button component.
Button button = new Button();
Icon icon = new Icon(VaadinIcon.ARROW_RIGHT);
button.getElement().appendChild(icon.getElement());
button.getElement().appendChild(new Div("Button label"));
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">
<link rel="import" href="../../bower_components/vaadin-button/vaadin-button.html">
<dom-module id="icon-button">
<template>
<vaadin-button>
<iron-icon id="iconx" icon="vaadin:plus"></iron-icon>
<div id="label">Label</div>
</vaadin-button>
</template>
<script>
class IconButton extends Polymer.Element {
static get is() {
return 'icon-button';
}
static get properties() {
return {
// Declare your properties here.
};
}
}
customElements.define(IconButton.is, IconButton);
</script>
</dom-module>
Thanks
now it works
Jouni Koivuviita:
Hey Martin!You should really avoid recreating existing components like this. Now your button is missing basic accessibility features like keyboard navigation and screen reader support.
I can suggest two better alternatives, reusing the existing Button component.
- Use the Element API:
Button button = new Button(); Icon icon = new Icon(VaadinIcon.ARROW_RIGHT); button.getElement().appendChild(icon.getElement()); button.getElement().appendChild(new Div("Button label"));
- Use PolymerTemplate (like you did) and reuse vaadin-button:
<link rel="import" href="../../bower_components/polymer/polymer.html"> <link rel="import" href="../../bower_components/iron-icon/iron-icon.html"> <link rel="import" href="../../bower_components/vaadin-button/vaadin-button.html"> <dom-module id="icon-button"> <template> <vaadin-button> <iron-icon id="iconx" icon="vaadin:plus"></iron-icon> <div id="label">Label</div> </vaadin-button> </template> <script> class IconButton extends Polymer.Element { static get is() { return 'icon-button'; } static get properties() { return { // Declare your properties here. }; } } customElements.define(IconButton.is, IconButton); </script> </dom-module>
Thank it work fine!
I am using the Material theme using Vaadin 18, and a Button with an Icon and no text and it is not centred - the padding appears either in front of, or after the icon depending on whether setIconAfterText is true or false.
The examples provided in the documentation show the icons correctly centred.
[https://vaadin.com/components/vaadin-button/java-examples]
(https://vaadin.com/components/vaadin-button/java-examples)
Any thoughts on this ?
On further testing, this appears to be an issue with the Materials Theme…