From 129354dec16089a4124649247ad09e9ed1777d95 Mon Sep 17 00:00:00 2001
From: Adam Piontek <adam@73k.us>
Date: Thu, 25 Feb 2021 16:39:03 -0500
Subject: [PATCH] svg icons implemented with initial POC

---
 assets/css/app.scss                           | 28 +++++++++++++++
 lib/bones73k/util/list.ex                     |  4 +++
 lib/bones73k_web.ex                           |  3 ++
 .../templates/layout/_navbar.html.eex         |  5 ++-
 lib/bones73k_web/views/icon_helper.ex         | 35 +++++++++++++++++++
 5 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 lib/bones73k/util/list.ex
 create mode 100644 lib/bones73k_web/views/icon_helper.ex

diff --git a/assets/css/app.scss b/assets/css/app.scss
index 9d3145e..3287440 100644
--- a/assets/css/app.scss
+++ b/assets/css/app.scss
@@ -1,6 +1,34 @@
 /* Bootstrap v5 */
 @import "~bootstrap/scss/bootstrap";
 
+/* SVG icon style helper */
+// [class*=" icon"],
+// [class^="icon"] {
+//   width: 1em;
+//   height: 1em;
+//   stroke: currentColor;
+//   fill: currentColor;
+// }
+
+/*SVG ICON SYSTEM*/
+.icon {
+  display: inline-flex;
+  align-self: center;
+}
+
+.icon svg,
+.icon img {
+  height: 1em;
+  width: 1em;
+  fill: currentColor;
+}
+
+.icon.baseline svg,
+.icon img {
+  top: 0.125em;
+  position: relative;
+}
+
 /* LiveView specific classes for your customizations */
 .phx-no-feedback.invalid-feedback,
 .phx-no-feedback .invalid-feedback {
diff --git a/lib/bones73k/util/list.ex b/lib/bones73k/util/list.ex
new file mode 100644
index 0000000..311c044
--- /dev/null
+++ b/lib/bones73k/util/list.ex
@@ -0,0 +1,4 @@
+defmodule Bones73k.Util.List do
+  def prepend_if(list, condition, item), do: (!!condition && [item | list]) || list
+  def append_if(list, condition, item), do: (!!condition && list ++ [item]) || list
+end
diff --git a/lib/bones73k_web.ex b/lib/bones73k_web.ex
index bb72582..6a6c372 100644
--- a/lib/bones73k_web.ex
+++ b/lib/bones73k_web.ex
@@ -102,6 +102,9 @@ defmodule Bones73kWeb do
       # Import basic rendering functionality (render, render_layout, etc)
       import Phoenix.View
 
+      # Import SVG Icon helper
+      import Bones73kWeb.IconHelper
+
       import Bones73kWeb.ErrorHelpers
       import Bones73kWeb.Gettext
       alias Bones73kWeb.Router.Helpers, as: Routes
diff --git a/lib/bones73k_web/templates/layout/_navbar.html.eex b/lib/bones73k_web/templates/layout/_navbar.html.eex
index 1b00be2..5d02c53 100644
--- a/lib/bones73k_web/templates/layout/_navbar.html.eex
+++ b/lib/bones73k_web/templates/layout/_navbar.html.eex
@@ -1,7 +1,10 @@
 <nav class="navbar navbar-expand-lg navbar-light bg-light">
   <div class="container">
 
-    <a class="navbar-brand" href="#">Navbar</a>
+    <a class="navbar-brand" href="#">
+      <%= icon_div @conn, "fas-skull-crossbones", class: "icon baseline" %>
+      Bones73k
+    </a>
 
     <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
       <span class="navbar-toggler-icon"></span>
diff --git a/lib/bones73k_web/views/icon_helper.ex b/lib/bones73k_web/views/icon_helper.ex
new file mode 100644
index 0000000..91b699d
--- /dev/null
+++ b/lib/bones73k_web/views/icon_helper.ex
@@ -0,0 +1,35 @@
+defmodule Bones73kWeb.IconHelper do
+  @moduledoc """
+  Generate SVG sprite use tags for SVG icons
+  """
+
+  use Phoenix.HTML
+  import Bones73k.Util.List
+  alias Bones73kWeb.Router.Helpers, as: Routes
+
+  def icon_div(conn, name, div_opts \\ [], svg_opts \\ []) do
+    content_tag(:div, tag_opts(name, div_opts)) do
+      icon_svg(conn, name, svg_opts)
+    end
+  end
+
+  def icon_svg(conn, name, opts \\ []) do
+    content_tag(:svg, tag_opts(name, opts)) do
+      tag(:use, "xlink:href": Routes.static_path(conn, "/images/icons.svg#" <> name))
+    end
+  end
+
+  defp tag_opts(name, opts) do
+    classes = "#{Keyword.get(opts, :class, "")} #{name}" |> String.trim_leading()
+    styles = Keyword.get(opts, :style)
+    width = Keyword.get(opts, :width)
+    height = Keyword.get(opts, :height)
+    id = Keyword.get(opts, :id)
+
+    [class: classes]
+    |> prepend_if(styles, {:style, styles})
+    |> prepend_if(width, {:style, width})
+    |> prepend_if(height, {:style, height})
+    |> prepend_if(id, {:id, id})
+  end
+end