You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR implements comprehensive icon action functionality, allowing
users to configure separate actions when clicking, holding, or
double-tapping icons versus the card itself, similar to Home Assistant's
Tile Card functionality.
## Overview
The new icon action configuration options enable elegant UX patterns
where:
- Tapping the card performs one action (e.g., toggle)
- Tapping the icon performs a different action (e.g., more-info)
- Holding the icon performs another action (e.g., navigate)
- Double-tapping the icon performs yet another action (e.g.,
call-service)
This addresses the common use case where users want quick toggle
functionality on the card while having multiple interaction options via
the icon.
## Example Usage
```yaml
- type: 'custom:button-card'
entity: light.living_room
name: Living Room Light
tap_action:
action: toggle
icon_tap_action:
action: more-info
icon_hold_action:
action: navigate
navigation_path: /lovelace/lights
icon_double_tap_action:
action: call-service
service: light.turn_on
service_data:
brightness: 255
```
In this example:
- Tapping the card toggles the light
- Tapping the icon opens the more-info dialog
- Holding the icon navigates to the lights dashboard
- Double-tapping the icon turns the light to full brightness
## Implementation Details
- **Type Safety**: Added `icon_tap_action`, `icon_hold_action`, and
`icon_double_tap_action` to both `ButtonCardConfig` and
`ExternalButtonCardConfig` interfaces
- **Default Behavior**: All actions default to `{ action: 'none' }` to
maintain backward compatibility
- **Unified Action Handling**: Uses the existing `_handleAction` method
with smart target detection instead of separate handlers
- **Event Handling**: Uses `stopPropagation()` to prevent card actions
when icon actions are triggered
- **Action Support**: Supports all existing action types (more-info,
navigate, call-service, etc.)
- **Performance Optimized**: Only adds action handlers when actions are
configured and not 'none'
- **Universal Support**: Works with both `ha-state-icon` and `img`
elements
## Key Changes
1. **Type Definitions**: Updated type interfaces to include all three
icon actions
2. **Configuration**: Added default configuration and validation for new
actions
3. **Rendering**: Modified icon rendering to conditionally add
appropriate action handlers
4. **Event Handling**: Enhanced existing `_handleAction` method to
handle both card and icon actions
5. **Documentation**: Updated test cases with comprehensive examples and
README.md documentation
6. **Testing**: Added test cases in ui-lovelace.yaml for all icon action
types
## Testing
- All existing functionality remains unchanged
- New features work with all action types and combinations
- Proper event isolation prevents conflicts between card and icon
actions
- Comprehensive test cases added for validation
- Build and lint validation passes
The implementation is minimal and surgical, adding only the necessary
code to support the comprehensive icon action feature while maintaining
full backward compatibility and using existing action infrastructure.
Fixescustom-cards#739.
## Progress
- [x] Implement icon_tap_action with type definitions and handlers
- [x] Add icon_hold_action and icon_double_tap_action features
- [x] Refactor to use existing _handleAction method instead of separate
handlers
- [x] Add comprehensive test cases in ui-lovelace.yaml
- [x] Update documentation with examples
- [x] Remove HTML test files per reviewer feedback
- [x] Add gitignore rule to prevent future HTML test files
- [x] Add missing icon_hold_action and icon_double_tap_action
documentation to README.md
- [x] Validate build and lint passes
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: RomRider <[email protected]>
Co-authored-by: Jérôme Wiedemann <[email protected]>
Co-authored-by: dcapslock <[email protected]>
Copy file name to clipboardExpand all lines: README.md
+67-18Lines changed: 67 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -53,8 +53,9 @@ Lovelace Button card for your entities.
53
53
-[Configuration with states](#configuration-with-states)
54
54
-[Default behavior](#default-behavior)
55
55
-[With Operator on state](#with-operator-on-state)
56
-
-[`tap_action` Navigate](#tap_action-navigate)
57
56
-[blink](#blink)
57
+
-[`tap_action` Navigate](#tap_action-navigate)
58
+
-[`icon_*_action`](#icon__action)
58
59
-[Play with width, height and icon size](#play-with-width-height-and-icon-size)
59
60
-[Templates Support](#templates-support)
60
61
-[Playing with label templates](#playing-with-label-templates)
@@ -71,6 +72,7 @@ Lovelace Button card for your entities.
71
72
72
73
- works with any toggleable entity
73
74
- 6 available actions on **tap** and/or **hold** and/or **double click**: `none`, `toggle`, `more-info`, `navigate`, `url`, `assist` and `call-service`
75
+
-**icon tap action**: Separate action when clicking the icon specifically which takes precedence over main card actions.
74
76
- state display (optional)
75
77
- custom color (optional), or based on light rgb value/temperature
76
78
- custom state definition with customizable color, icon and style (optional)
@@ -112,6 +114,9 @@ Lovelace Button card for your entities.
112
114
|`tap_action`| object | optional | See [Action](#Action)| Define the type of action on click, if undefined, toggle will be used for domains that support toggle, or button press for input_button. |
113
115
|`hold_action`| object | optional | See [Action](#Action)| Define the type of action on hold, if undefined, nothing happens. |
114
116
|`double_tap_action`| object | optional | See [Action](#Action)| Define the type of action on double click, if undefined, nothing happens. |
117
+
|`icon_tap_action`| object | optional | See [Action](#Action)| Define the type of action on icon click, if undefined, nothing happens. When configured, the icon becomes clickable separately from the card. See note in [icon\_\*\_action](#icon__action)|
118
+
|`icon_hold_action`| object | optional | See [Action](#Action)| Define the type of action on icon hold, if undefined, nothing happens. When configured, the icon becomes holdable separately from the card. See note in [icon\_\*\_action](#icon__action)|
119
+
|`icon_double_tap_action`| object | optional | See [Action](#Action)| Define the type of action on icon double click, if undefined, nothing happens. When configured, the icon becomes double-clickable separately from the card. See note in [icon\_\*\_action](#icon__action)|
115
120
|`name`| string | optional |`Air conditioner`| Define an optional text to show below the icon. Supports templates, see [templates](#javascript-templates)|
116
121
|`state_display`| string | optional |`On`| Override the way the state is displayed. Supports templates, see [templates](#javascript-templates)|
117
122
|`label`| string | optional | Any string that you want | Display a label below the card. See [Layouts](#layout) for more information. Supports templates, see [templates](#javascript-templates)|
@@ -289,7 +294,9 @@ To enable compatibility with sections (meaning the card adjusts its size automat
289
294
290
295
For users with heavily modified cards using `styles`, you might need to adjust your configuration once enabling `section_mode`.
291
296
292
-
⚠️ While `section_mode` is enabled: using `aspect_ratio` or setting the card's `height` or `width` using CSS will probably the layout and is considered incompatible. There might be other incompatible options, if you find any, please update this documentation by submitting a PR.
297
+
> [!IMPORTANT]
298
+
>
299
+
> While `section_mode` is enabled: using `aspect_ratio` or setting the card's `height` or `width` using CSS will probably break the layout and is considered incompatible. There might be other incompatible options, if you find any, please update this documentation by submitting a PR.
293
300
294
301

295
302
@@ -1371,22 +1378,6 @@ The definition order matters, the first item to match will be the one selected.
1371
1378
- opacity: 0.5
1372
1379
```
1373
1380
1374
-
#### `tap_action` Navigate
1375
-
1376
-
Buttons can link to different views using the `navigate` action:
1377
-
1378
-
```yaml
1379
-
- type: 'custom:button-card'
1380
-
color_type: label-card
1381
-
icon: mdi:home
1382
-
name: Go To Home
1383
-
tap_action:
1384
-
action: navigate
1385
-
navigation_path: /lovelace/0
1386
-
```
1387
-
1388
-
The `navigation_path` also accepts any Home Assistant internal URL such as /dev-info or /hassio/dashboard for example.
1389
-
1390
1381
#### blink
1391
1382
1392
1383
You can make the whole button blink:
@@ -1410,6 +1401,64 @@ You can make the whole button blink:
1410
1401
icon: mdi:shield-check
1411
1402
```
1412
1403
1404
+
### `tap_action` Navigate
1405
+
1406
+
Buttons can link to different views using the `navigate` action:
1407
+
1408
+
```yaml
1409
+
- type: 'custom:button-card'
1410
+
color_type: label-card
1411
+
icon: mdi:home
1412
+
name: Go To Home
1413
+
tap_action:
1414
+
action: navigate
1415
+
navigation_path: /lovelace/0
1416
+
```
1417
+
1418
+
The `navigation_path` also accepts any Home Assistant internal URL such as /dev-info or /hassio/dashboard for example.
1419
+
1420
+
### `icon_*_action`
1421
+
1422
+
You can configure a separate action for when clicking the icon specifically, while the card itself has a different action:
1423
+
1424
+
```yaml
1425
+
- type: 'custom:button-card'
1426
+
entity: light.living_room
1427
+
name: Living Room Light
1428
+
tap_action:
1429
+
action: toggle
1430
+
icon_tap_action:
1431
+
action: more-info
1432
+
```
1433
+
1434
+
> [!IMPORTANT]
1435
+
>
1436
+
> If any `icon_*_action` is defined, the icon will capture **all** the actions for its area. For eg. in the case below, clicking on the icon will not do anything unless you hold it. To execute `tap_action` you'll have to click outside of the icon area.
1437
+
1438
+
```yaml
1439
+
type: 'custom:button-card'
1440
+
entity: light.living_room
1441
+
name: Living Room Light
1442
+
tap_action:
1443
+
action: toggle
1444
+
icon_hold_action:
1445
+
action: more-info
1446
+
```
1447
+
1448
+
In this case, if you want to have the same action as the button also on the icon for `tap`, you'll have to define the `icon_tap_action` explicitely.
1449
+
1450
+
```yaml
1451
+
type: 'custom:button-card'
1452
+
entity: light.living_room
1453
+
name: Living Room Light
1454
+
tap_action:
1455
+
action: toggle
1456
+
icon_tap_action:
1457
+
action: toggle
1458
+
icon_hold_action:
1459
+
action: more-info
1460
+
```
1461
+
1413
1462
### Play with width, height and icon size
1414
1463
1415
1464
Through the `styles` you can specify the `width` and `height` of the card, and also the icon size through the main `size` option. Playing with icon size will growth the card unless a `height` is specified.
0 commit comments