Skip to content

Commit

Permalink
fix(core/checkbox): remove :disable selector to render disable correct (
Browse files Browse the repository at this point in the history
  • Loading branch information
danielleroux authored Jan 30, 2025
1 parent 6ce2929 commit 3f5d0a4
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 34 deletions.
5 changes: 5 additions & 0 deletions .changeset/itchy-sloths-destroy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@siemens/ix': patch
---

Fix the disable state of `ix-checkbox` if `disabled=undefined` is provided.
53 changes: 25 additions & 28 deletions packages/core/src/components/checkbox/checkbox.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
@import 'mixins/shadow-dom/component';
@import 'mixins/shadow-dom/component';

:host {
--ix-checkbox-check-color: var(--theme-color-primary--contrast);
Expand Down Expand Up @@ -43,7 +43,7 @@
outline-offset: var(--theme-checkbox--focus--outline-offset);
}

input[type="checkbox"] {
input[type='checkbox'] {
display: none;
}

Expand Down Expand Up @@ -114,7 +114,6 @@
}
}

:host(:disabled),
:host(.disabled) {
button {
background-color: var(--theme-checkbox-unchecked--background--disabled);
Expand All @@ -123,9 +122,7 @@
}
}

:host(.checked:disabled),
:host(.checked.disabled),
:host(.indeterminate:disabled),
:host(.indeterminate.disabled) {
button {
background-color: var(--theme-checkbox-checked--background--disabled);
Expand Down Expand Up @@ -188,7 +185,6 @@
}
}

:host(#{$selector}:disabled),
:host(#{$selector}.disabled) {
button {
background-color: var(--theme-checkbox-unchecked--background--disabled);
Expand All @@ -197,9 +193,7 @@
}
}

:host(#{$selector}.checked:disabled),
:host(#{$selector}.checked.disabled),
:host(#{$selector}.indeterminate:disabled),
:host(#{$selector}.indeterminate.disabled) {
button {
background-color: var(--theme-checkbox-checked--background--disabled);
Expand All @@ -210,49 +204,52 @@
}

@mixin define-checkbox-vars($state, $type) {
--theme-checkbox-#{$state}--background: var(--theme-checkbox-#{$state}--background--#{$type});
--theme-checkbox-#{$state}--background--hover: var(--theme-checkbox-#{$state}--background--#{$type}--hover);
--theme-checkbox-#{$state}--background--active: var(--theme-checkbox-#{$state}--background--#{$type}--active);

--theme-checkbox-#{$state}--border-color: var(--theme-checkbox-#{$state}--border-color--#{$type});
--theme-checkbox-#{$state}--border-color--hover: var(--theme-checkbox-#{$state}--border-color--#{$type}--hover);
--theme-checkbox-#{$state}--border-color--active: var(--theme-checkbox-#{$state}--border-color--#{$type}--active);
--theme-checkbox-#{$state}--background: var(
--theme-checkbox-#{$state}--background--#{$type}
);
--theme-checkbox-#{$state}--background--hover: var(
--theme-checkbox-#{$state}--background--#{$type}--hover
);
--theme-checkbox-#{$state}--background--active: var(
--theme-checkbox-#{$state}--background--#{$type}--active
);

--theme-checkbox-#{$state}--border-color: var(
--theme-checkbox-#{$state}--border-color--#{$type}
);
--theme-checkbox-#{$state}--border-color--hover: var(
--theme-checkbox-#{$state}--border-color--#{$type}--hover
);
--theme-checkbox-#{$state}--border-color--active: var(
--theme-checkbox-#{$state}--border-color--#{$type}--active
);
}

@include checkbox-base();
@include checkbox-variant(
$selector: '.ix-info',
) {
@include checkbox-variant($selector: '.ix-info') {
@include define-checkbox-vars('unchecked', 'info');
@include define-checkbox-vars('checked', 'info');
@include define-checkbox-vars('mixed', 'info');
}

@include checkbox-variant(
$selector: '.ix-warning',
) {
@include checkbox-variant($selector: '.ix-warning') {
@include define-checkbox-vars('unchecked', 'warning');
@include define-checkbox-vars('checked', 'warning');
@include define-checkbox-vars('mixed', 'warning');
}

@include checkbox-variant(
$selector: '.ix-invalid--required',
) {
@include checkbox-variant($selector: '.ix-invalid--required') {
@include define-checkbox-vars('unchecked', 'invalid');
@include define-checkbox-vars('checked', 'invalid');
@include define-checkbox-vars('mixed', 'invalid');
}

@include checkbox-variant(
$selector: '.ix-invalid',
) {
@include checkbox-variant($selector: '.ix-invalid') {
@include define-checkbox-vars('unchecked', 'invalid');
@include define-checkbox-vars('checked', 'invalid');
@include define-checkbox-vars('mixed', 'invalid');
}

:host(:disabled),
:host(.disabled) {
pointer-events: none;

Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/components/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from '@stencil/core';
import { HookValidationLifecycle, IxFormComponent } from '../utils/input';
import { makeRef } from '../utils/make-ref';
import { a11yBoolean } from '../utils/a11y';

/**
* @since 2.6.0
Expand Down Expand Up @@ -176,8 +177,8 @@ export class Checkbox implements IxFormComponent<string> {
render() {
return (
<Host
aria-checked={`${this.checked}`}
aria-disabled={`${this.disabled}`}
aria-checked={a11yBoolean(this.checked)}
aria-disabled={a11yBoolean(this.disabled)}
role="checkbox"
class={{
disabled: this.disabled,
Expand All @@ -187,7 +188,7 @@ export class Checkbox implements IxFormComponent<string> {
>
<label>
<input
aria-checked={`${this.checked}`}
aria-checked={a11yBoolean(this.checked)}
disabled={this.disabled}
checked={this.checked}
ref={this.inputRef}
Expand Down
27 changes: 27 additions & 0 deletions packages/core/src/components/checkbox/tests/checkbox.ct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,33 @@ test(`disabled`, async ({ mount, page }) => {
await expect(checkboxElement).toBeDisabled();
});

test(`disabled = undefined`, async ({ mount, page }) => {
await mount(`<ix-checkbox label="some label"></ix-checkbox>`);
const checkboxElement = page.locator('ix-checkbox');
const nativeInput = checkboxElement.locator('input');
const label = checkboxElement.locator('ix-typography');

const checkedChange$ = checkboxElement.evaluate(
(element: HTMLIxCheckboxElement) => {
// Needs to be tested because at runtime undefined assignment could happen
// eslint-disable-next-line @typescript-eslint/no-explicit-any
element.disabled = undefined as any;
return new Promise<void>((resolve) => {
element.addEventListener('checkedChange', () => resolve());
});
}
);

await checkboxElement.click();
await checkedChange$;

await expect(checkboxElement).not.toHaveClass(/disabled/);
await expect(nativeInput).not.toBeDisabled();

const checkboxLabelColor = 'rgba(245, 252, 255, 0.93)';
await expect(label).toHaveCSS('color', checkboxLabelColor);
});

test('label', async ({ mount, page }) => {
await mount(`<ix-checkbox label="some label"></ix-checkbox>`);
const checkboxElement = page.locator('ix-checkbox').locator('label');
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/components/radio/radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from '@stencil/core';
import { makeRef } from '../utils/make-ref';
import { IxFormComponent } from '../utils/input';
import { a11yBoolean } from '../utils/a11y';

/**
* @since 2.6.0
Expand Down Expand Up @@ -132,8 +133,8 @@ export class Radio implements IxFormComponent<string> {
render() {
return (
<Host
aria-checked={`${this.checked}`}
aria-disabled={`${this.disabled}`}
aria-checked={a11yBoolean(this.checked)}
aria-disabled={a11yBoolean(this.disabled)}
role="radio"
class={{
disabled: this.disabled,
Expand All @@ -142,7 +143,7 @@ export class Radio implements IxFormComponent<string> {
>
<label>
<input
aria-checked={`${this.checked}`}
aria-checked={a11yBoolean(this.checked)}
disabled={this.disabled}
checked={this.checked}
ref={this.inputRef}
Expand Down

0 comments on commit 3f5d0a4

Please sign in to comment.