Custom Kaffy Styling

I recently gave a talk at Empex NYC (link to talk) on why you should be writing admin tools from day one.  In my talk, one thing I highly suggest is to make it very obvious what environment you are in when providing a web admin UI for your team.   We've been using Kaffy at SwayDM since the beginning.  At the time, you couldn't easily overwrite the styling.  I maintain a private fork of Kaffy for changes I've made, which included the ability to change the background color.

I recently merged the past few minor Kaffy releases back into my fork, and saw that Kaffy now has the ability to provide Extensions which allow you to inject custom html, css and javascript.  I spent a little time making a custom CSS file to change the color of the Kaffy nav, and add a title which notes which environment you are in.



For each environment, I have a static file for CSS styling overrides.

  • kaffy-ext-local.css
  • kaffy-ext-staging.css
  • kaffy-ext-production.css

defmodule SwayDMWeb.Admin.KaffyExtension do
  def stylesheets(conn) do

    env = case conn.host do
      "localhost:4000" -> "localhost"
      "staging.example.com" -> "staging"
      "prod.example.com" -> "production"
      _ -> "default"
    end

    [
      {:safe, ~s(<link rel="stylesheet" href="/css/kaffy-ext-#{env}.css" />)}
    ]
  end
end

Then, the extension is configure din config.exs


config :kaffy,
  extensions: [
    SwayDMWeb.Admin.KaffyExtension
  ]

Finally, add the custom CSS. I'm not a CSS expert, but this seems to work pretty well. There is also probably a fancy way to template this so I don't have 4 of the same files, but I just did it the quick and dirty way. This will most likely not have to be modified again for a long time.  I also am sure there is a better way than using !important everywhere, but again, this is a quick and dirty solution that does not need to be maintained regularly. 


nav.navbar,
nav.sidebar,
nav div.navbar-menu-wrapper {
  background-color: purple;
}

ul.nav li.nav-item.active {
  background-color: lightgoldenrodyellow !important;
}

ul.nav li:hover {
  background-color: lightgoldenrodyellow !important;
}

ul.nav li:hover span.menu-title {
  color: purple !important;
}

nav li.nav-item.active ::before,
nav li.nav-item.active,
nav li.nav-item.active a {
  color: purple !important;
}

.navbar ::before,
.nav-item *,
.nav-item ::before {
  color: lightgoldenrodyellow !important;
}

.nav-item:hover,
.nav-item:hover .nav-link,
.nav-item:hover .nav-link::before,
.nav-item:hover .nav-link *::before,
.nav-item.active * {
  color: purple !important;
}

.nav-item .nav-link:hover {
  color: #ea2eff !important;
}

/*
  Add text to the header bar. Need to use media query as otherwise
  it will show up on the wrong side of the hamburger menu.
*/

@media (min-width: 991px) {
  .container-scroller nav .navbar-menu-wrapper::after {
    pading: 20px;
    margin-top: 25px;
    color: lightgoldenrodyellow;
    content: "Test Environment";
  }
}

@media (max-width: 991px) {
  .container-scroller nav .navbar-menu-wrapper::before {
    pading: 20px;
    margin-top: 25px;
    color: lightgoldenrodyellow;
    content: "Test Environment";
  }
}


I hope you find this guide useful, feel free to use this code! - Andy

Comments

Popular posts from this blog

Write Admin Tools From Day One

Phoenix LiveView: Async Assign Pattern

Ecto - Using select_merge for flexible aggregates