styling improvements, including implementing alerts with phx hook to clear flash after bootstrap alert close event
This commit is contained in:
parent
9ddb8e3978
commit
951249be93
12 changed files with 100 additions and 18 deletions
|
@ -10,3 +10,5 @@ $font-family-sans-serif: Lato, system-ui, -apple-system, "Segoe UI", Roboto,
|
||||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important;
|
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important;
|
||||||
// $font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas,
|
// $font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas,
|
||||||
// "Liberation Mono", "Courier New", monospace !important;
|
// "Liberation Mono", "Courier New", monospace !important;
|
||||||
|
|
||||||
|
$enable-shadows: true;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// @import "../node_modules/@fontsource/lato/300-italic.css"; /* light | italic */
|
// @import "../node_modules/@fontsource/lato/300-italic.css"; /* light | italic */
|
||||||
@import "../node_modules/@fontsource/lato/400.css"; /* normal | normal */
|
@import "../node_modules/@fontsource/lato/400.css"; /* normal | normal */
|
||||||
// @import "../node_modules/@fontsource/lato/400-italic.css"; /* normal | italic */
|
// @import "../node_modules/@fontsource/lato/400-italic.css"; /* normal | italic */
|
||||||
// @import "../node_modules/@fontsource/lato/700.css"; /* bold | normal */
|
@import "../node_modules/@fontsource/lato/700.css"; /* bold | normal */
|
||||||
// @import "../node_modules/@fontsource/lato/700-italic.css"; /* bold | italic */
|
// @import "../node_modules/@fontsource/lato/700-italic.css"; /* bold | italic */
|
||||||
// @import "../node_modules/@fontsource/lato/900.css"; /* black | normal */
|
// @import "../node_modules/@fontsource/lato/900.css"; /* black | normal */
|
||||||
// @import "../node_modules/@fontsource/lato/900-italic.css"; /* black | italic */
|
// @import "../node_modules/@fontsource/lato/900-italic.css"; /* black | italic */
|
||||||
|
|
|
@ -16,10 +16,7 @@
|
||||||
/* Navbar toggler icon override */
|
/* Navbar toggler icon override */
|
||||||
@import "nav-burger";
|
@import "nav-burger";
|
||||||
|
|
||||||
/* Alerts and form errors */
|
/* Form errors */
|
||||||
.alert:empty {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.invalid-feedback {
|
.invalid-feedback {
|
||||||
color: #a94442;
|
color: #a94442;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
10
assets/js/_alert-remover.js
Normal file
10
assets/js/_alert-remover.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// This will tell liveview to clear a flash key
|
||||||
|
// after a bootstrap alert close event
|
||||||
|
export const AlertRemover = {
|
||||||
|
mounted() {
|
||||||
|
this.el.addEventListener("closed.bs.alert", () => {
|
||||||
|
// Bootstrap finished removing the alert element
|
||||||
|
this.pushEvent("lv:clear-flash", this.el.dataset);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
|
@ -6,6 +6,8 @@ import "../css/app.scss";
|
||||||
// Import icons for sprite-loader
|
// Import icons for sprite-loader
|
||||||
// navbar brand icon
|
// navbar brand icon
|
||||||
import "../node_modules/@mdi/svg/svg/skull-crossbones.svg";
|
import "../node_modules/@mdi/svg/svg/skull-crossbones.svg";
|
||||||
|
// x/close for alerts etc
|
||||||
|
import "../node_modules/bootstrap-icons/icons/x.svg";
|
||||||
|
|
||||||
// webpack automatically bundles all modules in your
|
// webpack automatically bundles all modules in your
|
||||||
// entry points. Those entry points can be configured
|
// entry points. Those entry points can be configured
|
||||||
|
@ -24,15 +26,20 @@ import { LiveSocket } from "phoenix_live_view";
|
||||||
// Bootstrap v5 js imports
|
// Bootstrap v5 js imports
|
||||||
import "bootstrap/js/dist/collapse";
|
import "bootstrap/js/dist/collapse";
|
||||||
import "bootstrap/js/dist/dropdown";
|
import "bootstrap/js/dist/dropdown";
|
||||||
|
import "bootstrap/js/dist/alert";
|
||||||
// Boostrap helpers
|
// Boostrap helpers
|
||||||
import "./_hamburger";
|
import "./_hamburger-helper";
|
||||||
|
import { AlertRemover } from "./_alert-remover";
|
||||||
|
|
||||||
// LiveSocket setup
|
// LiveSocket setup
|
||||||
|
let Hooks = {};
|
||||||
|
Hooks.AlertRemover = AlertRemover;
|
||||||
let csrfToken = document
|
let csrfToken = document
|
||||||
.querySelector("meta[name='csrf-token']")
|
.querySelector("meta[name='csrf-token']")
|
||||||
.getAttribute("content");
|
.getAttribute("content");
|
||||||
let liveSocket = new LiveSocket("/live", Socket, {
|
let liveSocket = new LiveSocket("/live", Socket, {
|
||||||
params: { _csrf_token: csrfToken },
|
params: { _csrf_token: csrfToken },
|
||||||
|
hooks: Hooks,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show progress bar on live navigation and form submits
|
// Show progress bar on live navigation and form submits
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-4">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<%= link to: Routes.page_path(@conn, :index), class: "navbar-brand py-0 fs-4" do %>
|
<%= link to: Routes.page_path(@conn, :index), class: "navbar-brand py-0 fs-4" do %>
|
||||||
|
@ -12,7 +12,9 @@
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent" phx-update="ignore">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
|
||||||
|
<%# nav LEFT items %>
|
||||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
|
@ -35,7 +37,7 @@
|
||||||
</li>
|
</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<li class="nav-item dropdown" phx-update="ignore">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownExample" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</a>
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownExample" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</a>
|
||||||
<ul class="dropdown-menu" aria-labelledby="navbarDropdownExample">
|
<ul class="dropdown-menu" aria-labelledby="navbarDropdownExample">
|
||||||
<li><a class="dropdown-item" href="#">Action</a></li>
|
<li><a class="dropdown-item" href="#">Action</a></li>
|
||||||
|
@ -47,6 +49,7 @@
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<%# nav RIGHT items %>
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
|
|
||||||
<%= render "navbar/_user_menu.html", assigns %>
|
<%= render "navbar/_user_menu.html", assigns %>
|
||||||
|
|
|
@ -1,5 +1,17 @@
|
||||||
<main role="main" class="container">
|
<main role="main" class="container">
|
||||||
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
|
|
||||||
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
|
<%# phoenix flash alerts: %>
|
||||||
|
<div class="container">
|
||||||
|
<%= for {kind, class} <- alert_kinds() do %>
|
||||||
|
<%= if flash_content = get_flash(@conn, kind) do %>
|
||||||
|
<div class="<%= class %> alert-dismissible fade show" role="alert">
|
||||||
|
<%= flash_content %>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
<%= @inner_content %>
|
<%= @inner_content %>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
<main role="main" class="container">
|
<main role="main" class="container">
|
||||||
<p class="alert alert-info" role="alert"
|
|
||||||
phx-click="lv:clear-flash"
|
|
||||||
phx-value-key="info"><%= live_flash(@flash, :info) %></p>
|
|
||||||
|
|
||||||
<p class="alert alert-danger" role="alert"
|
<%# liveview flash alerts: %>
|
||||||
phx-click="lv:clear-flash"
|
<div class="container">
|
||||||
phx-value-key="error"><%= live_flash(@flash, :error) %></p>
|
<%= for {kind, class} <- alert_kinds() do %>
|
||||||
|
<%= if flash_content = live_flash(@flash, kind) do %>
|
||||||
|
<div class="<%= class %> alert-dismissible fade show" role="alert" id="lv-alert-<%= kind %>" phx-hook="AlertRemover" data-key="<%= kind %>">
|
||||||
|
<%= flash_content %>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
<%= @inner_content %>
|
<%= @inner_content %>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<li class="nav-item dropdown" phx-update="ignore">
|
<li class="nav-item dropdown">
|
||||||
|
|
||||||
<a href="#" class="nav-link dropdown-toggle" id="navbarDropdownUserMenu" data-bs-toggle="dropdown" aria-expanded="false">
|
<a href="#" class="nav-link dropdown-toggle" id="navbarDropdownUserMenu" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<%= @current_user && "Account" || "Welcome" %>
|
<%= @current_user && "Account" || "Welcome" %>
|
||||||
|
|
|
@ -24,3 +24,37 @@
|
||||||
<%= link "Log in", to: Routes.user_session_path(@conn, :new) %> |
|
<%= link "Log in", to: Routes.user_session_path(@conn, :new) %> |
|
||||||
<%= link "Forgot your password?", to: Routes.user_reset_password_path(@conn, :new) %>
|
<%= link "Forgot your password?", to: Routes.user_reset_password_path(@conn, :new) %>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Lorem</h2>
|
||||||
|
<p>
|
||||||
|
Nulla blandit cursus aliquet. Sed vel sollicitudin est, eget luctus massa. Vestibulum et posuere felis, vitae convallis risus. Duis sit amet vulputate est. Morbi sed risus eget augue tristique congue. Aliquam erat volutpat. Nam rhoncus purus ut velit scelerisque, vitae iaculis elit iaculis. Aliquam erat volutpat. Etiam lacinia interdum diam.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Ut vulputate dignissim eros, a venenatis erat convallis ac. Nullam dictum ac mi eu scelerisque. Curabitur sed enim ut felis consequat iaculis id in nibh. Aliquam vel turpis in tortor mollis placerat non ut augue. Duis pharetra velit at enim porta tincidunt. Donec non nulla vel tortor scelerisque semper. Morbi sapien ante, tempor sed est vitae, vestibulum lacinia tellus. Nulla a diam ac dui porta porta et sed nisl. Mauris accumsan ex eu urna pulvinar efficitur. Nam feugiat ex velit, vel interdum turpis semper vel. Phasellus ut elementum nunc, eu facilisis metus. Integer velit nulla, egestas ut dolor vel, ultrices aliquet neque. Fusce ut imperdiet diam.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
In mattis nulla libero, eu scelerisque mi mollis non. Nulla facilisi. Aenean in nibh ligula. Praesent a mi ullamcorper libero placerat ultrices. Aenean eget lorem non eros vestibulum luctus. Nullam dictum vehicula elit, auctor eleifend nibh. Nunc lectus sem, convallis et sapien ac, consectetur viverra nibh. Nullam ac felis at tortor pulvinar laoreet ut a tellus. Mauris nec risus in est ornare lobortis. Maecenas quis magna sit amet nibh aliquam ornare. Maecenas aliquet, leo ut tincidunt tincidunt, sem turpis maximus magna, eget interdum diam justo pulvinar diam. Proin tincidunt ac risus sit amet egestas. Maecenas ut tortor pulvinar, vehicula lacus maximus, egestas turpis.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Praesent et consectetur turpis. Sed suscipit id leo non iaculis. Praesent fringilla diam a felis laoreet, quis dignissim nulla laoreet. Vivamus id mollis eros, eget volutpat erat. Nunc finibus sed purus et hendrerit. Sed quis tincidunt lorem. Vivamus condimentum nisl lacus, at tincidunt nulla maximus nec. Pellentesque at porttitor turpis. Etiam feugiat eu orci ultrices eleifend. Praesent in ipsum imperdiet, accumsan felis eget, iaculis mi. In imperdiet leo vel est gravida luctus. Vestibulum et risus eu leo varius porttitor. Donec laoreet mauris sed eleifend ultrices. Nulla in ultrices felis. Aliquam gravida quis purus nec auctor.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Donec nec diam viverra, fringilla nulla ac, pulvinar ante. Proin pretium ligula imperdiet vestibulum sodales. Suspendisse potenti. Morbi auctor arcu purus, quis semper massa pharetra sed. Suspendisse varius sapien sem, ut imperdiet sapien pharetra a. Donec sodales libero ut felis finibus porta. Sed semper libero eget diam hendrerit vulputate. Nullam elit dui, ultricies at leo eget, suscipit malesuada elit. Nullam eget lacus sed justo efficitur viverra. Donec rhoncus id metus sed finibus. Suspendisse augue nunc, sollicitudin quis tincidunt eget, auctor vulputate libero. Maecenas dictum laoreet augue, nec tristique lectus fermentum ut. Nulla mauris mi, faucibus eget metus sed, ultricies tristique dolor.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Ipsum</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Fusce at venenatis leo, eget ullamcorper lorem. Nulla rhoncus massa ut mi malesuada pharetra. Nunc a velit volutpat, congue massa ac, molestie dui. Duis fermentum maximus odio, ac dapibus sem accumsan eget. Maecenas nulla felis, auctor sed dapibus ut, imperdiet a risus. Ut ac velit ac libero mattis porttitor. Etiam non justo sed velit molestie tincidunt. Etiam iaculis ante at lorem efficitur sollicitudin. Ut sollicitudin libero lacus, id tempor lacus auctor eget. Mauris at mauris aliquet purus sagittis faucibus eget et felis. Cras imperdiet sem in ligula sagittis, in dignissim lectus maximus.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Aenean cursus finibus lacus vel mollis. Integer non viverra nunc. Morbi cursus leo vitae augue ultrices lacinia. Maecenas nec nulla neque. Vivamus at orci ornare, ullamcorper nisl sed, hendrerit enim. Nunc interdum purus magna, in mattis risus mattis a. Pellentesque mollis quam consectetur, venenatis justo non, ultricies mauris. Fusce a faucibus eros, ut ultrices sapien. In mollis quam interdum lorem sodales, eu facilisis orci pharetra. Donec eget quam leo. Nulla et maximus velit.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Curabitur volutpat, elit id dictum tincidunt, velit massa ornare elit, et tempus mauris metus sed sem. Phasellus ultrices augue non nisl tempus pharetra eget at magna. Mauris eros orci, mollis ac convallis sed, facilisis sit amet est. In dignissim, nibh nec hendrerit tincidunt, ex ligula convallis ante, id varius quam lorem eget ligula. Proin at varius massa. Proin finibus aliquet quam, non blandit lectus luctus vel. In vel magna lorem. Mauris a interdum mauris, nec tincidunt leo. Nulla venenatis suscipit neque non porta. Maecenas feugiat tellus eu fringilla lobortis.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Sed dignissim mi felis, eu ornare enim ullamcorper in. In nibh lorem, tincidunt a dapibus et, rhoncus eget est. Cras tristique ante urna, sit amet hendrerit purus suscipit eu. Donec consectetur felis quis massa bibendum, non facilisis turpis facilisis. Nam a massa quis erat pretium auctor. Maecenas molestie venenatis dui, sed lobortis urna luctus et. Phasellus laoreet, ex eu posuere mollis, lacus felis varius lectus, elementum ultrices magna odio ac neque. Donec luctus blandit bibendum. Proin non sollicitudin felis. Phasellus posuere efficitur dolor maximus tempor. Donec sed odio mi.
|
||||||
|
</p>
|
||||||
|
|
|
@ -7,4 +7,15 @@ defmodule Bones73kWeb.LayoutView do
|
||||||
true -> Keyword.update(opts, :class, "active", fn c -> "#{c} active" end)
|
true -> Keyword.update(opts, :class, "active", fn c -> "#{c} active" end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def alert_kinds do
|
||||||
|
[
|
||||||
|
success: "alert alert-success",
|
||||||
|
info: "alert alert-info",
|
||||||
|
error: "alert alert-danger",
|
||||||
|
warning: "alert alert-warning",
|
||||||
|
primary: "alert alert-primary",
|
||||||
|
secondary: "alert alert-secondary"
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue