Skip to content

Commit 51fb984

Browse files
authored
Merge pull request #706 from dcapslock/expander-on-dom-event
feat: Set expander card state from another card action
2 parents 795c428 + 12cd910 commit 51fb984

File tree

4 files changed

+75
-6
lines changed

4 files changed

+75
-6
lines changed

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ Yaml Options:
7676
| show-button-users | object[] | **optional** | * | Choose the users that button is visible to them |
7777
| start-expanded-users | object[] | **optional** | * | Choose the users that card will be start expanded for them|
7878
| animation | boolean | _true_ | true\|false | Should the opening/closing of expander be animated? |
79+
| expander-card-id | string | **optional** | * | An id to use with [Set state via action](#set-state-via-action) |
7980

8081

8182
### Deprecation Warning
@@ -190,6 +191,47 @@ Example with title that is clickable and has 2 nested cards with are automatical
190191
show_wind: speed
191192
```
192193

194+
## Set state via action
195+
196+
You can set the state of expander card(s) using the `fire-dom-event` action on any card that supports actions.
197+
198+
1. Set expander card(s) to have `expander-card-id`. Multiple expander cards can shared the same id if you wish to set their state together.
199+
2. Set action on another card using the `fire-dom-event` action.
200+
201+
```yaml
202+
tap_action:
203+
action: fire-dom-event
204+
expander-card:
205+
data:
206+
expander-card-id: <expander-card-id>
207+
action: < open | close | toggle >
208+
```
209+
210+
Example
211+
212+
### Expander card config
213+
214+
```yaml
215+
- type: custom:expander-card
216+
expander-card-id: my-expander-card
217+
```
218+
219+
### Action on another card
220+
221+
```yaml
222+
show_name: true
223+
show_icon: true
224+
type: button
225+
name: Expand my-expander-card
226+
icon: mdi:chevron-down
227+
tap_action:
228+
action: fire-dom-event
229+
expander-card:
230+
data:
231+
expander-card-id: my-expander-card
232+
action: open
233+
```
234+
193235
## Card Mod
194236
195237
With the help of the integration [card mod](https://github.com/thomasloven/lovelace-card-mod), the card can be flexibly adapted. This is also possible based on the card status. A CSS class “open” or “close” is always set.

src/ExpanderCard.svelte

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
}}/>
3838

3939
<script lang="ts">
40-
import type { HomeAssistant } from './types';
40+
import type { ExpanderCardDomEventDetail, HomeAssistant } from './types';
4141
import Card from './Card.svelte';
4242
import { onMount } from 'svelte';
4343
import type { ExpanderConfig } from './configtype';
@@ -59,15 +59,15 @@
5959
const showButtonUsers = (config['show-button-users'] === undefined || config['show-button-users']?.includes(hass?.user.name));
6060
6161
62-
function toggleOpen() {
62+
function toggleOpen(openState?: boolean) {
6363
if (animationTimeout) {
6464
clearTimeout(animationTimeout);
6565
animationTimeout = null;
6666
}
67-
const openState = !open;
67+
const newOpenState = openState !== undefined ? openState : !open;
6868
if (config.animation) {
69-
animationState = openState ? 'opening' : 'closing';
70-
if (openState) {
69+
animationState = newOpenState ? 'opening' : 'closing';
70+
if (newOpenState) {
7171
setOpenState(true);
7272
animationTimeout = setTimeout(() => {
7373
animationState = 'idle';
@@ -81,7 +81,7 @@
8181
}, 350);
8282
}
8383
} else {
84-
setOpenState(openState);
84+
setOpenState(newOpenState);
8585
// animation state is always 'idle' if no animation
8686
}
8787
}
@@ -98,6 +98,23 @@
9898
}
9999
}
100100
101+
function handleDomEvent(event: Event) {
102+
const data: ExpanderCardDomEventDetail = (event as CustomEvent).detail?.['expander-card']?.data;
103+
if (data?.['expander-card-id'] === config['expander-card-id']) {
104+
if (data.action === 'open' && !open) {
105+
toggleOpen(true);
106+
} else if (data.action === 'close' && open) {
107+
toggleOpen(false);
108+
} else if (data.action === 'toggle') {
109+
toggleOpen();
110+
}
111+
}
112+
};
113+
114+
function cleanup() {
115+
document.body.removeEventListener('ll-custom', handleDomEvent);
116+
};
117+
101118
onMount(() => {
102119
const minWidthExpanded = config['min-width-expanded'];
103120
const maxWidthExpanded = config['max-width-expanded'];
@@ -135,6 +152,10 @@
135152
setOpenState(config.expanded);
136153
}
137154
}
155+
156+
document.body.addEventListener('ll-custom', handleDomEvent);
157+
158+
return cleanup;
138159
});
139160
140161
const buttonClick = (event: MouseEvent) => {

src/configtype.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ export interface ExpanderConfig {
4343
'show-button-users'?: { type: string }[];
4444
'start-expanded-users'?: { type: string }[];
4545
animation?: boolean;
46+
'expander-card-id'?: string;
4647
}

src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ export interface HuiCard extends LovelaceCard {
2424
load(): void;
2525
_element?: LovelaceCard;
2626
}
27+
28+
export interface ExpanderCardDomEventDetail {
29+
'expander-card-id'?: string;
30+
action?: 'open' | 'close' | 'toggle';
31+
}

0 commit comments

Comments
 (0)