View Source Love.Component (love_ex v0.2.0)
Extend LiveComponents.
usage
Usage
Add use Love.Component
to a Phoenix.LiveComponent
. This adds:
@behaviour Love.Events
for the optionalLove.Events.handle_message/4
callbackimport Love.Component
to make macros and functions locally availableprop :id
to define the required:id
prop assignmount/1
andupdate/2
default implementations (can safely overriden)
love-component-example
Love.Component Example
defmodule MyAppWeb.UserProfileComponent do
use Phoenix.LiveComponent
use Love.Component
prop :profile
prop :show_avatar?, default: false
state :age
state :expand_details?, default: false
slot :inner_block
event :on_selected
def handle_event("toggle-details", _, socket) do
{:noreply, put_state(socket, socket, expand_details?: not socket.assigns.expand_details?)}
end
def handle_event("select", %{"profile_id" => profile_id}}, socket) do
{:noreply, emit(socket, :on_selected, profile_id)}
end
@react to: :profile
defp put_age(socket) do
age = trunc(Date.diff(Date.utc_today(), socket.assigns.profile.birthday) / 365)
put_state(socket, age: age)
end
end
Link to this section Summary
Field Definitions
Defines an event prop.
Defines a prop.
Defines a slot prop.
Defines a state assign.
Link to this section Field Definitions
@spec event(name :: atom()) :: nil
Defines an event prop.
Event props are always optional, and default to nil
.
The value of this prop must be a destination to receive the event, either a PID or {module, id}
.
See emit/3
for details on raising events.
The emitted event name defaults to the name of the event prop. The event name can be overridden
by the parent specifying {pid, :my_custom_event_name}
or {module, id, :my_custom_event_name}
.
example
Example
event :on_selected
# To raise it:
emit(socket, :on_selected, "some payload")
# To handle it:
handle_event(:on_selected, {module, id}, "some payload", socket)
Defines a prop.
prop :id
is automatically defined as a required prop for all components that use Love.Component
,
because every stateful LiveComponent
requires an :id
.
options
Options
:default
- optional; if specified, this prop is considered optional, and will be assigned the default value during mount. If not specified, the prop is considered required.nil
is a valid default value. The expression for the default value is wrapped in a function and its evaluation is deferred until runtime at the moment the component is mounted.
example
Example
# A required prop
prop :visible?
# An optional prop
prop :thumbnail_url, default: nil
Defines a slot prop.
options
Options
:required?
- defaults totrue
. Whenfalse
, the prop given the empty slot value of[]
example
Example
# Default slot name
slot :inner_block
# Optional slot
slot :navbar, required?: false
Defines a state assign.
State is internal to the component and is modified via put_state/2
.
options
Options
:default
- optional; if specified, the state will be assigned the default value during mount. The expression for the default value is wrapped in a function and its evaluation is deferred until runtime at the moment the component is mounted. If not specified, you shouldput_state/2
during component initialization to set an initial value.
example
Example
# State with no initial value
state :changeset
# State with an initial value, evaluated during mount
state :now, default: DateTime.utc_now()
Link to this section Functions
@spec emit(Phoenix.LiveView.Socket.t(), name :: atom(), payload :: any()) :: Phoenix.LiveView.Socket.t()
Sends an event message.
The event name
is an event prop defined by event/1
. The destination for the event is determined
by the value of the event prop. See Love.Events.send_message/4
for details on valid destinations.
@spec put_state(Phoenix.LiveView.Socket.t(), map() | keyword()) :: Phoenix.LiveView.Socket.t()
Updates state assigns.
When called outside of a reactive function, any reactive functions that depend on the changed
state will be immediately evaluated, so call this function as infrequently as possible. In
other words, try to batch state changes and limit put_state/2
calls to once per lifecycle event.
Within a reactive function, any additionally-triggered reactive functions will be deferred until after the current reactive function completely executes.
Returns the socket with the new state and after any reactive callbacks have run.
example
Example
state :first_name
put_state(socket, first_name: "Marvin")