diff --git a/vaadin/.gitignore b/vaadin/.gitignore
new file mode 100644
index 0000000000..1ef3efefbd
--- /dev/null
+++ b/vaadin/.gitignore
@@ -0,0 +1 @@
+frontend/generated
\ No newline at end of file
diff --git a/vaadin/frontend/index.html b/vaadin/frontend/index.html
new file mode 100644
index 0000000000..d36e593475
--- /dev/null
+++ b/vaadin/frontend/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vaadin/pom.xml b/vaadin/pom.xml
index e3786471f5..ea9a3ed75a 100644
--- a/vaadin/pom.xml
+++ b/vaadin/pom.xml
@@ -1,13 +1,12 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.test
vaadin
1.0-SNAPSHOT
vaadin
- war
com.baeldung
@@ -16,6 +15,11 @@
../parent-boot-3
+
+ 17
+ 24.3.3
+
+
@@ -30,39 +34,24 @@
- javax.servlet
- javax.servlet-api
- 4.0.1
- provided
+ com.vaadin
+ vaadin-core
com.vaadin
- vaadin-server
- ${vaadin-server.version}
-
-
- com.vaadin
- vaadin-push
- ${vaadin-push.version}
-
-
- com.vaadin
- vaadin-client-compiled
- ${vaadin-client-compiled.version}
-
-
- com.vaadin
- vaadin-themes
- ${vaadin-themes.version}
+ vaadin-spring-boot-starter
org.springframework.boot
spring-boot-starter-data-jpa
- com.vaadin
- vaadin-spring-boot-starter
- ${vaadin-spring-boot-starter.version}
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ io.projectreactor
+ reactor-core
com.h2database
@@ -77,47 +66,17 @@
-
- org.apache.maven.plugins
- maven-war-plugin
- ${maven-war-plugin.version}
-
- false
-
- WEB-INF/classes/VAADIN/widgetsets/WEB-INF/**
-
-
com.vaadin
vaadin-maven-plugin
- ${vaadin.plugin.version}
-
-
- org.apache.maven.plugins
- maven-clean-plugin
- ${maven-clean-plugin.version}
-
-
-
-
- src/main/webapp/VAADIN/themes
-
- **/styles.css
- **/styles.scss.cache
-
-
-
-
-
-
-
-
- org.eclipse.jetty
- jetty-maven-plugin
- ${jetty.plugin.version}
-
- 2
-
+ ${vaadin.version}
+
+
+
+ prepare-frontend
+
+
+
org.springframework.boot
@@ -126,68 +85,41 @@
-
-
- vaadin-addons
- https://maven.vaadin.com/vaadin-addons
-
-
-
- vaadin-prerelease
-
- false
-
-
-
-
- vaadin-prereleases
- https://maven.vaadin.com/vaadin-prereleases
-
-
- vaadin-snapshots
- https://oss.sonatype.org/content/repositories/vaadin-snapshots/
-
- false
-
-
- true
-
-
-
-
-
- vaadin-prereleases
- https://maven.vaadin.com/vaadin-prereleases
-
-
- vaadin-snapshots
- https://oss.sonatype.org/content/repositories/vaadin-snapshots/
-
- false
-
-
- true
-
-
-
+
+ production
+
+
+
+ com.vaadin
+ vaadin-core
+
+
+ com.vaadin
+ vaadin-dev
+
+
+
+
+
+
+
+ com.vaadin
+ vaadin-maven-plugin
+ ${vaadin.version}
+
+
+
+ build-frontend
+
+ compile
+
+
+
+
+
-
-
- 13.0.9
- 13.0.9
- 13.0.9
- 8.8.5
- 8.8.5
- 8.8.5
- 8.8.5
- 9.3.9.v20160517
- local
- mytheme
- 3.0.0
-
-
\ No newline at end of file
diff --git a/vaadin/src/main/java/com/baeldung/Application.java b/vaadin/src/main/java/com/baeldung/Application.java
index 1d3084723a..b62dd79158 100644
--- a/vaadin/src/main/java/com/baeldung/Application.java
+++ b/vaadin/src/main/java/com/baeldung/Application.java
@@ -1,15 +1,19 @@
package com.baeldung;
+import com.baeldung.data.Employee;
+import com.baeldung.data.EmployeeRepository;
+import com.vaadin.flow.component.page.AppShellConfigurator;
+import com.vaadin.flow.component.page.Push;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
+@Push
@SpringBootApplication
-public class Application {
+public class Application implements AppShellConfigurator {
private static final Logger log = LoggerFactory.getLogger(Application.class);
diff --git a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/EmployeeEditor.java
deleted file mode 100644
index ee312786d1..0000000000
--- a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.baeldung;
-
-import com.vaadin.flow.component.Key;
-import com.vaadin.flow.component.KeyNotifier;
-import com.vaadin.flow.component.button.Button;
-import com.vaadin.flow.component.icon.VaadinIcon;
-import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
-import com.vaadin.flow.component.orderedlayout.VerticalLayout;
-import com.vaadin.flow.component.textfield.TextField;
-import com.vaadin.flow.data.binder.Binder;
-import com.vaadin.flow.spring.annotation.SpringComponent;
-import com.vaadin.flow.spring.annotation.UIScope;
-import org.springframework.beans.factory.annotation.Autowired;
-
-@SpringComponent
-@UIScope
-public class EmployeeEditor extends VerticalLayout implements KeyNotifier {
-
- private final EmployeeRepository repository;
-
- private Employee employee;
-
- TextField firstName = new TextField("First name");
- TextField lastName = new TextField("Last name");
-
- Button save = new Button("Save", VaadinIcon.CHECK.create());
- Button cancel = new Button("Cancel");
- Button delete = new Button("Delete", VaadinIcon.TRASH.create());
- HorizontalLayout actions = new HorizontalLayout(save, cancel, delete);
-
- Binder binder = new Binder<>(Employee.class);
- private ChangeHandler changeHandler;
-
- @Autowired
- public EmployeeEditor(EmployeeRepository repository) {
- this.repository = repository;
-
- add(firstName, lastName, actions);
-
- binder.bindInstanceFields(this);
-
- setSpacing(true);
-
- save.getElement().getThemeList().add("primary");
- delete.getElement().getThemeList().add("error");
-
- addKeyPressListener(Key.ENTER, e -> save());
-
- save.addClickListener(e -> save());
- delete.addClickListener(e -> delete());
- cancel.addClickListener(e -> editEmployee(employee));
- setVisible(false);
- }
-
- void delete() {
- repository.delete(employee);
- changeHandler.onChange();
- }
-
- void save() {
- repository.save(employee);
- changeHandler.onChange();
- }
-
- public interface ChangeHandler {
- void onChange();
- }
-
- public final void editEmployee(Employee c) {
- if (c == null) {
- setVisible(false);
- return;
- }
- final boolean persisted = c.getId() != null;
- if (persisted) {
- employee = repository.findById(c.getId()).get();
- } else {
- employee = c;
- }
-
- cancel.setVisible(persisted);
- binder.setBean(employee);
- setVisible(true);
- firstName.focus();
- }
-
- public void setChangeHandler(ChangeHandler h) {
- changeHandler = h;
- }
-}
diff --git a/vaadin/src/main/java/com/baeldung/IndexView.java b/vaadin/src/main/java/com/baeldung/IndexView.java
new file mode 100644
index 0000000000..45ab534ef6
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/IndexView.java
@@ -0,0 +1,25 @@
+package com.baeldung;
+
+import com.baeldung.introduction.PushView;
+import com.baeldung.introduction.basics.VaadinFlowBasics;
+import com.baeldung.introduction.FormView;
+import com.baeldung.introduction.GridView;
+import com.baeldung.spring.EmployeesView;
+import com.vaadin.flow.component.html.H1;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.router.Route;
+import com.vaadin.flow.router.RouterLink;
+
+@Route("")
+public class IndexView extends VerticalLayout {
+
+ public IndexView() {
+ add(new H1("Vaadin Flow examples"));
+
+ add(new RouterLink("Basics", VaadinFlowBasics.class));
+ add(new RouterLink("Grid", GridView.class));
+ add(new RouterLink("Form", FormView.class));
+ add(new RouterLink("Push", PushView.class));
+ add(new RouterLink("CRUD", EmployeesView.class));
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/MainView.java b/vaadin/src/main/java/com/baeldung/MainView.java
deleted file mode 100644
index 6d4c0aaa88..0000000000
--- a/vaadin/src/main/java/com/baeldung/MainView.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.baeldung;
-
-import org.springframework.util.StringUtils;
-
-import com.vaadin.flow.component.button.Button;
-import com.vaadin.flow.component.grid.Grid;
-import com.vaadin.flow.component.icon.VaadinIcon;
-import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
-import com.vaadin.flow.component.orderedlayout.VerticalLayout;
-import com.vaadin.flow.component.textfield.TextField;
-import com.vaadin.flow.data.value.ValueChangeMode;
-import com.vaadin.flow.router.Route;
-
-@Route
-public class MainView extends VerticalLayout {
-
- private final EmployeeRepository employeeRepository;
-
- private final EmployeeEditor editor;
-
- final Grid grid;
-
- final TextField filter;
-
- private final Button addNewBtn;
-
- public MainView(EmployeeRepository repo, EmployeeEditor editor) {
- this.employeeRepository = repo;
- this.editor = editor;
- this.grid = new Grid<>(Employee.class);
- this.filter = new TextField();
- this.addNewBtn = new Button("New employee", VaadinIcon.PLUS.create());
-
- HorizontalLayout actions = new HorizontalLayout(filter, addNewBtn);
- add(actions, grid, editor);
-
- grid.setHeight("200px");
- grid.setColumns("id", "firstName", "lastName");
- grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0);
-
- filter.setPlaceholder("Filter by last name");
-
- filter.setValueChangeMode(ValueChangeMode.EAGER);
- filter.addValueChangeListener(e -> listEmployees(e.getValue()));
-
- grid.asSingleSelect().addValueChangeListener(e -> {
- editor.editEmployee(e.getValue());
- });
-
- addNewBtn.addClickListener(e -> editor.editEmployee(new Employee("", "")));
-
- editor.setChangeHandler(() -> {
- editor.setVisible(false);
- listEmployees(filter.getValue());
- });
-
- listEmployees(null);
- }
-
- void listEmployees(String filterText) {
- if (StringUtils.isEmpty(filterText)) {
- grid.setItems(employeeRepository.findAll());
- } else {
- grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText));
- }
- }
-}
diff --git a/vaadin/src/main/java/com/baeldung/data/Contact.java b/vaadin/src/main/java/com/baeldung/data/Contact.java
new file mode 100644
index 0000000000..8e534d5bb0
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/data/Contact.java
@@ -0,0 +1,73 @@
+package com.baeldung.data;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Pattern;
+
+@Entity
+public class Contact {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+ @NotBlank
+ private String name;
+ @Email
+ private String email;
+ @Pattern(regexp = "\\d{3}-\\d{3}-\\d{4}")
+ private String phone;
+
+ public Contact() {
+ }
+
+ public Contact(String name, String email, String phone) {
+ this.name = name;
+ this.email = email;
+ this.phone = phone;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ @Override
+ public String toString() {
+ return "Contact {" +
+ "id=" + id +
+ ", name='" + name + "'" +
+ ", email='" + email + "'" +
+ ", phone='" + phone + "'" +
+ " }";
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/data/ContactRepository.java b/vaadin/src/main/java/com/baeldung/data/ContactRepository.java
new file mode 100644
index 0000000000..15c4adaaa9
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/data/ContactRepository.java
@@ -0,0 +1,6 @@
+package com.baeldung.data;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ContactRepository extends JpaRepository {
+}
diff --git a/vaadin/src/main/java/com/baeldung/data/DataInitializer.java b/vaadin/src/main/java/com/baeldung/data/DataInitializer.java
new file mode 100644
index 0000000000..dba162d4e4
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/data/DataInitializer.java
@@ -0,0 +1,46 @@
+package com.baeldung.data;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+@Component
+public class DataInitializer implements CommandLineRunner {
+
+ private final ContactRepository contactRepository;
+
+ public DataInitializer(ContactRepository contactRepository) {
+ this.contactRepository = contactRepository;
+ }
+
+ private final List firstNames = List.of(
+ "John", "Jane", "Emily", "Michael", "Sarah", "James", "Mary", "Robert",
+ "Patricia", "William", "Linda", "David", "Barbara", "Richard", "Susan",
+ "Joseph", "Jessica", "Thomas", "Karen", "Charles"
+ );
+ private final List lastNames = List.of(
+ "Doe", "Smith", "Johnson", "Brown", "Davis", "Miller", "Wilson", "Moore",
+ "Taylor", "Anderson", "Thomas", "Jackson", "White", "Harris", "Martin",
+ "Thompson", "Garcia", "Martinez", "Robinson", "Clark"
+ );
+
+ @Override
+ public void run(String... args) throws Exception {
+ var contacts = new ArrayList();
+ Random random = new Random();
+
+ for (int i = 0; i < 100; i++) {
+ String firstName = firstNames.get(random.nextInt(firstNames.size()));
+ String lastName = lastNames.get(random.nextInt(lastNames.size()));
+ String email = String.format("%s.%s@example.com", firstName.toLowerCase(), lastName.toLowerCase());
+ String phone = String.format("555-%03d-%04d", random.nextInt(1000), random.nextInt(10000));
+
+ contacts.add(new Contact(firstName + " " + lastName, email, phone));
+ }
+
+ contactRepository.saveAll(contacts);
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/Employee.java b/vaadin/src/main/java/com/baeldung/data/Employee.java
similarity index 75%
rename from vaadin/src/main/java/com/baeldung/Employee.java
rename to vaadin/src/main/java/com/baeldung/data/Employee.java
index 75a0dc84b3..cdaa426eeb 100644
--- a/vaadin/src/main/java/com/baeldung/Employee.java
+++ b/vaadin/src/main/java/com/baeldung/data/Employee.java
@@ -1,8 +1,10 @@
-package com.baeldung;
+package com.baeldung.data;
+
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
+import jakarta.validation.constraints.Size;
@Entity
public class Employee {
@@ -11,11 +13,13 @@ public class Employee {
@GeneratedValue
private Long id;
+ @Size(min = 2, message = "First name must have at least 2 characters")
private String firstName;
+ @Size(min = 2, message = "Last name must have at least 2 characters")
private String lastName;
- protected Employee() {
+ public Employee() {
}
public Employee(String firstName, String lastName) {
@@ -27,6 +31,10 @@ public class Employee {
return id;
}
+ public void setId(Long id) {
+ this.id = id;
+ }
+
public String getFirstName() {
return firstName;
}
diff --git a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java b/vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java
similarity index 89%
rename from vaadin/src/main/java/com/baeldung/EmployeeRepository.java
rename to vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java
index 044160da78..0d54148c85 100644
--- a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java
+++ b/vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.data;
import java.util.List;
diff --git a/vaadin/src/main/java/com/baeldung/introduction/BindData.java b/vaadin/src/main/java/com/baeldung/introduction/BindData.java
deleted file mode 100644
index 299554c039..0000000000
--- a/vaadin/src/main/java/com/baeldung/introduction/BindData.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.baeldung.introduction;
-
-public class BindData {
-
- private String bindName;
-
- public BindData(String bindName){
- this.bindName = bindName;
- }
-
- public String getBindName() {
- return bindName;
- }
-
- public void setBindName(String bindName) {
- this.bindName = bindName;
- }
-
-
-}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/FormView.java b/vaadin/src/main/java/com/baeldung/introduction/FormView.java
new file mode 100644
index 0000000000..34bc334b27
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/FormView.java
@@ -0,0 +1,88 @@
+package com.baeldung.introduction;
+
+import com.baeldung.data.Contact;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.html.H2;
+import com.vaadin.flow.component.notification.Notification;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.data.binder.BeanValidationBinder;
+import com.vaadin.flow.data.binder.Binder;
+import com.vaadin.flow.router.Route;
+
+@Route("form")
+public class FormView extends HorizontalLayout {
+
+ public FormView() {
+ addBeanValidationExample();
+ addCustomValidationExample();
+ }
+
+ private void addBeanValidationExample() {
+ var nameField = new TextField("Name");
+ var emailField = new TextField("Email");
+ var phoneField = new TextField("Phone");
+ var saveButton = new Button("Save");
+
+ var binder = new BeanValidationBinder<>(Contact.class);
+
+ binder.forField(nameField).bind(Contact::getName, Contact::setName);
+ binder.forField(emailField).bind(Contact::getEmail, Contact::setEmail);
+ binder.forField(phoneField).bind(Contact::getPhone, Contact::setPhone);
+
+ var contact = new Contact("John Doe", "john@doe.com", "123-456-7890");
+ binder.setBean(contact);
+
+ saveButton.addClickListener(e -> {
+ if (binder.validate().isOk()) {
+ Notification.show("Saved " + contact);
+ }
+ });
+
+ add(new VerticalLayout(
+ new H2("Bean Validation Example"),
+ nameField,
+ emailField,
+ phoneField,
+ saveButton
+ ));
+ }
+
+ private void addCustomValidationExample() {
+
+ var nameField = new TextField("Name");
+ var emailField = new TextField("Email");
+ var phoneField = new TextField("Phone");
+ var saveButton = new Button("Save");
+
+ var binder = new Binder<>(Contact.class);
+
+ binder.forField(nameField)
+ .asRequired()
+ .bind(Contact::getName, Contact::setName);
+ binder.forField(emailField)
+ .withValidator(email -> email.contains("@"), "Not a valid email address")
+ .bind(Contact::getEmail, Contact::setEmail);
+ binder.forField(phoneField)
+ .withValidator(phone -> phone.matches("\\d{3}-\\d{3}-\\d{4}"), "Not a valid phone number")
+ .bind(Contact::getPhone, Contact::setPhone);
+
+ var contact = new Contact("John Doe", "john@doe.com", "123-456-7890");
+ binder.setBean(contact);
+
+ saveButton.addClickListener(e -> {
+ if (binder.validate().isOk()) {
+ Notification.show("Saved " + contact);
+ }
+ });
+
+ add(new VerticalLayout(
+ new H2("Custom Validation Example"),
+ nameField,
+ emailField,
+ phoneField,
+ saveButton
+ ));
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/GridView.java b/vaadin/src/main/java/com/baeldung/introduction/GridView.java
new file mode 100644
index 0000000000..3d9500d7d8
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/GridView.java
@@ -0,0 +1,40 @@
+package com.baeldung.introduction;
+
+import com.baeldung.data.Contact;
+import com.baeldung.data.ContactRepository;
+import com.vaadin.flow.component.grid.Grid;
+import com.vaadin.flow.component.html.H1;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.router.Route;
+import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
+
+@Route("grid")
+public class GridView extends VerticalLayout {
+
+ public GridView(ContactRepository contactRepository) {
+
+ add(new H1("Using data grids"));
+
+ // Define a grid for a Contact entity
+ var grid = new Grid();
+ grid.addColumn(Contact::getName).setHeader("Name");
+ grid.addColumn(Contact::getEmail).setHeader("Email");
+ grid.addColumn(Contact::getPhone).setHeader("Phone");
+
+ // There are two ways to populate the grid with data:
+
+ // 1) In-memory with a list of items
+ var contacts = contactRepository.findAll();
+ grid.setItems(contacts);
+
+ // 2) with a callback to lazily load items from a data source.
+ grid.setItems(query -> {
+ // Turn the page, offset, filter, sort and other info in query into a Spring Data PageRequest
+ var pageRequest = VaadinSpringDataHelpers.toSpringPageRequest(query);
+ return contactRepository.findAll(pageRequest).stream();
+ });
+
+ add(grid);
+
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/PushView.java b/vaadin/src/main/java/com/baeldung/introduction/PushView.java
new file mode 100644
index 0000000000..b49aa06e4d
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/PushView.java
@@ -0,0 +1,32 @@
+package com.baeldung.introduction;
+
+import com.vaadin.flow.component.html.Span;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.router.Route;
+import reactor.core.publisher.Flux;
+
+import java.time.Duration;
+import java.time.Instant;
+
+// Ensure you have @Push annotation in your Application class
+@Route("push")
+public class PushView extends VerticalLayout {
+
+ public PushView() {
+ var output = new Span();
+
+ // Publish server time once a second
+ var serverTime = Flux.interval(Duration.ofSeconds(1))
+ .map(o -> "Server time: " + Instant.now());
+
+
+ serverTime.subscribe(time ->
+ // ui.access is required to update the UI from a background thread
+ getUI().ifPresent(ui ->
+ ui.access(() -> output.setText(time))
+ )
+ );
+
+ add(output);
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/Row.java b/vaadin/src/main/java/com/baeldung/introduction/Row.java
deleted file mode 100644
index 412a286376..0000000000
--- a/vaadin/src/main/java/com/baeldung/introduction/Row.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.baeldung.introduction;
-
-public class Row {
-
- private String column1;
-
- private String column2;
-
- private String column3;
-
- public Row() {
-
- }
-
- public Row(String column1, String column2, String column3) {
- super();
- this.column1 = column1;
- this.column2 = column2;
- this.column3 = column3;
- }
-
- public String getColumn1() {
- return column1;
- }
-
- public void setColumn1(String column1) {
- this.column1 = column1;
- }
-
- public String getColumn2() {
- return column2;
- }
-
- public void setColumn2(String column2) {
- this.column2 = column2;
- }
-
- public String getColumn3() {
- return column3;
- }
-
- public void setColumn3(String column3) {
- this.column3 = column3;
- }
-}
\ No newline at end of file
diff --git a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java b/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java
deleted file mode 100644
index 05a8340bde..0000000000
--- a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java
+++ /dev/null
@@ -1,281 +0,0 @@
-package com.baeldung.introduction;
-
-import java.time.Instant;
-import java.time.LocalDate;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import com.vaadin.annotations.Push;
-import com.vaadin.annotations.Theme;
-import com.vaadin.annotations.VaadinServletConfiguration;
-import com.vaadin.data.Binder;
-import com.vaadin.data.validator.StringLengthValidator;
-import com.vaadin.icons.VaadinIcons;
-import com.vaadin.server.ExternalResource;
-import com.vaadin.server.VaadinRequest;
-import com.vaadin.server.VaadinServlet;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.CheckBox;
-import com.vaadin.ui.ComboBox;
-import com.vaadin.ui.DateField;
-import com.vaadin.ui.FormLayout;
-import com.vaadin.ui.Grid;
-import com.vaadin.ui.GridLayout;
-import com.vaadin.ui.HorizontalLayout;
-import com.vaadin.ui.InlineDateField;
-import com.vaadin.ui.Label;
-import com.vaadin.ui.Link;
-import com.vaadin.ui.ListSelect;
-import com.vaadin.ui.NativeButton;
-import com.vaadin.ui.NativeSelect;
-import com.vaadin.ui.Panel;
-import com.vaadin.ui.PasswordField;
-import com.vaadin.ui.RichTextArea;
-import com.vaadin.ui.TextArea;
-import com.vaadin.ui.TextField;
-import com.vaadin.ui.TwinColSelect;
-import com.vaadin.ui.UI;
-import com.vaadin.ui.VerticalLayout;
-import jakarta.servlet.annotation.WebServlet;
-
-@SuppressWarnings("serial")
-@Push
-@Theme("mytheme")
-public class VaadinUI extends UI {
-
- private Label currentTime;
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override
- protected void init(VaadinRequest vaadinRequest) {
- final VerticalLayout verticalLayout = new VerticalLayout();
- verticalLayout.setSpacing(true);
- verticalLayout.setMargin(true);
- final GridLayout gridLayout = new GridLayout(3, 2);
- gridLayout.setSpacing(true);
- gridLayout.setMargin(true);
- final HorizontalLayout horizontalLayout = new HorizontalLayout();
- horizontalLayout.setSpacing(true);
- horizontalLayout.setMargin(true);
- final FormLayout formLayout = new FormLayout();
- formLayout.setSpacing(true);
- formLayout.setMargin(true);
- final GridLayout buttonLayout = new GridLayout(3, 5);
- buttonLayout.setMargin(true);
- buttonLayout.setSpacing(true);
-
- final Label label = new Label();
- label.setId("Label");
- label.setValue("Label Value");
- label.setCaption("Label");
- gridLayout.addComponent(label);
-
- final Link link = new Link("Baeldung", new ExternalResource("http://www.baeldung.com/"));
- link.setId("Link");
- link.setTargetName("_blank");
- gridLayout.addComponent(link);
-
- final TextField textField = new TextField();
- textField.setId("TextField");
- textField.setCaption("TextField:");
- textField.setValue("TextField Value");
- textField.setIcon(VaadinIcons.USER);
- gridLayout.addComponent(textField);
-
- final TextArea textArea = new TextArea();
- textArea.setCaption("TextArea");
- textArea.setId("TextArea");
- textArea.setValue("TextArea Value");
- gridLayout.addComponent(textArea);
-
- final DateField dateField = new DateField("DateField", LocalDate.ofEpochDay(0));
- dateField.setId("DateField");
- gridLayout.addComponent(dateField);
-
- final PasswordField passwordField = new PasswordField();
- passwordField.setId("PasswordField");
- passwordField.setCaption("PasswordField:");
- passwordField.setValue("password");
- gridLayout.addComponent(passwordField);
-
- final RichTextArea richTextArea = new RichTextArea();
- richTextArea.setCaption("Rich Text Area");
- richTextArea.setValue("RichTextArea
");
- richTextArea.setSizeFull();
-
- Panel richTextPanel = new Panel();
- richTextPanel.setContent(richTextArea);
-
- final InlineDateField inlineDateField = new InlineDateField();
- inlineDateField.setValue(LocalDate.ofEpochDay(0));
- inlineDateField.setCaption("Inline Date Field");
- horizontalLayout.addComponent(inlineDateField);
-
- Button normalButton = new Button("Normal Button");
- normalButton.setId("NormalButton");
- normalButton.addClickListener(e -> {
- label.setValue("CLICK");
- });
- buttonLayout.addComponent(normalButton);
-
- Button tinyButton = new Button("Tiny Button");
- tinyButton.addStyleName("tiny");
- buttonLayout.addComponent(tinyButton);
-
- Button smallButton = new Button("Small Button");
- smallButton.addStyleName("small");
- buttonLayout.addComponent(smallButton);
-
- Button largeButton = new Button("Large Button");
- largeButton.addStyleName("large");
- buttonLayout.addComponent(largeButton);
-
- Button hugeButton = new Button("Huge Button");
- hugeButton.addStyleName("huge");
- buttonLayout.addComponent(hugeButton);
-
- Button disabledButton = new Button("Disabled Button");
- disabledButton.setDescription("This button cannot be clicked");
- disabledButton.setEnabled(false);
- buttonLayout.addComponent(disabledButton);
-
- Button dangerButton = new Button("Danger Button");
- dangerButton.addStyleName("danger");
- buttonLayout.addComponent(dangerButton);
-
- Button friendlyButton = new Button("Friendly Button");
- friendlyButton.addStyleName("friendly");
- buttonLayout.addComponent(friendlyButton);
-
- Button primaryButton = new Button("Primary Button");
- primaryButton.addStyleName("primary");
- buttonLayout.addComponent(primaryButton);
-
- NativeButton nativeButton = new NativeButton("Native Button");
- buttonLayout.addComponent(nativeButton);
-
- Button iconButton = new Button("Icon Button");
- iconButton.setIcon(VaadinIcons.ALIGN_LEFT);
- buttonLayout.addComponent(iconButton);
-
- Button borderlessButton = new Button("BorderLess Button");
- borderlessButton.addStyleName("borderless");
- buttonLayout.addComponent(borderlessButton);
-
- Button linkButton = new Button("Link Button");
- linkButton.addStyleName("link");
- buttonLayout.addComponent(linkButton);
-
- Button quietButton = new Button("Quiet Button");
- quietButton.addStyleName("quiet");
- buttonLayout.addComponent(quietButton);
-
- horizontalLayout.addComponent(buttonLayout);
-
- final CheckBox checkbox = new CheckBox("CheckBox");
- checkbox.setValue(true);
- checkbox.addValueChangeListener(e -> checkbox.setValue(!checkbox.getValue()));
- formLayout.addComponent(checkbox);
-
- List numbers = new ArrayList();
- numbers.add("One");
- numbers.add("Ten");
- numbers.add("Eleven");
- ComboBox comboBox = new ComboBox("ComboBox");
- comboBox.setItems(numbers);
- formLayout.addComponent(comboBox);
-
- ListSelect listSelect = new ListSelect("ListSelect");
- listSelect.setItems(numbers);
- listSelect.setRows(2);
- formLayout.addComponent(listSelect);
-
- NativeSelect nativeSelect = new NativeSelect("NativeSelect");
- nativeSelect.setItems(numbers);
- formLayout.addComponent(nativeSelect);
-
- TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect");
- twinColSelect.setItems(numbers);
-
- Grid grid = new Grid(Row.class);
- grid.setColumns("column1", "column2", "column3");
- Row row1 = new Row("Item1", "Item2", "Item3");
- Row row2 = new Row("Item4", "Item5", "Item6");
- List rows = new ArrayList();
- rows.add(row1);
- rows.add(row2);
- grid.setItems(rows);
-
- Panel panel = new Panel("Panel");
- panel.setContent(grid);
- panel.setSizeUndefined();
-
- Panel serverPushPanel = new Panel("Server Push");
- FormLayout timeLayout = new FormLayout();
- timeLayout.setSpacing(true);
- timeLayout.setMargin(true);
- currentTime = new Label("No TIME...");
- timeLayout.addComponent(currentTime);
- serverPushPanel.setContent(timeLayout);
- serverPushPanel.setSizeUndefined();
- ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1);
- Runnable task = () -> {
- currentTime.setValue("Current Time : " + Instant.now());
- };
- scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);
-
- FormLayout dataBindingLayout = new FormLayout();
- dataBindingLayout.setSpacing(true);
- dataBindingLayout.setMargin(true);
-
- Binder binder = new Binder<>();
- BindData bindData = new BindData("BindData");
- binder.readBean(bindData);
- TextField bindedTextField = new TextField();
- bindedTextField.setWidth("250px");
- binder.forField(bindedTextField).bind(BindData::getBindName, BindData::setBindName);
- dataBindingLayout.addComponent(bindedTextField);
-
- FormLayout validatorLayout = new FormLayout();
- validatorLayout.setSpacing(true);
- validatorLayout.setMargin(true);
-
- HorizontalLayout textValidatorLayout = new HorizontalLayout();
- textValidatorLayout.setSpacing(true);
- textValidatorLayout.setMargin(true);
-
-
- BindData stringValidatorBindData = new BindData("");
- TextField stringValidator = new TextField();
- Binder stringValidatorBinder = new Binder<>();
- stringValidatorBinder.setBean(stringValidatorBindData);
- stringValidatorBinder.forField(stringValidator)
- .withValidator(new StringLengthValidator("String must have 2-5 characters lenght", 2, 5))
- .bind(BindData::getBindName, BindData::setBindName);
-
- textValidatorLayout.addComponent(stringValidator);
- Button buttonStringValidator = new Button("Validate String");
- buttonStringValidator.addClickListener(e -> stringValidatorBinder.validate());
- textValidatorLayout.addComponent(buttonStringValidator);
-
- validatorLayout.addComponent(textValidatorLayout);
- verticalLayout.addComponent(gridLayout);
- verticalLayout.addComponent(richTextPanel);
- verticalLayout.addComponent(horizontalLayout);
- verticalLayout.addComponent(formLayout);
- verticalLayout.addComponent(twinColSelect);
- verticalLayout.addComponent(panel);
- verticalLayout.addComponent(serverPushPanel);
- verticalLayout.addComponent(dataBindingLayout);
- verticalLayout.addComponent(validatorLayout);
- setContent(verticalLayout);
- }
-
- @WebServlet(urlPatterns = "/VAADIN/*", name = "MyUIServlet", asyncSupported = true)
- @VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false)
- public static class MyUIServlet extends VaadinServlet {
- }
-}
\ No newline at end of file
diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java b/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java
new file mode 100644
index 0000000000..6d6e2b2b7d
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java
@@ -0,0 +1,45 @@
+package com.baeldung.introduction.basics;
+
+import com.baeldung.data.Contact;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.grid.Grid;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.splitlayout.SplitLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.router.Route;
+
+import java.util.List;
+
+@Route("example-layout")
+public class ExampleLayout extends SplitLayout {
+
+ public ExampleLayout() {
+ var grid = new Grid<>(Contact.class);
+ grid.setColumns("name", "email", "phone");
+ grid.setItems(List.of(
+ new Contact("John Doe", "john@doe.com", "123 456 789"),
+ new Contact("Jane Doe", "jane@doe.com", "987 654 321")
+ ));
+
+ var form = new VerticalLayout();
+
+ var nameField = new TextField("Name");
+ var emailField = new TextField("Email");
+ var phoneField = new TextField("Phone");
+ var saveButton = new Button("Save");
+ var cancelButton = new Button("Cancel");
+
+ form.add(
+ nameField,
+ emailField,
+ phoneField,
+ new HorizontalLayout(saveButton, cancelButton)
+ );
+
+ setSizeFull();
+ setSplitterPosition(70);
+ addToPrimary(grid);
+ addToSecondary(form);
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java b/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java
new file mode 100644
index 0000000000..477cf378c6
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java
@@ -0,0 +1,13 @@
+package com.baeldung.introduction.basics;
+
+import com.vaadin.flow.component.html.H1;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.router.Route;
+
+@Route("hello-world")
+public class HelloWorldView extends VerticalLayout {
+
+ public HelloWorldView() {
+ add(new H1("Hello, World!"));
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java
new file mode 100644
index 0000000000..7a22eea0ab
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java
@@ -0,0 +1,63 @@
+package com.baeldung.introduction.basics;
+
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.checkbox.Checkbox;
+import com.vaadin.flow.component.html.H1;
+import com.vaadin.flow.component.notification.Notification;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.router.Route;
+import com.vaadin.flow.router.RouterLink;
+
+// The @Route annotation defines the URL path for the view
+// Any component, most commonly a layout, can be used as a view
+@Route("basics")
+public class VaadinFlowBasics extends VerticalLayout {
+ public VaadinFlowBasics() {
+
+ // Add components to the layout with the add method
+ add(new H1("Vaadin Flow Basics"));
+
+ // Components are Java objects
+ var textField = new TextField("Name");
+ var button = new Button("Click me");
+
+ // Layouts define the structure of the UI
+ var verticalLayout = new VerticalLayout(
+ new Button("Top"),
+ new Button("Middle"),
+ new Button("Bottom")
+ );
+ add(verticalLayout);
+
+ var horizontalLayout = new HorizontalLayout(
+ new Button("Left"),
+ new Button("Center"),
+ new Button("Right")
+ );
+ add(horizontalLayout);
+
+ // Layouts can be nested for more complex structures
+ var nestedLayout = new VerticalLayout(
+ new HorizontalLayout(new Button("Top Left"), new Button("Top Right")),
+ new HorizontalLayout(new Button("Bottom Left"), new Button("Bottom Right"))
+ );
+ add(nestedLayout);
+
+ add(new RouterLink("Example layout", ExampleLayout.class));
+
+ // Use RouterLink to navigate to other views
+ var link = new RouterLink("Hello world view", HelloWorldView.class);
+ add(link);
+
+ // Use events to react to user input
+ var nameField = new TextField("Your name");
+ var helloButton = new Button("Say hello");
+ helloButton.addClickListener(e -> {
+ Notification.show("Hello, " + nameField.getValue());
+ });
+ add(nameField, helloButton);
+
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java
new file mode 100644
index 0000000000..7984ecce05
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java
@@ -0,0 +1,86 @@
+package com.baeldung.spring;
+
+import com.baeldung.data.Employee;
+import com.vaadin.flow.component.Composite;
+import com.vaadin.flow.component.Key;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.button.ButtonVariant;
+import com.vaadin.flow.component.icon.VaadinIcon;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.data.binder.BeanValidationBinder;
+import com.vaadin.flow.data.binder.Binder;
+
+public class EmployeeEditor extends Composite {
+
+ public interface SaveListener {
+ void onSave(Employee employee);
+ }
+
+ public interface DeleteListener {
+ void onDelete(Employee employee);
+ }
+
+ public interface CancelListener {
+ void onCancel();
+ }
+
+ private Employee employee;
+
+ private SaveListener saveListener;
+ private DeleteListener deleteListener;
+ private CancelListener cancelListener;
+
+ private final Binder binder = new BeanValidationBinder<>(Employee.class);
+
+public EmployeeEditor() {
+ var firstName = new TextField("First name");
+ var lastName = new TextField("Last name");
+
+ var save = new Button("Save", VaadinIcon.CHECK.create());
+ var cancel = new Button("Cancel");
+ var delete = new Button("Delete", VaadinIcon.TRASH.create());
+
+ binder.forField(firstName).bind("firstName");
+ binder.forField(lastName).bind("lastName");
+
+ save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
+ save.addClickListener(e -> save());
+ save.addClickShortcut(Key.ENTER);
+
+ delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
+ delete.addClickListener(e -> deleteListener.onDelete(employee));
+
+ cancel.addClickListener(e -> cancelListener.onCancel());
+
+ getContent().add(firstName, lastName, new HorizontalLayout(save, cancel, delete));
+}
+
+ private void save() {
+ // Save the form into a new instance of Employee
+ var updated = new Employee();
+ updated.setId(employee.getId());
+
+ if (binder.writeBeanIfValid(updated)) {
+ saveListener.onSave(updated);
+ }
+ }
+
+ public void setEmployee(Employee employee) {
+ this.employee = employee;
+ binder.readBean(employee);
+ }
+
+ public void setSaveListener(SaveListener saveListener) {
+ this.saveListener = saveListener;
+ }
+
+ public void setDeleteListener(DeleteListener deleteListener) {
+ this.deleteListener = deleteListener;
+ }
+
+ public void setCancelListener(CancelListener cancelListener) {
+ this.cancelListener = cancelListener;
+ }
+}
diff --git a/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java b/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java
new file mode 100644
index 0000000000..edb1f7a75b
--- /dev/null
+++ b/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java
@@ -0,0 +1,95 @@
+package com.baeldung.spring;
+
+import com.baeldung.data.Employee;
+import com.baeldung.data.EmployeeRepository;
+
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.grid.Grid;
+import com.vaadin.flow.component.icon.VaadinIcon;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.data.value.ValueChangeMode;
+import com.vaadin.flow.router.Route;
+
+@Route("employees")
+public class EmployeesView extends VerticalLayout {
+
+ private final EmployeeRepository employeeRepository;
+
+ private final TextField filter;
+ private final Grid grid;
+ private final EmployeeEditor editor;
+
+
+ public EmployeesView(EmployeeRepository repo) {
+ employeeRepository = repo;
+
+ // Create components
+ var addButton = new Button("New employee", VaadinIcon.PLUS.create());
+ filter = new TextField();
+ grid = new Grid<>(Employee.class);
+ editor = new EmployeeEditor();
+
+ // Configure components
+ configureEditor();
+
+ addButton.addClickListener(e -> editEmployee(new Employee()));
+
+ filter.setPlaceholder("Filter by last name");
+ filter.setValueChangeMode(ValueChangeMode.LAZY);
+ filter.addValueChangeListener(e -> updateEmployees(e.getValue()));
+
+ grid.setHeight("200px");
+ grid.asSingleSelect().addValueChangeListener(e -> editEmployee(e.getValue()));
+
+ // Compose layout
+ var actionsLayout = new HorizontalLayout(filter, addButton);
+ add(actionsLayout, grid, editor);
+
+ // List customers
+ updateEmployees("");
+ }
+
+ private void configureEditor() {
+ editor.setVisible(false);
+
+ editor.setSaveListener(employee -> {
+ var saved = employeeRepository.save(employee);
+ updateEmployees(filter.getValue());
+ editor.setEmployee(null);
+ grid.asSingleSelect().setValue(saved);
+ });
+
+ editor.setDeleteListener(employee -> {
+ employeeRepository.delete(employee);
+ updateEmployees(filter.getValue());
+ editEmployee(null);
+ });
+
+ editor.setCancelListener(() -> {
+ editEmployee(null);
+ });
+ }
+
+ private void editEmployee(Employee employee) {
+ editor.setEmployee(employee);
+
+ if (employee != null) {
+ editor.setVisible(true);
+ } else {
+ // Deselect grid
+ grid.asSingleSelect().setValue(null);
+ editor.setVisible(false);
+ }
+
+ }
+
+ private void updateEmployees(String filterText) {
+ if (filterText.isEmpty()) {
+ grid.setItems(employeeRepository.findAll());
+ } else {
+ grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText));
+ }
+ }
+}
diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss
deleted file mode 100644
index a5670b70c7..0000000000
--- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-/* This file is automatically managed and will be overwritten from time to time. */
-/* Do not manually edit this file. */
-
-/* Import and include this mixin into your project theme to include the addon themes */
-@mixin addons {
-}
-
diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico b/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico
deleted file mode 100644
index ffb34a65c7..0000000000
Binary files a/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico and /dev/null differ
diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss
deleted file mode 100644
index 2c5fb8b944..0000000000
--- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-// If you edit this file you need to compile the theme. See README.md for details.
-
-// Global variable overrides. Must be declared before importing Valo.
-
-// Defines the plaintext font size, weight and family. Font size affects general component sizing.
-//$v-font-size: 16px;
-//$v-font-weight: 300;
-//$v-font-family: "Open Sans", sans-serif;
-
-// Defines the border used by all components.
-//$v-border: 1px solid (v-shade 0.7);
-//$v-border-radius: 4px;
-
-// Affects the color of some component elements, e.g Button, Panel title, etc
-//$v-background-color: hsl(210, 0%, 98%);
-// Affects the color of content areas, e.g Panel and Window content, TextField input etc
-//$v-app-background-color: $v-background-color;
-
-// Affects the visual appearance of all components
-//$v-gradient: v-linear 8%;
-//$v-bevel-depth: 30%;
-//$v-shadow-opacity: 5%;
-
-// Defines colors for indicating status (focus, success, failure)
-//$v-focus-color: valo-focus-color(); // Calculates a suitable color automatically
-//$v-friendly-color: #2c9720;
-//$v-error-indicator-color: #ed473b;
-
-// For more information, see: https://vaadin.com/book/-/page/themes.valo.html
-// Example variants can be copy/pasted from https://vaadin.com/wiki/-/wiki/Main/Valo+Examples
-
-@import "../valo/valo.scss";
-
-@mixin mytheme {
- @include valo;
-
- // Insert your own theme rules here
-}
diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss
deleted file mode 100644
index bba1d493c0..0000000000
--- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-@import "mytheme.scss";
-@import "addons.scss";
-
-// This file prefixes all rules with the theme name to avoid causing conflicts with other themes.
-// The actual styles should be defined in mytheme.scss
-
-.mytheme {
- @include addons;
- @include mytheme;
-
-}