Corex.PasswordInput (Corex v0.1.0-alpha.29)

View Source

Phoenix implementation of Zag.js Password Input.

Examples

Minimal

<.password_input class="password-input">
  <:label>Password</:label>
  <:visible_indicator><.icon name="hero-eye" /></:visible_indicator>
  <:hidden_indicator><.icon name="hero-eye-slash" /></:hidden_indicator>
</.password_input>

Custom Error

This example assumes the import of .icon from Core Components, you are free to replace it

<.password_input field={@form[:password]} class="password-input">
  <:label>Password</:label>
  <:error :let={msg}>
    <.icon name="hero-exclamation-circle" class="icon" />
    {msg}
  </:error>
  <:visible_indicator><.icon name="hero-eye" /></:visible_indicator>
  <:hidden_indicator><.icon name="hero-eye-slash" /></:hidden_indicator>
</.password_input>

Phoenix Form Integration

When using with Phoenix forms, you must add an id to the form using the Corex.Form.get_form_id/1 function.

Controller

defmodule MyAppWeb.PageController do
  use MyAppWeb, :controller

  def home(conn, params) do
    form = Phoenix.Component.to_form(Map.get(params, "user", %{}), as: :user)
    render(conn, :home, form: form)
  end
end
<.form :let={f} as={:user} for={@form} id={get_form_id(@form)} method="post">
  <.password_input field={f[:password]} class="password-input">
    <:label>Password</:label>
    <:error :let={msg}>
      <.icon name="hero-exclamation-circle" class="icon" />
      {msg}
    </:error>
    <:visible_indicator><.icon name="hero-eye" /></:visible_indicator>
    <:hidden_indicator><.icon name="hero-eye-slash" /></:hidden_indicator>
  </.password_input>
  <button type="submit">Submit</button>
</.form>

LiveView

defmodule MyAppWeb.LoginLive do
  use MyAppWeb, :live_view

  def mount(_params, _session, socket) do
    form = to_form(%{"password" => ""}, as: :user)
    {:ok, assign(socket, :form, form)}
  end

  def render(assigns) do
    ~H"""
    <.form as={:user} for={@form} id={get_form_id(@form)}>
      <.password_input field={@form[:password]} class="password-input">
        <:label>Password</:label>
        <:error :let={msg}>
          <.icon name="hero-exclamation-circle" class="icon" />
          {msg}
        </:error>
        <:visible_indicator><.icon name="hero-eye" /></:visible_indicator>
        <:hidden_indicator><.icon name="hero-eye-slash" /></:hidden_indicator>
      </.password_input>
      <button type="submit">Submit</button>
    </.form>
    """
  end
end

With Ecto changeset

First create your schema and changeset:

defmodule MyApp.Accounts.User do
  use Ecto.Schema
  import Ecto.Changeset

  schema "users" do
    field :email, :string
    field :password, :string
    timestamps(type: :utc_datetime)
  end

  def changeset(user, attrs) do
    user
    |> cast(attrs, [:email, :password])
    |> validate_required([:email, :password])
    |> validate_length(:password, min: 8)
  end
end
defmodule MyAppWeb.UserLive do
  use MyAppWeb, :live_view
  alias MyApp.Accounts.User

  def mount(_params, _session, socket) do
    {:ok, assign(socket, :form, to_form(User.changeset(%User{}, %{})))}
  end

  def handle_event("validate", %{"user" => user_params}, socket) do
    changeset = User.changeset(%User{}, user_params)
    {:noreply, assign(socket, form: to_form(changeset, action: :validate))}
  end

  def render(assigns) do
    ~H"""
    <.form for={@form} id={get_form_id(@form)} phx-change="validate">
      <.password_input field={@form[:password]} class="password-input">
        <:label>Password</:label>
        <:error :let={msg}>
          <.icon name="hero-exclamation-circle" class="icon" />
          {msg}
        </:error>
        <:visible_indicator><.icon name="hero-eye" /></:visible_indicator>
        <:hidden_indicator><.icon name="hero-eye-slash" /></:hidden_indicator>
      </.password_input>
    </.form>
    """
  end
end

Styling

Use data attributes to target elements:

[data-scope="password-input"][data-part="root"] {}
[data-scope="password-input"][data-part="label"] {}
[data-scope="password-input"][data-part="control"] {}
[data-scope="password-input"][data-part="input"] {}
[data-scope="password-input"][data-part="visibility-trigger"] {}
[data-scope="password-input"][data-part="indicator"] {}

If you wish to use the default Corex styling, you can use the class password-input on the component. This requires to install Mix.Tasks.Corex.Design first and import the component css file.

@import "../corex/main.css";
@import "../corex/tokens/themes/neo/light.css";
@import "../corex/components/password-input.css";

You can then use modifiers

<.password_input class="password-input password-input--accent password-input--lg">
  <:visible_indicator><.icon name="hero-eye" /></:visible_indicator>
  <:hidden_indicator><.icon name="hero-eye-slash" /></:hidden_indicator>
</.password_input>

Learn more about modifiers and Corex Design

Summary

Components

password_input(assigns)

Attributes

  • id (:string)
  • visible (:boolean) - Defaults to false.
  • controlled_visible (:boolean) - Defaults to false.
  • disabled (:boolean) - Defaults to false.
  • invalid (:boolean) - Defaults to false.
  • read_only (:boolean) - Defaults to false.
  • required (:boolean) - Defaults to false.
  • ignore_password_managers (:boolean) - Defaults to true.
  • name (:string)
  • form (:string)
  • dir (:string) - Defaults to nil.Must be one of nil, "ltr", or "rtl".
  • auto_complete (:string) - Defaults to "current-password". Must be one of "current-password", or "new-password".
  • on_visibility_change (:string) - Defaults to nil.
  • on_visibility_change_client (:string) - Defaults to nil.
  • errors (:list) - List of error messages to display. Defaults to [].
  • field (Phoenix.HTML.FormField) - A form field struct retrieved from the form, for example: @form[:password]. Automatically sets id, name, form, invalid state, and errors from the form field.
  • Global attributes are accepted.

Slots

  • label
  • error - Accepts attributes:
    • class (:string)
  • visible_indicator - Icon shown when password is visible.
  • hidden_indicator - Icon shown when password is hidden.