Skip to content

refactor!: Base checkbox styles #9008

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
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
80 changes: 73 additions & 7 deletions dev/checkbox.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
Expand All @@ -8,15 +8,81 @@
<script type="module" src="./common.js"></script>

<script type="module">
import '@vaadin/checkbox';
import '@vaadin/tooltip';
import '@vaadin/checkbox/src/vaadin-lit-checkbox.js';
import '@vaadin/checkbox-group/src/vaadin-lit-checkbox-group.js';
</script>
</head>

<body>
<vaadin-checkbox>
<label slot="label">I accept <a href="http://vaadin.com">the terms and conditions</a></label>
<vaadin-tooltip slot="tooltip" text="Please read first"></vaadin-tooltip>
</vaadin-checkbox>
<section>
<h2>Plain</h2>
<vaadin-checkbox checked label="I accept the terms and conditions"></vaadin-checkbox>
<br />
<br />
<vaadin-checkbox-group label="Export data" theme="vertical">
<vaadin-checkbox label="Order ID" value="1"></vaadin-checkbox>
<vaadin-checkbox checked label="Product name" value="2"></vaadin-checkbox>
<vaadin-checkbox label="Customer" value="3"></vaadin-checkbox>
<vaadin-checkbox label="Status" value="4"></vaadin-checkbox>
</vaadin-checkbox-group>
</section>

<section>
<h2>States</h2>
<vaadin-checkbox-group disabled label="Disabled" theme="vertical">
<vaadin-checkbox label="Engineering" value="1"></vaadin-checkbox>
<vaadin-checkbox checked label="Human Resources" value="2"></vaadin-checkbox>
<vaadin-checkbox indeterminate label="Marketing" value="3"></vaadin-checkbox>
<vaadin-checkbox label="Operations" value="4"></vaadin-checkbox>
<vaadin-checkbox label="Sales" value="5"></vaadin-checkbox>
</vaadin-checkbox-group>
<br />
<br />
<vaadin-checkbox-group label="Read-Only" readonly theme="vertical">
<vaadin-checkbox label="Order ID" value="1"></vaadin-checkbox>
<vaadin-checkbox checked label="Product name" value="2"></vaadin-checkbox>
<vaadin-checkbox indeterminate label="Customer" value="3"></vaadin-checkbox>
<vaadin-checkbox label="Status" value="4"></vaadin-checkbox>
</vaadin-checkbox-group>
<br />
<br />
<vaadin-checkbox
error-message="This field is required"
invalid
label="Grant view permissions"
required
></vaadin-checkbox>
<br />
<br />
<vaadin-checkbox indeterminate label="Notify users"></vaadin-checkbox>
</section>

<section>
<h2>Orientation</h2>
<vaadin-checkbox-group label="Permissions">
<vaadin-checkbox label="Read" value="1"></vaadin-checkbox>
<vaadin-checkbox label="Edit" value="2"></vaadin-checkbox>
<vaadin-checkbox label="Delete" value="3"></vaadin-checkbox>
</vaadin-checkbox-group>
</section>

<section>
<h2>Helper Text</h2>
<vaadin-checkbox label="Label" helper-text="Helper text"></vaadin-checkbox>
<br />
<br />
<vaadin-checkbox-group label="Label" helper-text="Helper text">
<vaadin-checkbox label="Item 1" value="1"></vaadin-checkbox>
<vaadin-checkbox label="Item 2" value="2"></vaadin-checkbox>
<vaadin-checkbox label="Item 3" value="3"></vaadin-checkbox>
</vaadin-checkbox-group>
<br />
<br />
<vaadin-checkbox-group helper-text="Helper text" label="Label" theme="helper-above-field">
<vaadin-checkbox label="Item 1" value="1"></vaadin-checkbox>
<vaadin-checkbox label="Item 2" value="2"></vaadin-checkbox>
<vaadin-checkbox label="Item 3" value="3"></vaadin-checkbox>
</vaadin-checkbox-group>
</section>
</body>
</html>
21 changes: 3 additions & 18 deletions packages/checkbox-group/src/vaadin-checkbox-group-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,17 @@
import { css } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

export const checkboxGroupStyles = css`
:host {
display: inline-flex;
}

:host::before {
content: '\\2003';
width: 0;
display: inline-block;
}

:host([hidden]) {
display: none !important;
}

.vaadin-group-field-container {
display: flex;
flex-direction: column;
width: 100%;
}

[part='group-field'] {
display: flex;
flex-wrap: wrap;
gap: var(--vaadin-checkbox-group-gap, 0.5em 1em);
}

:host(:not([has-label])) [part='label'] {
display: none;
:host([theme~='vertical']) [part='group-field'] {
flex-direction: column;
}
`;
4 changes: 3 additions & 1 deletion packages/checkbox-group/src/vaadin-lit-checkbox-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { html, LitElement } from 'lit';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { fieldShared } from '@vaadin/field-base/src/styles/field-shared-styles.js';
import { inputFieldContainer } from '@vaadin/field-base/src/styles/input-field-container-styles.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { CheckboxGroupMixin } from './vaadin-checkbox-group-mixin.js';
import { checkboxGroupStyles } from './vaadin-checkbox-group-styles.js';
Expand All @@ -27,7 +29,7 @@ class CheckboxGroup extends CheckboxGroupMixin(ElementMixin(ThemableMixin(Polyli
}

static get styles() {
return checkboxGroupStyles;
return [fieldShared, inputFieldContainer, checkboxGroupStyles];
}

/** @protected */
Expand Down
105 changes: 87 additions & 18 deletions packages/checkbox/src/vaadin-checkbox-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,32 @@
* Copyright (c) 2017 - 2025 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import '@vaadin/component-base/src/style-props.js';
import { css } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

export const checkboxStyles = css`
:host {
display: inline-block;
align-items: baseline;
display: inline-grid;
gap: var(--vaadin-checkbox-gap, 0.5em);
grid-template-columns: auto 1fr;
}

:host::before {
content: none;
}

:host([hidden]) {
display: none !important;
display: none;
}

:host([disabled]) {
-webkit-tap-highlight-color: transparent;
:host([focus-ring]) [part='checkbox'] {
outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
outline-offset: 1px;
}

.vaadin-checkbox-container {
display: grid;
grid-template-columns: auto 1fr;
align-items: baseline;
display: contents;
}

[part='checkbox'],
Expand All @@ -46,28 +53,90 @@ export const checkboxStyles = css`
}

[part='checkbox'] {
width: var(--vaadin-checkbox-size, 1em);
background-color: var(--vaadin-checkbox-background, transparent);
border: var(--vaadin-checkbox-border-width, 1px) solid
var(--vaadin-checkbox-border-color, var(--_vaadin-border-color-strong));
border-radius: var(--vaadin-checkbox-border-radius, var(--_vaadin-radius-s));
color: var(--vaadin-checkbox-color, transparent);
height: var(--vaadin-checkbox-size, 1em);
--_input-border-width: var(--vaadin-input-field-border-width, 0);
--_input-border-color: var(--vaadin-input-field-border-color, transparent);
box-shadow: inset 0 0 0 var(--_input-border-width, 0) var(--_input-border-color);
position: relative;
width: var(--vaadin-checkbox-size, 1em);
}

[part='checkbox']::before {
display: block;
contain: paint;
content: '\\202F';
display: block;
line-height: var(--vaadin-checkbox-size, 1em);
contain: paint;
}

/* visually hidden */
[part='checkbox']::after {
content: '';
height: var(--vaadin-checkbox-size, 1em);
inset: 0;
position: absolute;
width: var(--vaadin-checkbox-size, 1em);
}

/* Checked, indeterminate */
:host(:is([checked], [indeterminate])) {
--vaadin-checkbox-background: var(--_vaadin-color-strong);
--vaadin-checkbox-border-color: transparent;
--vaadin-checkbox-color: var(--_vaadin-background);
}

:host([checked]) [part='checkbox']::after {
background: currentColor;
mask-image: var(--_vaadin-icon-checkmark);
}

:host([indeterminate]) [part='checkbox']::after {
background: currentColor;
mask-image: var(--_vaadin-icon-minus);
}

/* Read-only */
:host([readonly]) {
--vaadin-checkbox-background: transparent;
--vaadin-checkbox-border-color: var(--_vaadin-border-color-strong);
--vaadin-checkbox-color: var(--_vaadin-color-strong);
}

:host([readonly]) [part='checkbox'] {
border-style: dashed;
}

/* Disabled */
:host([disabled]) {
--vaadin-checkbox-background: var(
--vaadin-input-field-disabled-background,
var(--_vaadin-background-container-strong)
);
--vaadin-checkbox-border-color: transparent;
--vaadin-checkbox-color: var(--_vaadin-color-strong);
--vaadin-checkbox-label-color: var(--vaadin-input-field-disabled-text-color, var(--_vaadin-color-subtle));
}

/* Visually hidden */
::slotted(input) {
align-self: stretch;
appearance: none;
cursor: inherit;
height: initial;
margin: 0;
align-self: stretch;
-webkit-appearance: none;
width: initial;
height: initial;
}

[part='label'] {
--vaadin-input-field-label-color: var(--vaadin-checkbox-label-color, var(--_vaadin-color-strong));
--vaadin-input-field-label-font-size: var(--vaadin-checkbox-label-font-size, inherit);
--vaadin-input-field-label-font-weight: var(--vaadin-checkbox-label-font-weight, 400);
--vaadin-input-field-label-line-height: var(--vaadin-checkbox-label-line-height, inherit);
padding: var(--vaadin-checkbox-label-padding, 0);
}

[part='required-indicator'] {
display: inline-block;
}

@media (forced-colors: active) {
Expand All @@ -82,9 +151,9 @@ export const checkboxStyles = css`
}

:host(:is([checked], [indeterminate])) [part='checkbox']::after {
border-radius: inherit;
outline: 1px solid;
outline-offset: -1px;
border-radius: inherit;
}

:host([focused]) [part='checkbox'],
Expand Down
3 changes: 2 additions & 1 deletion packages/checkbox/src/vaadin-lit-checkbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
import { fieldShared } from '@vaadin/field-base/src/styles/field-shared-styles.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { CheckboxMixin } from './vaadin-checkbox-mixin.js';
import { checkboxStyles } from './vaadin-checkbox-styles.js';
Expand All @@ -27,7 +28,7 @@ export class Checkbox extends CheckboxMixin(ElementMixin(ThemableMixin(PolylitMi
}

static get styles() {
return checkboxStyles;
return [fieldShared, checkboxStyles];
}

/** @protected */
Expand Down
8 changes: 7 additions & 1 deletion test/integration/component-tooltip.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ before(() => {
[
{ tagName: Button.is },
{ tagName: Checkbox.is, ariaTargetSelector: 'input' },
{ tagName: CheckboxGroup.is },
{
tagName: CheckboxGroup.is,
children: `
<vaadin-checkbox value="foo" label="Foo"></vaadin-checkbox>
<vaadin-checkbox value="bar" label="Bar"></vaadin-checkbox>
`,
},
{
tagName: ComboBox.is,
position: 'top',
Expand Down
Loading