Replace checkboxes in list items with check-list-item (#11610)

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
Bram Kragten 2022-02-09 16:50:48 +01:00 committed by GitHub
parent 9eea17b793
commit 4ef5f3af89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 330 additions and 283 deletions

View File

@ -0,0 +1,22 @@
import { css } from "lit";
import { CheckListItemBase } from "@material/mwc-list/mwc-check-list-item-base";
import { styles } from "@material/mwc-list/mwc-control-list-item.css";
import { customElement } from "lit/decorators";
@customElement("ha-check-list-item")
export class HaCheckListItem extends CheckListItemBase {
static override styles = [
styles,
css`
:host {
--mdc-theme-secondary: var(--primary-color);
}
`,
];
}
declare global {
interface HTMLElementTagNameMap {
"ha-check-list-item": HaCheckListItem;
}
}

View File

@ -1,12 +1,18 @@
import { Checkbox } from "@material/mwc-checkbox";
import { CheckboxBase } from "@material/mwc-checkbox/mwc-checkbox-base";
import { styles } from "@material/mwc-checkbox/mwc-checkbox.css";
import { css } from "lit";
import { customElement } from "lit/decorators";
@customElement("ha-checkbox")
export class HaCheckbox extends Checkbox {
public firstUpdated() {
super.firstUpdated();
this.style.setProperty("--mdc-theme-secondary", "var(--primary-color)");
}
export class HaCheckbox extends CheckboxBase {
static override styles = [
styles,
css`
:host {
--mdc-theme-secondary: var(--primary-color);
}
`,
];
}
declare global {

View File

@ -1,6 +1,7 @@
import { Dialog } from "@material/mwc-dialog";
import { DialogBase } from "@material/mwc-dialog/mwc-dialog-base";
import { styles } from "@material/mwc-dialog/mwc-dialog.css";
import { mdiClose } from "@mdi/js";
import { css, CSSResultGroup, html, TemplateResult } from "lit";
import { css, html, TemplateResult } from "lit";
import { customElement } from "lit/decorators";
import { computeRTLDirection } from "../common/util/compute_rtl";
import type { HomeAssistant } from "../types";
@ -21,8 +22,7 @@ export const createCloseHeading = (
`;
@customElement("ha-dialog")
// @ts-expect-error
export class HaDialog extends Dialog {
export class HaDialog extends DialogBase {
public scrollToPos(x: number, y: number) {
this.contentElement?.scrollTo(x, y);
}
@ -31,77 +31,75 @@ export class HaDialog extends Dialog {
return html`<slot name="heading"> ${super.renderHeading()} </slot>`;
}
protected static get styles(): CSSResultGroup {
return [
Dialog.styles,
css`
.mdc-dialog {
--mdc-dialog-scroll-divider-color: var(--divider-color);
z-index: var(--dialog-z-index, 7);
-webkit-backdrop-filter: var(--dialog-backdrop-filter, none);
backdrop-filter: var(--dialog-backdrop-filter, none);
}
.mdc-dialog__actions {
justify-content: var(--justify-action-buttons, flex-end);
padding-bottom: max(env(safe-area-inset-bottom), 8px);
}
.mdc-dialog__actions span:nth-child(1) {
flex: var(--secondary-action-button-flex, unset);
}
.mdc-dialog__actions span:nth-child(2) {
flex: var(--primary-action-button-flex, unset);
}
.mdc-dialog__container {
align-items: var(--vertial-align-dialog, center);
}
.mdc-dialog__title::before {
display: block;
height: 20px;
}
.mdc-dialog .mdc-dialog__content {
position: var(--dialog-content-position, relative);
padding: var(--dialog-content-padding, 20px 24px);
}
:host([hideactions]) .mdc-dialog .mdc-dialog__content {
padding-bottom: max(
var(--dialog-content-padding, 20px),
env(safe-area-inset-bottom)
);
}
.mdc-dialog .mdc-dialog__surface {
position: var(--dialog-surface-position, relative);
top: var(--dialog-surface-top);
min-height: var(--mdc-dialog-min-height, auto);
border-radius: var(
--ha-dialog-border-radius,
var(--ha-card-border-radius, 4px)
);
}
:host([flexContent]) .mdc-dialog .mdc-dialog__content {
display: flex;
flex-direction: column;
}
.header_button {
position: absolute;
right: 16px;
top: 10px;
text-decoration: none;
color: inherit;
}
.header_title {
margin-right: 40px;
}
[dir="rtl"].header_button {
right: auto;
left: 16px;
}
[dir="rtl"].header_title {
margin-left: 40px;
margin-right: 0px;
}
`,
];
}
static override styles = [
styles,
css`
.mdc-dialog {
--mdc-dialog-scroll-divider-color: var(--divider-color);
z-index: var(--dialog-z-index, 7);
-webkit-backdrop-filter: var(--dialog-backdrop-filter, none);
backdrop-filter: var(--dialog-backdrop-filter, none);
}
.mdc-dialog__actions {
justify-content: var(--justify-action-buttons, flex-end);
padding-bottom: max(env(safe-area-inset-bottom), 8px);
}
.mdc-dialog__actions span:nth-child(1) {
flex: var(--secondary-action-button-flex, unset);
}
.mdc-dialog__actions span:nth-child(2) {
flex: var(--primary-action-button-flex, unset);
}
.mdc-dialog__container {
align-items: var(--vertial-align-dialog, center);
}
.mdc-dialog__title::before {
display: block;
height: 20px;
}
.mdc-dialog .mdc-dialog__content {
position: var(--dialog-content-position, relative);
padding: var(--dialog-content-padding, 20px 24px);
}
:host([hideactions]) .mdc-dialog .mdc-dialog__content {
padding-bottom: max(
var(--dialog-content-padding, 20px),
env(safe-area-inset-bottom)
);
}
.mdc-dialog .mdc-dialog__surface {
position: var(--dialog-surface-position, relative);
top: var(--dialog-surface-top);
min-height: var(--mdc-dialog-min-height, auto);
border-radius: var(
--ha-dialog-border-radius,
var(--ha-card-border-radius, 4px)
);
}
:host([flexContent]) .mdc-dialog .mdc-dialog__content {
display: flex;
flex-direction: column;
}
.header_button {
position: absolute;
right: 16px;
top: 10px;
text-decoration: none;
color: inherit;
}
.header_title {
margin-right: 40px;
}
[dir="rtl"].header_button {
right: auto;
left: 16px;
}
[dir="rtl"].header_title {
margin-left: 40px;
margin-right: 0px;
}
`,
];
}
declare global {

View File

@ -1,21 +1,21 @@
import "@material/mwc-textfield";
import type { TextField } from "@material/mwc-textfield";
import { css, html, LitElement, TemplateResult, PropertyValues } from "lit";
import { customElement, property, query } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import type { HaTextField } from "../ha-textfield";
import "../ha-textfield";
import { HaFormElement, HaFormFloatData, HaFormFloatSchema } from "./types";
@customElement("ha-form-float")
export class HaFormFloat extends LitElement implements HaFormElement {
@property() public schema!: HaFormFloatSchema;
@property({ attribute: false }) public schema!: HaFormFloatSchema;
@property() public data!: HaFormFloatData;
@property({ attribute: false }) public data!: HaFormFloatData;
@property() public label!: string;
@property({ type: Boolean }) public disabled = false;
@query("mwc-textfield") private _input?: HTMLElement;
@query("ha-textfield") private _input?: HaTextField;
public focus() {
if (this._input) {
@ -25,7 +25,7 @@ export class HaFormFloat extends LitElement implements HaFormElement {
protected render(): TemplateResult {
return html`
<mwc-textfield
<ha-textfield
inputMode="decimal"
.label=${this.label}
.value=${this.data !== undefined ? this.data : ""}
@ -35,7 +35,7 @@ export class HaFormFloat extends LitElement implements HaFormElement {
.suffix=${this.schema.description?.suffix}
.validationMessage=${this.schema.required ? "Required" : undefined}
@input=${this._valueChanged}
></mwc-textfield>
></ha-textfield>
`;
}
@ -46,7 +46,7 @@ export class HaFormFloat extends LitElement implements HaFormElement {
}
private _valueChanged(ev: Event) {
const source = ev.target as TextField;
const source = ev.target as HaTextField;
const rawValue = source.value.replace(",", ".");
let value: number | undefined;
@ -81,7 +81,7 @@ export class HaFormFloat extends LitElement implements HaFormElement {
:host([own-margin]) {
margin-bottom: 5px;
}
mwc-textfield {
ha-textfield {
display: block;
}
`;

View File

@ -1,6 +1,3 @@
import "@material/mwc-textfield";
import type { TextField } from "@material/mwc-textfield";
import type { Slider } from "@material/mwc-slider";
import {
css,
CSSResultGroup,
@ -14,18 +11,21 @@ import { fireEvent } from "../../common/dom/fire_event";
import { HaCheckbox } from "../ha-checkbox";
import { HaFormElement, HaFormIntegerData, HaFormIntegerSchema } from "./types";
import "../ha-slider";
import { HaTextField } from "../ha-textfield";
@customElement("ha-form-integer")
export class HaFormInteger extends LitElement implements HaFormElement {
@property() public schema!: HaFormIntegerSchema;
@property({ attribute: false }) public schema!: HaFormIntegerSchema;
@property() public data?: HaFormIntegerData;
@property({ attribute: false }) public data?: HaFormIntegerData;
@property() public label?: string;
@property({ type: Boolean }) public disabled = false;
@query("mwc-textfield ha-slider") private _input?: HTMLElement;
@query("ha-textfield ha-slider") private _input?:
| HaTextField
| HTMLInputElement;
private _lastValue?: HaFormIntegerData;
@ -70,7 +70,7 @@ export class HaFormInteger extends LitElement implements HaFormElement {
}
return html`
<mwc-textfield
<ha-textfield
type="number"
inputMode="numeric"
.label=${this.label}
@ -81,7 +81,7 @@ export class HaFormInteger extends LitElement implements HaFormElement {
.suffix=${this.schema.description?.suffix}
.validationMessage=${this.schema.required ? "Required" : undefined}
@input=${this._valueChanged}
></mwc-textfield>
></ha-textfield>
`;
}
@ -138,7 +138,7 @@ export class HaFormInteger extends LitElement implements HaFormElement {
}
private _valueChanged(ev: Event) {
const source = ev.target as TextField | Slider;
const source = ev.target as HaTextField | HTMLInputElement;
const rawValue = source.value;
let value: number | undefined;
@ -172,7 +172,7 @@ export class HaFormInteger extends LitElement implements HaFormElement {
ha-slider {
flex: 1;
}
mwc-textfield {
ha-textfield {
display: block;
}
`;

View File

@ -1,25 +1,27 @@
import "@material/mwc-select/mwc-select";
import { mdiMenuDown, mdiMenuUp } from "@mdi/js";
import "@material/mwc-textfield";
import "@material/mwc-formfield";
import {
css,
CSSResultGroup,
html,
LitElement,
TemplateResult,
PropertyValues,
TemplateResult,
} from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import "../ha-button-menu";
import { HaCheckListItem } from "../ha-check-list-item";
import "../ha-checkbox";
import type { HaCheckbox } from "../ha-checkbox";
import "../ha-formfield";
import "../ha-svg-icon";
import "../ha-textfield";
import {
HaFormElement,
HaFormMultiSelectData,
HaFormMultiSelectSchema,
} from "./types";
import "../ha-checkbox";
import type { HaCheckbox } from "../ha-checkbox";
function optionValue(item: string | string[]): string {
return Array.isArray(item) ? item[0] : item;
@ -57,23 +59,23 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement {
: Object.entries(this.schema.options);
const data = this.data || [];
const renderedOptions = options.map((item: string | [string, string]) => {
const value = optionValue(item);
return html`
<mwc-formfield .label=${optionLabel(item)}>
<ha-checkbox
.checked=${data.includes(value)}
.value=${value}
.disabled=${this.disabled}
@change=${this._valueChanged}
></ha-checkbox>
</mwc-formfield>
`;
});
// We will just render all checkboxes.
if (options.length < SHOW_ALL_ENTRIES_LIMIT) {
return html`<div>${this.label}${renderedOptions}</div> `;
return html`<div>
${this.label}${options.map((item: string | [string, string]) => {
const value = optionValue(item);
return html`
<ha-formfield .label=${optionLabel(item)}>
<ha-checkbox
.checked=${data.includes(value)}
.value=${value}
.disabled=${this.disabled}
@change=${this._valueChanged}
></ha-checkbox>
</ha-formfield>
`;
})}
</div> `;
}
return html`
@ -83,8 +85,10 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement {
corner="BOTTOM_START"
@opened=${this._handleOpen}
@closed=${this._handleClose}
multi
activatable
>
<mwc-textfield
<ha-textfield
slot="trigger"
.label=${this.label}
.value=${data
@ -92,12 +96,25 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement {
.join(", ")}
.disabled=${this.disabled}
tabindex="-1"
></mwc-textfield>
></ha-textfield>
<ha-svg-icon
slot="trigger"
.path=${this._opened ? mdiMenuUp : mdiMenuDown}
></ha-svg-icon>
${renderedOptions}
${options.map((item: string | [string, string]) => {
const value = optionValue(item);
const selected = data.includes(value);
return html`<ha-check-list-item
left
.selected=${selected}
.activated=${selected}
@request-selected=${this._selectedChanged}
.value=${value}
.disabled=${this.disabled}
>
${optionLabel(item)}
</ha-check-list-item>`;
})}
</ha-button-menu>
`;
}
@ -105,7 +122,7 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement {
protected firstUpdated() {
this.updateComplete.then(() => {
const { formElement, mdcRoot } =
this.shadowRoot?.querySelector("mwc-textfield") || ({} as any);
this.shadowRoot?.querySelector("ha-textfield") || ({} as any);
if (formElement) {
formElement.style.textOverflow = "ellipsis";
}
@ -125,9 +142,23 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement {
}
}
private _selectedChanged(ev: CustomEvent): void {
ev.stopPropagation();
if (ev.detail.source === "property") {
return;
}
this._handleValueChanged(
(ev.target as HaCheckListItem).value,
ev.detail.selected
);
}
private _valueChanged(ev: CustomEvent): void {
const { value, checked } = ev.target as HaCheckbox;
this._handleValueChanged(value, checked);
}
private _handleValueChanged(value, checked: boolean): void {
let newValue: string[];
if (checked) {
@ -171,11 +202,11 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement {
display: block;
cursor: pointer;
}
mwc-formfield {
ha-formfield {
display: block;
padding-right: 16px;
}
mwc-textfield {
ha-textfield {
display: block;
pointer-events: none;
}

View File

@ -1,17 +1,17 @@
import { mdiEye, mdiEyeOff } from "@mdi/js";
import "@material/mwc-textfield";
import type { TextField } from "@material/mwc-textfield";
import {
css,
CSSResultGroup,
html,
LitElement,
TemplateResult,
PropertyValues,
TemplateResult,
} from "lit";
import { customElement, property, state, query } from "lit/decorators";
import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import "../ha-icon-button";
import "../ha-textfield";
import type { HaTextField } from "../ha-textfield";
import type {
HaFormElement,
HaFormStringData,
@ -32,7 +32,7 @@ export class HaFormString extends LitElement implements HaFormElement {
@state() private _unmaskedPassword = false;
@query("mwc-textfield") private _input?: HTMLElement;
@query("ha-textfield") private _input?: HaTextField;
public focus(): void {
if (this._input) {
@ -45,7 +45,7 @@ export class HaFormString extends LitElement implements HaFormElement {
this.schema.name.includes(field)
);
return html`
<mwc-textfield
<ha-textfield
.type=${!isPassword
? this._stringType
: this._unmaskedPassword
@ -62,7 +62,7 @@ export class HaFormString extends LitElement implements HaFormElement {
: this.schema.description?.suffix}
.validationMessage=${this.schema.required ? "Required" : undefined}
@input=${this._valueChanged}
></mwc-textfield>
></ha-textfield>
${isPassword
? html`<ha-icon-button
toggles
@ -85,7 +85,7 @@ export class HaFormString extends LitElement implements HaFormElement {
}
private _valueChanged(ev: Event): void {
let value: string | undefined = (ev.target as TextField).value;
let value: string | undefined = (ev.target as HaTextField).value;
if (this.data === value) {
return;
}
@ -118,7 +118,7 @@ export class HaFormString extends LitElement implements HaFormElement {
:host([own-margin]) {
margin-bottom: 5px;
}
mwc-textfield {
ha-textfield {
display: block;
}
ha-icon-button {

View File

@ -1,11 +1,11 @@
import { Formfield } from "@material/mwc-formfield";
import { css, CSSResultGroup } from "lit";
import { FormfieldBase } from "@material/mwc-formfield/mwc-formfield-base";
import { styles } from "@material/mwc-formfield/mwc-formfield.css";
import { css } from "lit";
import { customElement } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event";
@customElement("ha-formfield")
// @ts-expect-error
export class HaFormfield extends Formfield {
export class HaFormfield extends FormfieldBase {
protected _labelClick() {
const input = this.input;
if (input) {
@ -23,20 +23,18 @@ export class HaFormfield extends Formfield {
}
}
protected static get styles(): CSSResultGroup {
return [
Formfield.styles,
css`
:host(:not([alignEnd])) ::slotted(ha-switch) {
margin-right: 10px;
}
:host([dir="rtl"]:not([alignEnd])) ::slotted(ha-switch) {
margin-left: 10px;
margin-right: auto;
}
`,
];
}
static override styles = [
styles,
css`
:host(:not([alignEnd])) ::slotted(ha-switch) {
margin-right: 10px;
}
:host([dir="rtl"]:not([alignEnd])) ::slotted(ha-switch) {
margin-left: 10px;
margin-right: auto;
}
`,
];
}
declare global {

View File

@ -1,7 +1,6 @@
import "@material/mwc-button/mwc-button";
import "@material/mwc-list/mwc-list-item";
import "@material/mwc-select/mwc-select";
import "@material/mwc-textfield/mwc-textfield";
import type { TextField } from "@material/mwc-textfield/mwc-textfield";
import { mdiCamera } from "@mdi/js";
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, query, state } from "lit/decorators";
@ -11,7 +10,8 @@ import { stopPropagation } from "../common/dom/stop_propagation";
import { LocalizeFunc } from "../common/translations/localize";
import "./ha-alert";
import "./ha-button-menu";
import "@material/mwc-button/mwc-button";
import "./ha-textfield";
import type { HaTextField } from "./ha-textfield";
@customElement("ha-qr-scanner")
class HaQrScanner extends LitElement {
@ -29,7 +29,7 @@ class HaQrScanner extends LitElement {
@query("#canvas-container", true) private _canvasContainer!: HTMLDivElement;
@query("mwc-textfield") private _manualInput?: TextField;
@query("ha-textfield") private _manualInput?: HaTextField;
public disconnectedCallback(): void {
super.disconnectedCallback();
@ -102,11 +102,11 @@ class HaQrScanner extends LitElement {
</ha-alert>
<p>${this.localize("ui.components.qr-scanner.manual_input")}</p>
<div class="row">
<mwc-textfield
<ha-textfield
.label=${this.localize("ui.components.qr-scanner.enter_qr_code")}
@keyup=${this._manualKeyup}
@paste=${this._manualPaste}
></mwc-textfield>
></ha-textfield>
<mwc-button @click=${this._manualSubmit}
>${this.localize("ui.common.submit")}</mwc-button
>
@ -161,7 +161,7 @@ class HaQrScanner extends LitElement {
private _manualKeyup(ev: KeyboardEvent) {
if (ev.key === "Enter") {
this._qrCodeScanned((ev.target as TextField).value);
this._qrCodeScanned((ev.target as HaTextField).value);
}
}
@ -199,7 +199,7 @@ class HaQrScanner extends LitElement {
display: flex;
align-items: center;
}
mwc-textfield {
ha-textfield {
flex: 1;
margin-right: 8px;
}

View File

@ -1,12 +1,18 @@
import { Radio } from "@material/mwc-radio";
import { RadioBase } from "@material/mwc-radio/mwc-radio-base";
import { styles } from "@material/mwc-radio/mwc-radio.css";
import { css } from "lit";
import { customElement } from "lit/decorators";
@customElement("ha-radio")
export class HaRadio extends Radio {
public firstUpdated() {
super.firstUpdated();
this.style.setProperty("--mdc-theme-secondary", "var(--primary-color)");
}
export class HaRadio extends RadioBase {
static override styles = [
styles,
css`
:host {
--mdc-theme-secondary: var(--primary-color);
}
`,
];
}
declare global {

View File

@ -5,7 +5,7 @@ import { fireEvent } from "../../common/dom/fire_event";
import { NumberSelector } from "../../data/selector";
import { HomeAssistant } from "../../types";
import "../ha-slider";
import "@material/mwc-textfield/mwc-textfield";
import "../ha-textfield";
@customElement("ha-selector-number")
export class HaNumberSelector extends LitElement {
@ -36,7 +36,7 @@ export class HaNumberSelector extends LitElement {
>
</ha-slider>`
: ""}
<mwc-textfield
<ha-textfield
inputMode="numeric"
pattern="[0-9]+([\\.][0-9]+)?"
.label=${this.selector.number.mode !== "box" ? undefined : this.label}
@ -50,13 +50,14 @@ export class HaNumberSelector extends LitElement {
.suffix=${this.selector.number.unit_of_measurement}
type="number"
autoValidate
?no-spinner=${this.selector.number.mode !== "box"}
@input=${this._handleInputChange}
>
</mwc-textfield>`;
</ha-textfield>`;
}
private get _value() {
return this.value || 0;
return this.value ?? 0;
}
private _handleInputChange(ev) {
@ -90,10 +91,11 @@ export class HaNumberSelector extends LitElement {
ha-slider {
flex: 1;
}
mwc-textfield {
width: 70px;
ha-textfield {
--ha-textfield-input-width: 40px;
}
.single {
--ha-textfield-input-width: unset;
flex: 1;
}
`;

View File

@ -1,5 +1,4 @@
import "@material/mwc-textarea/mwc-textarea";
import "@material/mwc-textfield/mwc-textfield";
import { mdiEye, mdiEyeOff } from "@mdi/js";
import { css, CSSResultGroup, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators";
@ -7,6 +6,7 @@ import { fireEvent } from "../../common/dom/fire_event";
import { StringSelector } from "../../data/selector";
import { HomeAssistant } from "../../types";
import "../ha-icon-button";
import "../ha-textfield";
@customElement("ha-selector-text")
export class HaTextSelector extends LitElement {
@ -38,7 +38,7 @@ export class HaTextSelector extends LitElement {
required
></mwc-textarea>`;
}
return html`<mwc-textfield
return html`<ha-textfield
.value=${this.value || ""}
.placeholder=${this.placeholder || ""}
.disabled=${this.disabled}
@ -50,7 +50,7 @@ export class HaTextSelector extends LitElement {
html`<div style="width: 24px"></div>`
: this.selector.text?.suffix}
required
></mwc-textfield>
></ha-textfield>
${this.selector.text?.type === "password"
? html`<ha-icon-button
toggles
@ -79,7 +79,7 @@ export class HaTextSelector extends LitElement {
display: block;
position: relative;
}
mwc-textfield,
ha-textfield,
mwc-textarea {
width: 100%;
}

View File

@ -3,7 +3,7 @@ import "@polymer/paper-slider";
const PaperSliderClass = customElements.get("paper-slider");
let subTemplate;
class HaSlider extends PaperSliderClass {
export class HaSlider extends PaperSliderClass {
static get template() {
if (!subTemplate) {
subTemplate = PaperSliderClass.template.cloneNode(true);

View File

@ -1,11 +1,11 @@
import { Switch } from "@material/mwc-switch/deprecated";
import { css, CSSResultGroup } from "lit";
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 { customElement, property } from "lit/decorators";
import { forwardHaptic } from "../data/haptics";
@customElement("ha-switch")
// @ts-expect-error
export class HaSwitch extends 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.
@ -13,10 +13,6 @@ export class HaSwitch extends Switch {
protected firstUpdated() {
super.firstUpdated();
this.style.setProperty(
"--mdc-theme-secondary",
"var(--switch-checked-color)"
);
this.addEventListener("change", () => {
if (this.haptic) {
forwardHaptic("light");
@ -24,29 +20,30 @@ export class HaSwitch extends Switch {
});
}
static get styles(): CSSResultGroup {
return [
Switch.styles,
css`
.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);
}
`,
];
}
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);
}
`,
];
}
declare global {

View File

@ -1,9 +1,10 @@
import { TextField } from "@material/mwc-textfield";
import { TemplateResult, html, PropertyValues } from "lit";
import { TextFieldBase } from "@material/mwc-textfield/mwc-textfield-base";
import { styles } from "@material/mwc-textfield/mwc-textfield.css";
import { TemplateResult, html, PropertyValues, css } from "lit";
import { customElement, property } from "lit/decorators";
@customElement("ha-textfield")
export class HaTextField extends TextField {
export class HaTextField extends TextFieldBase {
@property({ type: Boolean }) public invalid?: boolean;
@property({ attribute: "error-message" }) public errorMessage?: string;
@ -37,6 +38,15 @@ export class HaTextField extends TextField {
</span>
`;
}
static override styles = [
styles,
css`
.mdc-text-field__input {
width: var(--ha-textfield-input-width, 100%);
}
`,
];
}
declare global {

View File

@ -1,12 +1,12 @@
import "@material/mwc-button";
import "@material/mwc-textfield/mwc-textfield";
import type { TextField } from "@material/mwc-textfield/mwc-textfield";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { property, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-alert";
import "../../../../components/ha-card";
import type { HaSwitch } from "../../../../components/ha-switch";
import "../../../../components/ha-textfield";
import type { HaTextField } from "../../../../components/ha-textfield";
import { CloudStatusLoggedIn, updateCloudPref } from "../../../../data/cloud";
import { syncCloudGoogleEntities } from "../../../../data/google_assistant";
import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box";
@ -136,7 +136,7 @@ export class CloudGooglePref extends LitElement {
${this.hass.localize(
"ui.panel.config.cloud.account.google.enter_pin_info"
)}
<mwc-textfield
<ha-textfield
id="google_secure_devices_pin"
.label=${this.hass.localize(
"ui.panel.config.cloud.account.google.devices_pin"
@ -146,7 +146,7 @@ export class CloudGooglePref extends LitElement {
)}
.value=${google_secure_devices_pin || ""}
@change=${this._pinChanged}
></mwc-textfield>
></ha-textfield>
</div>
`}
</div>
@ -229,7 +229,7 @@ export class CloudGooglePref extends LitElement {
}
private async _pinChanged(ev) {
const input = ev.target as TextField;
const input = ev.target as HaTextField;
try {
await updateCloudPref(this.hass, {
[input.id]: input.value || null,
@ -260,7 +260,7 @@ export class CloudGooglePref extends LitElement {
right: auto;
left: 24px;
}
mwc-textfield {
ha-textfield {
width: 250px;
display: block;
margin-top: 8px;

View File

@ -1,11 +1,11 @@
import "@material/mwc-textfield/mwc-textfield";
import type { TextField } from "@material/mwc-textfield/mwc-textfield";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/buttons/ha-progress-button";
import "../../../../components/ha-alert";
import "../../../../components/ha-card";
import type { HaTextField } from "../../../../components/ha-textfield";
import "../../../../components/ha-textfield";
import { cloudForgotPassword } from "../../../../data/cloud";
import "../../../../layouts/hass-subpage";
import { haStyle } from "../../../../resources/styles";
@ -23,7 +23,7 @@ export class CloudForgotPassword extends LitElement {
@state() private _error?: string;
@query("#email", true) private _emailField!: TextField;
@query("#email", true) private _emailField!: HaTextField;
protected render(): TemplateResult {
return html`
@ -49,7 +49,7 @@ export class CloudForgotPassword extends LitElement {
${this._error
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
: ""}
<mwc-textfield
<ha-textfield
autofocus
id="email"
label=${this.hass.localize(
@ -62,7 +62,7 @@ export class CloudForgotPassword extends LitElement {
.validationMessage=${this.hass.localize(
"ui.panel.config.cloud.forgot_password.email_error_msg"
)}
></mwc-textfield>
></ha-textfield>
</div>
<div class="card-actions">
<ha-progress-button
@ -133,7 +133,7 @@ export class CloudForgotPassword extends LitElement {
h1 {
margin: 0;
}
mwc-textfield {
ha-textfield {
width: 100%;
}
.card-actions {

View File

@ -1,6 +1,4 @@
import "@material/mwc-button";
import "@material/mwc-textfield/mwc-textfield";
import type { TextField } from "@material/mwc-textfield/mwc-textfield";
import "@polymer/paper-input/paper-input";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-item/paper-item-body";
@ -12,6 +10,8 @@ import "../../../../components/buttons/ha-progress-button";
import "../../../../components/ha-alert";
import "../../../../components/ha-card";
import "../../../../components/ha-icon-next";
import type { HaTextField } from "../../../../components/ha-textfield";
import "../../../../components/ha-textfield";
import { cloudLogin } from "../../../../data/cloud";
import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box";
import "../../../../layouts/hass-subpage";
@ -38,9 +38,9 @@ export class CloudLogin extends LitElement {
@state() private _error?: string;
@query("#email", true) private _emailField!: TextField;
@query("#email", true) private _emailField!: HaTextField;
@query("#password", true) private _passwordField!: TextField;
@query("#password", true) private _passwordField!: HaTextField;
protected render(): TemplateResult {
return html`
@ -108,7 +108,7 @@ export class CloudLogin extends LitElement {
${this._error
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
: ""}
<mwc-textfield
<ha-textfield
.label=${this.hass.localize(
"ui.panel.config.cloud.login.email"
)}
@ -121,8 +121,8 @@ export class CloudLogin extends LitElement {
.validationMessage=${this.hass.localize(
"ui.panel.config.cloud.login.email_error_msg"
)}
></mwc-textfield>
<mwc-textfield
></ha-textfield>
<ha-textfield
id="password"
.label=${this.hass.localize(
"ui.panel.config.cloud.login.password"
@ -136,7 +136,7 @@ export class CloudLogin extends LitElement {
.validationMessage=${this.hass.localize(
"ui.panel.config.cloud.login.password_error_msg"
)}
></mwc-textfield>
></ha-textfield>
<button
class="link pwd-forgot-link"
.disabled=${this._requestInProgress}

View File

@ -1,11 +1,11 @@
import "@material/mwc-textfield/mwc-textfield";
import type { TextField } from "@material/mwc-textfield/mwc-textfield";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/buttons/ha-progress-button";
import "../../../../components/ha-alert";
import "../../../../components/ha-card";
import "../../../../components/ha-textfield";
import type { HaTextField } from "../../../../components/ha-textfield";
import { cloudRegister, cloudResendVerification } from "../../../../data/cloud";
import "../../../../layouts/hass-subpage";
import { haStyle } from "../../../../resources/styles";
@ -28,9 +28,9 @@ export class CloudRegister extends LitElement {
@state() private _error?: string;
@query("#email", true) private _emailField!: TextField;
@query("#email", true) private _emailField!: HaTextField;
@query("#password", true) private _passwordField!: TextField;
@query("#password", true) private _passwordField!: HaTextField;
protected render(): TemplateResult {
return html`
@ -128,7 +128,7 @@ export class CloudRegister extends LitElement {
${this._error
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
: ""}
<mwc-textfield
<ha-textfield
autofocus
id="email"
.label=${this.hass.localize(
@ -141,8 +141,8 @@ export class CloudRegister extends LitElement {
validationMessage=${this.hass.localize(
"ui.panel.config.cloud.register.email_error_msg"
)}
></mwc-textfield>
<mwc-textfield
></ha-textfield>
<ha-textfield
id="password"
label="Password"
.value=${this._password}
@ -153,7 +153,7 @@ export class CloudRegister extends LitElement {
validationMessage=${this.hass.localize(
"ui.panel.config.cloud.register.password_error_msg"
)}
></mwc-textfield>
></ha-textfield>
</div>
<div class="card-actions">
<ha-progress-button

View File

@ -1,4 +1,3 @@
import "@material/mwc-list/mwc-list-item";
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
import { mdiCancel, mdiFilterVariant, mdiPlus } from "@mdi/js";
import "@polymer/paper-tooltip/paper-tooltip";
@ -19,6 +18,7 @@ import "../../../components/entity/ha-battery-icon";
import "../../../components/ha-button-menu";
import "../../../components/ha-fab";
import "../../../components/ha-icon-button";
import "../../../components/ha-check-list-item";
import { AreaRegistryEntry } from "../../../data/area_registry";
import { ConfigEntry } from "../../../data/config_entries";
import {
@ -435,19 +435,15 @@ export class HaConfigDeviceDashboard extends LitElement {
)}
.path=${mdiFilterVariant}
></ha-icon-button>
<mwc-list-item
<ha-check-list-item
left
@request-selected=${this._showDisabledChanged}
graphic="control"
.selected=${this._showDisabled}
>
<ha-checkbox
slot="graphic"
.checked=${this._showDisabled}
></ha-checkbox>
${this.hass!.localize(
"ui.panel.config.devices.picker.filter.show_disabled"
)}
</mwc-list-item>
</ha-check-list-item>
</ha-button-menu>
</hass-tabs-subpage-data-table>
`;

View File

@ -1,4 +1,3 @@
import "@material/mwc-list/mwc-list-item";
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
import {
mdiAlertCircle,
@ -35,6 +34,7 @@ import type {
import "../../../components/ha-button-menu";
import "../../../components/ha-icon-button";
import "../../../components/ha-svg-icon";
import "../../../components/ha-check-list-item";
import {
AreaRegistryEntry,
subscribeAreaRegistry,
@ -586,45 +586,35 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
)}
.path=${mdiFilterVariant}
></ha-icon-button>
<mwc-list-item
<ha-check-list-item
@request-selected=${this._showDisabledChanged}
graphic="control"
.selected=${this._showDisabled}
left
>
<ha-checkbox
slot="graphic"
.checked=${this._showDisabled}
></ha-checkbox>
${this.hass!.localize(
"ui.panel.config.entities.picker.filter.show_disabled"
)}
</mwc-list-item>
<mwc-list-item
</ha-check-list-item>
<ha-check-list-item
@request-selected=${this._showRestoredChanged}
graphic="control"
.selected=${this._showUnavailable}
left
>
<ha-checkbox
slot="graphic"
.checked=${this._showUnavailable}
></ha-checkbox>
${this.hass!.localize(
"ui.panel.config.entities.picker.filter.show_unavailable"
)}
</mwc-list-item>
<mwc-list-item
</ha-check-list-item>
<ha-check-list-item
@request-selected=${this._showReadOnlyChanged}
graphic="control"
.selected=${this._showReadOnly}
left
>
<ha-checkbox
slot="graphic"
.checked=${this._showReadOnly}
></ha-checkbox>
${this.hass!.localize(
"ui.panel.config.entities.picker.filter.show_readonly"
)}
</mwc-list-item>
</ha-check-list-item>
</ha-button-menu>`}
${includeZHAFab
? html`<a href="/config/zha/add" slot="fab">

View File

@ -1,5 +1,4 @@
import { ActionDetail } from "@material/mwc-list";
import "@material/mwc-list/mwc-list-item";
import { mdiFilterVariant, mdiPlus } from "@mdi/js";
import Fuse from "fuse.js";
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
@ -26,6 +25,8 @@ import "../../../components/ha-checkbox";
import "../../../components/ha-fab";
import "../../../components/ha-icon-button";
import "../../../components/ha-svg-icon";
import "../../../components/ha-check-list-item";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { ConfigEntry, getConfigEntries } from "../../../data/config_entries";
import {
@ -308,21 +309,16 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
.path=${mdiFilterVariant}
>
</ha-icon-button>
<mwc-list-item graphic="control" .selected=${this._showIgnored}>
<ha-checkbox slot="graphic" .checked=${this._showIgnored}></ha-checkbox>
<ha-check-list-item left .selected=${this._showIgnored}>
${this.hass.localize(
"ui.panel.config.integrations.ignore.show_ignored"
)}
</mwc-list-item>
<mwc-list-item graphic="control" .selected=${this._showDisabled}>
<ha-checkbox
slot="graphic"
.checked=${this._showDisabled}
></ha-checkbox>
</ha-check-list-item>
<ha-check-list-item left .selected=${this._showDisabled}>
${this.hass.localize(
"ui.panel.config.integrations.disable.show_disabled"
)}
</mwc-list-item>
</ha-check-list-item>
</ha-button-menu>`;
return html`

View File

@ -1,5 +1,4 @@
import "@material/mwc-button/mwc-button";
import "@material/mwc-textfield/mwc-textfield";
import { mdiAlertCircle, mdiCheckCircle, mdiQrcodeScan } from "@mdi/js";
import "@polymer/paper-input/paper-input";
import type { PaperInputElement } from "@polymer/paper-input/paper-input";
@ -811,10 +810,6 @@ class DialogZWaveJSAddNode extends LitElement {
}
}
mwc-textfield {
width: 100%;
}
ha-svg-icon {
width: 68px;
height: 48px;