Skip to content

Conversation

dcapslock
Copy link
Collaborator

Need to intercept Frontend haptics to be able to use custom. Otherwise custom haptics may not apply.

Best method would have been to intercept the forwardHaptic events. However since they are fired at window, its impossible to capture.

Next best method is to intercept the three type of calls:

  1. navigator.vibrate - perhaps used on devices when not using App.
  2. Android external app messaging
  3. webkit (iOS) external app messaging

See homeassistant.ts types for link to Frontend external messaging code.

Intercept is temporary as we have no idea of what the latest state of the messaging interfaces are. Binding methods is critical espeically with Anroid as these are created by companion app java interface and it will complain otherwise.

dependabot bot and others added 12 commits September 17, 2025 13:57
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.

Fixes custom-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]>
## [5.0.0-dev.1](custom-cards/button-card@v4.3.0...v5.0.0-dev.1) (2025-09-16)

### ⚠ BREAKING CHANGES

* **color:** Card background color will always be `var
(--card-background-color)` when state is inactive and `color_type:
card`. You can set card background with state.

### Features

* Add `icon_*_action` support ([custom-cards#984](custom-cards#984)) ([4e02887](custom-cards@4e02887)), closes [custom-cards#739](custom-cards#739)
* Support update timer ([custom-cards#981](custom-cards#981)) ([4717feb](custom-cards@4717feb)), closes [custom-cards#436](custom-cards#436)

### Bug Fixes

* **color:** inactive card background no longer inactive color when `colour_type: card` and `color` set. ([custom-cards#987](custom-cards#987)) ([b4f00f9](custom-cards@b4f00f9)), closes [custom-cards#754](custom-cards#754)
* Embedded light card handle issue ([custom-cards#989](custom-cards#989)) ([d01ef37](custom-cards@d01ef37)), closes [custom-cards#427](custom-cards#427) [custom-cards#901](custom-cards#901)
* Hold action on picture entity ([custom-cards#996](custom-cards#996)) ([9f2501f](custom-cards@9f2501f)), closes [custom-cards#994](custom-cards#994)
* Move while hold on touch devices ([custom-cards#993](custom-cards#993)) ([2c17386](custom-cards@2c17386))
Update dev to haptics-2
Merge dev to haptics-2
@dcapslock
Copy link
Collaborator Author

@RomRider draft for now so you can see this solution. Confirming there is no way that the browser events can be captured as testing shows that as the target is window, the event phase goes straight to target and bubbling listeners are fired before capture. So intercepting function/app calls is next best. I have tested quite robustly, and am happy that this will work, and only gets used if user sets haptic: so if the code would for some reason break then users just remove haptic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants