## Overview
The `WebComponentHook` is a custom Phoenix LiveView hook that enables seamless integration between custom web components and Phoenix LiveView. It provides a declarative way to handle bidirectional communication between your web components and LiveView server.
## Installation
### 1. Import the Hook
```js
import "phoenix_duskmoon";
const WebComponentHook = window.__WebComponentHook__;
const liveSocket = new LiveSocket("/live", Socket, {
hooks: { WebComponentHook }
});
```
### 2. Import CSS
```css
import "phoenix_duskmoon/css"
```
## Features
### 📤 Sending Events to LiveView
Use the `darkmoon-send-*` attributes to send custom events from your web components to LiveView:
```html
<!-- Basic event sending -->
<Element
darkmoon-send-sync-content="load_content"
phx-hook="WebComponentHook"
/>
<!-- Event with callback -->
<Element
darkmoon-send-sync-content="load_content;loadAccepted"
phx-hook="WebComponentHook"
/>
```
**How it works:**
- When the element triggers a `sync-content` custom event, it automatically sends `load_content` to LiveView via `pushEvent`
- The second example includes a callback (`loadAccepted`) that will be invoked on the element when the server responds
### 📥 Receiving Events from LiveView
Use the `darkmoon-receive-*` attributes to handle events sent from LiveView to your web components:
```html
<!-- Explicit method mapping -->
<Element
darkmoon-receive-update_content="updateContent"
phx-hook="WebComponentHook"
/>
<!-- Shorthand - same event name -->
<Element
darkmoon-receive="update_content;updateContent"
phx-hook="WebComponentHook"
/>
<!-- Auto-mapping - triggers same event on element -->
<Element
darkmoon-receive-update_content=""
phx-hook="WebComponentHook"
/>
```
**How it works:**
- When LiveView fires an `update_content` event, the hook triggers the corresponding method on the element
- If the method name is empty, it triggers an event with the same name on the element
- Supports multiple event mappings separated by semicolons
## Advanced Usage
### Multiple Event Mappings
```html
<Element
darkmoon-send-click="button_clicked;handleClick"
darkmoon-send-change="value_changed;handleChange"
darkmoon-receive-data="updateData;refreshUI"
darkmoon-receive-status="updateStatus"
phx-hook="WebComponentHook"
/>
```
### LiveView Integration
```elixir
defmodule MyAppWeb.LiveComponent do
use Phoenix.LiveComponent
def update(assigns, socket) do
{:ok, socket}
end
def handle_event("button_clicked", %{"data" => data}, socket) do
# Process the data
{:noreply, push_event(socket, "updateData", %{result: processed_data})}
end
def handle_event("value_changed", %{"value" => value}, socket) do
{:noreply, push_event(socket, "updateStatus", %{status: "updated"})}
end
end
```
## Best Practices
✅ **Do:**
- Use descriptive event names
- Implement proper error handling in your web components
- Keep event payloads small for better performance
- Use TypeScript for better type safety
❌ **Don't:**
- Send sensitive data through events
- Create circular event loops
- Overload single elements with too many event mappings
## Troubleshooting
**Hook not working?**
- Ensure `phoenix_duskmoon` is imported before creating the LiveSocket
- Verify the element has `phx-hook="WebComponentHook"`
- Check browser console for JavaScript errors
**Events not firing?**
- Verify custom event names match exactly
- Check that the element actually triggers the specified custom events
- Use `console.log` to debug event flow