From 01cede6d2828883712b934196296589e36756e4f Mon Sep 17 00:00:00 2001 From: Edwin Collazos Date: Mon, 11 May 2026 13:52:19 -0400 Subject: [PATCH 1/9] GAUD-8847: Removes checkbox.scss file - Updates package-lock.json file --- package-lock.json | 69 ----------------------------------------------- 1 file changed, 69 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2268dedc124..5daead31c9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1375,9 +1375,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1399,9 +1396,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1423,9 +1417,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1447,9 +1438,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1471,9 +1459,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1495,9 +1480,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1907,9 +1889,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1924,9 +1903,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1941,9 +1917,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1958,9 +1931,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1975,9 +1945,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1992,9 +1959,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2009,9 +1973,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2026,9 +1987,6 @@ "ppc64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2043,9 +2001,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2060,9 +2015,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2077,9 +2029,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2094,9 +2043,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2111,9 +2057,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -8480,9 +8423,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8504,9 +8444,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8528,9 +8465,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8552,9 +8486,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ From 4ea51f7daa86f4259ed8a71b2bb04eeb708a8f39 Mon Sep 17 00:00:00 2001 From: Edwin Collazos Date: Mon, 11 May 2026 13:54:43 -0400 Subject: [PATCH 2/9] Removes checkbox.scss file and update vdiff tests and sass.scss files --- components/inputs/sass/checkbox.scss | 37 ------------------- .../inputs/test/input-checkbox.vdiff.js | 24 ------------ test/sass.scss | 4 -- 3 files changed, 65 deletions(-) delete mode 100644 components/inputs/sass/checkbox.scss diff --git a/components/inputs/sass/checkbox.scss b/components/inputs/sass/checkbox.scss deleted file mode 100644 index c0e16def5f7..00000000000 --- a/components/inputs/sass/checkbox.scss +++ /dev/null @@ -1,37 +0,0 @@ -@use "../../colors/colors.scss"; - -@mixin d2l-input-checkbox() { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-position: center center; - background-repeat: no-repeat; - background-size: 1.2rem 1.2rem; - border-radius: 0.3rem; - border-style: solid; - box-sizing: border-box; - display: inline-block; - height: 1.2rem; - margin: 0; - padding: 0; - vertical-align: middle; - width: 1.2rem; - &:checked { - background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20fill%3D%22%23494C4E%22%20d%3D%22M8.4%2016.6c.6.6%201.5.6%202.1%200l8-8c.6-.6.6-1.5%200-2.1-.6-.6-1.5-.6-2.1%200l-6.9%207-1.9-1.9c-.6-.6-1.5-.6-2.1%200-.6.6-.6%201.5%200%202.1l2.9%202.9z%22/%3E%3C/svg%3E%0A"); - } - &, - &:hover:disabled { - background-color: colors.$d2l-color-regolith; - border-color: colors.$d2l-color-galena; - border-width: 1px; - } - &:hover, - &:focus { - border-color: colors.$d2l-color-celestine; - border-width: 2px; - outline: none; - } - &:disabled { - opacity: 0.5; - } -} diff --git a/components/inputs/test/input-checkbox.vdiff.js b/components/inputs/test/input-checkbox.vdiff.js index e35adbd4746..41d11a0ae32 100644 --- a/components/inputs/test/input-checkbox.vdiff.js +++ b/components/inputs/test/input-checkbox.vdiff.js @@ -108,28 +108,4 @@ describe('d2l-input-checkbox', () => { }); }); - - describe('sass', () => { - [false, true].forEach(disabled => { - [true, false].forEach(checked => { - - const name = `${disabled ? 'disabled' : 'default'}-${checked ? 'checked' : 'unchecked'}`; - const checkboxFixture = html``; - - it(name, async() => { - const elem = await fixture(checkboxFixture); - await expect(elem).to.be.golden(); - }); - if (!disabled) { - it(`${name}-focus`, async() => { - const elem = await fixture(checkboxFixture); - await focusElem(elem); - await expect(elem).to.be.golden(); - }); - } - - }); - }); - }); - }); diff --git a/test/sass.scss b/test/sass.scss index f2177c2b32e..9068c0f48ce 100644 --- a/test/sass.scss +++ b/test/sass.scss @@ -1,5 +1,4 @@ @use "../components/colors/colors.scss"; -@use "../components/inputs/sass/checkbox.scss"; @use "../components/inputs/sass/label.scss"; @use "../components/inputs/sass/radio.scss"; @use "../components/inputs/sass/select.scss"; @@ -35,9 +34,6 @@ .d2l-test-heading-4 { @include typography.d2l-heading-4(); } -.d2l-test-input-checkbox { - @include checkbox.d2l-input-checkbox(); -} .d2l-test-input-label { @include label.d2l-input-label(); } From bc3f1705f25879e559fd22d29ad2f88cc7265ddc Mon Sep 17 00:00:00 2001 From: Edwin Collazos Date: Mon, 11 May 2026 16:15:10 -0400 Subject: [PATCH 3/9] Reverts changes in package-lock.json --- package-lock.json | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/package-lock.json b/package-lock.json index 5daead31c9d..2268dedc124 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1375,6 +1375,9 @@ "arm" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1396,6 +1399,9 @@ "arm" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1417,6 +1423,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1438,6 +1447,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1459,6 +1471,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1480,6 +1495,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1889,6 +1907,9 @@ "arm" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1903,6 +1924,9 @@ "arm" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1917,6 +1941,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1931,6 +1958,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1945,6 +1975,9 @@ "loong64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1959,6 +1992,9 @@ "loong64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1973,6 +2009,9 @@ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1987,6 +2026,9 @@ "ppc64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2001,6 +2043,9 @@ "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2015,6 +2060,9 @@ "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2029,6 +2077,9 @@ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2043,6 +2094,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2057,6 +2111,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -8423,6 +8480,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8444,6 +8504,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8465,6 +8528,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8486,6 +8552,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ From 7a3ccb5d6a5ecbf43f2ab48f5e6aee34368f1039 Mon Sep 17 00:00:00 2001 From: Edwin Collazos Date: Tue, 12 May 2026 12:59:46 -0400 Subject: [PATCH 4/9] Adds new inpuit-checkbox-styles.js file to encapsulate the styles removed from the scss file --- components/inputs/input-checkbox-styles.js | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 components/inputs/input-checkbox-styles.js diff --git a/components/inputs/input-checkbox-styles.js b/components/inputs/input-checkbox-styles.js new file mode 100644 index 00000000000..1052b73ae6f --- /dev/null +++ b/components/inputs/input-checkbox-styles.js @@ -0,0 +1,48 @@ +import { css, unsafeCSS } from 'lit'; +import { _isValidCssSelector } from '../../helpers/internal/css.js'; + +/** + * A private helper method that should not be used by general consumers + */ +export const _generateInputCheckboxStyles = (selector) => { + if (!_isValidCssSelector(selector)) return; + + const selectorCSS = unsafeCSS(selector); + return css` + ${selectorCSS} { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-position: center center; + background-repeat: no-repeat; + background-size: 1.2rem 1.2rem; + border-radius: 0.3rem; + border-style: solid; + box-sizing: border-box; + display: inline-block; + height: 1.2rem; + margin: 0; + padding: 0; + vertical-align: middle; + width: 1.2rem; + } + ${selectorCSS}, + ${selectorCSS}:disabled { + background-color: #f9fbff; /* TODO: update this to the proper value */ + border-color: #6e7477; /* TODO: update this to the proper value */ + border-width: 1px; + } + ${selectorCSS}:checked { + background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20fill%3D%22%23494C4E%22%20d%3D%22M8.4%2016.6c.6.6%201.5.6%202.1%200l8-8c.6-.6.6-1.5%200-2.1-.6-.6-1.5-.6-2.1%200l-6.9%207-1.9-1.9c-.6-.6-1.5-.6-2.1%200-.6.6-.6%201.5%200%202.1l2.9%202.9z%22/%3E%3C/svg%3E%0A"); + } + ${selectorCSS}:hover, + ${selectorCSS}:focus { + border-color: #006fbf; /* TODO: update this to the proper value */ + border-width: 2px; + outline: none; + } + ${selectorCSS}:disabled { + opacity: 0.5; + } + `; +}; From 8874a1be6a749b71e067624c8b15c1fb3533a469 Mon Sep 17 00:00:00 2001 From: Edwin Collazos Date: Wed, 13 May 2026 15:50:31 -0400 Subject: [PATCH 5/9] Moves the checkbox styles to input-checkbox-styles.js --- components/inputs/input-checkbox-styles.js | 95 +++++++++++++++--- components/inputs/input-checkbox.js | 110 +-------------------- components/table/table-wrapper.js | 2 +- helpers/internal/css.js | 2 +- helpers/test/css.test.js | 11 +++ 5 files changed, 98 insertions(+), 122 deletions(-) create mode 100644 helpers/test/css.test.js diff --git a/components/inputs/input-checkbox-styles.js b/components/inputs/input-checkbox-styles.js index 1052b73ae6f..dd478b1593c 100644 --- a/components/inputs/input-checkbox-styles.js +++ b/components/inputs/input-checkbox-styles.js @@ -1,5 +1,25 @@ import { css, unsafeCSS } from 'lit'; import { _isValidCssSelector } from '../../helpers/internal/css.js'; +import { registerSemanticVariableForSvgImageUrl } from '../colors/colors.js'; + +registerSemanticVariableForSvgImageUrl( + '--d2l-input-checkbox-check-image', + ` + \ + ` +); + +registerSemanticVariableForSvgImageUrl( + '--d2l-input-checkbox-indeterminate-image', + ` + + ` +); + +export const cssSizes = { + inputBoxSize: 1.2, + checkboxMargin: 0.5, +}; /** * A private helper method that should not be used by general consumers @@ -10,39 +30,90 @@ export const _generateInputCheckboxStyles = (selector) => { const selectorCSS = unsafeCSS(selector); return css` ${selectorCSS} { + --d2l-input-checkbox-background-image: none; + --d2l-input-checkbox-background-color: var(--d2l-theme-background-color-interactive-faint-default); + --d2l-input-checkbox-background-image-disabled: + linear-gradient( + var(--d2l-theme-background-color-interactive-faint-disabled), + var(--d2l-theme-background-color-interactive-faint-disabled) + ), + var(--d2l-input-checkbox-background-image); -webkit-appearance: none; -moz-appearance: none; appearance: none; + background-image: var(--d2l-input-checkbox-background-image); background-position: center center; background-repeat: no-repeat; - background-size: 1.2rem 1.2rem; + background-size: ${cssSizes.inputBoxSize}rem ${cssSizes.inputBoxSize}rem; border-radius: 0.3rem; border-style: solid; box-sizing: border-box; display: inline-block; - height: 1.2rem; + height: ${cssSizes.inputBoxSize}rem; margin: 0; padding: 0; vertical-align: middle; - width: 1.2rem; + width: ${cssSizes.inputBoxSize}rem; + } + ${selectorCSS}:checked { + --d2l-input-checkbox-background-image: var(--d2l-input-checkbox-check-image); + } + ${selectorCSS}:indeterminate { + --d2l-input-checkbox-background-image: var(--d2l-input-checkbox-indeterminate-image); } ${selectorCSS}, - ${selectorCSS}:disabled { - background-color: #f9fbff; /* TODO: update this to the proper value */ - border-color: #6e7477; /* TODO: update this to the proper value */ + ${selectorCSS}:hover:disabled { + background-color: var(--d2l-input-checkbox-background-color); + border-color: var(--d2l-theme-border-color-emphasized); border-width: 1px; } - ${selectorCSS}:checked { - background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20fill%3D%22%23494C4E%22%20d%3D%22M8.4%2016.6c.6.6%201.5.6%202.1%200l8-8c.6-.6.6-1.5%200-2.1-.6-.6-1.5-.6-2.1%200l-6.9%207-1.9-1.9c-.6-.6-1.5-.6-2.1%200-.6.6-.6%201.5%200%202.1l2.9%202.9z%22/%3E%3C/svg%3E%0A"); + ${selectorCSS}:hover:disabled { + border-color: var(--d2l-theme-border-color-disabled); } ${selectorCSS}:hover, - ${selectorCSS}:focus { - border-color: #006fbf; /* TODO: update this to the proper value */ + ${selectorCSS}:focus, + ${selectorCSS}.d2l-input-checkbox-focus, + :host(.d2l-hovering) input[type="checkbox"]:not(:disabled).d2l-input-checkbox { + border-color: var(--d2l-input-checkbox-border-color-hover-focus, var(--d2l-theme-border-color-focus)); border-width: 2px; outline: none; } - ${selectorCSS}:disabled { - opacity: 0.5; + ${selectorCSS}:disabled, + ${selectorCSS}:where([aria-disabled="true"]) { + background-image: var(--d2l-input-checkbox-background-image-disabled); + border-color: var(--d2l-theme-border-color-disabled); + } + @media (forced-colors: active) { + ${selectorCSS}:checked, + ${selectorCSS}:indeterminate { + background-image: none; + position: relative; + } + ${selectorCSS}:checked::after, + ${selectorCSS}:indeterminate::after { + background-color: FieldText; + content: ""; + display: block; + height: ${cssSizes.inputBoxSize}rem; + left: 50%; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + width: ${cssSizes.inputBoxSize}rem; + } + + ${selectorCSS}:disabled, + ${selectorCSS}:where([aria-disabled="true"]) { + opacity: var(--d2l-theme-opacity-disabled-control); + } + + ${selectorCSS}:checked::after { + mask-image: var(--d2l-input-checkbox-check-image); + } + + ${selectorCSS}:indeterminate::after { + mask-image: var(--d2l-input-checkbox-indeterminate-image); + } } `; }; diff --git a/components/inputs/input-checkbox.js b/components/inputs/input-checkbox.js index 287cd0ec191..960bc77155e 100644 --- a/components/inputs/input-checkbox.js +++ b/components/inputs/input-checkbox.js @@ -1,5 +1,6 @@ import '../expand-collapse/expand-collapse-content.js'; import '../tooltip/tooltip.js'; +import { _generateInputCheckboxStyles, cssSizes } from './input-checkbox-styles.js'; import { css, html, LitElement, nothing } from 'lit'; import { classMap } from 'lit/directives/class-map.js'; import { FocusMixin } from '../../mixins/focus/focus-mixin.js'; @@ -8,116 +9,9 @@ import { getUniqueId } from '../../helpers/uniqueId.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { InputInlineHelpMixin } from './input-inline-help.js'; import { offscreenStyles } from '../offscreen/offscreen.js'; -import { registerSemanticVariableForSvgImageUrl } from '../colors/colors.js'; import { SkeletonMixin } from '../skeleton/skeleton-mixin.js'; -registerSemanticVariableForSvgImageUrl( - '--d2l-input-checkbox-check-image', - ` - \ - ` -); - -registerSemanticVariableForSvgImageUrl( - '--d2l-input-checkbox-indeterminate-image', - ` - - ` -); - -export const cssSizes = { - inputBoxSize: 1.2, - checkboxMargin: 0.5, -}; - -export const checkboxStyles = css` - input[type="checkbox"].d2l-input-checkbox { - --d2l-input-checkbox-background-image: none; - --d2l-input-checkbox-background-color: var(--d2l-theme-background-color-interactive-faint-default); - --d2l-input-checkbox-background-image-disabled: - linear-gradient( - var(--d2l-theme-background-color-interactive-faint-disabled), - var(--d2l-theme-background-color-interactive-faint-disabled) - ), - var(--d2l-input-checkbox-background-image); - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-image: var(--d2l-input-checkbox-background-image); - background-position: center center; - background-repeat: no-repeat; - background-size: ${cssSizes.inputBoxSize}rem ${cssSizes.inputBoxSize}rem; - border-radius: 0.3rem; - border-style: solid; - box-sizing: border-box; - display: inline-block; - height: ${cssSizes.inputBoxSize}rem; - margin: 0; - padding: 0; - vertical-align: middle; - width: ${cssSizes.inputBoxSize}rem; - } - input[type="checkbox"].d2l-input-checkbox:checked { - --d2l-input-checkbox-background-image: var(--d2l-input-checkbox-check-image); - } - input[type="checkbox"].d2l-input-checkbox:indeterminate { - --d2l-input-checkbox-background-image: var(--d2l-input-checkbox-indeterminate-image); - } - input[type="checkbox"].d2l-input-checkbox, - input[type="checkbox"].d2l-input-checkbox:hover:disabled { - background-color: var(--d2l-input-checkbox-background-color); - border-color: var(--d2l-theme-border-color-emphasized); - border-width: 1px; - } - input[type="checkbox"].d2l-input-checkbox:hover:disabled { - border-color: var(--d2l-theme-border-color-disabled); - } - input[type="checkbox"].d2l-input-checkbox:hover, - input[type="checkbox"].d2l-input-checkbox:focus, - input[type="checkbox"].d2l-input-checkbox.d2l-input-checkbox-focus, - :host(.d2l-hovering) input[type="checkbox"]:not(:disabled).d2l-input-checkbox { - border-color: var(--d2l-input-checkbox-border-color-hover-focus, var(--d2l-theme-border-color-focus)); - border-width: 2px; - outline: none; - } - input[type="checkbox"].d2l-input-checkbox:disabled, - input[type="checkbox"].d2l-input-checkbox:where([aria-disabled="true"]) { - background-image: var(--d2l-input-checkbox-background-image-disabled); - border-color: var(--d2l-theme-border-color-disabled); - } - @media (forced-colors: active) { - input[type="checkbox"].d2l-input-checkbox:checked, - input[type="checkbox"].d2l-input-checkbox:indeterminate { - background-image: none; - position: relative; - } - input[type="checkbox"].d2l-input-checkbox:checked::after, - input[type="checkbox"].d2l-input-checkbox:indeterminate::after { - background-color: FieldText; - content: ""; - display: block; - height: ${cssSizes.inputBoxSize}rem; - left: 50%; - position: absolute; - top: 50%; - transform: translate(-50%, -50%); - width: ${cssSizes.inputBoxSize}rem; - } - - input[type="checkbox"].d2l-input-checkbox:disabled, - input[type="checkbox"].d2l-input-checkbox:where([aria-disabled="true"]) { - opacity: var(--d2l-theme-opacity-disabled-control); - } - - input[type="checkbox"].d2l-input-checkbox:checked::after { - mask-image: var(--d2l-input-checkbox-check-image); - } - - input[type="checkbox"].d2l-input-checkbox:indeterminate::after { - mask-image: var(--d2l-input-checkbox-indeterminate-image); - } - } -`; +export const checkboxStyles = _generateInputCheckboxStyles('input[type="checkbox"].d2l-input-checkbox'); /** * A component that can be used to show a checkbox and optional visible label. diff --git a/components/table/table-wrapper.js b/components/table/table-wrapper.js index 780249f5348..48cfec4545d 100644 --- a/components/table/table-wrapper.js +++ b/components/table/table-wrapper.js @@ -2,7 +2,7 @@ import '../colors/colors.js'; import '../scroll-wrapper/scroll-wrapper.js'; import '../backdrop/backdrop-loading.js'; import { css, html, LitElement, nothing } from 'lit'; -import { cssSizes } from '../inputs/input-checkbox.js'; +import { cssSizes } from '../inputs/input-checkbox-styles.js'; import { getComposedParent } from '../../helpers/dom.js'; import { getFlag } from '../../helpers/flags.js'; import { ifDefined } from 'lit/directives/if-defined.js'; diff --git a/helpers/internal/css.js b/helpers/internal/css.js index e7231ed9cba..623a793b01a 100644 --- a/helpers/internal/css.js +++ b/helpers/internal/css.js @@ -1,6 +1,6 @@ export function _isValidCssSelector(selector) { const partIsValid = (part) => { - const re = /([a-zA-Z0-9-_ >.#]+)(\[[a-zA-Z0-9-_]+\])?([a-zA-Z0-9-_ >.#]+)?/g; + const re = /([a-zA-Z0-9-_ >.#]+)(\[[a-zA-Z0-9-_="]+\])?([a-zA-Z0-9-_ >.#]+)?/g; if (part === ':host') return true; const match = part.match(re); const isValid = !!match && match.length === 1 && match[0].length === part.length; diff --git a/helpers/test/css.test.js b/helpers/test/css.test.js new file mode 100644 index 00000000000..98079b9ec77 --- /dev/null +++ b/helpers/test/css.test.js @@ -0,0 +1,11 @@ +import { _isValidCssSelector } from '../internal/css.js'; +import { expect } from '@brightspace-ui/testing'; + +describe('_isValidCssSelector', () => { + it('should return true for valid selectors', () => { + expect(_isValidCssSelector('input[type="checkbox"].d2l-input-checkbox')).to.be.true; + expect(_isValidCssSelector('input[type="checkbox"]')).to.be.true; + expect(_isValidCssSelector('.d2l-input-checkbox')).to.be.true; + expect(_isValidCssSelector('.d2l-link')).to.be.true; + }); +}); From 3cfdb0ee857931135bfd7f02db9868045eb2d908 Mon Sep 17 00:00:00 2001 From: Edwin Collazos Date: Wed, 13 May 2026 16:41:18 -0400 Subject: [PATCH 6/9] Remove styles.test.js and migrate the tests into css.test.js --- components/typography/test/styles.test.js | 65 ----------------------- helpers/test/css.test.js | 63 ++++++++++++++++++++-- 2 files changed, 59 insertions(+), 69 deletions(-) delete mode 100644 components/typography/test/styles.test.js diff --git a/components/typography/test/styles.test.js b/components/typography/test/styles.test.js deleted file mode 100644 index 6e7d94a78ff..00000000000 --- a/components/typography/test/styles.test.js +++ /dev/null @@ -1,65 +0,0 @@ -import { _isValidCssSelector } from '../../../helpers/internal/css.js'; -import { expect } from '@brightspace-ui/testing'; - -describe('_isValidCssSelector', () => { - - it('should support simple tag names', () => { - expect(_isValidCssSelector('a')).to.be.true; - expect(_isValidCssSelector('button')).to.be.true; - expect(_isValidCssSelector('table')).to.be.true; - expect(_isValidCssSelector('dl')).to.be.true; - }); - - it('should support simple class selectors', () => { - expect(_isValidCssSelector('.d2l-label-styles')).to.be.true; - expect(_isValidCssSelector('.d2l-body-compact')).to.be.true; - expect(_isValidCssSelector('.className')).to.be.true; - }); - - it('should support simple id selectors', () => { - expect(_isValidCssSelector('#opener')).to.be.true; - }); - - it('should support simple property selectors', () => { - expect(_isValidCssSelector('button[loading]')).to.be.true; - expect(_isValidCssSelector('p[loading]')).to.be.true; - }); - - it('should support complex selectors', () => { - expect(_isValidCssSelector('dl dd')).to.be.true; - expect(_isValidCssSelector('dt.class')).to.be.true; - expect(_isValidCssSelector('dt#id')).to.be.true; - expect(_isValidCssSelector('dl .class')).to.be.true; - expect(_isValidCssSelector('dl #id')).to.be.true; - expect(_isValidCssSelector('dl > dt')).to.be.true; - expect(_isValidCssSelector('dl > dt > dd')).to.be.true; - }); - - it('should support simple :host selector', () => { - expect(_isValidCssSelector(':host')).to.be.true; - }); - - it('should support sets of selectors', () => { - expect(_isValidCssSelector('.class1, .class2')).to.be.true; - }); - - it('should not support sets with invalid selectors', () => { - expect(_isValidCssSelector('.valid, invalid$')).to.be.false; - }); - - it('should not support complex :host selectors', () => { - expect(_isValidCssSelector(':host p')).to.be.false; - expect(_isValidCssSelector(':host([hidden])')).to.be.false; - expect(_isValidCssSelector(':host([dir="rtl"])')).to.be.false; - }); - - it('should not support invalid selectors', () => { - expect(_isValidCssSelector('a[b[c]]')).to.be.false; - expect(_isValidCssSelector('abc$')).to.be.false; - expect(_isValidCssSelector('@')).to.be.false; - expect(_isValidCssSelector('@import')).to.be.false; - expect(_isValidCssSelector('@media')).to.be.false; - expect(_isValidCssSelector('%')).to.be.false; - expect(_isValidCssSelector('.class-name{display:block}')).to.be.false; - }); -}); diff --git a/helpers/test/css.test.js b/helpers/test/css.test.js index 98079b9ec77..ea867169229 100644 --- a/helpers/test/css.test.js +++ b/helpers/test/css.test.js @@ -2,10 +2,65 @@ import { _isValidCssSelector } from '../internal/css.js'; import { expect } from '@brightspace-ui/testing'; describe('_isValidCssSelector', () => { - it('should return true for valid selectors', () => { + + it('should support simple tag names', () => { + expect(_isValidCssSelector('a')).to.be.true; + expect(_isValidCssSelector('button')).to.be.true; + expect(_isValidCssSelector('table')).to.be.true; + expect(_isValidCssSelector('dl')).to.be.true; + }); + + it('should support simple class selectors', () => { + expect(_isValidCssSelector('.d2l-label-styles')).to.be.true; + expect(_isValidCssSelector('.d2l-body-compact')).to.be.true; + expect(_isValidCssSelector('.className')).to.be.true; + }); + + it('should support simple id selectors', () => { + expect(_isValidCssSelector('#opener')).to.be.true; + }); + + it('should support simple property selectors', () => { + expect(_isValidCssSelector('button[loading]')).to.be.true; + expect(_isValidCssSelector('p[loading]')).to.be.true; + }); + + it('should support complex selectors', () => { + expect(_isValidCssSelector('dl dd')).to.be.true; + expect(_isValidCssSelector('dt.class')).to.be.true; + expect(_isValidCssSelector('dt#id')).to.be.true; + expect(_isValidCssSelector('dl .class')).to.be.true; + expect(_isValidCssSelector('dl #id')).to.be.true; + expect(_isValidCssSelector('dl > dt')).to.be.true; + expect(_isValidCssSelector('dl > dt > dd')).to.be.true; expect(_isValidCssSelector('input[type="checkbox"].d2l-input-checkbox')).to.be.true; - expect(_isValidCssSelector('input[type="checkbox"]')).to.be.true; - expect(_isValidCssSelector('.d2l-input-checkbox')).to.be.true; - expect(_isValidCssSelector('.d2l-link')).to.be.true; + }); + + it('should support simple :host selector', () => { + expect(_isValidCssSelector(':host')).to.be.true; + }); + + it('should support sets of selectors', () => { + expect(_isValidCssSelector('.class1, .class2')).to.be.true; + }); + + it('should not support sets with invalid selectors', () => { + expect(_isValidCssSelector('.valid, invalid$')).to.be.false; + }); + + it('should not support complex :host selectors', () => { + expect(_isValidCssSelector(':host p')).to.be.false; + expect(_isValidCssSelector(':host([hidden])')).to.be.false; + expect(_isValidCssSelector(':host([dir="rtl"])')).to.be.false; + }); + + it('should not support invalid selectors', () => { + expect(_isValidCssSelector('a[b[c]]')).to.be.false; + expect(_isValidCssSelector('abc$')).to.be.false; + expect(_isValidCssSelector('@')).to.be.false; + expect(_isValidCssSelector('@import')).to.be.false; + expect(_isValidCssSelector('@media')).to.be.false; + expect(_isValidCssSelector('%')).to.be.false; + expect(_isValidCssSelector('.class-name{display:block}')).to.be.false; }); }); From 0f835004d3f3d874b992ffe5a73aa60a1d6ff26d Mon Sep 17 00:00:00 2001 From: Edwin Collazos Date: Thu, 14 May 2026 16:30:10 -0400 Subject: [PATCH 7/9] Re-adds the checkbox.scss file so to only first include the changes related to the new way of generating styles --- components/inputs/sass/checkbox.scss | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 components/inputs/sass/checkbox.scss diff --git a/components/inputs/sass/checkbox.scss b/components/inputs/sass/checkbox.scss new file mode 100644 index 00000000000..c0e16def5f7 --- /dev/null +++ b/components/inputs/sass/checkbox.scss @@ -0,0 +1,37 @@ +@use "../../colors/colors.scss"; + +@mixin d2l-input-checkbox() { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-position: center center; + background-repeat: no-repeat; + background-size: 1.2rem 1.2rem; + border-radius: 0.3rem; + border-style: solid; + box-sizing: border-box; + display: inline-block; + height: 1.2rem; + margin: 0; + padding: 0; + vertical-align: middle; + width: 1.2rem; + &:checked { + background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20fill%3D%22%23494C4E%22%20d%3D%22M8.4%2016.6c.6.6%201.5.6%202.1%200l8-8c.6-.6.6-1.5%200-2.1-.6-.6-1.5-.6-2.1%200l-6.9%207-1.9-1.9c-.6-.6-1.5-.6-2.1%200-.6.6-.6%201.5%200%202.1l2.9%202.9z%22/%3E%3C/svg%3E%0A"); + } + &, + &:hover:disabled { + background-color: colors.$d2l-color-regolith; + border-color: colors.$d2l-color-galena; + border-width: 1px; + } + &:hover, + &:focus { + border-color: colors.$d2l-color-celestine; + border-width: 2px; + outline: none; + } + &:disabled { + opacity: 0.5; + } +} From 1e5d1f8f05efe5addb7374f8258ca55ee0f1e541 Mon Sep 17 00:00:00 2001 From: Edwin Collazos Date: Thu, 14 May 2026 16:33:59 -0400 Subject: [PATCH 8/9] Re-adds sass test for the input-checkbox component (will be removed in a separate PR) --- .../inputs/test/input-checkbox.vdiff.js | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/components/inputs/test/input-checkbox.vdiff.js b/components/inputs/test/input-checkbox.vdiff.js index 41d11a0ae32..e35adbd4746 100644 --- a/components/inputs/test/input-checkbox.vdiff.js +++ b/components/inputs/test/input-checkbox.vdiff.js @@ -108,4 +108,28 @@ describe('d2l-input-checkbox', () => { }); }); + + describe('sass', () => { + [false, true].forEach(disabled => { + [true, false].forEach(checked => { + + const name = `${disabled ? 'disabled' : 'default'}-${checked ? 'checked' : 'unchecked'}`; + const checkboxFixture = html``; + + it(name, async() => { + const elem = await fixture(checkboxFixture); + await expect(elem).to.be.golden(); + }); + if (!disabled) { + it(`${name}-focus`, async() => { + const elem = await fixture(checkboxFixture); + await focusElem(elem); + await expect(elem).to.be.golden(); + }); + } + + }); + }); + }); + }); From 8582f33dfdcbdeafaeb21af56011c398138f2628 Mon Sep 17 00:00:00 2001 From: Edwin Collazos Date: Thu, 14 May 2026 16:37:07 -0400 Subject: [PATCH 9/9] Re-adds the sass styles for test --- test/sass.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/sass.scss b/test/sass.scss index 9068c0f48ce..f2177c2b32e 100644 --- a/test/sass.scss +++ b/test/sass.scss @@ -1,4 +1,5 @@ @use "../components/colors/colors.scss"; +@use "../components/inputs/sass/checkbox.scss"; @use "../components/inputs/sass/label.scss"; @use "../components/inputs/sass/radio.scss"; @use "../components/inputs/sass/select.scss"; @@ -34,6 +35,9 @@ .d2l-test-heading-4 { @include typography.d2l-heading-4(); } +.d2l-test-input-checkbox { + @include checkbox.d2l-input-checkbox(); +} .d2l-test-input-label { @include label.d2l-input-label(); }