diff --git a/src/panels/lovelace/views/hui-sections-view.ts b/src/panels/lovelace/views/hui-sections-view.ts
index 8dff28e127..944e3a1632 100644
--- a/src/panels/lovelace/views/hui-sections-view.ts
+++ b/src/panels/lovelace/views/hui-sections-view.ts
@@ -7,7 +7,7 @@ import {
mdiViewGridPlus,
} from "@mdi/js";
import type { CSSResultGroup, PropertyValues } from "lit";
-import { LitElement, css, html, nothing } from "lit";
+import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { repeat } from "lit/directives/repeat";
@@ -20,6 +20,7 @@ import "../../../components/ha-sortable";
import "../../../components/ha-svg-icon";
import type { LovelaceViewElement } from "../../../data/lovelace";
import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
+import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
import type { HomeAssistant } from "../../../types";
@@ -27,8 +28,19 @@ import type { HuiBadge } from "../badges/hui-badge";
import "../badges/hui-view-badges";
import type { HuiCard } from "../cards/hui-card";
import "../components/hui-badge-edit-mode";
-import { addSection, deleteSection, moveSection } from "../editor/config-util";
-import { findLovelaceContainer } from "../editor/lovelace-path";
+import {
+ addSection,
+ deleteSection,
+ moveCard,
+ moveSection,
+} from "../editor/config-util";
+import type { LovelaceCardPath } from "../editor/lovelace-path";
+import {
+ findLovelaceContainer,
+ findLovelaceItems,
+ getLovelaceContainerPath,
+ parseLovelaceCardPath,
+} from "../editor/lovelace-path";
import { showEditSectionDialog } from "../editor/section-editor/show-edit-section-dialog";
import type { HuiSection } from "../sections/hui-section";
import type { Lovelace } from "../types";
@@ -231,19 +243,35 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
)}
${editMode
? html`
-
+
+
+
+ ${this.hass.localize(
+ "ui.panel.lovelace.editor.section.drop_card_create_section"
+ )}
+
+
+
+
+
`
: nothing}
${editMode && this._config?.cards?.length
@@ -280,6 +308,52 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
`;
}
+ private _defaultSection(includeHeading: boolean): LovelaceSectionConfig {
+ return {
+ type: "grid",
+ cards: includeHeading
+ ? [
+ {
+ type: "heading",
+ heading: this.hass!.localize(
+ "ui.panel.lovelace.editor.section.default_section_title"
+ ),
+ },
+ ]
+ : [],
+ };
+ }
+
+ private _handleCardAdded(ev) {
+ const { data } = ev.detail;
+ const oldPath = data as LovelaceCardPath;
+
+ const { cardIndex } = parseLovelaceCardPath(oldPath);
+ const containerPath = getLovelaceContainerPath(oldPath);
+ const cards = findLovelaceItems(
+ "cards",
+ this.lovelace!.config,
+ containerPath
+ );
+ const cardConfig = cards![cardIndex];
+
+ const configWithNewSection = addSection(
+ this.lovelace!.config,
+ this.index!,
+ this._defaultSection(cardConfig.type !== "heading") // If we move a heading card, we don't want to include a heading in the new section
+ );
+ const viewConfig = configWithNewSection.views[
+ this.index!
+ ] as LovelaceViewConfig;
+ const newPath = [
+ this.index!,
+ viewConfig.sections!.length - 1,
+ 1,
+ ] as LovelaceCardPath;
+ const newConfig = moveCard(configWithNewSection, oldPath, newPath);
+ this.lovelace!.saveConfig(newConfig);
+ }
+
private _importedCardSectionConfig = memoizeOne(
(cards: LovelaceCardConfig[]) => ({
type: "grid",
@@ -288,17 +362,11 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
);
private _createSection(): void {
- const newConfig = addSection(this.lovelace!.config, this.index!, {
- type: "grid",
- cards: [
- {
- type: "heading",
- heading: this.hass!.localize(
- "ui.panel.lovelace.editor.section.default_section_title"
- ),
- },
- ],
- });
+ const newConfig = addSection(
+ this.lovelace!.config,
+ this.index!,
+ this._defaultSection(true)
+ );
this.lovelace!.saveConfig(newConfig);
}
@@ -415,8 +483,55 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
padding: 8px;
}
- .create-section {
+ .create-section-container {
+ position: relative;
+ display: flex;
+ flex-direction: column;
margin-top: 36px;
+ }
+
+ .create-section-container .card {
+ display: none;
+ }
+
+ .create-section-container:has(.card) .drop-helper {
+ display: flex;
+ }
+ .create-section-container:has(.card) .create-section {
+ display: none;
+ }
+
+ .drop-helper {
+ display: none;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ outline: none;
+ background: none;
+ cursor: pointer;
+ border-radius: var(--ha-card-border-radius, 12px);
+ border: 2px dashed var(--primary-color);
+ height: calc(var(--row-height) + 2 * (var(--row-gap) + 2px));
+ padding: 8px;
+ box-sizing: border-box;
+ width: 100%;
+ --ha-ripple-color: var(--primary-color);
+ --ha-ripple-hover-opacity: 0.04;
+ --ha-ripple-pressed-opacity: 0.12;
+ }
+
+ .drop-helper p {
+ color: var(--primary-text-color);
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 24px;
+ text-align: center;
+ }
+
+ .create-section {
+ display: block;
+ position: relative;
outline: none;
background: none;
cursor: pointer;
@@ -426,6 +541,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
height: calc(var(--row-height) + 2 * (var(--row-gap) + 2px));
padding: 8px;
box-sizing: border-box;
+ width: 100%;
--ha-ripple-color: var(--primary-color);
--ha-ripple-hover-opacity: 0.04;
--ha-ripple-pressed-opacity: 0.12;
diff --git a/src/translations/en.json b/src/translations/en.json
index df961152e8..8d775b4ce5 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -5895,6 +5895,7 @@
"section": {
"add_badge": "Add badge",
"add_card": "[%key:ui::panel::lovelace::editor::edit_card::add%]",
+ "drop_card_create_section": "Drop card here to create a new section",
"create_section": "Create section",
"default_section_title": "New section",
"imported_cards_title": "Imported cards",