1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-04-17 23:54:28 +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 type { HassEntity } from "home-assistant-js-websocket";
import { css, html, LitElement, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
@@ -6,6 +7,7 @@ import { SubscribeMixin } from "../mixins/subscribe-mixin";
import type { HomeAssistant } from "../types"; import type { HomeAssistant } from "../types";
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker"; import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
import "./ha-area-picker"; import "./ha-area-picker";
import "./ha-sortable";
@customElement("ha-areas-picker") @customElement("ha-areas-picker")
export class HaAreasPicker extends SubscribeMixin(LitElement) { 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 required = false;
@property({ type: Boolean }) public reorder = false;
protected render() { protected render() {
if (!this.hass) { if (!this.hass) {
return nothing; return nothing;
@@ -69,26 +73,42 @@ export class HaAreasPicker extends SubscribeMixin(LitElement) {
const currentAreas = this._currentAreas; const currentAreas = this._currentAreas;
return html` return html`
${currentAreas.map( <ha-sortable
(area) => html` .disabled=${!this.reorder || this.disabled}
<div> handle-selector=".area-handle"
<ha-area-picker @item-moved=${this._areaMoved}
.curValue=${area} >
.noAdd=${this.noAdd} <div class="list">
.hass=${this.hass} ${currentAreas.map(
.value=${area} (area) => html`
.label=${this.pickedAreaLabel} <div class="area">
.includeDomains=${this.includeDomains} <ha-area-picker
.excludeDomains=${this.excludeDomains} .curValue=${area}
.includeDeviceClasses=${this.includeDeviceClasses} .noAdd=${this.noAdd}
.deviceFilter=${this.deviceFilter} .hass=${this.hass}
.entityFilter=${this.entityFilter} .value=${area}
.disabled=${this.disabled} .label=${this.pickedAreaLabel}
@value-changed=${this._areaChanged} .includeDomains=${this.includeDomains}
></ha-area-picker> .excludeDomains=${this.excludeDomains}
</div> .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> <div>
<ha-area-picker <ha-area-picker
.noAdd=${this.noAdd} .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[] { private get _currentAreas(): string[] {
return this.value || []; return this.value || [];
} }
@@ -159,6 +190,19 @@ export class HaAreasPicker extends SubscribeMixin(LitElement) {
div { div {
margin-top: 8px; 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} : undefined}
.disabled=${this.disabled} .disabled=${this.disabled}
.required=${this.required} .required=${this.required}
.reorder=${this.selector.area?.reorder ?? false}
></ha-areas-picker> ></ha-areas-picker>
`; `;
} }

View File

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