# PhxFrontend
Helpers for rendering components from typical single-page-app frameworks from Phoenix LiveView.
Works with adapters for different frameworks, e.g.
- [Svelte adapter](https://github.com/hungry-egg/phx-frontend-svelte)
- [React adapter](https://github.com/hungry-egg/phx-frontend-react)
- [Vue adapter](https://github.com/hungry-egg/phx-frontend-vue)
## Installation
This package is [on Hex](https://hexdocs.pm/phx_frontend), so you can add`phx_frontend` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:phx_frontend, "~> 0.1.0"}
]
end
```
## Setup
Given a Phoenix app `MyApp`:
1. Import the provided components for use in heex templates
In `my_app_web.ex`:
```diff
defmodule MyAppWeb do
# ...
def html_helpers do
# ...
+ import PhxFrontend.Components
# ...
end
# ...
end
```
2. Add the provided hook to the LiveSocket
In `app.js`:
```diff
// ...
+ import { createJsAppsHook } from "phx-frontend";
// ...
let liveSocket = new LiveSocket("/live", Socket, {
// ...
hooks: {
+ jsApp: createJsAppsHook({
+ apps: {
+ // individual JS components will go here
+ }
+ })
}
});
// ...
```
## Rendering a component from LiveView
Let's say we have a React `Counter` component that we would normally use in React like so
```jsx
<Counter count={4} onIncrement={() => console.log(`Increment count!`)} />
```
1. Use the helper in your liveview:
```elixir
def render(assigns) do
~H"""
<.js_app
id="my-js-app"
component="Counter"
props={%{count: @count}}
callbacks={%{onIncrement: "increment"}}
/>
"""
end
def handle_event("increment", _params, socket) do
IO.puts("Increment count!")
{:noreply, socket}
end
```
2. Register the component using the relevant adapter
In `app.js`:
```diff
// ...
+import reactAdapter from "phx-frontend-react";
+import Counter from "path/to/react/counter/component";
let liveSocket = new LiveSocket("/live", Socket, {
// ...
hooks: {
// ...
jsApp: createJsAppsHook({
apps: {
// ...
+ Counter: reactAdapter(Counter)
},
}),
},
});
// ...
```
### Passing params to `handle_event`
By default, `handle_event` receives an empty map `%{}` for the params.
If you wish to pass params back from the js app to the liveview, refer to the documentation for the particular adapter you're using how to do this.
## Adapters
Adapters for each framework are small and easy to write for new libraries. See the top of page for some examples.