Skip to content

Commit ca292a7

Browse files
committed
add flex direction option
1 parent f841bf8 commit ca292a7

File tree

7 files changed

+158
-19
lines changed

7 files changed

+158
-19
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type: custom:datetime-card
3131
title: Chinese money
3232
image: /local/plant_chinese_money.png
3333
show_names: false
34+
flex_direction: row
3435
entities:
3536
- id: input_datetime.plant_chinese_money_w
3637
max: 9

images/configuration.png

1.34 KB
Loading

src/DatetimeCard.svelte

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@
2727
entities = config.entities;
2828
header = config.title !== undefined ? config.title : DEFAULT_TITLE;
2929
shownames = config.show_names || false;
30+
flex_direction = config.flex_direction || "row";
3031
src = config.image !== undefined ? config.image : DEFAULT_SRC;
3132
}
3233
3334
$: entities = entities || getDefaultEntities(hass);
3435
36+
let flex_direction = "row";
3537
let header: string;
3638
let shownames: boolean;
3739
let src: string;
@@ -42,10 +44,15 @@
4244
<h1 class="card-header">{header}</h1>
4345
{/if}
4446

45-
<div class="card-content">
47+
<div
48+
data-testid="card-content"
49+
class="card-content"
50+
style:flex-direction={flex_direction}
51+
>
4652
{#if !!src}
4753
<img {src} alt="card-pict" />
4854
{/if}
55+
4956
<div class="grid">
5057
{#each entities as entity}
5158
<datetime-icon role="listitem" {entity} {hass} />
@@ -72,16 +79,17 @@
7279
}
7380
7481
img {
75-
max-width: 50%;
82+
max-width: 40%;
7683
}
7784
7885
.grid {
7986
display: grid;
8087
flex-grow: 1;
8188
grid-template-columns: 24px auto min-content;
82-
margin-left: 5px;
89+
margin: 10px;
8390
gap: 10px;
8491
align-items: center;
92+
width: 100%;
8593
}
8694
8795
datetime-label {

src/DatetimeCardEditor.svelte

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
export function setConfig(config: IConfig): void {
1313
draggableEntities = toDraggableEntities(config.entities);
1414
show_names = config.show_names || false;
15+
column = config.flex_direction?.includes("column");
16+
reverse = config.flex_direction?.includes("reverse");
1517
image = config.image || "";
1618
title = config.title || "";
1719
}
@@ -24,6 +26,8 @@
2426
const flipDurationMs = 200;
2527
const svelteDispatch = createEventDispatcher();
2628
29+
let column = false;
30+
let reverse = false;
2731
let key = 0;
2832
let draggableEntities: DraggableEntity[] = [new DraggableEntity(newKey())];
2933
let dragDisabled = true;
@@ -38,7 +42,16 @@
3842
function dispatchConfigChanged(): void {
3943
const type = "custom:datetime-card";
4044
const entities = draggableEntities.map(toEntity);
41-
const config = { entities, image, show_names, title, type };
45+
const flex_direction =
46+
(column ? "column" : "row") + (reverse ? "-reverse" : "");
47+
const config = {
48+
entities,
49+
flex_direction,
50+
image,
51+
show_names,
52+
title,
53+
type,
54+
};
4255
svelteDispatch("config-changed", { config });
4356
}
4457
@@ -108,23 +121,18 @@
108121
return { id, max: parseInt(max) || 0 };
109122
}
110123
111-
function updateTitle($event: Event): void {
112-
title = (<HTMLInputElement>$event.target).value;
124+
function updateColumn($event: Event): void {
125+
column = (<HTMLInputElement>$event.target).checked;
113126
dispatchConfigChanged();
114127
}
115128
116-
function updateImage($event: Event): void {
117-
image = (<HTMLInputElement>$event.target).value;
118-
dispatchConfigChanged();
119-
}
120-
121-
function updateShowNames($event: Event): void {
122-
show_names = (<HTMLInputElement>$event.target).checked;
129+
function updateId($event: CustomEvent, entity: DraggableEntity): void {
130+
entity.id = $event.detail.value;
123131
dispatchConfigChanged();
124132
}
125133
126-
function updateId($event: CustomEvent, entity: DraggableEntity): void {
127-
entity.id = $event.detail.value;
134+
function updateImage($event: Event): void {
135+
image = (<HTMLInputElement>$event.target).value;
128136
dispatchConfigChanged();
129137
}
130138
@@ -140,6 +148,21 @@
140148
entity.max = value.toString();
141149
dispatchConfigChanged();
142150
}
151+
152+
function updateReverse($event: Event): void {
153+
reverse = (<HTMLInputElement>$event.target).checked;
154+
dispatchConfigChanged();
155+
}
156+
157+
function updateShowNames($event: Event): void {
158+
show_names = (<HTMLInputElement>$event.target).checked;
159+
dispatchConfigChanged();
160+
}
161+
162+
function updateTitle($event: Event): void {
163+
title = (<HTMLInputElement>$event.target).value;
164+
dispatchConfigChanged();
165+
}
143166
</script>
144167

145168
<ha-textfield
@@ -158,13 +181,28 @@
158181

159182
<section class="switches">
160183
<ha-switch
161-
aria-labelledby="show-names-switch-label"
184+
id="show-names-switch"
185+
aria-label="Show names"
162186
checked={show_names}
163187
on:change={updateShowNames}
164188
/>
165-
<label id="show-names-switch-label" for="show-names-switch"
166-
>Show names</label
167-
>
189+
<label for="show-names-switch">Show names</label>
190+
191+
<ha-switch
192+
id="column-switch"
193+
aria-label="Column"
194+
checked={column}
195+
on:change={updateColumn}
196+
/>
197+
<label for="column-switch">Column</label>
198+
199+
<ha-switch
200+
id="reverse-switch"
201+
aria-label="Reverse"
202+
checked={reverse}
203+
on:change={updateReverse}
204+
/>
205+
<label for="reverse-switch">Reverse</label>
168206
</section>
169207

170208
<h3>Entities (required)</h3>
@@ -246,6 +284,10 @@
246284
margin-top: 15px;
247285
}
248286
287+
ha-switch {
288+
margin-left: 30px;
289+
}
290+
249291
.entity {
250292
display: flex;
251293
align-items: center;

src/__tests__/DatetimeCard.svelte.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ describe('DatetimeCard.svelte', () => {
3737
await component.setConfig(config);
3838
expect(getAllByRole("listitem")).toHaveLength(1);
3939
});
40+
41+
test("flex_direction should be row", async () => {
42+
const hass = { states: { input_datetime_test: { state: "2022-05-11" } } };
43+
const { component, getByTestId } = render(DatetimeCard, { hass });
44+
await component.setConfig(config);
45+
expect(getByTestId("card-content")).toHaveStyle("flex-direction: row");
46+
});
4047
});
4148

4249
test("when config.title is defined title should be in the document", async () => {
@@ -51,6 +58,12 @@ describe('DatetimeCard.svelte', () => {
5158
expect(getByAltText('card-pict')).toHaveAttribute("src", "/local/my-image.png");
5259
});
5360

61+
test("when config.flex_direction is defined the style should be applied", async () => {
62+
const { component, getByTestId } = render(DatetimeCard);
63+
await component.setConfig({ flex_direction: "column" });
64+
expect(getByTestId("card-content")).toHaveStyle("flex-direction: column");
65+
});
66+
5467
test("when config.title is empty title should not be in the document", async () => {
5568
const { component, queryByRole } = render(DatetimeCard);
5669
await component.setConfig({ type: "custom:datetime-card", title: "" })

src/__tests__/DatetimeCardEditor.svelte.spec.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ describe('DatetimeCardEditor.svelte', () => {
6868
expect(eventDispatcher).toHaveBeenCalledWith("config-changed", {
6969
config: {
7070
entities: [{ "id": "", "max": 0 }],
71+
flex_direction: "row",
7172
image: "",
7273
show_names: false,
7374
title: "My Datetime Card",
@@ -84,6 +85,7 @@ describe('DatetimeCardEditor.svelte', () => {
8485
expect(eventDispatcher).toHaveBeenCalledWith("config-changed", {
8586
config: {
8687
entities: [{ id: "", max: 0 },],
88+
flex_direction: "row",
8789
image: "/local/image.png",
8890
show_names: false,
8991
type: "custom:datetime-card",
@@ -100,6 +102,7 @@ describe('DatetimeCardEditor.svelte', () => {
100102
expect(eventDispatcher).toHaveBeenCalledWith("config-changed", {
101103
config: {
102104
entities: [{ id: "", max: 0 },],
105+
flex_direction: "row",
103106
image: "",
104107
show_names: true,
105108
type: "custom:datetime-card",
@@ -108,6 +111,59 @@ describe('DatetimeCardEditor.svelte', () => {
108111
});
109112
});
110113

114+
test("when column changes config should change", async () => {
115+
getByLabelText("Column").checked = true;
116+
117+
await fireEvent.change(getByLabelText("Column"));
118+
119+
expect(eventDispatcher).toHaveBeenCalledWith("config-changed", {
120+
config: {
121+
entities: [{ id: "", max: 0 },],
122+
flex_direction: "column",
123+
image: "",
124+
show_names: false,
125+
type: "custom:datetime-card",
126+
title: ""
127+
}
128+
});
129+
});
130+
131+
test("when reverse changes config should change", async () => {
132+
getByLabelText("Reverse").checked = true;
133+
134+
await fireEvent.change(getByLabelText("Reverse"));
135+
136+
expect(eventDispatcher).toHaveBeenCalledWith("config-changed", {
137+
config: {
138+
entities: [{ id: "", max: 0 },],
139+
flex_direction: "row-reverse",
140+
image: "",
141+
show_names: false,
142+
type: "custom:datetime-card",
143+
title: ""
144+
}
145+
});
146+
});
147+
148+
test("when column and reverse change config should change", async () => {
149+
getByLabelText("Column").checked = true;
150+
getByLabelText("Reverse").checked = true;
151+
152+
await fireEvent.change(getByLabelText("Column"));
153+
await fireEvent.change(getByLabelText("Reverse"));
154+
155+
expect(eventDispatcher).toHaveBeenCalledWith("config-changed", {
156+
config: {
157+
entities: [{ id: "", max: 0 },],
158+
flex_direction: "column-reverse",
159+
image: "",
160+
show_names: false,
161+
type: "custom:datetime-card",
162+
title: ""
163+
}
164+
});
165+
});
166+
111167
test("when click on plus a new entity should be added", async () => {
112168
await fireEvent.click(getByTestId("plus"));
113169

@@ -135,6 +191,20 @@ describe('DatetimeCardEditor.svelte', () => {
135191
expect(getByLabelText("Show names")).toHaveAttribute("checked", "true");
136192
});
137193

194+
[{ flex_direction: "column", column: "true", reverse: "false" },
195+
{ flex_direction: "row", column: "false", reverse: "false" },
196+
{ flex_direction: "column-reverse", column: "true", reverse: "true" },
197+
{ flex_direction: "row-reverse", column: "false", reverse: "true" }
198+
].forEach(({ flex_direction, column, reverse }) => {
199+
test(`when flex_direction is ${flex_direction}`, async () => {
200+
const config = { flex_direction };
201+
await component.setConfig(config);
202+
203+
expect(getByLabelText("Column")).toHaveAttribute("checked", column);
204+
expect(getByLabelText("Reverse")).toHaveAttribute("checked", reverse);
205+
});
206+
});
207+
138208
describe("when config.entities is not empty", () => {
139209
let entity1: IEntity;
140210
let entity2: IEntity;
@@ -175,6 +245,7 @@ describe('DatetimeCardEditor.svelte', () => {
175245
expect(eventDispatcher).toHaveBeenCalledWith("config-changed", {
176246
config: {
177247
entities: [{ id: "input_datetime.test", "max": 10 }, entity2],
248+
flex_direction: "row",
178249
image: "",
179250
show_names: false,
180251
title: "",
@@ -191,6 +262,7 @@ describe('DatetimeCardEditor.svelte', () => {
191262
expect(eventDispatcher).toHaveBeenCalledWith("config-changed", {
192263
config: {
193264
entities: [{ "id": "input_datetime.test_1", "max": 20 }, entity2],
265+
flex_direction: "row",
194266
image: "",
195267
show_names: false,
196268
title: "",
@@ -213,6 +285,7 @@ describe('DatetimeCardEditor.svelte', () => {
213285
expect(eventDispatcher).toHaveBeenCalledWith("config-changed", {
214286
config: {
215287
entities: [{ "id": "input_datetime.test_2", "max": 20, }],
288+
flex_direction: "row",
216289
image: "",
217290
show_names: false,
218291
title: "",
@@ -231,6 +304,7 @@ describe('DatetimeCardEditor.svelte', () => {
231304
expect(eventDispatcher).toHaveBeenCalledWith("config-changed", {
232305
config: {
233306
entities: [],
307+
flex_direction: "row",
234308
image: "",
235309
show_names: false,
236310
title: "",

src/types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface IAutocompleteItem {
77
export interface IConfig {
88
readonly type: string = "custom:datetime-card";
99
entities?: IEntity[] = [];
10+
flex_direction: "column" | "row" | "column-reverse" | "row-reverse";
1011
image?: string;
1112
title?: string;
1213
show_names: boolean;

0 commit comments

Comments
 (0)