From aa8fbb4838c13d95fa4c52be2112a48c2eeb036f Mon Sep 17 00:00:00 2001 From: Pit Friedrich Date: Sat, 11 Jul 2026 17:38:32 +0200 Subject: [PATCH] [FEATURE] Custom Theme (Part II) --- src/main/java/com/example/views/FormView.java | 25 ++++++++ .../resources/META-INF/resources/styles.css | 61 ++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/views/FormView.java b/src/main/java/com/example/views/FormView.java index b401c8c..c1dc1b3 100644 --- a/src/main/java/com/example/views/FormView.java +++ b/src/main/java/com/example/views/FormView.java @@ -28,6 +28,10 @@ import com.vaadin.flow.data.validator.IntegerRangeValidator; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; +import java.text.DateFormatSymbols; +import java.util.List; +import java.util.Locale; + /** * Example view demonstrating a broad set of Vaadin form controls bound @@ -42,16 +46,36 @@ public class FormView extends VerticalLayout { public FormView() { addClassName("dialect-content"); add(card("Registrierung", buildForm())); + // + addClassName("form-view-vertical-layout-1"); } private Component buildForm() { TextField vorname = new TextField("Vorname"); +vorname.setAutofocus(true); TextField nachname = new TextField("Nachname"); EmailField email = new EmailField("E-Mail"); PasswordField passwort = new PasswordField("Passwort"); + // + passwort.addClassName("form-view-password-field-1"); IntegerField alter = new IntegerField("Alter"); + alter.setReadOnly(true); BigDecimalField gehalt = new BigDecimalField("Gehalt (€)"); DatePicker geburtsdatum = new DatePicker("Geburtsdatum"); + geburtsdatum.setLocale(Locale.GERMANY); + + DateFormatSymbols symbols = new DateFormatSymbols(Locale.GERMANY); + List monate = List.of(symbols.getMonths()).subList(0, 12); + List wochentage = List.of(symbols.getWeekdays()).subList(1, 8); + List wochentageKurz = List.of(symbols.getShortWeekdays()).subList(1, 8); + + geburtsdatum.setI18n(new DatePicker.DatePickerI18n() + .setMonthNames(monate) + .setWeekdays(wochentage) + .setWeekdaysShort(wochentageKurz) + .setFirstDayOfWeek(1) + .setToday("Heute") + .setCancel("Abbrechen")); TimePicker uhrzeit = new TimePicker("Bevorzugte Uhrzeit"); ComboBox land = new ComboBox<>("Land"); @@ -109,6 +133,7 @@ public class FormView extends VerticalLayout { .bind(Registration::getBemerkung, Registration::setBemerkung); Registration registration = new Registration(); + registration.setAlter(37); binder.readBean(registration); FormLayout formLayout = new FormLayout(); diff --git a/src/main/resources/META-INF/resources/styles.css b/src/main/resources/META-INF/resources/styles.css index b029ffd..08f2217 100644 --- a/src/main/resources/META-INF/resources/styles.css +++ b/src/main/resources/META-INF/resources/styles.css @@ -15,10 +15,69 @@ --aura-background-color-light: var(--dialect-bg); --aura-orange: var(--dialect-primary); --aura-yellow: var(--dialect-secondary); + + /* Flush, square app-layout content (no floating rounded card) */ + --aura-app-layout-inset: 0px; + --aura-app-layout-radius: 0px; + + /* Minimal (near-square) control + overlay corners, overriding Aura's rounded defaults */ + --vaadin-radius-s: 1px; + --vaadin-radius-m: 2px; + --vaadin-radius-l: 2px; + + /* Sidebar defaults to width: auto (shrink-to-content) — force a real column width */ + --vaadin-app-layout-drawer-width: 260px; +} + +/* Readonly/disabled fields: Aura's default cue is a dashed border, which reads + as "incomplete" rather than "not editable". Use a solid muted border + tinted + background instead (readonly: field-like but flat; disabled: same border, faded text). */ +[readonly]::part(input-field) { + border-style: solid; + border-color: var(--dialect-border); + background: var(--dialect-bg); +} + +[readonly]:focus-within::part(input-field) { + outline-style: solid; +} + +[disabled]::part(input-field) { + border-style: solid; + border-color: var(--dialect-border); +} + +[readonly]::part(checkbox), +[readonly]::part(radio-button) { + border-style: solid; +} + +/* Top bar: solid white, opaque, divider + soft shadow below. + Separates it from the sidebar/content instead of blending into one surface. */ +vaadin-app-layout::part(navbar) { + background: var(--dialect-surface); + -webkit-backdrop-filter: none; + backdrop-filter: none; + border-bottom: 1px solid var(--dialect-border); + box-shadow: 0 1px 3px rgba(20, 23, 31, 0.05); +} + +/* Sidebar: solid white, right divider separates it from the canvas */ +vaadin-app-layout::part(drawer) { + background: var(--dialect-surface); + border-inline-end: 1px solid var(--dialect-border); +} + +/* Canvas: gray, so white chrome and white cards both read against it */ +vaadin-app-layout::part(content) { + background: var(--dialect-bg); + border: none; } .dialect-title { font-weight: 600; + font-size: 1.05rem; + letter-spacing: -0.01em; color: var(--dialect-ink); } @@ -40,4 +99,4 @@ font-weight: 600; color: var(--dialect-ink); margin: 0 0 12px 0; -} +} \ No newline at end of file