Skip to content

First implementation#1

Open
ngonzalezpazFC wants to merge 60 commits intomasterfrom
develop
Open

First implementation#1
ngonzalezpazFC wants to merge 60 commits intomasterfrom
develop

Conversation

@ngonzalezpazFC
Copy link
Copy Markdown
Collaborator

@ngonzalezpazFC ngonzalezpazFC commented Mar 21, 2026

Summary

  • Add ToggleButton component extending AbstractSinglePropertyField<ToggleButton, Boolean>,
    implementing HasSize, HasComponents, HasLabel, HasAriaLabel, HasTooltip, and
    HasThemeVariant<ToggleButtonVariant>
  • Add ToggleButtonVariant enum with color variants (PRIMARY, SUCCESS, WARNING,
    ERROR, CONTRAST), size variants (SMALL, MEDIUM, LARGE), and touch variant (LONGSWIPE)
  • Implement fc-toggle-button LitElement web component with shadow DOM, Lumo token
    integration, and symmetric active-state animations for all size variants
  • Add LONGSWIPE variant producing a wider switch track optimized for touch; combinable with
    size variants (LONGSWIPE + SMALL/MEDIUM/LARGE)
  • Add mobile swipe gesture support: horizontal drag moves the slider in real time; releasing
    past the 50% threshold snaps to the new state with a smooth CSS transition
  • Expose fluent API: setLeftLabel, setRightLabel, setLeftIcon, setRightIcon,
    setItemLabelGenerator, withHighlightLabel, withoutHighlightLabel, withIconsInside,
    withIconsOutside
  • Label highlighting respects the active color variant: the active-side label uses the color
    of the SUCCESS, WARNING, ERROR, or CONTRAST variant instead of always defaulting to
    primary
  • withIconsInside() swaps the default layout to [label] [icon] [switch] [icon] [label],
    placing icons adjacent to the switch and labels on the outer edges
  • Add tabbed demo with three views: Labels & Icons, Theme Variants, and Events & Accessibility
  • Migrate all classes from the template package to com.flowingcode.vaadin.addons.togglebutton
  • Update pom.xml name and description per AddonsInternal guidelines
  • Update README.md with correct badges, links, features list, and Getting Started examples

Test plan

  • Run mvn clean install — build passes
  • Run mvn clean install jetty:run and verify all three demo tabs render correctly
  • Verify toggle animations are symmetric for all size variants (small, medium, large)
  • Verify withHighlightLabel() highlights the active side label
  • Verify theme variants apply correct colors and sizes
  • Verify disabled and read-only states behave correctly
  • Run mvn test
  • Integration tests run on CI (require Vaadin TestBench license)

Rename and move all classes from the template package to
com.flowingcode.vaadin.addons.fctogglebutton:

- SerializationTest now tests FCToggleButton
- TemplateDemo → FCToggleButtonDemo (updated title and route)
- TemplateDemoView → FCToggleButtonDemoView (route, GitHub link)
- DemoView forwards to FCToggleButtonDemoView
- AbstractViewTest and ViewIT moved to fctogglebutton.it package
- ViewIT now queries fc-toggle-button instead of paper-input
Replace all template references with FC Toggle Button content:
badges, description, features list, demo URL, getting started examples, and release notes link.
Add FCToggleButtonVariant.CONTRAST, applying --lumo-contrast-color to the switch track when checked, consistent with Vaadin Button's contrast variant behavior.
Add FCToggleButtonVariant.MEDIUM as an explicit variant matching the default size, allowing it to be set programmatically alongside other theme variants.
Replace TEMPLATE_ADDON placeholder with FC Toggle Button Add-On in bug-report.yml and feature-request.yml descriptions.
Split demo content into three focused tabs:
- FCToggleButtonDemo: labels and icons combinations
- FCToggleButtonVariantsDemo: all color, size, and state variants
- FCToggleButtonEventsDemo: value change, aria-label, and tooltip
Add width transition to slider so the squeeze animation is smooth.
Add explicit active-state rules for medium, small, and large variants to override specificity from their resting-state rules, ensuring the expansion is symmetric (left-only when checked, right-only when unchecked) for all sizes.
Label color change based on toggle state was always active.
Add highlightLabel property (default false) to the web component and expose withHighlightLabel()/withoutHighlightLabel() fluent methods on FCToggleButton to control the behavior explicitly.
Add a "With label highlighting" section to FCToggleButtonDemo with two examples using withHighlightLabel(): one with labels only and one combining labels and icons.
@ngonzalezpazFC ngonzalezpazFC changed the title Develop First implementation Mar 21, 2026
@ngonzalezpazFC ngonzalezpazFC self-assigned this Mar 21, 2026
@ngonzalezpazFC ngonzalezpazFC added the enhancement New feature or request label Mar 21, 2026
@ngonzalezpazFC ngonzalezpazFC requested a review from mlopezFC March 21, 2026 01:00
@ngonzalezpazFC
Copy link
Copy Markdown
Collaborator Author

It would be better also to rename toggle-button.js to fc-toggle-button.js as well to avoid conflict with any other frontend file a project could have with the same name.

dcd67bf

Copy link
Copy Markdown
Member

@javier-godoy javier-godoy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the v25 profile, please add the jakarta.servlet-api dependency (as done in AddonStarter24). Vaadin 25 uses Jakarta Servlet, so the javax.servlet:javax.servlet-api declared in the main dependencies won't be compatible when building with -Pv25.

<profile>
    <id>v25</id>
    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-dev</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.1.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</profile>

}

@Override
public Tooltip setTooltipText(String text) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setTooltipText creates a new Tooltip on every call. Tooltip.forComponent(this) allocates a fresh tooltip each time, which deviates from the standard HasTooltip contract. Either delegate to getTooltip().setText(text) and return getTooltip(), or remove this override and rely on the default HasTooltip implementation.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const maxTranslate = switchEl ? switchEl.offsetWidth - sliderWidth - gap * 2 : 20;
const threshold = maxTranslate * 0.5;

const newChecked = dx > 0 ? true : false;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary ternary. dx > 0 ? true : false is equivalent to dx > 0. Please simplify.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


/* Readonly Styles: Unify the look for both checked/unchecked and variants */
:host([readonly]) .switch {
background-color: var(--lumo-contrast-10pct, var(--vaadin-background-container)) !important;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!important in Shadow DOM readonly styles. Since these rules live inside the shadow root, selector specificity is already scoped — !important is not needed and prevents consumers from overriding the readonly appearance via CSS custom properties or ::part. Please remove all !important declarations from this block.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paodb
Copy link
Copy Markdown
Member

paodb commented Apr 6, 2026

Some comments about read-only styles:

Vaadin 25 uses Jakarta Servlet, so the javax.servlet:javax.servlet-api declared in the main dependencies won't be compatible when building with -Pv25.
@ngonzalezpazFC
Copy link
Copy Markdown
Collaborator Author

In the v25 profile, please add the jakarta.servlet-api dependency (as done in AddonStarter24). Vaadin 25 uses Jakarta Servlet, so the javax.servlet:javax.servlet-api declared in the main dependencies won't be compatible when building with -Pv25.

<profile>
    <id>v25</id>
    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-dev</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.1.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</profile>

411c095

Copy link
Copy Markdown
Member

@javier-godoy javier-godoy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments above.

@ngonzalezpazFC
Copy link
Copy Markdown
Collaborator Author

Some comments about read-only styles:

a451e6a

/* Readonly Styles: Unify the look for both checked/unchecked and variants */
:host([readonly]) .switch {
background-color: transparent;
border: 2px dashed var(--lumo-contrast-30pct, var(--vaadin-border-color));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use 1px, so it looks thinner and more in sync with vaadin components

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants