mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-15 15:14:35 +00:00
Compare commits
2 Commits
serial-sel
...
migrate-ha
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afc129526a | ||
|
|
c27d127fed |
@@ -3,37 +3,68 @@ title: Switch / Toggle
|
||||
---
|
||||
|
||||
<style>
|
||||
ha-switch {
|
||||
display: block;
|
||||
.wrapper {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
# Switch `<ha-switch>`
|
||||
|
||||
A toggle switch can represent two states: on and off.
|
||||
A toggle switch representing two states: on and off.
|
||||
|
||||
## Examples
|
||||
## Implementation
|
||||
|
||||
Switch in on state
|
||||
### Example usage
|
||||
|
||||
<div class="wrapper">
|
||||
<ha-switch checked></ha-switch>
|
||||
<ha-switch></ha-switch>
|
||||
<ha-switch disabled></ha-switch>
|
||||
<ha-switch disabled checked></ha-switch>
|
||||
</div>
|
||||
|
||||
```html
|
||||
<ha-switch checked></ha-switch>
|
||||
|
||||
Switch in off state
|
||||
<ha-switch></ha-switch>
|
||||
|
||||
Disabled switch
|
||||
<ha-switch disabled></ha-switch>
|
||||
|
||||
## CSS variables
|
||||
<ha-switch disabled checked></ha-switch>
|
||||
```
|
||||
|
||||
For the switch / toggle there are always two variables, one for the on / checked state and one for the off / unchecked state.
|
||||
### API
|
||||
|
||||
The track element (background rounded rectangle that the round circular handle travels on) is set to being half transparent, so the final color will also be impacted by the color behind the track.
|
||||
This component is based on the webawesome switch component.
|
||||
Check the [webawesome documentation](https://webawesome.com/docs/components/switch/) for more details.
|
||||
|
||||
`switch-checked-color` / `switch-unchecked-color`
|
||||
Set both the color of the round handle and the track behind it. If you want to control them separately, use the variables below instead.
|
||||
**Properties/Attributes**
|
||||
|
||||
`switch-checked-button-color` / `switch-unchecked-button-color`
|
||||
Color of the round handle
|
||||
| Name | Type | Default | Description |
|
||||
| -------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| checked | Boolean | false | The checked state of the switch. |
|
||||
| disabled | Boolean | false | Disables the switch and prevents user interaction. |
|
||||
| required | Boolean | false | Makes the switch a required field. |
|
||||
| haptic | Boolean | false | Enables haptic vibration on toggle. Only use when the new state is applied immediately (not when save is required). |
|
||||
|
||||
`switch-checked-track-color` / `switch-unchecked-track-color`
|
||||
Color of the track behind the round handle
|
||||
**CSS Custom Properties**
|
||||
|
||||
- `--ha-switch-size` - The size of the switch track height. Defaults to `14px`.
|
||||
- `--ha-switch-thumb-size` - The size of the thumb. Defaults to `20px`.
|
||||
- `--ha-switch-width` - The width of the switch track. Defaults to `36px`.
|
||||
- `--ha-switch-box-shadow` - The box shadow of the thumb. Defaults to `var(--ha-box-shadow-s)`.
|
||||
- `--ha-switch-background-color` - Background color of the unchecked track.
|
||||
- `--ha-switch-border-color` - Border color of the unchecked track and thumb.
|
||||
- `--ha-switch-thumb-background-color` - Background color of the unchecked thumb.
|
||||
- `--ha-switch-background-color-hover` - Background color of the unchecked track on hover.
|
||||
- `--ha-switch-thumb-background-color-hover` - Background color of the unchecked thumb on hover.
|
||||
- `--ha-switch-checked-background-color` - Background color of the checked track.
|
||||
- `--ha-switch-checked-border-color` - Border color of the checked track.
|
||||
- `--ha-switch-checked-thumb-background-color` - Background color of the checked thumb.
|
||||
- `--ha-switch-checked-thumb-border-color` - Border color of the checked thumb.
|
||||
- `--ha-switch-checked-background-color-hover` - Background color of the checked track on hover.
|
||||
- `--ha-switch-checked-thumb-background-color-hover` - Background color of the checked thumb on hover.
|
||||
- `--ha-switch-required-marker` - The marker shown after the label for required fields. Defaults to `"*"`.
|
||||
- `--ha-switch-required-marker-offset` - Offset of the required marker. Defaults to `0.1rem`.
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"@material/mwc-formfield": "patch:@material/mwc-formfield@npm%3A0.27.0#~/.yarn/patches/@material-mwc-formfield-npm-0.27.0-9528cb60f6.patch",
|
||||
"@material/mwc-list": "patch:@material/mwc-list@npm%3A0.27.0#~/.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch",
|
||||
"@material/mwc-radio": "0.27.0",
|
||||
"@material/mwc-switch": "0.27.0",
|
||||
"@material/mwc-top-app-bar": "0.27.0",
|
||||
"@material/mwc-top-app-bar-fixed": "0.27.0",
|
||||
"@material/top-app-bar": "=14.0.0-canary.53b3cad2f.0",
|
||||
|
||||
@@ -1,49 +1,195 @@
|
||||
import { SwitchBase } from "@material/mwc-switch/deprecated/mwc-switch-base";
|
||||
import { styles } from "@material/mwc-switch/deprecated/mwc-switch.css";
|
||||
import { css } from "lit";
|
||||
import Switch from "@home-assistant/webawesome/dist/components/switch/switch";
|
||||
import { css, type CSSResultGroup, type PropertyValues } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { forwardHaptic } from "../data/haptics";
|
||||
|
||||
/**
|
||||
* Home Assistant switch component
|
||||
*
|
||||
* @element ha-switch
|
||||
* @extends {Switch}
|
||||
*
|
||||
* @summary
|
||||
* A toggle switch component supporting Home Assistant theming, based on the webawesome switch.
|
||||
* Represents two states: on and off.
|
||||
*
|
||||
* @cssprop --ha-switch-size - The size of the switch track height. Defaults to `14px`.
|
||||
* @cssprop --ha-switch-thumb-size - The size of the thumb. Defaults to `20px`.
|
||||
* @cssprop --ha-switch-width - The width of the switch track. Defaults to `36px`.
|
||||
* @cssprop --ha-switch-box-shadow - The box shadow of the thumb. Defaults to `var(--ha-box-shadow-s)`.
|
||||
* @cssprop --ha-switch-background-color - Background color of the unchecked track.
|
||||
* @cssprop --ha-switch-border-color - Border color of the unchecked track and thumb.
|
||||
* @cssprop --ha-switch-thumb-background-color - Background color of the unchecked thumb.
|
||||
* @cssprop --ha-switch-background-color-hover - Background color of the unchecked track on hover.
|
||||
* @cssprop --ha-switch-thumb-background-color-hover - Background color of the unchecked thumb on hover.
|
||||
* @cssprop --ha-switch-checked-background-color - Background color of the checked track.
|
||||
* @cssprop --ha-switch-checked-border-color - Border color of the checked track.
|
||||
* @cssprop --ha-switch-checked-thumb-background-color - Background color of the checked thumb.
|
||||
* @cssprop --ha-switch-checked-thumb-border-color - Border color of the checked thumb.
|
||||
* @cssprop --ha-switch-checked-background-color-hover - Background color of the checked track on hover.
|
||||
* @cssprop --ha-switch-checked-thumb-background-color-hover - Background color of the checked thumb on hover.
|
||||
* @cssprop --ha-switch-required-marker - The marker shown after the label for required fields. Defaults to `"*"`.
|
||||
* @cssprop --ha-switch-required-marker-offset - Offset of the required marker. Defaults to `0.1rem`.
|
||||
*
|
||||
* @attr {boolean} checked - The checked state of the switch.
|
||||
* @attr {boolean} disabled - Disables the switch and prevents user interaction.
|
||||
* @attr {boolean} required - Makes the switch a required field.
|
||||
* @attr {boolean} haptic - Enables haptic vibration on toggle. Only use when the new state is applied immediately (not when a save action is required).
|
||||
*/
|
||||
@customElement("ha-switch")
|
||||
export class HaSwitch extends SwitchBase {
|
||||
// Generate a haptic vibration.
|
||||
// Only set to true if the new value of the switch is applied right away when toggling.
|
||||
// Do not add haptic when a user is required to press save.
|
||||
export class HaSwitch extends Switch {
|
||||
/**
|
||||
* Enables haptic vibration on toggle.
|
||||
* Only set to true if the new value of the switch is applied right away when toggling.
|
||||
* Do not add haptic when a user is required to press save.
|
||||
*/
|
||||
@property({ type: Boolean }) public haptic = false;
|
||||
|
||||
protected firstUpdated() {
|
||||
super.firstUpdated();
|
||||
this.addEventListener("change", () => {
|
||||
public updated(changedProperties: PropertyValues<typeof this>) {
|
||||
super.updated(changedProperties);
|
||||
if (changedProperties.has("haptic")) {
|
||||
if (this.haptic) {
|
||||
forwardHaptic(this, "light");
|
||||
this.addEventListener("change", this._forwardHaptic);
|
||||
} else {
|
||||
this.removeEventListener("change", this._forwardHaptic);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static override styles = [
|
||||
styles,
|
||||
css`
|
||||
:host {
|
||||
--mdc-theme-secondary: var(--switch-checked-color);
|
||||
}
|
||||
.mdc-switch.mdc-switch--checked .mdc-switch__thumb {
|
||||
background-color: var(--switch-checked-button-color);
|
||||
border-color: var(--switch-checked-button-color);
|
||||
}
|
||||
.mdc-switch.mdc-switch--checked .mdc-switch__track {
|
||||
background-color: var(--switch-checked-track-color);
|
||||
border-color: var(--switch-checked-track-color);
|
||||
}
|
||||
.mdc-switch:not(.mdc-switch--checked) .mdc-switch__thumb {
|
||||
background-color: var(--switch-unchecked-button-color);
|
||||
border-color: var(--switch-unchecked-button-color);
|
||||
}
|
||||
.mdc-switch:not(.mdc-switch--checked) .mdc-switch__track {
|
||||
background-color: var(--switch-unchecked-track-color);
|
||||
border-color: var(--switch-unchecked-track-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
public disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.removeEventListener("change", this._forwardHaptic);
|
||||
}
|
||||
|
||||
private _forwardHaptic = () => {
|
||||
forwardHaptic(this, "light");
|
||||
};
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
Switch.styles,
|
||||
css`
|
||||
:host {
|
||||
--wa-form-control-toggle-size: var(--ha-switch-size, 14px);
|
||||
--wa-form-control-required-content: var(
|
||||
--ha-switch-required-marker,
|
||||
var(--ha-input-required-marker, "*")
|
||||
);
|
||||
--wa-form-control-required-content-offset: var(
|
||||
--ha-switch-required-marker-offset,
|
||||
0.1rem
|
||||
);
|
||||
--thumb-size: var(--ha-switch-thumb-size, 20px);
|
||||
--width: var(--ha-switch-width, 36px);
|
||||
}
|
||||
|
||||
label {
|
||||
height: max(var(--thumb-size), var(--wa-form-control-toggle-size));
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
.switch {
|
||||
background-color: var(
|
||||
--ha-switch-background-color,
|
||||
var(--ha-color-form-background)
|
||||
);
|
||||
border-color: var(
|
||||
--ha-switch-border-color,
|
||||
var(--ha-color-border-neutral-normal)
|
||||
);
|
||||
}
|
||||
|
||||
.switch .thumb {
|
||||
background-color: var(
|
||||
--ha-switch-thumb-background-color,
|
||||
var(--ha-color-form-background)
|
||||
);
|
||||
border-color: var(
|
||||
--ha-switch-border-color,
|
||||
var(--ha-color-border-neutral-normal)
|
||||
);
|
||||
border-style: var(--wa-form-control-border-style);
|
||||
border-width: var(--wa-form-control-border-width);
|
||||
box-shadow: var(--ha-switch-box-shadow, var(--ha-box-shadow-s));
|
||||
}
|
||||
|
||||
label:not(.disabled):hover .switch,
|
||||
label:not(.disabled) .input:focus-visible ~ .switch,
|
||||
label:not(.disabled):active .switch {
|
||||
background-color: var(
|
||||
--ha-switch-background-color-hover,
|
||||
var(
|
||||
--ha-switch-background-color,
|
||||
var(--ha-color-fill-neutral-normal-hover)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
label:not(.disabled):hover .switch .thumb,
|
||||
label:not(.disabled) .input:focus-visible ~ .switch .thumb,
|
||||
label:not(.disabled):active .switch .thumb {
|
||||
background-color: var(
|
||||
--ha-switch-thumb-background-color-hover,
|
||||
var(
|
||||
--ha-switch-thumb-background-color,
|
||||
var(--ha-color-form-background-hover)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
.checked .switch {
|
||||
background-color: var(
|
||||
--ha-switch-checked-background-color,
|
||||
var(--ha-color-fill-primary-normal-resting)
|
||||
);
|
||||
border-color: var(
|
||||
--ha-switch-checked-border-color,
|
||||
var(--ha-color-border-primary-loud)
|
||||
);
|
||||
}
|
||||
|
||||
.checked .switch .thumb {
|
||||
background-color: var(
|
||||
--ha-switch-checked-thumb-background-color,
|
||||
var(--ha-color-fill-primary-loud-resting)
|
||||
);
|
||||
border-color: var(
|
||||
--ha-switch-checked-thumb-border-color,
|
||||
var(--ha-color-fill-primary-loud-resting)
|
||||
);
|
||||
}
|
||||
|
||||
label:not(.disabled).checked:hover .switch,
|
||||
label:not(.disabled).checked .input:focus-visible ~ .switch,
|
||||
label:not(.disabled).checked:active .switch {
|
||||
background-color: var(
|
||||
--ha-switch-checked-background-color-hover,
|
||||
var(
|
||||
--ha-switch-checked-background-color,
|
||||
var(--ha-color-fill-primary-normal-hover)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
label:not(.disabled).checked:hover .switch .thumb,
|
||||
label:not(.disabled).checked .input:focus-visible ~ .switch .thumb,
|
||||
label:not(.disabled).checked:active .switch .thumb {
|
||||
background-color: var(
|
||||
--ha-switch-checked-thumb-background-color-hover,
|
||||
var(
|
||||
--ha-switch-checked-thumb-background-color,
|
||||
var(--ha-color-fill-primary-loud-hover)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
label.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -34,6 +34,7 @@ class EntityIdPickerRow extends LitElement {
|
||||
>
|
||||
<ha-switch
|
||||
slot="end"
|
||||
haptic
|
||||
.checked=${!!this.coreUserData &&
|
||||
!!this.coreUserData.showEntityIdPicker}
|
||||
.disabled=${this.coreUserData === undefined}
|
||||
|
||||
@@ -266,11 +266,6 @@ export const colorStyles = css`
|
||||
--sidebar-selected-text-color: var(--primary-color);
|
||||
--sidebar-selected-icon-color: var(--primary-color);
|
||||
--sidebar-icon-color: rgba(var(--rgb-primary-text-color), 0.6);
|
||||
--switch-checked-color: var(--primary-color);
|
||||
--switch-checked-button-color: var(--switch-checked-color, var(--primary-background-color));
|
||||
--switch-checked-track-color: var(--switch-checked-color, #000000);
|
||||
--switch-unchecked-button-color: var(--switch-unchecked-color, var(--primary-background-color));
|
||||
--switch-unchecked-track-color: var(--switch-unchecked-color, #000000);
|
||||
--slider-color: var(--primary-color);
|
||||
--slider-secondary-color: var(--light-primary-color);
|
||||
--slider-track-color: var(--scrollbar-thumb-color);
|
||||
@@ -352,8 +347,6 @@ export const darkColorStyles = css`
|
||||
--primary-text-color: #e1e1e1;
|
||||
--secondary-text-color: #9b9b9b;
|
||||
--disabled-text-color: #6f6f6f;
|
||||
--switch-unchecked-button-color: #999999;
|
||||
--switch-unchecked-track-color: #9b9b9b;
|
||||
--divider-color: rgba(225, 225, 225, 0.12);
|
||||
--outline-color: rgba(225, 225, 225, 0.12);
|
||||
--outline-hover-color: rgba(225, 225, 225, 0.24);
|
||||
|
||||
35
yarn.lock
35
yarn.lock
@@ -2690,19 +2690,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@material/mwc-switch@npm:0.27.0":
|
||||
version: 0.27.0
|
||||
resolution: "@material/mwc-switch@npm:0.27.0"
|
||||
dependencies:
|
||||
"@material/mwc-base": "npm:^0.27.0"
|
||||
"@material/mwc-ripple": "npm:^0.27.0"
|
||||
"@material/switch": "npm:=14.0.0-canary.53b3cad2f.0"
|
||||
lit: "npm:^2.0.0"
|
||||
tslib: "npm:^2.0.1"
|
||||
checksum: 10/620d55add1ee7064e21f4ab649b2d017ec235106a0dcd5f3f29c26a0ea2ec3f8b3c01489081609574f8475a8daa38a4b24fe6129b0fcc82d69e6d58e5483b7c2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@material/mwc-top-app-bar-fixed@npm:0.27.0":
|
||||
version: 0.27.0
|
||||
resolution: "@material/mwc-top-app-bar-fixed@npm:0.27.0"
|
||||
@@ -2833,27 +2820,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@material/switch@npm:=14.0.0-canary.53b3cad2f.0":
|
||||
version: 14.0.0-canary.53b3cad2f.0
|
||||
resolution: "@material/switch@npm:14.0.0-canary.53b3cad2f.0"
|
||||
dependencies:
|
||||
"@material/animation": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/base": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/density": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/dom": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/elevation": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/feature-targeting": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/focus-ring": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/ripple": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/rtl": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/shape": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/theme": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
"@material/tokens": "npm:14.0.0-canary.53b3cad2f.0"
|
||||
tslib: "npm:^2.1.0"
|
||||
checksum: 10/445415165ac20c6c80854bf5c8688ea9c2bc88844602b1ebe1f4a9325c9802a295b90c15b860e2af831657b163bd45f64ea5eb6e99e90de8198b100d6c9e52bc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@material/theme@npm:14.0.0-canary.53b3cad2f.0":
|
||||
version: 14.0.0-canary.53b3cad2f.0
|
||||
resolution: "@material/theme@npm:14.0.0-canary.53b3cad2f.0"
|
||||
@@ -8900,7 +8866,6 @@ __metadata:
|
||||
"@material/mwc-formfield": "patch:@material/mwc-formfield@npm%3A0.27.0#~/.yarn/patches/@material-mwc-formfield-npm-0.27.0-9528cb60f6.patch"
|
||||
"@material/mwc-list": "patch:@material/mwc-list@npm%3A0.27.0#~/.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch"
|
||||
"@material/mwc-radio": "npm:0.27.0"
|
||||
"@material/mwc-switch": "npm:0.27.0"
|
||||
"@material/mwc-top-app-bar": "npm:0.27.0"
|
||||
"@material/mwc-top-app-bar-fixed": "npm:0.27.0"
|
||||
"@material/top-app-bar": "npm:=14.0.0-canary.53b3cad2f.0"
|
||||
|
||||
Reference in New Issue
Block a user