This library helps you write encapsulated bits of HTML into a single unit called component in your server rendered Phoenix web site. Similar to how react/ember/web components do.
You can generate a new component with the built-in generator
$ mix phx.gen.component Button
* creating lib/app_web/components/button/view.ex
* creating lib/app_web/components/button/template.html.eex
* creating test/app_web/components/button_test.exs
Then you can use the new component in a template
# lib/app_web/views/page_view.ex
defmodule AppWeb.PageView do
use AppWeb, :view
use PhoenixComponents.View, namespace: AppWeb.Components
import_components [:button]
# you can also import from specific module, like external dependencies
import_components [:button], from: AwesomeComponentLibrary
end
# lib/app_web/templates/page/show.html.eex
<%= button type: :primary do %>
My cool button!
<% end %>
With the corresponding component definition
# lib/app_web/components/button/view.ex
defmodule AppWeb.Components.Button do
use PhoenixComponents.Component, namespace: AppWeb.Components,
root: "lib/app_web/components"
def class_for_type(type) do
"btn btn--" <> to_string(type)
end
end
# lib/app_web/components/button/template.html.eex
<button class="<%= class_for_type @attrs.type %>">
<%= @content %>
</button>
Add phoenix_components
to your mix.exs
deps:
def deps do
[{:phoenix_components, "~> 1.0.0"}]
end
If you're running Elixir 1.3 or lower, don't forget to add it under you applications list in mix.exs
def application do
[applications: [:phoenix_components]]
end
This is a quick overview of how to create and use a component in your application.
After installing the dependency you need to configure your application.
You can do this by adding this line to your lib/app_web.ex
file
Look for the line def view do
and update it to include the following:
def view do
quote do
use Phoenix.View, root: "lib/app_web/components"
namespace: AppWeb
# add this line
use PhoenixComponents.View, namespace: AppWeb.Components
..
end
# add this helper for components, usage example: `use AppWeb, :component`
def component do
quote do
use PhoenixComponents.Component, namespace: AppWeb.Components,
root: "lib/app_web/components"
end
end
Add components pattern to your live_reload config.
config :app, AppWeb.Endpoint,
live_reload: [
patterns: [
~r{priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$},
~r{priv/gettext/.*(po)$},
~r{lib/app_web/views/.*(ex)$},
~r{lib/app_web/templates/.*(eex)$},
~r{lib/app_web/components/*/.*(eex)$} # add this line
]
]
Phoenix components are defined by two different parts, a view and a template. The view contains helper functions and the template contains the HTML.
To create a button component you need to create the view file
lib/app_web/components/button/view.ex
with the following content
defmodule AppWeb.Components.Button do
use AppWeb, :component
def classes do
"btn btn-default"
end
end
Then create the template file lib/app_web/components/button/template.html.eex
with the following content
<button class="<%= classes %>">
<%= @content %>
</button>
Note that @content
variable will contain the content defined inside the button
block. Next section shows this in more detail.
You can use the component from any template by using the helper function
component
.
In any template, e.g. web/templates/pages/show.html.eex
add the button
component.
<%= component :button do %>
My cool button!
<% end %>
The content inside the component block is passed to the component as the
@content
variable.
You can import the components in any view by using the import_components
function. This allows you to avoid having to call component
helper and instead
just use the name of the component.
defmodule AppWeb.PageView do
use Phoenix.Web, :view
import_components [:button, :jumbotron]
end
Then you can use these helpers from your templates
<%= button type: :submit do %>
Submit form!
<% end %>
When calling a component you can pass any attribute you like.
<%= button type: :submit do %>
Submit form!
<% end %>
Inside the component's template these attributes are going to be available in
the @attrs
map.
<button type="<%= @attrs.type %>">
<%= @content %>
</button>
phoenix_components is licensed under the MIT license.
See LICENSE for the full license text.