From 87b0679451f6c3d707ddb7840cf2e26f2f663bf7 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Wed, 13 May 2026 15:28:10 -0300 Subject: [PATCH 1/3] refactor: add custom properties for color variants Close #3 --- .../resources/frontend/fc-toggle-button.js | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/main/resources/META-INF/resources/frontend/fc-toggle-button.js b/src/main/resources/META-INF/resources/frontend/fc-toggle-button.js index 4ba1291..3fdc3aa 100644 --- a/src/main/resources/META-INF/resources/frontend/fc-toggle-button.js +++ b/src/main/resources/META-INF/resources/frontend/fc-toggle-button.js @@ -46,6 +46,16 @@ class ToggleButton extends LitElement { cursor: pointer; user-select: none; transition: opacity 0.2s; + /* Color tokens: default to theme variables. Override these when using Base theme. */ + --toggle-button-primary-color: var(--lumo-primary-color, var(--aura-blue)); + --toggle-button-success-color: var(--lumo-success-color, var(--aura-green)); + --toggle-button-error-color: var(--lumo-error-color, var(--aura-red)); + --toggle-button-warning-color: var(--lumo-warning-color, var(--aura-yellow)); + --toggle-button-contrast-color: var(--lumo-contrast, var(--aura-neutral)); + --toggle-button-primary-text-color: var(--lumo-primary-text-color, var(--aura-blue-text)); + --toggle-button-success-text-color: var(--lumo-success-text-color, var(--aura-green-text)); + --toggle-button-error-text-color: var(--lumo-error-text-color, var(--aura-red-text)); + --toggle-button-warning-text-color: var(--lumo-warning-text-color, var(--aura-orange-text)); } .field-label { @@ -79,23 +89,23 @@ class ToggleButton extends LitElement { } .label.active { - color: var(--lumo-primary-text-color, var(--aura-blue-text)); + color: var(--toggle-button-primary-text-color); } :host([theme~="success"]) .label.active { - color: var(--lumo-success-text-color, var(--aura-green-text)); + color: var(--toggle-button-success-text-color); } :host([theme~="error"]) .label.active { - color: var(--lumo-error-text-color, var(--aura-red-text)); + color: var(--toggle-button-error-text-color); } :host([theme~="warning"]) .label.active { - color: var(--lumo-warning-text-color, var(--aura-orange-text)); + color: var(--toggle-button-warning-text-color); } :host([theme~="contrast"]) .label.active { - color: var(--lumo-contrast, var(--aura-neutral)); + color: var(--toggle-button-contrast-color); } .label.inactive { @@ -114,33 +124,33 @@ class ToggleButton extends LitElement { } :host([checked]) .switch { - background-color: var(--lumo-primary-color, var(--aura-blue)); + background-color: var(--toggle-button-primary-color); } /* Theme Variants */ :host([theme~="success"][checked]) .switch { - background-color: var(--lumo-success-color, var(--aura-green)); + background-color: var(--toggle-button-success-color); } :host([theme~="error"][checked]) .switch { - background-color: var(--lumo-error-color, var(--aura-red)); + background-color: var(--toggle-button-error-color); } :host([theme~="warning"][checked]) .switch { - background-color: var(--lumo-warning-color, var(--aura-yellow)); + background-color: var(--toggle-button-warning-color); color: rgba(0, 0, 0, 0.85); } :host([theme~="primary"][checked]) .switch { - background-color: var(--lumo-primary-color, var(--aura-blue)); + background-color: var(--toggle-button-primary-color); } :host([theme~="contrast"][checked]) .switch { - background-color: var(--lumo-contrast, var(--aura-neutral)); + background-color: var(--toggle-button-contrast-color); } :host([theme~="contrast"]) .slider { - background-color: var(--lumo-base-color, var(--vaadin-background-color)); + background-color: var(--lumo-base-color, var(--vaadin-background-color, #ffffff)); } /* Slider colors for variants if needed */ @@ -154,9 +164,9 @@ class ToggleButton extends LitElement { left: 3px; width: 18px; height: 18px; - background-color: var(--lumo-base-color, var(--vaadin-background-color)); + background-color: var(--lumo-base-color, var(--vaadin-background-color, #ffffff)); border-radius: 50%; - box-shadow: var(--lumo-box-shadow-s, var(--aura-shadow-xs)); + box-shadow: var(--lumo-box-shadow-s, var(--aura-shadow-xs, 0 1px 2px rgba(0,0,0,0.2))); transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), width 0.3s cubic-bezier(0.4, 0, 0.2, 1); } @@ -361,27 +371,27 @@ class ToggleButton extends LitElement { /* Readonly + checked + color variant: desaturated variant tint on the border. */ :host([theme~="primary"][checked][readonly]) .switch { background-color: transparent; - border-color: color-mix(in srgb, var(--lumo-primary-color, var(--aura-blue)) 40%, var(--lumo-contrast-30pct, var(--vaadin-border-color))); + border-color: color-mix(in srgb, var(--toggle-button-primary-color) 40%, var(--lumo-contrast-30pct, var(--vaadin-border-color))); } :host([theme~="success"][checked][readonly]) .switch { background-color: transparent; - border-color: color-mix(in srgb, var(--lumo-success-color, var(--aura-green)) 40%, var(--lumo-contrast-30pct, var(--vaadin-border-color))); + border-color: color-mix(in srgb, var(--toggle-button-success-color) 40%, var(--lumo-contrast-30pct, var(--vaadin-border-color))); } :host([theme~="error"][checked][readonly]) .switch { background-color: transparent; - border-color: color-mix(in srgb, var(--lumo-error-color, var(--aura-red)) 40%, var(--lumo-contrast-30pct, var(--vaadin-border-color))); + border-color: color-mix(in srgb, var(--toggle-button-error-color) 40%, var(--lumo-contrast-30pct, var(--vaadin-border-color))); } :host([theme~="warning"][checked][readonly]) .switch { background-color: transparent; - border-color: color-mix(in srgb, var(--lumo-warning-color, var(--aura-yellow)) 40%, var(--lumo-contrast-30pct, var(--vaadin-border-color))); + border-color: color-mix(in srgb, var(--toggle-button-warning-color) 40%, var(--lumo-contrast-30pct, var(--vaadin-border-color))); } :host([theme~="contrast"][checked][readonly]) .switch { background-color: transparent; - border-color: color-mix(in srgb, var(--lumo-contrast, var(--aura-neutral)) 40%, var(--lumo-contrast-30pct, var(--vaadin-border-color))); + border-color: color-mix(in srgb, var(--toggle-button-contrast-color) 40%, var(--lumo-contrast-30pct, var(--vaadin-border-color))); } `; From f5907485b6314e986910055909639fad21cfa063 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Wed, 13 May 2026 15:29:17 -0300 Subject: [PATCH 2/3] fix: center slider vertically across size variants Close #5 --- .../resources/frontend/fc-toggle-button.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/resources/META-INF/resources/frontend/fc-toggle-button.js b/src/main/resources/META-INF/resources/frontend/fc-toggle-button.js index 3fdc3aa..180d72f 100644 --- a/src/main/resources/META-INF/resources/frontend/fc-toggle-button.js +++ b/src/main/resources/META-INF/resources/frontend/fc-toggle-button.js @@ -362,12 +362,22 @@ class ToggleButton extends LitElement { } :host([readonly]) .slider { - top: 1px; - left: 1px; + top: 2px; + left: 2px; box-shadow: none; background-color: var(--lumo-contrast-40pct, var(--vaadin-background-container-strong)); } + :host([readonly][theme~="small"]) .slider { + top: 1px; + left: 1px; + } + + :host([readonly][theme~="large"]) .slider { + top: 3px; + left: 3px; + } + /* Readonly + checked + color variant: desaturated variant tint on the border. */ :host([theme~="primary"][checked][readonly]) .switch { background-color: transparent; From d926fc654207e7bdc90ffee92636b454205c2b10 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Wed, 13 May 2026 15:46:49 -0300 Subject: [PATCH 3/3] feat(demo): add read-only demo view covering all variants --- .../togglebutton/ToggleButtonDemoView.java | 1 + .../ToggleButtonReadOnlyDemo.java | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 src/test/java/com/flowingcode/vaadin/addons/togglebutton/ToggleButtonReadOnlyDemo.java diff --git a/src/test/java/com/flowingcode/vaadin/addons/togglebutton/ToggleButtonDemoView.java b/src/test/java/com/flowingcode/vaadin/addons/togglebutton/ToggleButtonDemoView.java index 915634d..df25f5c 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/togglebutton/ToggleButtonDemoView.java +++ b/src/test/java/com/flowingcode/vaadin/addons/togglebutton/ToggleButtonDemoView.java @@ -34,6 +34,7 @@ public class ToggleButtonDemoView extends TabbedDemo { public ToggleButtonDemoView() { addDemo(ToggleButtonDemo.class); addDemo(ToggleButtonVariantsDemo.class); + addDemo(ToggleButtonReadOnlyDemo.class); addDemo(ToggleButtonEventsDemo.class); setSizeFull(); } diff --git a/src/test/java/com/flowingcode/vaadin/addons/togglebutton/ToggleButtonReadOnlyDemo.java b/src/test/java/com/flowingcode/vaadin/addons/togglebutton/ToggleButtonReadOnlyDemo.java new file mode 100644 index 0000000..63a3bde --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/addons/togglebutton/ToggleButtonReadOnlyDemo.java @@ -0,0 +1,121 @@ +/*- + * #%L + * Toggle Button Add-On + * %% + * Copyright (C) 2026 Flowing Code + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package com.flowingcode.vaadin.addons.togglebutton; + +import com.flowingcode.vaadin.addons.demo.DemoSource; +import com.vaadin.flow.component.html.Div; +import com.vaadin.flow.component.html.H3; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; + +@DemoSource +@PageTitle("Read-only") +@SuppressWarnings("serial") +@Route(value = "togglebutton/readonly", layout = ToggleButtonDemoView.class) +public class ToggleButtonReadOnlyDemo extends Div { + + public ToggleButtonReadOnlyDemo() { + + // Sizes — unchecked + ToggleButton smallOff = readOnly(new ToggleButton().setRightLabel("Small"), + ToggleButtonVariant.SMALL); + ToggleButton mediumOff = readOnly(new ToggleButton().setRightLabel("Medium"), + ToggleButtonVariant.MEDIUM); + ToggleButton largeOff = readOnly(new ToggleButton().setRightLabel("Large"), + ToggleButtonVariant.LARGE); + + // Sizes — checked + ToggleButton smallOn = readOnly(new ToggleButton(true).setRightLabel("Small"), + ToggleButtonVariant.SMALL); + ToggleButton mediumOn = readOnly(new ToggleButton(true).setRightLabel("Medium"), + ToggleButtonVariant.MEDIUM); + ToggleButton largeOn = readOnly(new ToggleButton(true).setRightLabel("Large"), + ToggleButtonVariant.LARGE); + + // Long swipe — unchecked + ToggleButton lsSmallOff = readOnly(new ToggleButton().setRightLabel("Small"), + ToggleButtonVariant.LONGSWIPE, ToggleButtonVariant.SMALL); + ToggleButton lsMediumOff = readOnly(new ToggleButton().setRightLabel("Medium"), + ToggleButtonVariant.LONGSWIPE, ToggleButtonVariant.MEDIUM); + ToggleButton lsLargeOff = readOnly(new ToggleButton().setRightLabel("Large"), + ToggleButtonVariant.LONGSWIPE, ToggleButtonVariant.LARGE); + + // Long swipe — checked + ToggleButton lsSmallOn = readOnly(new ToggleButton(true).setRightLabel("Small"), + ToggleButtonVariant.LONGSWIPE, ToggleButtonVariant.SMALL); + ToggleButton lsMediumOn = readOnly(new ToggleButton(true).setRightLabel("Medium"), + ToggleButtonVariant.LONGSWIPE, ToggleButtonVariant.MEDIUM); + ToggleButton lsLargeOn = readOnly(new ToggleButton(true).setRightLabel("Large"), + ToggleButtonVariant.LONGSWIPE, ToggleButtonVariant.LARGE); + + // Colors — unchecked + ToggleButton primaryOff = readOnly(new ToggleButton().setLeftLabel("Primary"), + ToggleButtonVariant.PRIMARY); + ToggleButton successOff = readOnly(new ToggleButton().setLeftLabel("Success"), + ToggleButtonVariant.SUCCESS); + ToggleButton errorOff = readOnly(new ToggleButton().setLeftLabel("Error"), + ToggleButtonVariant.ERROR); + ToggleButton warningOff = readOnly(new ToggleButton().setLeftLabel("Warning"), + ToggleButtonVariant.WARNING); + ToggleButton contrastOff = readOnly(new ToggleButton().setLeftLabel("Contrast"), + ToggleButtonVariant.CONTRAST); + + // Colors — checked (border tint visible) + ToggleButton primaryOn = readOnly(new ToggleButton(true).setLeftLabel("Primary"), + ToggleButtonVariant.PRIMARY); + ToggleButton successOn = readOnly(new ToggleButton(true).setLeftLabel("Success"), + ToggleButtonVariant.SUCCESS); + ToggleButton errorOn = readOnly(new ToggleButton(true).setLeftLabel("Error"), + ToggleButtonVariant.ERROR); + ToggleButton warningOn = readOnly(new ToggleButton(true).setLeftLabel("Warning"), + ToggleButtonVariant.WARNING); + ToggleButton contrastOn = readOnly(new ToggleButton(true).setLeftLabel("Contrast"), + ToggleButtonVariant.CONTRAST); + + HorizontalLayout sizesOff = row(smallOff, mediumOff, largeOff); + HorizontalLayout sizesOn = row(smallOn, mediumOn, largeOn); + HorizontalLayout longswipeOff = row(lsSmallOff, lsMediumOff, lsLargeOff); + HorizontalLayout longswipeOn = row(lsSmallOn, lsMediumOn, lsLargeOn); + HorizontalLayout colorsOff = row(primaryOff, successOff, errorOff, warningOff, contrastOff); + HorizontalLayout colorsOn = row(primaryOn, successOn, errorOn, warningOn, contrastOn); + + add(new VerticalLayout( + new H3("Sizes - unchecked"), sizesOff, + new H3("Sizes - checked"), sizesOn, + new H3("Long swipe - unchecked"), longswipeOff, + new H3("Long swipe - checked"), longswipeOn, + new H3("Colors - unchecked"), colorsOff, + new H3("Colors - checked"), colorsOn)); + } + + private static ToggleButton readOnly(ToggleButton tb, ToggleButtonVariant... variants) { + tb.addThemeVariants(variants); + tb.setReadOnly(true); + return tb; + } + + private static HorizontalLayout row(ToggleButton... buttons) { + HorizontalLayout row = new HorizontalLayout(buttons); + row.getStyle().set("gap", "var(--lumo-space-l, var(--vaadin-gap-l))"); + return row; + } +}