Compare commits

...

3 Commits

Author SHA1 Message Date
renovate[bot] d0a279f576 Update dependency @material/web to v2.5.0 2026-07-20 14:09:23 +00:00
Aidan Timson fd3b25d13f Migrate to conditional visibility in clock card editor and use context (#53167) 2026-07-20 15:06:28 +01:00
Petar Petrov 0f31fb50f8 Wrap long logbook entries instead of truncating them (#52972)
* Wrap long logbook entries instead of truncating them

* Resolve merge conflict: use overflow-wrap with RTL-safe text-align: end

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-20 13:39:32 +00:00
4 changed files with 161 additions and 177 deletions
+1 -1
View File
@@ -77,7 +77,7 @@
"@lit/task": "1.0.3",
"@material/mwc-formfield": "patch:@material/mwc-formfield@npm%3A0.27.0#~/.yarn/patches/@material-mwc-formfield-npm-0.27.0-9528cb60f6.patch",
"@material/mwc-list": "patch:@material/mwc-list@npm%3A0.27.0#~/.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch",
"@material/web": "2.4.1",
"@material/web": "2.5.0",
"@mdi/js": "7.4.47",
"@mdi/svg": "7.4.47",
"@replit/codemirror-indentation-markers": "6.5.3",
+11 -9
View File
@@ -866,7 +866,10 @@ class HaLogbookEntry extends LitElement {
.primary {
display: flex;
align-items: center;
/* Baseline-align so a wrapped multi-line value keeps the subject and
the trailing time on its first line, while a single-line entry
stays aligned with the text. */
align-items: baseline;
gap: var(--ha-space-2);
color: var(--primary-text-color);
}
@@ -878,9 +881,9 @@ class HaLogbookEntry extends LitElement {
.primary-text {
flex: 1;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
/* Wrap long entries onto multiple lines instead of truncating them to
a single line with an ellipsis. */
overflow-wrap: anywhere;
}
.primary > .subject {
@@ -905,13 +908,12 @@ class HaLogbookEntry extends LitElement {
}
.value {
/* Don't shrink: the subject absorbs all truncation so a short state
stays whole. max-width still caps a long one. */
/* Don't shrink: the subject absorbs truncation so a short state stays
whole. A long value wraps within its max-width instead of being cut
off. */
flex: 0 0 auto;
max-width: 60%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
overflow-wrap: anywhere;
text-align: end;
}
@@ -1,5 +1,5 @@
import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { customElement, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import {
array,
@@ -12,14 +12,15 @@ import {
optional,
string,
} from "superstruct";
import { consumeLocalize } from "../../../../common/decorators/consume-context-entry";
import { fireEvent } from "../../../../common/dom/fire_event";
import type { LocalizeFunc } from "../../../../common/translations/localize";
import "../../../../components/ha-form/ha-form";
import type {
HaFormSchema,
SchemaUnion,
} from "../../../../components/ha-form/types";
import type { HomeAssistant, ValueChangedEvent } from "../../../../types";
import type { LocalizeFunc } from "../../../../common/translations/localize";
import type { ValueChangedEvent } from "../../../../types";
import type { ClockCardConfig } from "../../cards/types";
import type { LovelaceCardEditor } from "../../types";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
@@ -64,17 +65,13 @@ export class HuiClockCardEditor
extends LitElement
implements LovelaceCardEditor
{
@property({ attribute: false }) public hass?: HomeAssistant;
@consumeLocalize()
private _localize!: LocalizeFunc;
@state() private _config?: ClockCardConfig;
private _schema = memoizeOne(
(
localize: LocalizeFunc,
clockStyle: ClockCardConfig["clock_style"],
ticks: ClockCardConfig["ticks"],
showSeconds: boolean | undefined
) =>
(localize: LocalizeFunc) =>
[
{ name: "title", selector: { text: {} } },
{
@@ -114,124 +111,122 @@ export class HuiClockCardEditor
ui_clock_date_format: {},
},
},
...(clockStyle === "digital"
? ([
{
name: "time_format",
selector: {
select: {
mode: "dropdown",
options: ["auto", ...Object.values(TimeFormat)].map(
(value) => ({
value,
label: localize(
`ui.panel.lovelace.editor.card.clock.time_formats.${value}`
),
})
),
},
},
},
] as const satisfies readonly HaFormSchema[])
: clockStyle === "analog"
? ([
{
name: "border",
description: {
suffix: localize(
`ui.panel.lovelace.editor.card.clock.border.description`
),
},
default: false,
selector: {
boolean: {},
},
},
{
name: "ticks",
description: {
suffix: localize(
`ui.panel.lovelace.editor.card.clock.ticks.description`
),
},
default: "hour",
selector: {
select: {
mode: "dropdown",
options: ["none", "quarter", "hour", "minute"].map(
(value) => ({
value,
label: localize(
`ui.panel.lovelace.editor.card.clock.ticks.${value}.label`
),
description: localize(
`ui.panel.lovelace.editor.card.clock.ticks.${value}.description`
),
})
),
},
},
},
...(showSeconds
? ([
{
name: "seconds_motion",
description: {
suffix: localize(
`ui.panel.lovelace.editor.card.clock.seconds_motion.description`
),
},
default: "continuous",
selector: {
select: {
mode: "dropdown",
options: ["continuous", "tick"].map((value) => ({
value,
label: localize(
`ui.panel.lovelace.editor.card.clock.seconds_motion.${value}.label`
),
description: localize(
`ui.panel.lovelace.editor.card.clock.seconds_motion.${value}.description`
),
})),
},
},
},
] as const satisfies readonly HaFormSchema[])
: []),
...(ticks !== "none"
? ([
{
name: "face_style",
description: {
suffix: localize(
`ui.panel.lovelace.editor.card.clock.face_style.description`
),
},
default: "markers",
selector: {
select: {
mode: "dropdown",
options: [
"markers",
"numbers_upright",
"roman",
].map((value) => ({
value,
label: localize(
`ui.panel.lovelace.editor.card.clock.face_style.${value}.label`
),
description: localize(
`ui.panel.lovelace.editor.card.clock.face_style.${value}.description`
),
})),
},
},
},
] as const satisfies readonly HaFormSchema[])
: []),
] as const satisfies readonly HaFormSchema[])
: []),
{
name: "time_format",
hidden: {
field: "clock_style",
operator: "not_eq",
value: "digital",
},
selector: {
select: {
mode: "dropdown",
options: ["auto", ...Object.values(TimeFormat)].map((value) => ({
value,
label: localize(
`ui.panel.lovelace.editor.card.clock.time_formats.${value}`
),
})),
},
},
},
{
name: "border",
hidden: { field: "clock_style", operator: "not_eq", value: "analog" },
description: {
suffix: localize(
`ui.panel.lovelace.editor.card.clock.border.description`
),
},
default: false,
selector: {
boolean: {},
},
},
{
name: "ticks",
hidden: { field: "clock_style", operator: "not_eq", value: "analog" },
description: {
suffix: localize(
`ui.panel.lovelace.editor.card.clock.ticks.description`
),
},
default: "hour",
selector: {
select: {
mode: "dropdown",
options: ["none", "quarter", "hour", "minute"].map((value) => ({
value,
label: localize(
`ui.panel.lovelace.editor.card.clock.ticks.${value}.label`
),
description: localize(
`ui.panel.lovelace.editor.card.clock.ticks.${value}.description`
),
})),
},
},
},
{
name: "seconds_motion",
hidden: {
condition: "or",
conditions: [
{ field: "clock_style", operator: "not_eq", value: "analog" },
{ field: "show_seconds", operator: "not_eq", value: true },
],
},
description: {
suffix: localize(
`ui.panel.lovelace.editor.card.clock.seconds_motion.description`
),
},
default: "continuous",
selector: {
select: {
mode: "dropdown",
options: ["continuous", "tick"].map((value) => ({
value,
label: localize(
`ui.panel.lovelace.editor.card.clock.seconds_motion.${value}.label`
),
description: localize(
`ui.panel.lovelace.editor.card.clock.seconds_motion.${value}.description`
),
})),
},
},
},
{
name: "face_style",
hidden: {
condition: "or",
conditions: [
{ field: "clock_style", operator: "not_eq", value: "analog" },
{ field: "ticks", value: "none" },
],
},
description: {
suffix: localize(
`ui.panel.lovelace.editor.card.clock.face_style.description`
),
},
default: "markers",
selector: {
select: {
mode: "dropdown",
options: ["markers", "numbers_upright", "roman"].map((value) => ({
value,
label: localize(
`ui.panel.lovelace.editor.card.clock.face_style.${value}.label`
),
description: localize(
`ui.panel.lovelace.editor.card.clock.face_style.${value}.description`
),
})),
},
},
},
{ name: "time_zone", selector: { timezone: {} } },
] as const satisfies readonly HaFormSchema[]
);
@@ -265,20 +260,14 @@ export class HuiClockCardEditor
}
protected render() {
if (!this.hass || !this._config) {
if (!this._config) {
return nothing;
}
return html`
<ha-form
.hass=${this.hass}
.data=${this._data(this._config)}
.schema=${this._schema(
this.hass.localize,
this._data(this._config).clock_style,
this._data(this._config).ticks,
this._data(this._config).show_seconds
)}
.schema=${this._schema(this._localize)}
.computeLabel=${this._computeLabelCallback}
.computeHelper=${this._computeHelperCallback}
@value-changed=${this._valueChanged}
@@ -327,51 +316,43 @@ export class HuiClockCardEditor
) => {
switch (schema.name) {
case "title":
return this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.title"
);
return this._localize("ui.panel.lovelace.editor.card.generic.title");
case "clock_style":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.clock_style`
);
case "clock_size":
return this.hass!.localize(
`ui.panel.lovelace.editor.card.clock.clock_size`
);
return this._localize(`ui.panel.lovelace.editor.card.clock.clock_size`);
case "time_format":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.time_format`
);
case "time_zone":
return this.hass!.localize(
`ui.panel.lovelace.editor.card.clock.time_zone`
);
return this._localize(`ui.panel.lovelace.editor.card.clock.time_zone`);
case "show_seconds":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.show_seconds`
);
case "no_background":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.no_background`
);
case "date_format":
return this.hass!.localize(
`ui.panel.lovelace.editor.card.clock.date.label`
);
return this._localize(`ui.panel.lovelace.editor.card.clock.date.label`);
case "border":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.border.label`
);
case "ticks":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.ticks.label`
);
case "seconds_motion":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.seconds_motion.label`
);
case "face_style":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.face_style.label`
);
default:
@@ -384,23 +365,23 @@ export class HuiClockCardEditor
) => {
switch (schema.name) {
case "date_format":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.date.description`
);
case "border":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.border.description`
);
case "ticks":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.ticks.description`
);
case "seconds_motion":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.seconds_motion.description`
);
case "face_style":
return this.hass!.localize(
return this._localize(
`ui.panel.lovelace.editor.card.clock.face_style.description`
);
default:
+7 -6
View File
@@ -3417,7 +3417,7 @@ __metadata:
languageName: node
linkType: hard
"@lit/context@npm:1.1.6":
"@lit/context@npm:1.1.6, @lit/context@npm:^1.1.6":
version: 1.1.6
resolution: "@lit/context@npm:1.1.6"
dependencies:
@@ -3753,13 +3753,14 @@ __metadata:
languageName: node
linkType: hard
"@material/web@npm:2.4.1":
version: 2.4.1
resolution: "@material/web@npm:2.4.1"
"@material/web@npm:2.5.0":
version: 2.5.0
resolution: "@material/web@npm:2.5.0"
dependencies:
"@lit/context": "npm:^1.1.6"
lit: "npm:^2.8.0 || ^3.0.0"
tslib: "npm:^2.4.0"
checksum: 10/6f9afeb28faa7d9720228cd3f46d15116b6f8dce6e61ebebf4acb0e720389724d5aa9e31f612bfa24afc5d49f283efd4660337e3d4d7379aec6b4286a01eba71
checksum: 10/3864bce2034413e2f712ee663bbaf3db2ae24af30f758ea7f6b66b7a7756671e868b197ad8d2aa371439b664ad0e0db6c587981fe589a22322b6ccbb2f28fa2e
languageName: node
linkType: hard
@@ -9994,7 +9995,7 @@ __metadata:
"@lokalise/node-api": "npm:16.3.0"
"@material/mwc-formfield": "patch:@material/mwc-formfield@npm%3A0.27.0#~/.yarn/patches/@material-mwc-formfield-npm-0.27.0-9528cb60f6.patch"
"@material/mwc-list": "patch:@material/mwc-list@npm%3A0.27.0#~/.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch"
"@material/web": "npm:2.4.1"
"@material/web": "npm:2.5.0"
"@mdi/js": "npm:7.4.47"
"@mdi/svg": "npm:7.4.47"
"@octokit/auth-oauth-device": "npm:8.0.3"