Icons

Overview

ShipClojure uses SVG sprites for optimal icon performance. You'll find raw SVGs in the resources/icons directory. These are then compiled into a sprite using the bb run build:icons script, which generates the sprite.svg file, which is loaded into your html.

Here is a blog post I wrote about the full technique used in ShipClojure.

The SVGs used by default in ShipClojure come from lucide.dev. You can download additional SVG icons from there, or provide your own. Once you've added new files in the icons directory, run bb build:icons and you can then use the icon.cljc component to render it.

(ns example)

(defn render-my-cool-component
    []
    [:div
      [:ui/icon {:icon/name :moon
                 :icon/size :icon.size/lg
                 :class "text-red-300"}]))

The :icon/name prop is the name of the file without the .svg extension. I recommend using kebab-case filenames rather than PascalCase to avoid casing issues with different operating systems.

Note that the build_icons.clj script automatically removes width and height props from your SVGs to ensure they scale properly.

By default, all the icons will have a height and width of 1em so they should match the font-size of the text they're next to. You can also customize the size using the :size prop or :class "w-8 h-8"

You can use the icon component, on both frontend generated UIs and backend generated UIs.

Emacs utils

Since I'm using this a lot, I created some emacs util functions that help you search, save and insert icons from the lucide.dev project.

  • project-icons--insert-icon will look through the icons from icons dir and autocomplete them for your
  • project-icons--find-lucide-icon will issue a query on the lucide website based on the input you provided
  • project-icons--save-icon-from-kill will save to the correct directory the icon you have on the clipboard

Note: You need to run bb build:icons after each new icon saved.

These 3 functions made working with icons very easy for me.