mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-09 02:49:51 +00:00
Use fixed layout for automation sidebar to have scrollbar on the side (#26751)
Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { mdiDrag, mdiPlus } from "@mdi/js";
|
import { mdiDrag, mdiPlus } from "@mdi/js";
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import type { PropertyValues } from "lit";
|
import type { PropertyValues } from "lit";
|
||||||
import { LitElement, css, html, nothing } from "lit";
|
import { LitElement, html, nothing } from "lit";
|
||||||
import { customElement, property, queryAll, state } from "lit/decorators";
|
import { customElement, property, queryAll, state } from "lit/decorators";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
@@ -409,14 +409,7 @@ export default class HaAutomationAction extends LitElement {
|
|||||||
this._rowSortSelected = undefined;
|
this._rowSortSelected = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [
|
static styles = automationRowsStyles;
|
||||||
automationRowsStyles,
|
|
||||||
css`
|
|
||||||
:host([root]) .rows {
|
|
||||||
padding-right: 8px;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { mdiDrag, mdiPlus } from "@mdi/js";
|
import { mdiDrag, mdiPlus } from "@mdi/js";
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import type { PropertyValues } from "lit";
|
import type { PropertyValues } from "lit";
|
||||||
import { css, html, LitElement, nothing } from "lit";
|
import { html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, queryAll, state } from "lit/decorators";
|
import { customElement, property, queryAll, state } from "lit/decorators";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
@@ -428,14 +428,7 @@ export default class HaAutomationCondition extends LitElement {
|
|||||||
this._rowSortSelected = undefined;
|
this._rowSortSelected = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [
|
static styles = automationRowsStyles;
|
||||||
automationRowsStyles,
|
|
||||||
css`
|
|
||||||
:host([root]) .rows {
|
|
||||||
padding-right: 8px;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -1181,27 +1181,6 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
:not(.yaml-mode) > .alert-wrapper {
|
|
||||||
position: sticky;
|
|
||||||
top: -24px;
|
|
||||||
margin-top: -24px;
|
|
||||||
z-index: 1;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
:not(.yaml-mode) > .alert-wrapper ha-alert {
|
|
||||||
background-color: var(--card-background-color);
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
||||||
border-radius: var(--ha-border-radius-sm);
|
|
||||||
margin-bottom: 0;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
manual-automation-editor {
|
manual-automation-editor {
|
||||||
max-width: 1540px;
|
max-width: 1540px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import {
|
|||||||
extractSearchParam,
|
extractSearchParam,
|
||||||
removeSearchParam,
|
removeSearchParam,
|
||||||
} from "../../../common/url/search-params";
|
} from "../../../common/url/search-params";
|
||||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
|
||||||
import "../../../components/ha-button";
|
import "../../../components/ha-button";
|
||||||
import "../../../components/ha-fab";
|
import "../../../components/ha-fab";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
@@ -93,9 +92,6 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
|
|
||||||
@state() private _sidebarConfig?: SidebarConfig;
|
@state() private _sidebarConfig?: SidebarConfig;
|
||||||
|
|
||||||
@query(".content")
|
|
||||||
private _contentElement?: HTMLDivElement;
|
|
||||||
|
|
||||||
@query("ha-automation-sidebar") private _sidebarElement?: HaAutomationSidebar;
|
@query("ha-automation-sidebar") private _sidebarElement?: HaAutomationSidebar;
|
||||||
|
|
||||||
private _previousConfig?: ManualAutomationConfig;
|
private _previousConfig?: ManualAutomationConfig;
|
||||||
@@ -260,8 +256,7 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
"split-view": true,
|
"has-sidebar": this._sidebarConfig && !this.narrow,
|
||||||
"sidebar-hidden": !this._sidebarConfig,
|
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
@@ -269,31 +264,31 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
<slot name="alerts"></slot>
|
<slot name="alerts"></slot>
|
||||||
${this._renderContent()}
|
${this._renderContent()}
|
||||||
</div>
|
</div>
|
||||||
<ha-fab
|
<div class="fab-positioner">
|
||||||
slot="fab"
|
<ha-fab
|
||||||
class=${this.dirty ? "dirty" : ""}
|
slot="fab"
|
||||||
.label=${this.hass.localize("ui.common.save")}
|
class=${this.dirty ? "dirty" : ""}
|
||||||
.disabled=${this.saving}
|
.label=${this.hass.localize("ui.common.save")}
|
||||||
extended
|
.disabled=${this.saving}
|
||||||
@click=${this._saveAutomation}
|
extended
|
||||||
>
|
@click=${this._saveAutomation}
|
||||||
<ha-svg-icon slot="icon" .path=${mdiContentSave}></ha-svg-icon>
|
>
|
||||||
</ha-fab>
|
<ha-svg-icon slot="icon" .path=${mdiContentSave}></ha-svg-icon>
|
||||||
|
</ha-fab>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sidebar-positioner">
|
||||||
|
<ha-automation-sidebar
|
||||||
|
tabindex="-1"
|
||||||
|
class=${classMap({ hidden: !this._sidebarConfig })}
|
||||||
|
.isWide=${this.isWide}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
.config=${this._sidebarConfig}
|
||||||
|
@value-changed=${this._sidebarConfigChanged}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
></ha-automation-sidebar>
|
||||||
</div>
|
</div>
|
||||||
<ha-automation-sidebar
|
|
||||||
tabindex="-1"
|
|
||||||
class=${classMap({
|
|
||||||
sidebar: true,
|
|
||||||
overlay: !this.isWide && !this.narrow,
|
|
||||||
rtl: computeRTL(this.hass),
|
|
||||||
})}
|
|
||||||
.isWide=${this.isWide}
|
|
||||||
.hass=${this.hass}
|
|
||||||
.narrow=${this.narrow}
|
|
||||||
.config=${this._sidebarConfig}
|
|
||||||
@value-changed=${this._sidebarConfigChanged}
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
></ha-automation-sidebar>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -344,8 +339,6 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
|
|
||||||
private _handleCloseSidebar() {
|
private _handleCloseSidebar() {
|
||||||
this._sidebarConfig = undefined;
|
this._sidebarConfig = undefined;
|
||||||
// fix content shift when bottom rows are scrolled into view
|
|
||||||
this._contentElement?.scrollIntoView();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _triggerChanged(ev: CustomEvent): void {
|
private _triggerChanged(ev: CustomEvent): void {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export const indentStyle = css`
|
|||||||
.selector-row,
|
.selector-row,
|
||||||
:host([indent]) ha-form {
|
:host([indent]) ha-form {
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
padding: 12px 20px 16px 16px;
|
padding: 12px 0 16px 16px;
|
||||||
border-left: 2px solid var(--ha-color-border-neutral-quiet);
|
border-left: 2px solid var(--ha-color-border-neutral-quiet);
|
||||||
border-bottom: 2px solid var(--ha-color-border-neutral-quiet);
|
border-bottom: 2px solid var(--ha-color-border-neutral-quiet);
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
@@ -108,77 +108,59 @@ export const saveFabStyles = css`
|
|||||||
export const manualEditorStyles = css`
|
export const manualEditorStyles = css`
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
|
--sidebar-width: 0;
|
||||||
|
--sidebar-gap: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.split-view {
|
.has-sidebar {
|
||||||
|
--sidebar-width: min(35vw, 500px);
|
||||||
|
--sidebar-gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fab-positioner {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
justify-content: flex-end;
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
gap: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.split-view.sidebar-hidden {
|
.fab-positioner ha-fab {
|
||||||
gap: 0;
|
position: fixed;
|
||||||
|
right: unset;
|
||||||
|
left: unset;
|
||||||
|
bottom: calc(-80px - var(--safe-area-inset-bottom));
|
||||||
|
transition: bottom 0.3s;
|
||||||
|
}
|
||||||
|
.fab-positioner ha-fab.dirty {
|
||||||
|
bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-wrapper {
|
.content-wrapper {
|
||||||
position: relative;
|
padding-right: calc(var(--sidebar-width) + var(--sidebar-gap));
|
||||||
flex: 6;
|
padding-inline-end: calc(var(--sidebar-width) + var(--sidebar-gap));
|
||||||
|
padding-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
padding: 32px 16px 64px 0;
|
padding-top: 24px;
|
||||||
height: calc(100vh - 153px);
|
padding-bottom: 72px;
|
||||||
height: calc(100dvh - 153px);
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
ha-automation-sidebar {
|
||||||
padding: 12px 0;
|
|
||||||
flex: 4;
|
|
||||||
height: calc(100vh - 81px);
|
|
||||||
height: calc(100dvh - 81px);
|
|
||||||
width: 40%;
|
|
||||||
}
|
|
||||||
.split-view.sidebar-hidden .sidebar {
|
|
||||||
border-color: transparent;
|
|
||||||
border-width: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
flex: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar.overlay {
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 8px;
|
top: calc(var(--header-height) + 16px);
|
||||||
right: 8px;
|
height: calc(-81px + 100dvh);
|
||||||
height: calc(100% - 70px);
|
width: var(--sidebar-width);
|
||||||
padding: 0;
|
display: block;
|
||||||
z-index: 5;
|
|
||||||
box-shadow: -8px 0 16px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar.overlay.rtl {
|
ha-automation-sidebar.hidden {
|
||||||
right: unset;
|
display: none;
|
||||||
left: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (max-width: 870px) {
|
.sidebar-positioner {
|
||||||
.split-view {
|
display: flex;
|
||||||
gap: 0;
|
justify-content: flex-end;
|
||||||
}
|
|
||||||
.sidebar {
|
|
||||||
height: 0;
|
|
||||||
width: 0;
|
|
||||||
flex: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.split-view.sidebar-hidden .sidebar.overlay {
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
.description {
|
.description {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -189,9 +171,6 @@ export const manualEditorStyles = css`
|
|||||||
|
|
||||||
export const automationRowsStyles = css`
|
export const automationRowsStyles = css`
|
||||||
.rows {
|
.rows {
|
||||||
padding: 16px 0 16px 16px;
|
|
||||||
margin: -16px;
|
|
||||||
margin-right: -20px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { mdiDrag, mdiPlus } from "@mdi/js";
|
import { mdiDrag, mdiPlus } from "@mdi/js";
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import type { PropertyValues } from "lit";
|
import type { PropertyValues } from "lit";
|
||||||
import { css, html, LitElement, nothing } from "lit";
|
import { html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
@@ -368,14 +368,7 @@ export default class HaAutomationTrigger extends LitElement {
|
|||||||
this._rowSortSelected = undefined;
|
this._rowSortSelected = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [
|
static styles = automationRowsStyles;
|
||||||
automationRowsStyles,
|
|
||||||
css`
|
|
||||||
:host([root]) .rows {
|
|
||||||
padding-right: 8px;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import {
|
|||||||
extractSearchParam,
|
extractSearchParam,
|
||||||
removeSearchParam,
|
removeSearchParam,
|
||||||
} from "../../../common/url/search-params";
|
} from "../../../common/url/search-params";
|
||||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-markdown";
|
import "../../../components/ha-markdown";
|
||||||
import type { SidebarConfig } from "../../../data/automation";
|
import type { SidebarConfig } from "../../../data/automation";
|
||||||
@@ -199,8 +198,7 @@ export class HaManualScriptEditor extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
"split-view": true,
|
"has-sidebar": this._sidebarConfig && !this.narrow,
|
||||||
"sidebar-hidden": !this._sidebarConfig,
|
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
@@ -208,31 +206,33 @@ export class HaManualScriptEditor extends LitElement {
|
|||||||
<slot name="alerts"></slot>
|
<slot name="alerts"></slot>
|
||||||
${this._renderContent()}
|
${this._renderContent()}
|
||||||
</div>
|
</div>
|
||||||
<ha-fab
|
<div class="fab-positioner">
|
||||||
slot="fab"
|
<div class="fab-positioner">
|
||||||
class=${this.dirty ? "dirty" : ""}
|
<ha-fab
|
||||||
.label=${this.hass.localize("ui.common.save")}
|
slot="fab"
|
||||||
.disabled=${this.saving}
|
class=${this.dirty ? "dirty" : ""}
|
||||||
extended
|
.label=${this.hass.localize("ui.common.save")}
|
||||||
@click=${this._saveScript}
|
.disabled=${this.saving}
|
||||||
>
|
extended
|
||||||
<ha-svg-icon slot="icon" .path=${mdiContentSave}></ha-svg-icon>
|
@click=${this._saveScript}
|
||||||
</ha-fab>
|
>
|
||||||
|
<ha-svg-icon slot="icon" .path=${mdiContentSave}></ha-svg-icon>
|
||||||
|
</ha-fab>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sidebar-positioner">
|
||||||
|
<ha-automation-sidebar
|
||||||
|
tabindex="-1"
|
||||||
|
class=${classMap({ hidden: !this._sidebarConfig })}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
.isWide=${this.isWide}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.config=${this._sidebarConfig}
|
||||||
|
@value-changed=${this._sidebarConfigChanged}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
></ha-automation-sidebar>
|
||||||
</div>
|
</div>
|
||||||
<ha-automation-sidebar
|
|
||||||
tabindex="-1"
|
|
||||||
class=${classMap({
|
|
||||||
sidebar: true,
|
|
||||||
overlay: !this.isWide,
|
|
||||||
rtl: computeRTL(this.hass),
|
|
||||||
})}
|
|
||||||
.narrow=${this.narrow}
|
|
||||||
.isWide=${this.isWide}
|
|
||||||
.hass=${this.hass}
|
|
||||||
.config=${this._sidebarConfig}
|
|
||||||
@value-changed=${this._sidebarConfigChanged}
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
></ha-automation-sidebar>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user