View Source 💕 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

Example

defmodule MyAppWeb.UserProfileComponent
  use Phoenix.LiveComponent
  use Love.Component
  import Love.Component

  prop :profile
  prop :show_avatar?, default: false

  state :expand_details?, default: false

  computed :age

  slot :inner_block

  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 :profile assign is a required prop. If it is not passed in, a helpful runtime error will occur.

The :id assign is also a required prop, but it is implicitly defined, because every LiveComponent requires an :id.

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 :inner_block assign is a required slot prop. It is defined and used just a regular prop. A slot prop can be made optional with the default: [] option.

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

Gotchas

call-super-when-overriding-mount-1-and-update-2

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 Love.Component can continue to work its magic.

installation

Installation

The package can be installed by adding love_ex to your list of dependencies in mix.exs:

def deps do
  [
    {:love_ex, "~> 0.1.0"}
  ]
end