README.md

# SvgSpriteEx

`SvgSpriteEx` lets you turn SVG files into compile-time icon refs for Phoenix
components and LiveView.

You can render icons in two ways:

- `ref={sprite_ref("...")}` renders a `<svg><use ... /></svg>` wrapper backed
  by a generated sprite sheet
- `ref={inline_ref("...")}` renders the full SVG inline in the document

## Installation

Add `svg_sprite_ex` to your dependencies:

```elixir
def deps do
  [
    {:svg_sprite_ex, "~> 0.1.0"}
  ]
end
```

Then register the sprite compiler after the default Mix compilers so it can
discover `sprite_ref/1`, `sprite_ref/2`, and `inline_ref/1` usages.

```elixir
def project do
  [
    app: :my_app,
    version: "0.1.0",
    elixir: "~> 1.19",
    compilers: Mix.compilers() ++ [:svg_sprite_ex_assets],
    deps: deps()
  ]
end
```

## Configuration

```elixir
import Config

config :svg_sprite_ex,
  source_root: Path.expand("../priv/icons", __DIR__),
  build_path: Path.expand("../priv/static/svgs", __DIR__),
  public_path: "/svgs"
```

### Required configuration

- `source_root` - absolute path to the directory that contains source SVG files.
- `build_path` - absolute path where the compiler generates sprite sheets.
- `public_path` - public URL prefix for `sprite_ref/1` hrefs.

### Optional configuration

- `default_sheet` - default sprite sheet name when no `sheet` option is
  given. Defaults to `sprites`.

Given the config above, if your icon file lives at
`priv/icons/regular/xmark.svg`, the logical icon name is `regular/xmark`.

Note that `sprite_ref` and `inline_ref` only accept compile-time literal
values. This is how the compiler discovers which icons need to be included in
the generated outputs.

## How it works

When you run `mix compile`, the compiler:

- scans compiled modules for `sprite_ref` and `inline_ref` calls
- writes one SVG sprite sheet per sheet name into `build_path`
- compiles a `SvgSpriteEx.Generated.InlineIcons` module for inline SVG lookup

With the config above, `sprite_ref("regular/xmark")` returns a
`%SvgSpriteEx.SpriteRef{}` whose `href` looks like
`/svgs/sprites.svg#icon-812c65654d41`.

Your application must serve the generated files from the same public path you
configured. For example: Write sprite sheets into `priv/static/svgs`, and
serve them from `/svgs`.

## Phoenix usage

Use `SvgSpriteEx` in any component, LiveView, or HTML module that renders icons:

```elixir
defmodule MyAppWeb.MyComponents do
  use Phoenix.Component
  use SvgSpriteEx
end
```

This will import:

- the `<.svg>` function component from `SvgSpriteEx.Svg`
- the `sprite_ref` and `inline_ref` macros from `SvgSpriteEx.Ref`

### Render using a sprite sheet

```elixir
defmodule MyAppWeb.MyComponents do
  use Phoenix.Component
  use SvgSpriteEx

  def close_icon(assigns) do
    ~H"""
    <.svg ref={sprite_ref("regular/xmark")} class="size-4" />
    """
  end
end
```

By default the SVGs are placed in a sprite sheet called `sprites.svg`, but you
can also compile icons to other named sheets:

```elixir
<.svg ref={sprite_ref("regular/xmark", sheet: "dashboard")} class="size-4" />
```

### Render inline SVGs

Inline mode skips the sprite sheet and renders the SVG inline in the document.

```elixir
<.svg ref={inline_ref("regular/xmark")} class="size-4" />
```

This lets you serve the raw SVG markup in the page instead of a `<use>`
reference, without doing runtime file reads.