From c8db30fa0f475e5a1c58af47ae415010d9164947 Mon Sep 17 00:00:00 2001 From: lindsaym-fa Date: Wed, 18 Dec 2024 14:09:09 -0500 Subject: [PATCH] Add native checkbox styles and share with --- src/components/checkbox/checkbox.css | 68 -------------------- src/components/checkbox/checkbox.ts | 3 +- src/styles/native.css | 1 + src/styles/native/checkbox.css | 93 ++++++++++++++++++++++++++++ src/styles/native/form-control.css | 8 ++- 5 files changed, 103 insertions(+), 70 deletions(-) create mode 100644 src/styles/native/checkbox.css diff --git a/src/components/checkbox/checkbox.css b/src/components/checkbox/checkbox.css index ad7e20b55..19401b693 100644 --- a/src/components/checkbox/checkbox.css +++ b/src/components/checkbox/checkbox.css @@ -1,76 +1,9 @@ -:host { - --background-color: var(--wa-form-control-background-color); - --background-color-checked: var(--wa-form-control-activated-color); - --border-color: var(--wa-form-control-resting-color); - --border-color-checked: var(--wa-form-control-activated-color); - --border-radius: min( - calc(var(--toggle-size) * 0.375), - var(--wa-border-radius-xs) - ); /* min so it doesn't look like a circle/radio */ - --border-style: var(--wa-border-style); - --border-width: var(--wa-form-control-border-width); - --box-shadow: none; - --checked-icon-color: var(--wa-color-brand-on-loud); - --toggle-size: calc(1em * var(--wa-form-control-value-line-height)); - - display: inline-block; -} - [part~='base'] { position: relative; display: flex; align-items: flex-start; color: var(--wa-form-control-value-color); vertical-align: middle; - cursor: pointer; - - /* Disabled */ - &:has(input:disabled) { - opacity: 0.5; - cursor: not-allowed; - } -} - -.control { - flex: 0 0 auto; - position: relative; - display: flex; - align-items: center; - justify-content: center; - width: var(--toggle-size); - height: var(--toggle-size); - border-color: var(--border-color); - border-radius: var(--border-radius); - border-style: var(--border-style); - border-width: var(--border-width); - background-color: var(--background-color); - box-shadow: var(--box-shadow); - color: var(--wa-form-control-value-color); - transition: - background var(--wa-transition-normal), - border-color var(--wa-transition-fast), - box-shadow var(--wa-transition-fast), - color var(--wa-transition-fast); - transition-timing-function: var(--wa-transition-easing); - - /* Focus */ - &:has(> input:focus-visible:not(:checked, :disabled)) { - outline: var(--wa-focus-ring); - outline-offset: var(--wa-focus-ring-offset); - } - - /* Checked/indeterminate */ - &:has(:checked, :indeterminate) { - color: var(--checked-icon-color); - border-color: var(--border-color-checked); - background-color: var(--background-color-checked); - } - - /* Checked/indeterminate + focus */ - &:has(> input:focus-visible:is(:checked, :indeterminate):not(:disabled)) { - outline: var(--wa-focus-ring); - outline-offset: var(--wa-focus-ring-offset); - } } input { @@ -94,7 +27,6 @@ input { [part~='label'] { display: inline-block; line-height: var(--toggle-size); - margin-inline-start: var(--wa-space-xs); user-select: none; -webkit-user-select: none; } diff --git a/src/components/checkbox/checkbox.ts b/src/components/checkbox/checkbox.ts index 77bbdfbcc..f69dd19fe 100644 --- a/src/components/checkbox/checkbox.ts +++ b/src/components/checkbox/checkbox.ts @@ -12,6 +12,7 @@ import { HasSlotController } from '../../internal/slot.js'; import { RequiredValidator } from '../../internal/validators/required-validator.js'; import { watch } from '../../internal/watch.js'; import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-element.js'; +import nativeStyles from '../../styles/native/checkbox.css'; import formControlStyles from '../../styles/shadow/form-control.css'; import sizeStyles from '../../styles/utilities/size.css'; import '../icon/icon.js'; @@ -59,7 +60,7 @@ import styles from './checkbox.css'; */ @customElement('wa-checkbox') export default class WaCheckbox extends WebAwesomeFormAssociatedElement { - static shadowStyle = [formControlStyles, sizeStyles, styles]; + static shadowStyle = [formControlStyles, sizeStyles, nativeStyles, styles]; static shadowRootOptions = { ...WebAwesomeFormAssociatedElement.shadowRootOptions, delegatesFocus: true }; diff --git a/src/styles/native.css b/src/styles/native.css index 2d6e7864b..a05d2979e 100644 --- a/src/styles/native.css +++ b/src/styles/native.css @@ -1,3 +1,4 @@ @import url('./native/button.css'); +@import url('./native/checkbox.css'); @import url('./native/form-control.css'); @import url('./native/input.css'); diff --git a/src/styles/native/checkbox.css b/src/styles/native/checkbox.css new file mode 100644 index 000000000..020f33e00 --- /dev/null +++ b/src/styles/native/checkbox.css @@ -0,0 +1,93 @@ +input[type='checkbox']:where(:not(:host *, .wa-off, .wa-off-deep *)), +label:has(input[type='checkbox']):where(:not(:host *, .wa-off, .wa-off-deep *)), +:host { + --background-color: var(--wa-form-control-background-color); + --background-color-checked: var(--wa-form-control-activated-color); + --border-color: var(--wa-form-control-resting-color); + --border-color-checked: var(--wa-form-control-activated-color); + --border-radius: min( + calc(var(--toggle-size) * 0.375), + var(--wa-border-radius-xs) + ); /* min prevents entirely circular checkbox */ + --border-style: var(--wa-border-style); + --border-width: var(--wa-form-control-border-width); + --box-shadow: none; + --checked-icon-color: var(--wa-color-brand-on-loud); + --toggle-size: 1lh; + + display: inline-flex; + line-height: var(--wa-form-control-value-line-height); +} + +/* Replace native checkbox styles */ +input[type='checkbox']:where(:not(:host *, .wa-off, .wa-off-deep *)) { + appearance: none; + margin: 0; + + &:checked::after { + background-color: currentColor; + content: ''; + mask: url('data:image/svg+xml;utf8,') + center no-repeat; + position: absolute; + height: 100%; + width: 100%; + } +} + +input[type='checkbox']:where(:not(:host *, .wa-off, .wa-off-deep *)), +:host .control { + flex: 0 0 auto; + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + width: var(--toggle-size); + height: var(--toggle-size); + border-color: var(--border-color); + border-radius: var(--border-radius); + border-style: var(--border-style); + border-width: var(--border-width); + background-color: var(--background-color); + box-shadow: var(--box-shadow); + color: var(--wa-form-control-value-color); + transition: + background var(--wa-transition-normal), + border-color var(--wa-transition-fast), + box-shadow var(--wa-transition-fast), + color var(--wa-transition-fast); + transition-timing-function: var(--wa-transition-easing); + + margin-inline-end: var(--wa-space-xs); +} + +/* Set cursor for input and labels */ +input[type='checkbox']:where(:not(:host *, .wa-off, .wa-off-deep *)), +label:has(input[type='checkbox']):where(:not(:host *, .wa-off, .wa-off-deep *)), +input[type='checkbox']:where(:not(:host *, .wa-off, .wa-off-deep *)) + label, +:host [part~='base'] { + cursor: pointer; +} + +/* Checked */ +input[type='checkbox']:is(:checked, :indeterminate):where(:not(:host *, .wa-off, .wa-off-deep *)), +[part~='base'] .control:has(:checked, :indeterminate) /* scoping this rule to :host breaks in Firefox */ { + color: var(--checked-icon-color); + border-color: var(--border-color-checked); + background-color: var(--background-color-checked); +} + +/* Focus */ +input[type='checkbox']:focus-visible:where(:not(:host *, .wa-off, .wa-off-deep *)), +[part~='base'] .control:has(> input:focus-visible:not(:disabled)) /* scoping this rule to :host breaks in Firefox */ { + outline: var(--wa-focus-ring); + outline-offset: var(--wa-focus-ring-offset); +} + +/* Disabled */ +input[type='checkbox']:disabled:where(:not(:host *, .wa-off, .wa-off-deep *)), +label:has(input[type='checkbox']:disabled):where(:not(:host *, .wa-off, .wa-off-deep *)), +:host [part~='base']:has(input:disabled) { + opacity: 0.5; + cursor: not-allowed; +} diff --git a/src/styles/native/form-control.css b/src/styles/native/form-control.css index 205c85df6..8feb84573 100644 --- a/src/styles/native/form-control.css +++ b/src/styles/native/form-control.css @@ -6,7 +6,13 @@ label { margin-bottom: var(--wa-space-xs); } -label:has(+ input:required)::after { +input:is([type='checkbox'], [type='radio']) + label, +label:has(input:is([type='checkbox'], [type='radio'])) { + margin-bottom: 0; +} + +label:has(+ input:required)::after, +label:has(input:required)::after { content: var(--wa-form-control-required-content); margin-inline-start: var(--wa-form-control-required-content-offset); color: var(--wa-form-control-required-content-color);