Skip to content

Commit

Permalink
Merge pull request #1 from mveytsman/mv/caching
Browse files Browse the repository at this point in the history
Return to compile-time generation
  • Loading branch information
greven committed Sep 1, 2022
2 parents 141caa6 + 0fef953 commit 04b7dd5
Show file tree
Hide file tree
Showing 851 changed files with 101 additions and 40,023 deletions.
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Downloaded icons
/priv/icons/

# MacOS
.DS_Store
.AppleDouble
Expand Down Expand Up @@ -30,6 +33,6 @@ heroicons-*.tar
# Temporary files for e.g. tests
/tmp

# Elixir deps
# Nix deps
.nix-mix/
.nix-hex/
.nix-hex/
1 change: 1 addition & 0 deletions lib/heroicons.ex
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ defmodule Heroicons do

defp copy_svg_files(src_dir, style) do
dest_dir = Path.join(svgs_path(), style)
File.mkdir_p!(dest_dir)
File.cp_r!(src_dir, dest_dir)
end

Expand Down
80 changes: 80 additions & 0 deletions lib/heroicons/generator.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
defmodule Heroicons.Generator do
defmacro __using__(icon_dir: icon_dir) do
icon_paths =
Path.absname(icon_dir, :code.priv_dir(:heroicons))
|> Path.join("*.svg")
|> Path.wildcard()

require Phoenix.Component

if function_exported?(Phoenix.Component, :assigns_to_attributes, 2) do
Module.put_attribute(__CALLER__.module, :assign_mod, Phoenix.Component)
Module.put_attribute(__CALLER__.module, :assigns_to_attrs_mod, Phoenix.Component)
else
Module.put_attribute(__CALLER__.module, :assign_mod, Phoenix.LiveView)
Module.put_attribute(__CALLER__.module, :assigns_to_attrs_mod, Phoenix.LiveView.Helpers)
end

for path <- icon_paths do
generate(path)
end
end

@doc false
def generate(path) do
name =
Path.basename(path, ".svg")
|> String.replace("-", "_")
|> String.to_atom()

doc = """
![](assets/#{Path.relative_to(path, :code.priv_dir(:heroicons))}) {: width=24px}
## Examples
Use as a `Phoenix.Component`
<.#{name} />
<.#{name} class="h-6 w-6 text-gray-500" />
or as a function
<%= #{name}() %>
<%= #{name}(class: "h-6 w-6 text-gray-500") %>
"""

quote do
@doc unquote(doc)
def unquote(name)(assigns_or_opts \\ [])

def unquote(name)(var!(assigns)) when is_map(var!(assigns)) do
var!(attrs) = @assigns_to_attrs_mod.assigns_to_attributes(var!(assigns))
var!(assigns) = @assign_mod.assign(var!(assigns), :attrs, var!(attrs))

EEx.compile_string("<svg {@attrs}" <> Heroicons.IconCache.icon_body(unquote(path)),
engine: Phoenix.LiveView.HTMLEngine,
file: __ENV__.file,
line: __ENV__.line + 1,
module: __ENV__.module,
indentation: 0,
assigns: var!(assigns)
)
end

def unquote(name)(opts) when is_list(opts) do
attrs =
for {k, v} <- opts do
safe_k =
k |> Atom.to_string() |> String.replace("_", "-") |> Phoenix.HTML.Safe.to_iodata()

safe_v = v |> Phoenix.HTML.Safe.to_iodata()

{:safe, [?\s, safe_k, ?=, ?", safe_v, ?"]}
end

{:safe,
[
"<svg",
Phoenix.HTML.Safe.to_iodata(attrs),
" ",
Heroicons.IconCache.icon_body(unquote(path))
]}
end
end
end
end
12 changes: 12 additions & 0 deletions lib/heroicons/icon_cache.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule Heroicons.IconCache do

@doc "Get's an icon's body from the filesystem"
# TODO implement ETS-based caching & benchmark
def icon_body(path) do
icon = File.read!(path)

<<"<svg ", body::binary>> = icon

body
end
end
Loading

0 comments on commit 04b7dd5

Please sign in to comment.