[Switch] Simplify DOM & CSS

This commit is contained in:
Lea Verou
2024-12-18 21:33:52 -05:00
parent 96db264724
commit d33b5c4870
2 changed files with 55 additions and 64 deletions

View File

@@ -16,7 +16,7 @@
display: inline-block;
}
.switch {
label {
position: relative;
display: flex;
align-items: center;
@@ -26,7 +26,7 @@
cursor: pointer;
}
.control {
.switch {
flex: 0 0 auto;
position: relative;
display: flex;
@@ -40,23 +40,19 @@
border-style: var(--border-style);
border-width: var(--border-width);
box-shadow: var(--box-shadow);
transition:
background var(--wa-transition-normal) var(--wa-transition-easing),
border-color var(--wa-transition-normal) var(--wa-transition-easing);
transition-property: translate, background, border-color, box-shadow;
transition-duration: var(--wa-transition-normal);
transition-timing-function: var(--wa-transition-easing);
}
.control .thumb {
.switch .thumb {
width: var(--thumb-size);
height: var(--thumb-size);
background-color: var(--thumb-color);
border-radius: 50%;
box-shadow: var(--thumb-shadow);
translate: calc((var(--width) - var(--height)) / -2);
transition:
translate var(--wa-transition-normal) var(--wa-transition-easing),
background-color var(--wa-transition-normal) var(--wa-transition-easing),
border-color var(--wa-transition-normal) var(--wa-transition-easing),
box-shadow var(--wa-transition-normal) var(--wa-transition-easing);
transition: inherit;
}
.input {
@@ -68,29 +64,29 @@
}
/* Focus */
.switch:not(.switch--disabled) .input:focus-visible ~ .control .thumb {
label:not(.disabled) .input:focus-visible ~ .switch .thumb {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
/* Checked */
.switch--checked .control {
.checked .switch {
background-color: var(--background-color-checked);
border-color: var(--border-color-checked);
}
.switch--checked .control .thumb {
.checked .switch .thumb {
background-color: var(--thumb-color-checked);
translate: calc((var(--width) - var(--height)) / 2);
}
/* Disabled */
.switch--disabled {
label:has(> :disabled) {
opacity: 0.5;
cursor: not-allowed;
}
.label {
[part~='label'] {
display: inline-block;
line-height: var(--height);
margin-inline-start: 0.5em;
@@ -98,15 +94,15 @@
-webkit-user-select: none;
}
:host([required]) .label::after {
:host([required]) [part~='label']::after {
content: var(--wa-form-control-required-content);
color: var(--wa-form-control-required-content-color);
margin-inline-start: var(--wa-form-control-required-content-offset);
}
@media (forced-colors: active) {
.switch.switch--checked:not(.switch--disabled) .control:hover .thumb,
.switch--checked .control .thumb {
:checked:enabled + .switch:hover .thumb,
:checked + .switch .thumb {
background-color: ButtonText;
}
}

View File

@@ -239,54 +239,49 @@ export default class WaSwitch extends WebAwesomeFormAssociatedElement {
const hasHint = this.hint ? true : !!hasHintSlot;
return html`
<div class="form-control">
<label
part="base"
class=${classMap({
switch: true,
'switch--checked': this.checked,
'switch--disabled': this.disabled,
'switch--focused': this.hasFocus,
})}
>
<input
class="input"
type="checkbox"
title=${this.title /* An empty title prevents browser validation tooltips from appearing on hover */}
name=${this.name}
value=${ifDefined(this.value)}
.checked=${live(this.checked)}
.disabled=${this.disabled}
.required=${this.required}
role="switch"
aria-checked=${this.checked ? 'true' : 'false'}
aria-describedby="hint"
@click=${this.handleClick}
@input=${this.handleInput}
@blur=${this.handleBlur}
@focus=${this.handleFocus}
@keydown=${this.handleKeyDown}
/>
<label
part="base"
class=${classMap({
checked: this.checked,
disabled: this.disabled,
focused: this.hasFocus,
})}
>
<input
class="input"
type="checkbox"
title=${this.title /* An empty title prevents browser validation tooltips from appearing on hover */}
name=${this.name}
value=${ifDefined(this.value)}
.checked=${live(this.checked)}
.disabled=${this.disabled}
.required=${this.required}
role="switch"
aria-checked=${this.checked ? 'true' : 'false'}
aria-describedby="hint"
@click=${this.handleClick}
@input=${this.handleInput}
@blur=${this.handleBlur}
@focus=${this.handleFocus}
@keydown=${this.handleKeyDown}
/>
<span part="control" class="control">
<span part="thumb" class="thumb"></span>
</span>
<span part="control" class="switch">
<span part="thumb" class="thumb"></span>
</span>
<div part="label" class="label">
<slot></slot>
</div>
</label>
<slot part="label" class="label"></slot>
</label>
<slot
name="hint"
part="hint"
class=${classMap({
'has-slotted': hasHint,
})}
aria-hidden=${hasHint ? 'false' : 'true'}
>${this.hint}</slot
>
</div>
<slot
name="hint"
part="hint"
class=${classMap({
'has-slotted': hasHint,
})}
aria-hidden=${hasHint ? 'false' : 'true'}
>${this.hint}</slot
>
`;
}
}