diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 000000000..63370655d --- /dev/null +++ b/.stylelintignore @@ -0,0 +1 @@ +test/scss/fixtures/ diff --git a/CHANGELOG.md b/CHANGELOG.md index eea81fc7f..77146ac91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ## Changed - Relaxed NodeJS version requirement. +- The focus design tokens are now also used in `base/input-checkbox`, `base/input-radio`, and `base/select`. ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd1edc48d..c2dcf0746 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -58,7 +58,7 @@ yarn format:mdx ## Testing -After adding or changing anything that affects the final output CSS, you’ll need to update the fixtures. These record the expected state of the CSS output by the entire library in its default state, and when some configuration is being overidden. +After adding or changing anything that affects the final output CSS, you’ll need to update the fixtures. These record the expected state of the CSS output by the entire library in its default state, and when some configuration is being overridden. Run the build & comparison: diff --git a/scss/bitstyles/base/input-checkbox/_index.scss b/scss/bitstyles/base/input-checkbox/_index.scss index 16cee3d0c..4ad3ddfbd 100644 --- a/scss/bitstyles/base/input-checkbox/_index.scss +++ b/scss/bitstyles/base/input-checkbox/_index.scss @@ -1,6 +1,7 @@ @forward 'settings'; @use './settings'; @use '../../tools/design-token'; +@use '../../design-tokens/focus'; [type='checkbox'] { display: inline-block; @@ -31,6 +32,11 @@ color: settings.$color-hover; } + &:focus-visible { + outline: focus.$outline-color solid focus.$outline-width; + outline-offset: focus.$outline-offset; + } + &::after { content: ''; display: block; @@ -43,8 +49,12 @@ var(design-token.get('transition', 'default', 'easing')), transform calc(var(design-token.get('transition', 'default', 'duration')) / 2) + var(design-token.get('transition', 'default', 'duration')) + var(design-token.get('transition', 'default', 'easing')), + outline-offset var(design-token.get('transition', 'default', 'duration')) var(design-token.get('transition', 'default', 'easing')); + outline-offset: 0; opacity: 0; background-image: settings.$background-image-checked; background-repeat: no-repeat; diff --git a/scss/bitstyles/base/input-radio/_index.scss b/scss/bitstyles/base/input-radio/_index.scss index c8378a8c8..40a132b80 100644 --- a/scss/bitstyles/base/input-radio/_index.scss +++ b/scss/bitstyles/base/input-radio/_index.scss @@ -1,6 +1,7 @@ @forward 'settings'; @use './settings'; @use '../../tools/design-token'; +@use '../../design-tokens/focus'; [type='radio'] { display: inline-block; @@ -47,6 +48,11 @@ color: settings.$color-hover; } + &:focus-visible { + outline: focus.$outline-color solid focus.$outline-width; + outline-offset: focus.$outline-offset; + } + &:checked { border-color: settings.$border-color-checked; background-color: settings.$background-color-checked; diff --git a/scss/bitstyles/base/input-text/_index.scss b/scss/bitstyles/base/input-text/_index.scss index 576de4f44..5cd99bb24 100644 --- a/scss/bitstyles/base/input-text/_index.scss +++ b/scss/bitstyles/base/input-text/_index.scss @@ -1,6 +1,7 @@ @forward 'settings'; @use './settings'; @use '../../tools/design-token'; +@use '../../design-tokens/focus'; /* stylelint-disable selector-max-type */ textarea, @@ -10,6 +11,8 @@ input { background-color var(design-token.get('transition', 'default', 'duration')) var(design-token.get('transition', 'default', 'easing')), border var(design-token.get('transition', 'default', 'duration')) + var(design-token.get('transition', 'default', 'easing')), + outline-offset var(design-token.get('transition', 'default', 'duration')) var(design-token.get('transition', 'default', 'easing')); resize: vertical; diff --git a/scss/bitstyles/base/select/_index.scss b/scss/bitstyles/base/select/_index.scss index 09321cc54..80ae51095 100644 --- a/scss/bitstyles/base/select/_index.scss +++ b/scss/bitstyles/base/select/_index.scss @@ -1,6 +1,7 @@ @forward 'settings'; @use 'settings'; @use '../../tools/design-token'; +@use '../../design-tokens/focus'; @supports (-webkit-appearance: none) or (-moz-appearance: none) or (appearance: none) { @@ -17,9 +18,12 @@ var(design-token.get('transition', 'default', 'duration')) var(design-token.get('transition', 'default', 'easing')), border var(design-token.get('transition', 'default', 'duration')) + var(design-token.get('transition', 'default', 'easing')), + outline-offset var(design-token.get('transition', 'default', 'duration')) var(design-token.get('transition', 'default', 'easing')); border: settings.$border-width solid settings.$border-color; border-radius: settings.$border-radius; + outline-offset: 0; background-color: settings.$background-color; background-image: settings.$background-image; background-repeat: no-repeat; @@ -51,6 +55,11 @@ color: settings.$color-active; } + &:focus-visible { + outline: focus.$outline-color solid focus.$outline-width; + outline-offset: focus.$outline-offset; + } + &:invalid { border-color: settings.$border-color-invalid; background-color: settings.$background-color-invalid; diff --git a/test/scss/fixtures/bitstyles-overrides.css b/test/scss/fixtures/bitstyles-overrides.css index f68fbca7c..6ea8cf475 100644 --- a/test/scss/fixtures/bitstyles-overrides.css +++ b/test/scss/fixtures/bitstyles-overrides.css @@ -469,6 +469,11 @@ img { color: var(--bscpn-color-brand-1); outline: none; } + [type='checkbox']:focus-visible { + outline: var(--bscpn-color-brand-2) solid + calc(var(--bscpn-size-s7) + var(--bscpn-size-s7) / 2); + outline-offset: var(--bscpn-size-s7); + } [type='checkbox']:after { background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M83.07 11.71 38.66 56.3 16.93 34.49 1 50.48l37.65 37.81L99 27.7z'/%3E%3C/svg%3E"); background-position: 50% 50%; @@ -478,12 +483,15 @@ img { display: block; height: 100%; opacity: 0; + outline-offset: 0; transform: scale(0.7); transition: opacity calc(var(--bscpn-transition-default-duration) / 2) var(--bscpn-transition-default-duration) var(--bscpn-transition-default-easing), transform calc(var(--bscpn-transition-default-duration) / 2) var(--bscpn-transition-default-duration) + var(--bscpn-transition-default-easing), + outline-offset var(--bscpn-transition-default-duration) var(--bscpn-transition-default-easing); width: 100%; } @@ -551,6 +559,11 @@ img { color: var(--bscpn-color-brand-1); outline: none; } + [type='radio']:focus-visible { + outline: var(--bscpn-color-brand-2) solid + calc(var(--bscpn-size-s7) + var(--bscpn-size-s7) / 2); + outline-offset: var(--bscpn-size-s7); + } [type='radio']:checked { background-color: var(--bscpn-color-grayscale-white); border-color: var(--bscpn-color-brand-1); @@ -582,6 +595,8 @@ textarea { background-color var(--bscpn-transition-default-duration) var(--bscpn-transition-default-easing), border var(--bscpn-transition-default-duration) + var(--bscpn-transition-default-easing), + outline-offset var(--bscpn-transition-default-duration) var(--bscpn-transition-default-easing); } input::-moz-placeholder, @@ -767,6 +782,7 @@ textarea:disabled { cursor: pointer; display: block; font: inherit; + outline-offset: 0; overflow: hidden; padding: var(--bscpn-size-s5) calc(var(--bscpn-size-s1) * 2) var(--bscpn-size-s5) var(--bscpn-size-s1); @@ -776,6 +792,8 @@ textarea:disabled { background-color var(--bscpn-transition-default-duration) var(--bscpn-transition-default-easing), border var(--bscpn-transition-default-duration) + var(--bscpn-transition-default-easing), + outline-offset var(--bscpn-transition-default-duration) var(--bscpn-transition-default-easing); width: 100%; } @@ -796,6 +814,11 @@ textarea:disabled { color: var(--bscpn-color-grayscale-dark-1); outline: none; } + select:focus-visible { + outline: var(--bscpn-color-brand-2) solid + calc(var(--bscpn-size-s7) + var(--bscpn-size-s7) / 2); + outline-offset: var(--bscpn-size-s7); + } select:invalid { background-color: var(--bscpn-color-grayscale-white); background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath fill='var(--bscpn-color-warning)' d='M6.64 34.23a5.57 5.57 0 0 1 7.87-7.89l35.41 35.57 35.57-35.57a5.57 5.57 0 0 1 7.87 7.89L53.94 73.66a5.58 5.58 0 0 1-7.88 0Z'/%3E%3C/svg%3E"); diff --git a/test/scss/fixtures/bitstyles.css b/test/scss/fixtures/bitstyles.css index 22cb5d606..d91557d5a 100644 --- a/test/scss/fixtures/bitstyles.css +++ b/test/scss/fixtures/bitstyles.css @@ -716,6 +716,11 @@ img { color: var(--bs-color-brand-1); outline: none; } + [type='checkbox']:focus-visible { + outline: var(--bs-color-brand-2) solid + calc(var(--bs-size-s7) + var(--bs-size-s7) / 2); + outline-offset: var(--bs-size-s7); + } [type='checkbox']:after { background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M83.07 11.71 38.66 56.3 16.93 34.49 1 50.48l37.65 37.81L99 27.7z'/%3E%3C/svg%3E"); background-position: 50% 50%; @@ -725,12 +730,15 @@ img { display: block; height: 100%; opacity: 0; + outline-offset: 0; transform: scale(0.7); transition: opacity calc(var(--bs-transition-default-duration) / 2) var(--bs-transition-default-duration) var(--bs-transition-default-easing), transform calc(var(--bs-transition-default-duration) / 2) var(--bs-transition-default-duration) + var(--bs-transition-default-easing), + outline-offset var(--bs-transition-default-duration) var(--bs-transition-default-easing); width: 100%; } @@ -798,6 +806,11 @@ img { color: var(--bs-color-brand-1); outline: none; } + [type='radio']:focus-visible { + outline: var(--bs-color-brand-2) solid + calc(var(--bs-size-s7) + var(--bs-size-s7) / 2); + outline-offset: var(--bs-size-s7); + } [type='radio']:checked { background-color: var(--bs-color-grayscale-white); border-color: var(--bs-color-brand-1); @@ -829,6 +842,8 @@ textarea { background-color var(--bs-transition-default-duration) var(--bs-transition-default-easing), border var(--bs-transition-default-duration) + var(--bs-transition-default-easing), + outline-offset var(--bs-transition-default-duration) var(--bs-transition-default-easing); } input::-moz-placeholder, @@ -1011,6 +1026,7 @@ textarea:disabled { cursor: pointer; display: block; font: inherit; + outline-offset: 0; overflow: hidden; padding: var(--bs-size-s5) calc(var(--bs-size-s1) * 2) var(--bs-size-s5) var(--bs-size-s1); @@ -1020,6 +1036,8 @@ textarea:disabled { background-color var(--bs-transition-default-duration) var(--bs-transition-default-easing), border var(--bs-transition-default-duration) + var(--bs-transition-default-easing), + outline-offset var(--bs-transition-default-duration) var(--bs-transition-default-easing); width: 100%; } @@ -1040,6 +1058,11 @@ textarea:disabled { color: var(--bs-color-grayscale-dark-1); outline: none; } + select:focus-visible { + outline: var(--bs-color-brand-2) solid + calc(var(--bs-size-s7) + var(--bs-size-s7) / 2); + outline-offset: var(--bs-size-s7); + } select:invalid { background-color: var(--bs-color-grayscale-white); background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath fill='var(--bs-color-warning)' d='M6.64 34.23a5.57 5.57 0 0 1 7.87-7.89l35.41 35.57 35.57-35.57a5.57 5.57 0 0 1 7.87 7.89L53.94 73.66a5.58 5.58 0 0 1-7.88 0Z'/%3E%3C/svg%3E");