Skip to content
This repository has been archived by the owner on Oct 7, 2021. It is now read-only.
/ viewplex Public archive

A convenience library that allows you to further separate your views into scoped components

License

Notifications You must be signed in to change notification settings

thiagomajesk/viewplex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Viewplex

A convenience library that allows you to further separate your views into scoped components.

Installation

Add viewplex to your list of dependencies in mix.exs:

def deps do
  [
    {:viewplex, "~> 0.3.0"}
  ]
end

Documentation can be be found at https://hexdocs.pm/viewplex.

Usage

Components

Create new components by use-ing the Viewplex.Component module and creating a corresponding template with the same name:

lib/my_app_web/components/label_component.ex:

defmodule LabelComponent do
  use Viewplex.Component
end

lib/my_app_web/components/label_component.html.eex:

Hello World!

You can also use inline templates:

defmodule LabelComponent do
  use Viewplex.Component

  def render(_assigns), do: ~E"Hello World"
end

Then, call your component inside a template:

<%= component LabelComponent %>

Remember to import Viewplex.Helpers in your views.

Naming Conventions

Components should follow the same convention as Elixir modules.
So, if you have a MyAppWeb.Components.LabelComponent module, the file should be located at: my_app_web/components/label_component.ex. We also support (and encourage) prefixing the component module name with "Component", following the existant naming convention for Phoenix's views and controllers.

Filtering assigns

Like Structs, Components can also define fields:

defmodule LabelComponent do
  use Viewplex.Component, [:message]
end
<%= component LabelComponent, message: "Hello World" %>

Fields defined in the component will be available as an assign in your template:

<label><%= @message %></label>

This should allow you to simply pass down a map of assigns that will be filtered before actually invoking the component:

<%= component LabelComponent, assigns %>

Content blocks and slots

You can also pass aditional content to your components in two ways:

Inline:

<%= component LabelComponent, "Hello World" %>

Or using do-blocks:

<%= component LabelComponent do %>
  Hello World
<% end %>

Content passed like this will be available as an assign under the :content key:

<label><%= @content ></label>

Using named slots:

<%= component LabelComponent do %>
  <% slot(:message, "Hello World") %>
<% end %>
<label><%= @slots.message ></label>

Notice that we are using <% instead of <%=. This is necessary because if you output the return of the slot/2 function, you'll actually be rendering its content inside the component's block.
This happens because Viewplex will scan the component block for slot/2 function calls and then extract the slot content so it is available in the template. This means that if you pre-render the slot in any form we won't be able to extract the proper values.

Mouting

You can also customize how components are mounted by overriding the mount/1 function:

defmodule LabelComponent do
  use Viewplex.Component, [:message]

  def mount(assigns) do
    user = Users.get_user(assigns.user_id)
    {:ok, Map.put(assigns, :user, user)}
  end

end

Or disabling the component entirely by returning an {:error, reason} tuple:

defmodule LabelComponent do
  use Viewplex.Component, [:message]

  def mount(assigns) do
    case Users.get_user(assigns.user_id) do
      nil -> {:error, "could not fetch user"}
      user ->  {:ok, Map.put(assigns, :user, user)}
    end   
  end
end

Todo's

  • Improve documentation
  • Add real use-cases as examples
  • Improve function typespecs
  • Publish to Hex
  • Scaffold and setup tasks
  • Component documentation generation
  • Add test samples to README
  • Log mount errors using Logger

About

A convenience library that allows you to further separate your views into scoped components

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published