Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 41 additions & 21 deletions src/main/resources/META-INF/resources/frontend/fc-toggle-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 */
Expand All @@ -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);
}

Expand Down Expand Up @@ -352,36 +362,46 @@ 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;
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)));
}
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class ToggleButtonDemoView extends TabbedDemo {
public ToggleButtonDemoView() {
addDemo(ToggleButtonDemo.class);
addDemo(ToggleButtonVariantsDemo.class);
addDemo(ToggleButtonReadOnlyDemo.class);
addDemo(ToggleButtonEventsDemo.class);
setSizeFull();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Loading