1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-04-02 08:33:31 +01:00

Add reorder support to area selector (#30056)

This commit is contained in:
Bram Kragten
2026-03-09 09:24:20 +01:00
committed by GitHub
parent 5b981062f6
commit 6e2fdbb396
3 changed files with 66 additions and 20 deletions

View File

@@ -1,3 +1,4 @@
import { mdiDragHorizontalVariant } from "@mdi/js";
import type { HassEntity } from "home-assistant-js-websocket";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators";
@@ -6,6 +7,7 @@ import { SubscribeMixin } from "../mixins/subscribe-mixin";
import type { HomeAssistant } from "../types";
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
import "./ha-area-picker";
import "./ha-sortable";
@customElement("ha-areas-picker")
export class HaAreasPicker extends SubscribeMixin(LitElement) {
@@ -62,6 +64,8 @@ export class HaAreasPicker extends SubscribeMixin(LitElement) {
@property({ type: Boolean }) public required = false;
@property({ type: Boolean }) public reorder = false;
protected render() {
if (!this.hass) {
return nothing;
@@ -69,26 +73,42 @@ export class HaAreasPicker extends SubscribeMixin(LitElement) {
const currentAreas = this._currentAreas;
return html`
${currentAreas.map(
(area) => html`
<div>
<ha-area-picker
.curValue=${area}
.noAdd=${this.noAdd}
.hass=${this.hass}
.value=${area}
.label=${this.pickedAreaLabel}
.includeDomains=${this.includeDomains}
.excludeDomains=${this.excludeDomains}
.includeDeviceClasses=${this.includeDeviceClasses}
.deviceFilter=${this.deviceFilter}
.entityFilter=${this.entityFilter}
.disabled=${this.disabled}
@value-changed=${this._areaChanged}
></ha-area-picker>
</div>
`
)}
<ha-sortable
.disabled=${!this.reorder || this.disabled}
handle-selector=".area-handle"
@item-moved=${this._areaMoved}
>
<div class="list">
${currentAreas.map(
(area) => html`
<div class="area">
<ha-area-picker
.curValue=${area}
.noAdd=${this.noAdd}
.hass=${this.hass}
.value=${area}
.label=${this.pickedAreaLabel}
.includeDomains=${this.includeDomains}
.excludeDomains=${this.excludeDomains}
.includeDeviceClasses=${this.includeDeviceClasses}
.deviceFilter=${this.deviceFilter}
.entityFilter=${this.entityFilter}
.disabled=${this.disabled}
@value-changed=${this._areaChanged}
></ha-area-picker>
${this.reorder
? html`
<ha-svg-icon
class="area-handle"
.path=${mdiDragHorizontalVariant}
></ha-svg-icon>
`
: nothing}
</div>
`
)}
</div>
</ha-sortable>
<div>
<ha-area-picker
.noAdd=${this.noAdd}
@@ -110,6 +130,17 @@ export class HaAreasPicker extends SubscribeMixin(LitElement) {
`;
}
private _areaMoved(e: CustomEvent) {
e.stopPropagation();
const { oldIndex, newIndex } = e.detail;
const currentAreas = this._currentAreas;
const movedArea = currentAreas[oldIndex];
const newAreas = [...currentAreas];
newAreas.splice(oldIndex, 1);
newAreas.splice(newIndex, 0, movedArea);
this._updateAreas(newAreas);
}
private get _currentAreas(): string[] {
return this.value || [];
}
@@ -159,6 +190,19 @@ export class HaAreasPicker extends SubscribeMixin(LitElement) {
div {
margin-top: 8px;
}
.area {
display: flex;
flex-direction: row;
align-items: center;
}
.area ha-area-picker {
flex: 1;
}
.area-handle {
padding: 8px;
cursor: move; /* fallback if grab cursor is unsupported */
cursor: grab;
}
`;
}

View File

@@ -123,6 +123,7 @@ export class HaAreaSelector extends LitElement {
: undefined}
.disabled=${this.disabled}
.required=${this.required}
.reorder=${this.selector.area?.reorder ?? false}
></ha-areas-picker>
`;
}

View File

@@ -100,6 +100,7 @@ export interface AreaSelector {
entity?: EntitySelectorFilter | readonly EntitySelectorFilter[];
device?: DeviceSelectorFilter | readonly DeviceSelectorFilter[];
multiple?: boolean;
reorder?: boolean;
} | null;
}