1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-02-15 07:25:54 +00:00

Add select box component (#24370)

* Add select box component

* Add selector support

* Use it in markdown card

* Add select box to gallery

* Feedbacks
This commit is contained in:
Paul Bottein
2025-02-24 15:07:51 +01:00
committed by GitHub
parent ece4a6345f
commit fc4996412e
12 changed files with 437 additions and 5 deletions

View File

@@ -0,0 +1,10 @@
<svg width="94" height="64" viewBox="0 0 94 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="94" height="64" rx="8" fill="white"/>
<rect x="0.5" y="0.5" width="93" height="63" rx="7.5" stroke="black" stroke-opacity="0.12"/>
<path d="M8 14C8 10.6863 10.6863 8 14 8H33C36.3137 8 39 10.6863 39 14C39 17.3137 36.3137 20 33 20H14C10.6863 20 8 17.3137 8 14Z" fill="black" fill-opacity="0.32"/>
<path d="M8 27C8 25.3431 9.34315 24 11 24H31C32.6569 24 34 25.3431 34 27V29C34 30.6569 32.6569 32 31 32H11C9.34315 32 8 30.6569 8 29V27Z" fill="black" fill-opacity="0.12"/>
<path d="M38 27C38 25.3431 39.3431 24 41 24H83C84.6569 24 86 25.3431 86 27V29C86 30.6569 84.6569 32 83 32H41C39.3431 32 38 30.6569 38 29V27Z" fill="black" fill-opacity="0.12"/>
<path d="M8 39C8 37.3431 9.34315 36 11 36H53C54.6569 36 56 37.3431 56 39V41C56 42.6569 54.6569 44 53 44H11C9.34315 44 8 42.6569 8 41V39Z" fill="black" fill-opacity="0.12"/>
<path d="M60 39C60 37.3431 61.3431 36 63 36H83C84.6569 36 86 37.3431 86 39V41C86 42.6569 84.6569 44 83 44H63C61.3431 44 60 42.6569 60 41V39Z" fill="black" fill-opacity="0.12"/>
<path d="M8 51C8 49.3431 9.34315 48 11 48H31C32.6569 48 34 49.3431 34 51V53C34 54.6569 32.6569 56 31 56H11C9.34315 56 8 54.6569 8 53V51Z" fill="black" fill-opacity="0.12"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,7 @@
<svg width="94" height="48" viewBox="0 0 94 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 11C0 9.34315 1.34315 8 3 8H23C24.6569 8 26 9.34315 26 11V13C26 14.6569 24.6569 16 23 16H3C1.34315 16 0 14.6569 0 13V11Z" fill="black" fill-opacity="0.12"/>
<path d="M30 11C30 9.34315 31.3431 8 33 8H91C92.6569 8 94 9.34315 94 11V13C94 14.6569 92.6569 16 91 16H33C31.3431 16 30 14.6569 30 13V11Z" fill="black" fill-opacity="0.12"/>
<path d="M0 23C0 21.3431 1.34315 20 3 20H61C62.6569 20 64 21.3431 64 23V25C64 26.6569 62.6569 28 61 28H3C1.34315 28 0 26.6569 0 25V23Z" fill="black" fill-opacity="0.12"/>
<path d="M68 23C68 21.3431 69.3431 20 71 20H91C92.6569 20 94 21.3431 94 23V25C94 26.6569 92.6569 28 91 28H71C69.3431 28 68 26.6569 68 25V23Z" fill="black" fill-opacity="0.12"/>
<path d="M0 35C0 33.3431 1.34315 32 3 32H23C24.6569 32 26 33.3431 26 35V37C26 38.6569 24.6569 40 23 40H3C1.34315 40 0 38.6569 0 37V35Z" fill="black" fill-opacity="0.12"/>
</svg>

After

Width:  |  Height:  |  Size: 964 B

View File

@@ -0,0 +1,3 @@
---
title: Select box
---

View File

@@ -0,0 +1,152 @@
import type { TemplateResult } from "lit";
import { css, html, LitElement } from "lit";
import { customElement, state } from "lit/decorators";
import { repeat } from "lit/directives/repeat";
import "../../../../src/components/ha-card";
import "../../../../src/components/ha-select-box";
import type { SelectBoxOption } from "../../../../src/components/ha-select-box";
const basicOptions: SelectBoxOption[] = [
{
value: "text-only",
label: "Text only",
},
{
value: "card",
label: "Card",
},
{
value: "disabled",
label: "Disabled option",
disabled: true,
},
];
const fullOptions: SelectBoxOption[] = [
{
value: "text-only",
label: "Text only",
description: "Only text, no border and background",
image: "/images/select_box/text_only.svg",
},
{
value: "card",
label: "Card",
description: "With border and background",
image: "/images/select_box/card.svg",
},
{
value: "disabled",
label: "Disabled",
description: "Option that can not be selected",
disabled: true,
},
];
const selects: {
id: string;
label: string;
class?: string;
options: SelectBoxOption[];
disabled?: boolean;
}[] = [
{
id: "basic",
label: "Basic",
options: basicOptions,
},
{
id: "full",
label: "With description and image",
options: fullOptions,
},
];
@customElement("demo-components-ha-select-box")
export class DemoHaSelectBox extends LitElement {
@state() private value?: string = "off";
handleValueChanged(e: CustomEvent) {
this.value = e.detail.value as string;
}
protected render(): TemplateResult {
return html`
${repeat(selects, (select) => {
const { id, label, options } = select;
return html`
<ha-card>
<div class="card-content">
<label id=${id}>${label}</label>
<ha-select-box
.value=${this.value}
.options=${options}
@value-changed=${this.handleValueChanged}
>
</ha-select-box>
</div>
</ha-card>
`;
})}
<ha-card>
<div class="card-content">
<p class="title"><b>Column layout</b></p>
<div class="vertical-selects">
${repeat(selects, (select) => {
const { options } = select;
return html`
<ha-select-box
.value=${this.value}
.options=${options}
.maxColumns=${1}
@value-changed=${this.handleValueChanged}
>
</ha-select-box>
`;
})}
</div>
</div>
</ha-card>
`;
}
static styles = css`
ha-card {
max-width: 600px;
margin: 24px auto;
}
pre {
margin-top: 0;
margin-bottom: 8px;
}
p {
margin: 0;
}
label {
font-weight: 600;
margin-bottom: 8px;
display: block;
}
.custom {
--mdc-icon-size: 24px;
--control-select-color: var(--state-fan-active-color);
--control-select-thickness: 130px;
--control-select-border-radius: 36px;
}
p.title {
margin-bottom: 12px;
}
.vertical-selects ha-select-box {
display: block;
margin-bottom: 24px;
}
`;
}
declare global {
interface HTMLElementTagNameMap {
"demo-components-ha-select-box": DemoHaSelectBox;
}
}