implemented floating labels on inputs & selects, with icons

This commit is contained in:
Adam Piontek 2021-03-07 17:17:16 -05:00
parent 74678bd3ad
commit 89d9bc0cce
10 changed files with 199 additions and 202 deletions

View file

@ -17,9 +17,8 @@ import "../node_modules/bootstrap-icons/icons/at.svg"; // email field
import "../node_modules/bootstrap-icons/icons/key.svg"; // new password field
import "../node_modules/bootstrap-icons/icons/key-fill.svg"; // pw confirm field
import "../node_modules/bootstrap-icons/icons/lock.svg"; // current pw field
import "../node_modules/bootstrap-icons/icons/shield-shaded.svg"; // role
import "../node_modules/bootstrap-icons/icons/shield.svg"; // role
// live tables
import "../node_modules/bootstrap-icons/icons/filter.svg";
import "../node_modules/bootstrap-icons/icons/backspace.svg"; // clear filter
import "../node_modules/bootstrap-icons/icons/sort-down-alt.svg";
import "../node_modules/bootstrap-icons/icons/sort-up-alt.svg";

View file

@ -9,42 +9,42 @@
<%= form_for @changeset, "#", [phx_change: :validate, phx_submit: :save, novalidate: true, id: "reg_form"], fn f -> %>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :email) %>">
<%= label f, :email, class: "form-label" %>
<div class="input-group has-validation">
<span class="input-group-text">
<%= icon_div @socket, "bi-at", [class: "icon"] %>
</span>
<%= email_input f, :email,
value: input_value(f, :email),
class: input_class(f, :email, "form-control"),
placeholder: "e.g., babka@73k.us",
maxlength: User.max_email,
autofocus: true,
phx_debounce: "blur",
aria_describedby: error_ids(f, :email)
%>
<%= error_tag f, :email %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :email) %>">
<%= email_input f, :email,
value: input_value(f, :email),
class: input_class(f, :email, "form-control"),
placeholder: "e.g., babka@73k.us",
maxlength: User.max_email,
autofocus: true,
phx_debounce: "blur",
aria_describedby: error_ids(f, :email)
%>
<%= label f, :email do %>
<%= icon_div @socket, "bi-at", [class: "icon baseline text-muted"] %>
Email
<% end %>
<%= error_tag f, :email %>
</div>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :password) %>">
<%= label f, :password, class: "form-label" %>
<div class="input-group has-validation">
<span class="input-group-text">
<%= icon_div @socket, "bi-key", [class: "icon"] %>
</span>
<%= password_input f, :password,
value: input_value(f, :password),
class: input_class(f, :password, "form-control"),
maxlength: User.max_password,
phx_debounce: "250",
aria_describedby: error_ids(f, :password)
%>
<%= error_tag f, :password %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :password) %>">
<%= password_input f, :password,
value: input_value(f, :password),
class: input_class(f, :password, "form-control"),
placeholder: "Password",
maxlength: User.max_password,
phx_debounce: "250",
aria_describedby: error_ids(f, :password)
%>
<%= label f, :password do %>
<%= icon_div @socket, "bi-key", [class: "icon baseline text-muted"] %>
Password
<% end %>
<%= error_tag f, :password %>
</div>
<div class="mb-3">
<%= submit (@trigger_submit && "Saving..." || "Register"),
class: "btn btn-primary",

View file

@ -9,39 +9,39 @@
<%= form_for @changeset, "#", [phx_change: :validate, phx_submit: :save, novalidate: true, id: "pw_reset_form"], fn f -> %>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :password) %>">
<%= label f, :password, "New password", class: "form-label" %>
<div class="input-group has-validation">
<span class="input-group-text">
<%= icon_div @socket, "bi-key", [class: "icon"] %>
</span>
<%= password_input f, :password,
value: input_value(f, :password),
class: input_class(f, :password, "form-control"),
maxlength: User.max_password,
autofocus: true,
aria_describedby: error_ids(f, :password)
%>
<%= error_tag f, :password %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :password) %>">
<%= password_input f, :password,
value: input_value(f, :password),
class: input_class(f, :password, "form-control"),
placeholder: "New Password",
maxlength: User.max_password,
autofocus: true,
aria_describedby: error_ids(f, :password)
%>
<%= label f, :password do %>
<%= icon_div @socket, "bi-key", [class: "icon baseline text-muted"] %>
New password
<% end %>
<%= error_tag f, :password %>
</div>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :password_confirmation) %>">
<%= label f, :password_confirmation, "Confirm new password", class: "form-label" %>
<div class="input-group has-validation">
<span class="input-group-text">
<%= icon_div @socket, "bi-key-fill", [class: "icon"] %>
</span>
<%= password_input f, :password_confirmation,
value: input_value(f, :password_confirmation),
class: input_class(f, :password_confirmation, "form-control"),
maxlength: User.max_password,
aria_describedby: error_ids(f, :password_confirmation)
%>
<%= error_tag f, :password_confirmation %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :password_confirmation) %>">
<%= password_input f, :password_confirmation,
value: input_value(f, :password_confirmation),
class: input_class(f, :password_confirmation, "form-control"),
placeholder: "Confirm new password",
maxlength: User.max_password,
aria_describedby: error_ids(f, :password_confirmation)
%>
<%= label f, :password do %>
<%= icon_div @socket, "bi-key-fill", [class: "icon baseline text-muted"] %>
Confirm new password
<% end %>
<%= error_tag f, :password_confirmation %>
</div>
<div class="mb-3">
<%= submit "Reset password",
class: "btn btn-primary",

View file

@ -4,40 +4,39 @@
<%= form_for @changeset, "#", [phx_change: :validate, phx_submit: :save, phx_target: @myself], fn f -> %>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :email) %>">
<%= label f, :email, class: "form-label" %>
<div class="input-group has-validation">
<span class="input-group-text">
<%= icon_div @socket, "bi-at", [class: "icon"] %>
</span>
<%= email_input f, :email,
value: input_value(f, :email),
class: input_class(f, :email, "form-control"),
placeholder: "e.g., babka@73k.us",
maxlength: User.max_email,
phx_debounce: "500",
aria_describedby: error_ids(f, :email)
%>
<%= error_tag f, :email %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :email) %>">
<%= email_input f, :email,
value: input_value(f, :email),
class: input_class(f, :email, "form-control"),
placeholder: "e.g., babka@73k.us",
maxlength: User.max_email,
phx_debounce: "500",
aria_describedby: error_ids(f, :email)
%>
<%= label f, :email do %>
<%= icon_div @socket, "bi-at", [class: "icon baseline text-muted"] %>
Email
<% end %>
<%= error_tag f, :email %>
</div>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :current_password) %>">
<%= label f, :current_password, class: "form-label" %>
<div class="input-group">
<span class="input-group-text">
<%= icon_div @socket, "bi-lock", [class: "icon"] %>
</span>
<%= password_input f, :current_password,
value: input_value(f, :current_password),
class: "form-control",
aria_describedby: error_ids(f, :current_password)
%>
<%= error_tag f, :current_password %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :current_password) %>">
<%= password_input f, :current_password,
value: input_value(f, :current_password),
class: "form-control",
placeholder: "Current Password",
aria_describedby: error_ids(f, :current_password)
%>
<%= label f, :current_password do %>
<%= icon_div @socket, "bi-lock", [class: "icon baseline text-muted"] %>
Current password
<% end %>
<%= error_tag f, :current_password %>
</div>
<div class="mb-3">
<%= submit "Change email",
class: "btn btn-primary",

View file

@ -4,52 +4,52 @@
<%= form_for @changeset, "#", [phx_change: :validate, phx_submit: :save, phx_target: @myself], fn f -> %>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :password) %>">
<%= label f, :password, "New password", class: "form-label" %>
<div class="input-group has-validation">
<span class="input-group-text">
<%= icon_div @socket, "bi-key", [class: "icon"] %>
</span>
<%= password_input f, :password,
value: input_value(f, :password),
class: input_class(f, :password, "form-control"),
maxlength: User.max_password,
phx_debounce: "500",
aria_describedby: error_ids(f, :password)
%>
<%= error_tag f, :password %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :password) %>">
<%= password_input f, :password,
value: input_value(f, :password),
class: input_class(f, :password, "form-control"),
placeholder: "New Password",
maxlength: User.max_password,
phx_debounce: "500",
aria_describedby: error_ids(f, :password)
%>
<%= label f, :password do %>
<%= icon_div @socket, "bi-key", [class: "icon baseline text-muted"] %>
New password
<% end %>
<%= error_tag f, :password %>
</div>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :password_confirmation) %>">
<%= label f, :password_confirmation, "Confirm new password", class: "form-label" %>
<div class="input-group has-validation">
<span class="input-group-text">
<%= icon_div @socket, "bi-key-fill", [class: "icon"] %>
</span>
<%= password_input f, :password_confirmation,
value: input_value(f, :password_confirmation),
class: input_class(f, :password_confirmation, "form-control"),
maxlength: User.max_password,
aria_describedby: error_ids(f, :password_confirmation)
%>
<%= error_tag f, :password_confirmation %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :password_confirmation) %>">
<%= password_input f, :password_confirmation,
value: input_value(f, :password_confirmation),
class: input_class(f, :password_confirmation, "form-control"),
placeholder: "Confirm new password",
maxlength: User.max_password,
aria_describedby: error_ids(f, :password_confirmation)
%>
<%= label f, :password_confirmation do %>
<%= icon_div @socket, "bi-key-fill", [class: "icon baseline text-muted"] %>
Confirm new password
<% end %>
<%= error_tag f, :password_confirmation %>
</div>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :current_password) %>">
<%= label f, :current_password, class: "form-label" %>
<div class="input-group">
<span class="input-group-text">
<%= icon_div @socket, "bi-lock", [class: "icon"] %>
</span>
<%= password_input f, :current_password,
value: input_value(f, :current_password),
class: "form-control",
aria_describedby: error_ids(f, :current_password)
%>
<%= error_tag f, :current_password %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :current_password) %>">
<%= password_input f, :current_password,
value: input_value(f, :current_password),
class: "form-control",
placeholder: "Current Password",
aria_describedby: error_ids(f, :current_password)
%>
<%= label f, :current_password do %>
<%= icon_div @socket, "bi-lock", [class: "icon baseline text-muted"] %>
Current password
<% end %>
<%= error_tag f, :current_password %>
</div>
<div class="mb-3">

View file

@ -6,32 +6,49 @@
<div class="modal-body">
<div class="mb-3" phx-feedback-for="<%= input_id(f, :email)%>">
<%= label f, :email, class: "form-label" %>
<div class="input-group has-validation">
<span class="input-group-text">
<%= icon_div @socket, "bi-at", [class: "icon"] %>
</span>
<%= email_input f, :email,
value: input_value(f, :email),
class: input_class(f, :email, "form-control"),
placeholder: "e.g., babka@73k.us",
maxlength: User.max_email,
autofocus: true,
phx_debounce: "250",
aria_describedby: error_ids(f, :email)
%>
<%= error_tag f, :email %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :email) %>">
<%= email_input f, :email,
value: input_value(f, :email),
class: input_class(f, :email, "form-control"),
placeholder: "e.g., babka@73k.us",
maxlength: User.max_email,
autofocus: true,
phx_debounce: "250",
aria_describedby: error_ids(f, :email)
%>
<%= label f, :email do %>
<%= icon_div @socket, "bi-at", [class: "icon baseline text-muted"] %>
Email
<% end %>
<%= error_tag f, :email %>
</div>
<div class="form-floating mb-3" phx-feedback-for="<%= input_id(f, :password) %>">
<%= password_input f, :password,
value: input_value(f, :password),
class: input_class(f, :password, "form-control"),
placeholder: "Password",
maxlength: User.max_password,
aria_describedby: error_ids(f, :password)
%>
<%= label f, :password do %>
<%= icon_div @socket, "bi-key", [class: "icon baseline text-muted"] %>
Password
<% end %>
<%= error_tag f, :password %>
</div>
<%= if Roles.can?(@current_user, %User{}, :edit_role) do %>
<%= label f, :role, class: "form-label" %>
<div class="input-group mb-3">
<span class="input-group-text">
<%= icon_div @socket, "bi-shield-shaded", [class: "icon"] %>
</span>
<div class="form-floating">
<%= select f, :role, Enum.map(User.roles(), fn {k, _v} -> {String.capitalize(Atom.to_string(k)), k} end), class: "form-select" %>
<%= label f, :role do %>
<%= icon_div @socket, "bi-shield", [class: "icon baseline text-muted"] %>
User role
<% end %>
<span class="valid-feedback text-primary" style="display: block;">
<%= role_description(input_value(f, :role)) %>
</span>
@ -40,21 +57,6 @@
<%= hidden_input f, :role, value: input_value(f, :role) %>
<% end %>
<div phx-feedback-for="<%= input_id(f, :password) %>">
<%= label f, :password, class: "form-label" %>
<div class="input-group has-validation">
<span class="input-group-text">
<%= icon_div @socket, "bi-key", [class: "icon"] %>
</span>
<%= password_input f, :password,
value: input_value(f, :password),
class: input_class(f, :password, "form-control"),
maxlength: User.max_password,
aria_describedby: error_ids(f, :password)
%>
<%= error_tag f, :password %>
</div>
</div>
</div>
<div class="modal-footer">

View file

@ -33,18 +33,12 @@
<%= form_for :filter, "#", [phx_change: "filter-change"], fn flt -> %>
<div class="input-group">
<span class="input-group-text">
<%= icon_div @socket, "bi-filter", [class: "icon"] %>
</span>
<%= text_input flt, :filter, name: "filter", class: "form-control", placeholder: "Filter users...", value: @query.filter %>
</button>
<%= if @query.filter == "" do %>
<button class="btn btn-outline-secondary" type="button" aria-label="Clear filter" aria-disabled="true" disabled>
<button class="btn btn-outline-primary" type="button" aria-label="Clear filter" aria-disabled="true" disabled>
<% else %>
<button class="btn btn-outline-secondary" type="button" aria-label="Clear filter" phx-click="filter-clear">
<button class="btn btn-primary" type="button" aria-label="Clear filter" phx-click="filter-clear">
<% end %>
<%= icon_div @socket, "bi-backspace", [class: "icon baseline"], [role: "img", aria_hidden: false] %>
</button>

View file

@ -9,11 +9,7 @@
<%= form_for :user, Routes.user_confirmation_path(@conn, :create), [class: "needs-validation", novalidate: true], fn f -> %>
<%= label f, :email, class: "form-label" %>
<div class="input-group has-validation mb-3">
<span class="input-group-text">
<%= icon_div @conn, "bi-at", [class: "icon fs-5"] %>
</span>
<div class="form-floating mb-3">
<%= email_input f, :email,
value: @current_user && @current_user.email || "",
placeholder: "e.g., babka@73k.us",
@ -22,6 +18,10 @@
required: true,
autofocus: !@current_user
%>
<%= label f, :email do %>
<%= icon_div @conn, "bi-at", [class: "icon baseline text-muted"] %>
Email
<% end %>
<span class="invalid-feedback">must be a valid email address</span>
</div>

View file

@ -9,18 +9,17 @@
<%= form_for :user, Routes.user_reset_password_path(@conn, :create), [class: "needs-validation", novalidate: true], fn f -> %>
<%= label f, :email, class: "form-label" %>
<div class="input-group has-validation mb-3">
<span class="input-group-text">
<%= icon_div @conn, "bi-at", [class: "icon"] %>
</span>
<div class="form-floating mb-3">
<%= email_input f, :email,
placeholder: "e.g., babka@73k.us",
class: "form-control",
placeholder: "e.g., babka@73k.us",
maxlength: User.max_email,
required: true,
autofocus: true
required: true
%>
<%= label f, :email do %>
<%= icon_div @conn, "bi-at", [class: "icon baseline text-muted"] %>
Email
<% end %>
<span class="invalid-feedback">must be a valid email address</span>
</div>

View file

@ -15,32 +15,36 @@
</div>
<% end %>
<%= label f, :email, class: "form-label" %>
<div class="input-group has-validation mb-3">
<span class="input-group-text">
<%= icon_div @conn, "bi-at", [class: "icon"] %>
</span>
<div class="form-floating mb-3">
<%= email_input f, :email,
class: "form-control",
placeholder: "e.g., babka@73k.us",
maxlength: User.max_email,
required: true
%>
<%= label f, :email do %>
<%= icon_div @conn, "bi-at", [class: "icon baseline text-muted"] %>
Email
<% end %>
<span class="invalid-feedback">must be a valid email address</span>
</div>
<%= label f, :password, class: "form-label" %>
<div class="input-group has-validation mb-3">
<span class="input-group-text">
<%= icon_div @conn, "bi-lock", [class: "icon"] %>
</span>
<div class="form-floating mb-3">
<%= password_input f, :password,
class: "form-control",
placeholder: "Password",
required: true
%>
<%= label f, :password do %>
<%= icon_div @conn, "bi-lock", [class: "icon baseline text-muted"] %>
Password
<% end %>
<span class="invalid-feedback">password is required</span>
</div>
<div class="form-check mb-3 no-valid-style">
<%= checkbox f, :remember_me, class: "form-check-input" %>
<%= label f, :remember_me, "Keep me logged in for 60 days", class: "form-check-label" %>