diff --git a/dev/checkbox-group.html b/dev/checkbox-group.html index 9106f7163e8..858c58c7a40 100644 --- a/dev/checkbox-group.html +++ b/dev/checkbox-group.html @@ -1,4 +1,4 @@ - + @@ -8,68 +8,113 @@ + + - - - - - - +
+

Plain Text Labels

+ + + + + +
+ +
+

Horizontal

+ + + + + +
+ +
+

Read Only & Disabled

+ + + + + + + + + + + +
-
-
+
+

Bells & Whistles

+ + + + + + + + + + + +
- - - - - - - - - - - +
+

Content & Layout Variations

+

Resize the field to test how content flows.

+ + + + + + + + + +
diff --git a/dev/checkbox.html b/dev/checkbox.html index 1a948638d3e..15e3e2ceb89 100644 --- a/dev/checkbox.html +++ b/dev/checkbox.html @@ -1,4 +1,4 @@ - + @@ -8,15 +8,39 @@ - - - - +
+

Label & Description

+ + + +
+ +
+

All Features

+ +
+ +
+

Complex Label

+ + + +
diff --git a/dev/common.js b/dev/common.js index 697051b1e15..0aafba6e40a 100644 --- a/dev/common.js +++ b/dev/common.js @@ -26,5 +26,17 @@ addGlobalThemeStyles( margin: 2em 0 1.25em; text-box: cap alphabetic; } + + section { + display: flex; + flex-wrap: wrap; + gap: 1lh 1.5lh; + margin: 2lh 0; + } + + section > :is(h1, h2, h3, h4, h5, h6, p) { + width: 100%; + margin: 0; + } `, ); diff --git a/dev/radio-group.html b/dev/radio-group.html index d76e47bf73a..161c4ed17b7 100644 --- a/dev/radio-group.html +++ b/dev/radio-group.html @@ -1,4 +1,4 @@ - + @@ -8,68 +8,122 @@ + + - - - - - - +
+

Plain Text Labels

+ + + + + +
+ +
+

Horizontal

+ + + + + +
-
-
+
+

Read Only & Disabled

+ + + + + - - -
+ +
+

Bells & Whistles

+ + + - - - + + + - - - + + + - - + + Expiry date:10/2026 + + + +
+ +
+

Content & Layout Variations

+

Resize the field to test how content flows.

+ + + + + + + + + +
diff --git a/packages/checkbox-group/src/vaadin-checkbox-group-styles.d.ts b/packages/checkbox-group/src/vaadin-checkbox-group-styles.d.ts index e28da926571..04b9a18a59b 100644 --- a/packages/checkbox-group/src/vaadin-checkbox-group-styles.d.ts +++ b/packages/checkbox-group/src/vaadin-checkbox-group-styles.d.ts @@ -5,4 +5,4 @@ */ import type { CSSResult } from 'lit'; -export const checkboxGroupStyles: CSSResult; +export const checkboxGroupStyles: () => CSSResult; diff --git a/packages/checkbox-group/src/vaadin-checkbox-group-styles.js b/packages/checkbox-group/src/vaadin-checkbox-group-styles.js index d2f8bede567..1736163fdc4 100644 --- a/packages/checkbox-group/src/vaadin-checkbox-group-styles.js +++ b/packages/checkbox-group/src/vaadin-checkbox-group-styles.js @@ -3,35 +3,29 @@ * Copyright (c) 2018 - 2025 Vaadin Ltd. * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ */ -import { css } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; +import { css, unsafeCSS } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; -export const checkboxGroupStyles = css` +export const checkboxGroupStyles = (name = 'checkbox') => css` :host { - display: inline-flex; + width: fit-content; } - :host::before { - content: '\\2003'; - width: 0; - display: inline-block; - } - - :host([hidden]) { - display: none !important; + .vaadin-group-field-container { + display: contents; } - .vaadin-group-field-container { + :host, + [part='group-field'] { display: flex; flex-direction: column; - width: 100%; + gap: var(--vaadin-${unsafeCSS(name)}-group-gap, var(--_vaadin-gap-container-block)); } [part='group-field'] { - display: flex; - flex-wrap: wrap; + gap: 0.5lh 1.5em; } - :host(:not([has-label])) [part='label'] { - display: none; + :host([theme~='horizontal']) [part='group-field'] { + flex-flow: row wrap; } `; diff --git a/packages/checkbox-group/src/vaadin-lit-checkbox-group.js b/packages/checkbox-group/src/vaadin-lit-checkbox-group.js index 462be6362f8..9f9eefb0ea6 100644 --- a/packages/checkbox-group/src/vaadin-lit-checkbox-group.js +++ b/packages/checkbox-group/src/vaadin-lit-checkbox-group.js @@ -8,6 +8,7 @@ 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 { 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'; @@ -27,7 +28,7 @@ class CheckboxGroup extends CheckboxGroupMixin(ElementMixin(ThemableMixin(Polyli } static get styles() { - return checkboxGroupStyles; + return [fieldShared, checkboxGroupStyles()]; } /** @protected */ diff --git a/packages/checkbox-group/test/visual/base/checkbox-group.test.js b/packages/checkbox-group/test/visual/base/checkbox-group.test.js new file mode 100644 index 00000000000..1549e97248f --- /dev/null +++ b/packages/checkbox-group/test/visual/base/checkbox-group.test.js @@ -0,0 +1,140 @@ +import { sendKeys } from '@vaadin/test-runner-commands'; +import { fixtureSync } from '@vaadin/testing-helpers/dist/fixture.js'; +import { visualDiff } from '@web/test-runner-visual-regression'; +import '../common.js'; +import '../../../src/vaadin-lit-checkbox-group.js'; + +describe('checkbox-group', () => { + let div, element; + + beforeEach(() => { + div = document.createElement('div'); + div.style.display = 'inline-block'; + div.style.padding = '10px'; + + element = fixtureSync( + ` + + + + + + `, + div, + ); + }); + + describe('default', () => { + it('basic', async () => { + await visualDiff(div, 'basic'); + }); + + it('disabled', async () => { + element.disabled = true; + await visualDiff(div, 'disabled'); + }); + + it('horizontal', async () => { + element.setAttribute('theme', 'horizontal'); + await visualDiff(div, 'horizontal'); + }); + + it('label', async () => { + element.label = 'Label'; + await visualDiff(div, 'label'); + }); + + it('label focused', async () => { + element.label = 'Label'; + await sendKeys({ press: 'Tab' }); + await visualDiff(div, 'label-focused'); + }); + + it('label focused readonly', async () => { + element.label = 'Label'; + element.readonly = true; + await sendKeys({ press: 'Tab' }); + await visualDiff(div, 'label-focused-readonly'); + }); + + it('label disabled', async () => { + element.label = 'Label'; + element.disabled = true; + await visualDiff(div, 'label-disabled'); + }); + + it('value', async () => { + element.value = ['a', 'c']; + await visualDiff(div, 'value'); + }); + + it('readonly', async () => { + element.readonly = true; + element.value = ['a', 'c']; + await visualDiff(div, 'readonly'); + }); + + it('required', async () => { + element.label = 'Label'; + element.required = true; + await visualDiff(div, 'required'); + }); + + it('error message', async () => { + element.label = 'Label'; + element.errorMessage = 'This field is required'; + element.required = true; + element.validate(); + await visualDiff(div, 'error-message'); + }); + + it('helper text', async () => { + element.helperText = 'Helper text'; + await visualDiff(div, 'helper-text'); + }); + + it('helper above field', async () => { + element.label = 'Label'; + element.errorMessage = 'This field is required'; + element.required = true; + element.validate(); + element.helperText = 'Helper text'; + element.setAttribute('theme', 'helper-above-field'); + await visualDiff(div, 'helper-above-field'); + }); + + it('wrapped', async () => { + element.setAttribute('theme', 'horizontal'); + element.style.width = '150px'; + await visualDiff(div, 'wrapped'); + }); + }); + + describe('RTL', () => { + before(() => { + document.documentElement.setAttribute('dir', 'rtl'); + }); + + after(() => { + document.documentElement.removeAttribute('dir'); + }); + + it('RTL basic', async () => { + await visualDiff(div, 'rtl-basic'); + }); + + it('RTL error message', async () => { + element.label = 'Label'; + element.errorMessage = 'This field is required'; + element.required = true; + element.validate(); + await visualDiff(div, 'rtl-error-message'); + }); + + it('RTL wrapped', async () => { + element.setAttribute('theme', 'horizontal'); + element.style.width = '150px'; + await visualDiff(div, 'rtl-wrapped'); + }); + }); +}); diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/basic.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/basic.png new file mode 100644 index 00000000000..8df842b55cd Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/basic.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/disabled.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/disabled.png new file mode 100644 index 00000000000..2bbec818414 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/disabled.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/error-message.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/error-message.png new file mode 100644 index 00000000000..3c5780fd4d6 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/error-message.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/helper-above-field.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/helper-above-field.png new file mode 100644 index 00000000000..8b447da21e5 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/helper-above-field.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/helper-text.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/helper-text.png new file mode 100644 index 00000000000..8d9a2a8ba18 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/helper-text.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/horizontal.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/horizontal.png new file mode 100644 index 00000000000..0f2d70d1855 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/horizontal.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label-disabled.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label-disabled.png new file mode 100644 index 00000000000..d32e9966cb6 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label-disabled.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label-focused-readonly.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label-focused-readonly.png new file mode 100644 index 00000000000..ca23de58acf Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label-focused-readonly.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label-focused.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label-focused.png new file mode 100644 index 00000000000..4799c1c539c Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label-focused.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label.png new file mode 100644 index 00000000000..768fc835bb3 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/label.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/readonly.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/readonly.png new file mode 100644 index 00000000000..60163c7acae Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/readonly.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/required.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/required.png new file mode 100644 index 00000000000..fa76c31d918 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/required.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/rtl-basic.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/rtl-basic.png new file mode 100644 index 00000000000..597556baf54 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/rtl-basic.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/rtl-error-message.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/rtl-error-message.png new file mode 100644 index 00000000000..84b23833f22 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/rtl-error-message.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/rtl-wrapped.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/rtl-wrapped.png new file mode 100644 index 00000000000..3ed68de24c0 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/rtl-wrapped.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/value.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/value.png new file mode 100644 index 00000000000..5e2714bb155 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/value.png differ diff --git a/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/wrapped.png b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/wrapped.png new file mode 100644 index 00000000000..d65c351d228 Binary files /dev/null and b/packages/checkbox-group/test/visual/base/screenshots/checkbox-group/baseline/wrapped.png differ diff --git a/packages/checkbox/src/vaadin-checkbox-styles.js b/packages/checkbox/src/vaadin-checkbox-styles.js index c4068595088..e603ea5eaf8 100644 --- a/packages/checkbox/src/vaadin-checkbox-styles.js +++ b/packages/checkbox/src/vaadin-checkbox-styles.js @@ -3,93 +3,20 @@ * Copyright (c) 2017 - 2025 Vaadin Ltd. * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ */ -import { css } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; - -export const checkboxStyles = css` - :host { - display: inline-block; - } - - :host([hidden]) { - display: none !important; - } - - :host([disabled]) { - -webkit-tap-highlight-color: transparent; - } - - .vaadin-checkbox-container { - display: grid; - grid-template-columns: auto 1fr; - align-items: baseline; - } - - [part='checkbox'], - ::slotted(input), - [part='label'] { - grid-row: 1; - } - - [part='checkbox'], - ::slotted(input) { - grid-column: 1; - } - - [part='helper-text'], - [part='error-message'] { - grid-column: 2; - } - - :host(:not([has-helper])) [part='helper-text'], - :host(:not([has-error-message])) [part='error-message'] { - display: none; - } - - [part='checkbox'] { - width: var(--vaadin-checkbox-size, 1em); - 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); - } - - [part='checkbox']::before { - display: block; - content: '\\202F'; - line-height: var(--vaadin-checkbox-size, 1em); - contain: paint; - } - - /* visually hidden */ - ::slotted(input) { - cursor: inherit; - margin: 0; - align-self: stretch; - -webkit-appearance: none; - width: initial; - height: initial; - } - - @media (forced-colors: active) { - [part='checkbox'] { - outline: 1px solid; - outline-offset: -1px; - } - - :host([disabled]) [part='checkbox'], - :host([disabled]) [part='checkbox']::after { - outline-color: GrayText; - } - - :host(:is([checked], [indeterminate])) [part='checkbox']::after { - outline: 1px solid; - outline-offset: -1px; - border-radius: inherit; +import { css } from 'lit'; +import { checkboxRadio } from '@vaadin/field-base/src/styles/checkbox-radio-styles.js'; + +export const checkboxStyles = [ + checkboxRadio('checkbox'), + css` + [part='checkbox']::after { + inset: 0; + mask-image: var(--_vaadin-icon-checkmark); } - :host([focused]) [part='checkbox'], - :host([focused]) [part='checkbox']::after { - outline-width: 2px; + :host([indeterminate]) [part='checkbox']::after { + inset: calc(var(--_border-width) * -1); + mask-image: var(--_vaadin-icon-minus); } - } -`; + `, +]; diff --git a/packages/checkbox/src/vaadin-lit-checkbox.js b/packages/checkbox/src/vaadin-lit-checkbox.js index ab2dc97bdff..d2517936646 100644 --- a/packages/checkbox/src/vaadin-lit-checkbox.js +++ b/packages/checkbox/src/vaadin-lit-checkbox.js @@ -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'; @@ -27,7 +28,7 @@ export class Checkbox extends CheckboxMixin(ElementMixin(ThemableMixin(PolylitMi } static get styles() { - return checkboxStyles; + return [fieldShared, checkboxStyles]; } /** @protected */ diff --git a/packages/checkbox/test/checkbox.test.js b/packages/checkbox/test/checkbox.test.js index 411b080d4b5..7f2025ac651 100644 --- a/packages/checkbox/test/checkbox.test.js +++ b/packages/checkbox/test/checkbox.test.js @@ -2,7 +2,7 @@ import { expect } from '@vaadin/chai-plugins'; import { resetMouse, sendKeys, sendMouseToElement } from '@vaadin/test-runner-commands'; import { fixtureSync, mousedown, mouseup, nextFrame, nextRender, nextUpdate } from '@vaadin/testing-helpers'; import sinon from 'sinon'; -import '../src/vaadin-checkbox.js'; +import '../src/vaadin-lit-checkbox.js'; describe('checkbox', () => { let checkbox, input, label, link; diff --git a/packages/checkbox/test/visual/base/checkbox.test.js b/packages/checkbox/test/visual/base/checkbox.test.js new file mode 100644 index 00000000000..a71681c837e --- /dev/null +++ b/packages/checkbox/test/visual/base/checkbox.test.js @@ -0,0 +1,137 @@ +import { sendKeys } from '@vaadin/test-runner-commands'; +import { fixtureSync } from '@vaadin/testing-helpers'; +import { visualDiff } from '@web/test-runner-visual-regression'; +import '../common.js'; +import '../../../src/vaadin-lit-checkbox.js'; + +describe('checkbox', () => { + let div, element; + + beforeEach(() => { + div = document.createElement('div'); + div.style.display = 'inline-block'; + div.style.padding = '10px'; + element = fixtureSync('', div); + }); + + it('basic', async () => { + await visualDiff(div, 'basic'); + }); + + it('empty', async () => { + element.label = null; + await visualDiff(div, 'empty'); + }); + + it('checked', async () => { + element.checked = true; + await visualDiff(div, 'checked'); + }); + + it('indeterminate', async () => { + element.indeterminate = true; + await visualDiff(div, 'indeterminate'); + }); + + it('focus-ring', async () => { + await sendKeys({ press: 'Tab' }); + await visualDiff(div, 'focus-ring'); + }); + + it('checked focus-ring', async () => { + element.checked = true; + await sendKeys({ press: 'Tab' }); + await visualDiff(div, 'checked-focus-ring'); + }); + + it('required', async () => { + element.required = true; + await visualDiff(div, 'required'); + }); + + it('error message', async () => { + element.errorMessage = 'This field is required'; + element.required = true; + element.validate(); + await visualDiff(div, 'error-message'); + }); + + it('helper text', async () => { + element.helperText = 'Helper text'; + await visualDiff(div, 'helper-text'); + }); + + describe('disabled', () => { + beforeEach(() => { + element.disabled = true; + }); + + it('basic', async () => { + await visualDiff(div, 'disabled'); + }); + + it('checked', async () => { + element.checked = true; + await visualDiff(div, 'disabled-checked'); + }); + + it('indeterminate', async () => { + element.indeterminate = true; + await visualDiff(div, 'disabled-indeterminate'); + }); + + it('required', async () => { + element.required = true; + await visualDiff(div, 'disabled-required'); + }); + }); + + describe('readonly', () => { + beforeEach(() => { + element.readonly = true; + }); + + it('basic', async () => { + await visualDiff(div, 'readonly'); + }); + + it('checked', async () => { + element.checked = true; + await visualDiff(div, 'readonly-checked'); + }); + + it('indeterminate', async () => { + element.indeterminate = true; + await visualDiff(div, 'readonly-indeterminate'); + }); + + it('focus-ring', async () => { + await sendKeys({ press: 'Tab' }); + await visualDiff(div, 'readonly-focus-ring'); + }); + }); + + describe('RTL', () => { + before(() => { + document.documentElement.setAttribute('dir', 'rtl'); + }); + + after(() => { + document.documentElement.removeAttribute('dir'); + }); + + it('basic', async () => { + await visualDiff(div, 'rtl'); + }); + + it('empty', async () => { + element.label = ''; + await visualDiff(div, 'rtl-empty'); + }); + + it('required', async () => { + element.required = true; + await visualDiff(div, 'rtl-required'); + }); + }); +}); diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/basic.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/basic.png new file mode 100644 index 00000000000..83d3a4fe513 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/basic.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/checked-focus-ring.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/checked-focus-ring.png new file mode 100644 index 00000000000..9b6c227bad1 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/checked-focus-ring.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/checked.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/checked.png new file mode 100644 index 00000000000..dde44b490c2 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/checked.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled-checked.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled-checked.png new file mode 100644 index 00000000000..9883c373a9f Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled-checked.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled-indeterminate.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled-indeterminate.png new file mode 100644 index 00000000000..1958b0f2d24 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled-indeterminate.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled-required.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled-required.png new file mode 100644 index 00000000000..3624b5dac4c Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled-required.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled.png new file mode 100644 index 00000000000..9b230c1e2c9 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/disabled.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/empty.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/empty.png new file mode 100644 index 00000000000..f960c190b1e Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/empty.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/error-message.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/error-message.png new file mode 100644 index 00000000000..f9b178c0c70 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/error-message.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/focus-ring.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/focus-ring.png new file mode 100644 index 00000000000..f0f46a460d5 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/focus-ring.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/helper-text.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/helper-text.png new file mode 100644 index 00000000000..e364ff3601d Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/helper-text.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/indeterminate.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/indeterminate.png new file mode 100644 index 00000000000..1693b7e7b14 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/indeterminate.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly-checked.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly-checked.png new file mode 100644 index 00000000000..ad4360924ec Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly-checked.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly-focus-ring.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly-focus-ring.png new file mode 100644 index 00000000000..7f6bb23f6e6 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly-focus-ring.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly-indeterminate.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly-indeterminate.png new file mode 100644 index 00000000000..b6d85cade2e Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly-indeterminate.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly.png new file mode 100644 index 00000000000..abd06826f97 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/readonly.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/required.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/required.png new file mode 100644 index 00000000000..14c635fb9dc Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/required.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/rtl-empty.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/rtl-empty.png new file mode 100644 index 00000000000..08fcc1b5089 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/rtl-empty.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/rtl-required.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/rtl-required.png new file mode 100644 index 00000000000..862052d6430 Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/rtl-required.png differ diff --git a/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/rtl.png b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/rtl.png new file mode 100644 index 00000000000..2ef881c370b Binary files /dev/null and b/packages/checkbox/test/visual/base/screenshots/checkbox/baseline/rtl.png differ diff --git a/packages/component-base/src/style-props.js b/packages/component-base/src/style-props.js index 74d6d32facf..115b9dc585e 100644 --- a/packages/component-base/src/style-props.js +++ b/packages/component-base/src/style-props.js @@ -44,11 +44,11 @@ addGlobalThemeStyles( /* Focus outline */ --vaadin-focus-ring-width: 2px; - --vaadin-focus-ring-color: var(--_vaadin-color); + --vaadin-focus-ring-color: var(--_vaadin-color-strong); /* Icons, used as mask-image */ --_vaadin-icon-calendar: url('data:image/svg+xml,'); - --_vaadin-icon-checkmark: url('data:image/svg+xml;utf8,'); + --_vaadin-icon-checkmark: url('data:image/svg+xml;utf8,'); --_vaadin-icon-chevron-down: url('data:image/svg+xml,'); --_vaadin-icon-clock: url('data:image/svg+xml,'); --_vaadin-icon-cross: url('data:image/svg+xml;utf8,'); diff --git a/packages/field-base/src/styles/checkbox-radio-styles.d.ts b/packages/field-base/src/styles/checkbox-radio-styles.d.ts new file mode 100644 index 00000000000..63680914a4b --- /dev/null +++ b/packages/field-base/src/styles/checkbox-radio-styles.d.ts @@ -0,0 +1,8 @@ +/** + * @license + * Copyright (c) 2021 - 2025 Vaadin Ltd. + * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ + */ +import type { CSSResult } from 'lit'; + +export const checkboxRadio: CSSResult; diff --git a/packages/field-base/src/styles/checkbox-radio-styles.js b/packages/field-base/src/styles/checkbox-radio-styles.js new file mode 100644 index 00000000000..de3508cd9df --- /dev/null +++ b/packages/field-base/src/styles/checkbox-radio-styles.js @@ -0,0 +1,152 @@ +/** + * @license + * Copyright (c) 2021 - 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, unsafeCSS } from 'lit'; + +export const checkboxRadio = (part, propName = part) => css` + :host { + align-items: center; + display: inline-grid; + gap: var(--vaadin-${unsafeCSS(propName)}-gap, 0.25lh var(--_vaadin-gap-container-inline)); + grid-template-columns: auto 1fr; + -webkit-tap-highlight-color: transparent; + } + + :host([disabled]) { + cursor: not-allowed; + } + + .vaadin-${unsafeCSS(propName)}-container { + display: contents; + } + + [part='${unsafeCSS(part)}'], + ::slotted(input), + [part='label'], + ::slotted(label) { + grid-row: 1; + } + + [part='label'], + ::slotted(label) { + font-size: var(--vaadin-${unsafeCSS(propName)}-label-font-size, var(--vaadin-input-field-label-font-size, inherit)); + line-height: var(--vaadin-${unsafeCSS(propName)}-label-line-height, var(--vaadin-input-field-label-line-height, inherit)); + font-weight: var(--vaadin-${unsafeCSS(propName)}-font-weight, var(--vaadin-input-field-label-font-weight, 500)); + color: var(--vaadin-${unsafeCSS(propName)}-label-color, var(--vaadin-input-field-label-color, var(--_vaadin-color-strong))); + } + + [part='${unsafeCSS(part)}'], + ::slotted(input) { + grid-column: 1; + } + + [part='helper-text'], + [part='error-message'] { + grid-column: 2; + } + + /* Baseline vertical alignment */ + :host::before { + content: '\\2003'; + grid-column: 1; + grid-row: 1; + z-index: -1; + width: 0; + } + + /* visually hidden */ + ::slotted(input) { + cursor: inherit; + margin: 0; + align-self: stretch; + appearance: none; + width: 100%; + height: 100%; + } + + /* Control container (checkbox, radio button) */ + [part='${unsafeCSS(part)}'] { + background: var(--vaadin-${unsafeCSS(part)}-background, var(--_vaadin-background)); + border-color: var(--vaadin-${unsafeCSS(propName)}-border-color, var(--vaadin-input-field-border-color, var(--_vaadin-border-color-strong))); + border-radius: var(--vaadin-${unsafeCSS(propName)}-border-radius, var(--_vaadin-radius-s)); + border-style: solid; + --_border-width: var(--vaadin-${unsafeCSS(propName)}-border-width, var(--vaadin-input-field-border-width, 1px)); + border-width: var(--_border-width); + box-sizing: border-box; + color: var(--vaadin-${unsafeCSS(propName)}-color, var(--vaadin-input-field-text-color, var(--_vaadin-color-strong))); + height: var(--vaadin-${unsafeCSS(propName)}-size, 1lh); + width: var(--vaadin-${unsafeCSS(propName)}-size, 1lh); + position: relative; + } + + :host(:is([checked], [indeterminate])) { + --vaadin-${unsafeCSS(part)}-background: var(--_vaadin-color-strong); + --vaadin-${unsafeCSS(propName)}-border-color: transparent; + --vaadin-${unsafeCSS(propName)}-color: var(--_vaadin-background); + } + + :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='${unsafeCSS(part)}'] { + border-style: dashed; + } + + :host([disabled]) { + --vaadin-${unsafeCSS(part)}-background: var(--vaadin-input-field-disabled-background, var(--_vaadin-background-container-strong)); + --vaadin-${unsafeCSS(propName)}-border-color: transparent; + --vaadin-${unsafeCSS(propName)}-color: var(--_vaadin-color-subtle); + } + + /* Focus ring */ + :host([focus-ring]) [part='${unsafeCSS(part)}'] { + outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color); + outline-offset: calc(var(--_border-width) * -1); + } + + :host([focus-ring]:is([checked], [indeterminate])) [part='${unsafeCSS(part)}'] { + outline-offset: 1px; + } + + :host([readonly][focus-ring]) [part='${unsafeCSS(part)}'] { + --vaadin-${unsafeCSS(propName)}-border-color: transparent; + outline-offset: calc(var(--_border-width) * -1); + outline-style: dashed; + } + + /* Checked indicator (checkmark, dot) */ + [part='${unsafeCSS(part)}']::after { + content: ''; + position: absolute; + background: currentColor; + border-radius: inherit; + } + + :host(:not([checked], [indeterminate])) [part='${unsafeCSS(part)}']::after { + display: none; + } + + @media (forced-colors: active) { + :host(:is([checked], [indeterminate])) { + --vaadin-${unsafeCSS(propName)}-border-color: CanvasText; + } + + :host([readonly]) [part='${unsafeCSS(part)}']::after { + background: CanvasText; + } + + :host([disabled]) { + --vaadin-${unsafeCSS(propName)}-border-color: GrayText; + } + + :host([disabled]) [part='${unsafeCSS(part)}']::after { + background: GrayText; + } + } +`; diff --git a/packages/field-base/src/styles/field-shared-styles.js b/packages/field-base/src/styles/field-shared-styles.js index b54ac92beae..0c033fa5279 100644 --- a/packages/field-base/src/styles/field-shared-styles.js +++ b/packages/field-base/src/styles/field-shared-styles.js @@ -10,14 +10,8 @@ export const fieldShared = css` :host { display: inline-flex; outline: none; - } - - :host::before { - content: '\\2003'; - width: 0; - display: inline-block; - /* Size and position this element on the same vertical position as the input-field element - to make vertical align for the host element work as expected */ + cursor: default; + -webkit-tap-highlight-color: transparent; } :host([hidden]) { @@ -30,16 +24,35 @@ export const fieldShared = css` display: none; } - [part='label'] { + [part='label'], + ::slotted(label) { font-size: var(--vaadin-input-field-label-font-size, inherit); line-height: var(--vaadin-input-field-label-line-height, inherit); font-weight: var(--vaadin-input-field-label-font-weight, 500); color: var(--vaadin-input-field-label-color, var(--_vaadin-color-strong)); + word-break: break-word; + } + + ::slotted(label) { + cursor: inherit; + } + + [part='label'] { order: var(--vaadin-input-field-helper-order); } + :host([disabled]) [part='label'], + :host([disabled]) ::slotted(label) { + opacity: 0.5; + } + + :host([disabled]) [part='label'] ::slotted(label) { + opacity: 1; + } + [part='required-indicator'] { - color: var(--vaadin-input-field-required-indicator-color, inherit); + display: inline-block; + color: var(--vaadin-input-field-required-indicator-color, var(--_vaadin-color)); } [part='required-indicator']::after { diff --git a/packages/radio-group/src/vaadin-lit-radio-button.js b/packages/radio-group/src/vaadin-lit-radio-button.js index 8cda8bdccd2..8b73f5e1205 100644 --- a/packages/radio-group/src/vaadin-lit-radio-button.js +++ b/packages/radio-group/src/vaadin-lit-radio-button.js @@ -7,6 +7,7 @@ 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 { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; import { RadioButtonMixin } from './vaadin-radio-button-mixin.js'; import { radioButtonStyles } from './vaadin-radio-button-styles.js'; @@ -26,7 +27,7 @@ class RadioButton extends RadioButtonMixin(ElementMixin(ThemableMixin(PolylitMix } static get styles() { - return radioButtonStyles; + return [fieldShared, radioButtonStyles]; } /** @protected */ diff --git a/packages/radio-group/src/vaadin-lit-radio-group.js b/packages/radio-group/src/vaadin-lit-radio-group.js index 4d1f8636706..43e28b225a1 100644 --- a/packages/radio-group/src/vaadin-lit-radio-group.js +++ b/packages/radio-group/src/vaadin-lit-radio-group.js @@ -8,6 +8,7 @@ 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 { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; import { RadioGroupMixin } from './vaadin-radio-group-mixin.js'; import { radioGroupStyles } from './vaadin-radio-group-styles.js'; @@ -27,7 +28,7 @@ class RadioGroup extends RadioGroupMixin(ElementMixin(ThemableMixin(PolylitMixin } static get styles() { - return radioGroupStyles; + return [fieldShared, radioGroupStyles]; } /** @protected */ diff --git a/packages/radio-group/src/vaadin-radio-button-styles.js b/packages/radio-group/src/vaadin-radio-button-styles.js index 2f64b1aef29..3574e2642dc 100644 --- a/packages/radio-group/src/vaadin-radio-button-styles.js +++ b/packages/radio-group/src/vaadin-radio-button-styles.js @@ -3,75 +3,23 @@ * Copyright (c) 2017 - 2025 Vaadin Ltd. * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ */ -import { css } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; +import { css } from 'lit'; +import { checkboxRadio } from '@vaadin/field-base/src/styles/checkbox-radio-styles'; -export const radioButtonStyles = css` - :host { - display: inline-block; - } - - :host([hidden]) { - display: none !important; - } - - :host([disabled]) { - -webkit-tap-highlight-color: transparent; - } - - .vaadin-radio-button-container { - display: grid; - grid-template-columns: auto 1fr; - align-items: baseline; - } - - [part='radio'], - ::slotted(input), - ::slotted(label) { - grid-row: 1; - } - - [part='radio'], - ::slotted(input) { - grid-column: 1; - } - - [part='radio'] { - width: var(--vaadin-radio-button-size, 1em); - height: var(--vaadin-radio-button-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); - } - - [part='radio']::before { - display: block; - content: '\\202F'; - line-height: var(--vaadin-radio-button-size, 1em); - contain: paint; - } - - /* visually hidden */ - ::slotted(input) { - cursor: inherit; - margin: 0; - align-self: stretch; - -webkit-appearance: none; - width: initial; - height: initial; - } - - @media (forced-colors: active) { +export const radioButtonStyles = [ + checkboxRadio('radio', 'radio-button'), + css` [part='radio'] { - outline: 1px solid; - outline-offset: -1px; - } - - :host([focused]) [part='radio'] { - outline-width: 2px; + border-radius: 50%; } - :host([disabled]) [part='radio'] { - outline-color: GrayText; + [part='radio']::after { + top: 50%; + left: 50%; + translate: -50% -50%; + width: var(--vaadin-radio-button-dot-size, 50%); + height: var(--vaadin-radio-button-dot-size, 50%); + border-radius: 50%; } - } -`; + `, +]; diff --git a/packages/radio-group/src/vaadin-radio-group-styles.js b/packages/radio-group/src/vaadin-radio-group-styles.js index 2269a27eda8..6d80078722e 100644 --- a/packages/radio-group/src/vaadin-radio-group-styles.js +++ b/packages/radio-group/src/vaadin-radio-group-styles.js @@ -3,35 +3,6 @@ * Copyright (c) 2017 - 2025 Vaadin Ltd. * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ */ -import { css } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; +import { checkboxGroupStyles } from '@vaadin/checkbox-group/src/vaadin-checkbox-group-styles.js'; -export const radioGroupStyles = 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; - } - - :host(:not([has-label])) [part='label'] { - display: none; - } -`; +export const radioGroupStyles = checkboxGroupStyles('radio-button'); diff --git a/packages/radio-group/test/visual/base/radio-button.test.js b/packages/radio-group/test/visual/base/radio-button.test.js new file mode 100644 index 00000000000..cd973f635c4 --- /dev/null +++ b/packages/radio-group/test/visual/base/radio-button.test.js @@ -0,0 +1,74 @@ +import { sendKeys } from '@vaadin/test-runner-commands'; +import { fixtureSync } from '@vaadin/testing-helpers'; +import { visualDiff } from '@web/test-runner-visual-regression'; +import '../../../src/vaadin-lit-radio-button.js'; + +describe('radio-button', () => { + let div, element; + + beforeEach(() => { + div = document.createElement('div'); + div.style.display = 'inline-block'; + div.style.padding = '10px'; + element = fixtureSync('', div); + }); + + it('basic', async () => { + await visualDiff(div, 'basic'); + }); + + it('empty', async () => { + element.label = ''; + await visualDiff(div, 'empty'); + }); + + it('checked', async () => { + element.checked = true; + await visualDiff(div, 'checked'); + }); + + it('focus-ring', async () => { + await sendKeys({ press: 'Tab' }); + await visualDiff(div, 'focus-ring'); + }); + + it('checked focus-ring', async () => { + element.checked = true; + await sendKeys({ press: 'Tab' }); + await visualDiff(div, 'checked-focus-ring'); + }); + + describe('disabled', () => { + beforeEach(() => { + element.disabled = true; + }); + + it('basic', async () => { + await visualDiff(div, 'disabled'); + }); + + it('checked', async () => { + element.checked = true; + await visualDiff(div, 'disabled-checked'); + }); + }); + + describe('RTL', () => { + before(() => { + document.documentElement.setAttribute('dir', 'rtl'); + }); + + after(() => { + document.documentElement.removeAttribute('dir'); + }); + + it('basic', async () => { + await visualDiff(div, 'rtl'); + }); + + it('empty', async () => { + element.label = ''; + await visualDiff(div, 'rtl-empty'); + }); + }); +}); diff --git a/packages/radio-group/test/visual/base/radio-group.test.js b/packages/radio-group/test/visual/base/radio-group.test.js new file mode 100644 index 00000000000..9b564fe3bb9 --- /dev/null +++ b/packages/radio-group/test/visual/base/radio-group.test.js @@ -0,0 +1,127 @@ +import { sendKeys } from '@vaadin/test-runner-commands'; +import { fixtureSync } from '@vaadin/testing-helpers/dist/fixture.js'; +import { visualDiff } from '@web/test-runner-visual-regression'; +import '../common.js'; +import '../../../src/vaadin-lit-radio-group.js'; + +describe('radio-group', () => { + let div, element; + + beforeEach(() => { + div = document.createElement('div'); + div.style.display = 'inline-block'; + div.style.padding = '10px'; + + element = fixtureSync( + ` + + + + + + `, + div, + ); + }); + + describe('default', () => { + it('basic', async () => { + await visualDiff(div, 'basic'); + }); + + it('disabled', async () => { + element.disabled = true; + await visualDiff(div, 'disabled'); + }); + + it('horizontal', async () => { + element.setAttribute('theme', 'horizontal'); + await visualDiff(div, 'horizontal'); + }); + + it('label', async () => { + element.label = 'Label'; + await visualDiff(div, 'label'); + }); + + it('label focused', async () => { + element.label = 'Label'; + await sendKeys({ press: 'Tab' }); + await visualDiff(div, 'label-focused'); + }); + + it('label disabled', async () => { + element.label = 'Label'; + element.disabled = true; + await visualDiff(div, 'label-disabled'); + }); + + it('value', async () => { + element.value = 'a'; + await visualDiff(div, 'value'); + }); + + it('required', async () => { + element.label = 'Label'; + element.required = true; + await visualDiff(div, 'required'); + }); + + it('error message', async () => { + element.label = 'Label'; + element.errorMessage = 'This field is required'; + element.required = true; + element.validate(); + await visualDiff(div, 'error-message'); + }); + + it('helper text', async () => { + element.helperText = 'Helper text'; + await visualDiff(div, 'helper-text'); + }); + + it('helper above field', async () => { + element.label = 'Label'; + element.errorMessage = 'This field is required'; + element.required = true; + element.validate(); + element.helperText = 'Helper text'; + element.setAttribute('theme', 'helper-above-field'); + await visualDiff(div, 'helper-above-field'); + }); + + it('wrapped', async () => { + element.setAttribute('theme', 'horizontal'); + element.style.width = '150px'; + await visualDiff(div, 'wrapped'); + }); + }); + + describe('RTL', () => { + before(() => { + document.documentElement.setAttribute('dir', 'rtl'); + }); + + after(() => { + document.documentElement.removeAttribute('dir'); + }); + + it('RTL basic', async () => { + await visualDiff(div, 'rtl-basic'); + }); + + it('RTL error message', async () => { + element.label = 'Label'; + element.errorMessage = 'This field is required'; + element.required = true; + element.validate(); + await visualDiff(div, 'rtl-error-message'); + }); + + it('RTL wrapped', async () => { + element.setAttribute('theme', 'horizontal'); + element.style.width = '150px'; + await visualDiff(div, 'rtl-wrapped'); + }); + }); +}); diff --git a/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/basic.png b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/basic.png new file mode 100644 index 00000000000..785facfd1a7 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/basic.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/checked-focus-ring.png b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/checked-focus-ring.png new file mode 100644 index 00000000000..7b3b67d95a7 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/checked-focus-ring.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/checked.png b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/checked.png new file mode 100644 index 00000000000..e181edcdedb Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/checked.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/disabled-checked.png b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/disabled-checked.png new file mode 100644 index 00000000000..efdd29bae66 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/disabled-checked.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/disabled.png b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/disabled.png new file mode 100644 index 00000000000..784f8473089 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/disabled.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/empty.png b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/empty.png new file mode 100644 index 00000000000..68cc55293dc Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/empty.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/focus-ring.png b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/focus-ring.png new file mode 100644 index 00000000000..95ed60656fb Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/focus-ring.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/rtl-empty.png b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/rtl-empty.png new file mode 100644 index 00000000000..bd1357334c7 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/rtl-empty.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/rtl.png b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/rtl.png new file mode 100644 index 00000000000..0c727b0c330 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-button/baseline/rtl.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/basic.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/basic.png new file mode 100644 index 00000000000..0eec2a1c5c2 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/basic.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/disabled.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/disabled.png new file mode 100644 index 00000000000..dd60eefd65d Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/disabled.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/error-message.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/error-message.png new file mode 100644 index 00000000000..201c371ad4d Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/error-message.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/helper-above-field.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/helper-above-field.png new file mode 100644 index 00000000000..a5f4a940ed5 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/helper-above-field.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/helper-text.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/helper-text.png new file mode 100644 index 00000000000..4e40fe798d7 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/helper-text.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/horizontal.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/horizontal.png new file mode 100644 index 00000000000..34bdf312762 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/horizontal.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/label-disabled.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/label-disabled.png new file mode 100644 index 00000000000..79d21a0e885 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/label-disabled.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/label-focused.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/label-focused.png new file mode 100644 index 00000000000..86b8f9f5c62 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/label-focused.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/label.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/label.png new file mode 100644 index 00000000000..f7a89e80390 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/label.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/required.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/required.png new file mode 100644 index 00000000000..342c6e21e67 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/required.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/rtl-basic.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/rtl-basic.png new file mode 100644 index 00000000000..0148cbe2c28 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/rtl-basic.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/rtl-error-message.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/rtl-error-message.png new file mode 100644 index 00000000000..dd42ec97bbb Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/rtl-error-message.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/rtl-wrapped.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/rtl-wrapped.png new file mode 100644 index 00000000000..ac1c27cdd4a Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/rtl-wrapped.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/value.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/value.png new file mode 100644 index 00000000000..11d102c8033 Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/value.png differ diff --git a/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/wrapped.png b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/wrapped.png new file mode 100644 index 00000000000..7b2b798c30b Binary files /dev/null and b/packages/radio-group/test/visual/base/screenshots/radio-group/baseline/wrapped.png differ diff --git a/test/integration/component-tooltip.test.js b/test/integration/component-tooltip.test.js index b41e0b2ede2..386d8297026 100644 --- a/test/integration/component-tooltip.test.js +++ b/test/integration/component-tooltip.test.js @@ -36,7 +36,13 @@ before(() => { [ { tagName: Button.is }, { tagName: Checkbox.is, ariaTargetSelector: 'input' }, - { tagName: CheckboxGroup.is }, + { + tagName: CheckboxGroup.is, + children: ` + + + `, + }, { tagName: ComboBox.is, position: 'top',