# 💕 Love.Component 💕
Fall in love with LiveComponents all over again.
Love.Component provides functionality on top of Phoenix.LiveComponent to improve developer ergonomics through a few simple conventions.
- Explicit assign **definitions** in three different buckets:
- **Props** are passed in to the component and are never updated internally
- **State** is managed entirely by the component
- **Computed** values are derived entirely from other values
- Simple **reactivity** so that computed values and other side-effects are automatically invoked when component state changes
- **Runtime checks** to ensure that everything you define has been assigned, and nothing you haven't defined isn't
## Example
```elixir
defmodule MyAppWeb.UserProfileComponent
use Phoenix.LiveComponent
use Love.Component
import Love.Component
prop :id
prop :profile
prop :show_avatar?, default: false
state :expand_details?, initial: false
computed :age
def handle_click("toggle-details", _, socket) do
{:noreply, put_state(socket, expand_details?: not socket.assigns.expand_details)}
end
@react to: :profile
def compute_age(socket) do
age = trunc(Date.diff(Date.utc_today(), socket.assigns.profile.birthday) / 365)
put_computed(socket, age: age)
end
end
```
The `:id` and `:profile` assigns are **required props**. If they are not passed in, a helpful runtime error will occur.
The `:show_avatar?` assign is an **optional prop**.
The `:expand_details?` assign is **state** and has an initial value. It can be modified via `put_state/2`.
The `:age` assign is **computed** and is set by `put_computed/2`. If we forget to set it, a helpful runtime error will occur.
The `compute_age/1` function is a **reactive callback**. It is automatically evaluated whenever any of the assigns listed in the `@react to: ...` attribute have changed. The function can react to prop changes, state changes, and even _other_ reactive callbacks.
## Gotchas
### Call `super` when overriding `mount/1` and `update/2`
Love.Component implements the LiveComponent `mount/1` and `update/2` callbacks. If your component needs to override either of these functions, `super/{1,2}` _must_ be invoked so that Live.Component can continue to work its magic.
## Installation
The package can be installed by adding `love_ex` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:love_ex, "~> 0.1.0"}
]
end
```