# `PhoenixMountable.Igniter.HostAssets`
[🔗](https://github.com/hattoriai/phoenix_mountable/blob/v0.2.1/lib/phoenix_mountable/igniter/host_assets.ex#L2)

Edits of the host's `assets/js/app.js` and `assets/css/app.css`, for a
library whose components render in the host's own pages (a button in
its header, a palette, a picker) and need a LiveView hook and a style
sheet there. `PhoenixMountable.Igniter.add_hook/4` and
`PhoenixMountable.Igniter.add_css_imports/3` apply them.

They are pure functions on the source of each file. Each returns:

  * `{:changed, source}` - the new source;
  * `:unchanged` - the file already has everything;
  * `{:manual, text}` - the edit cannot be made safely; `text` tells the
    person what to add.

The `app.js` edit understands the `new LiveSocket(...)` of a generated
Phoenix app and the usual variations: an options object with or without
`hooks`, hooks as an object (with spreads, such as `colocatedHooks`) or
as a variable. It ignores strings and comments. Anything else (hooks
computed by a function, a quoted `"hooks"` key) is left to the person.

# `result`

```elixir
@type result() :: {:changed, String.t()} | :unchanged | {:manual, String.t()}
```

# `app_css`

```elixir
@spec app_css(String.t(), [{String.t(), :import | :comment}]) :: result()
```

Adds `@import` lines to the source of `app.css`, after its last
top-level `@import` (else after a `@charset`, else at the top).

`imports` are `{path, :import}` or `{path, :comment}`: a commented import
is an option the person turns on (a theme), added only with the first
import of the list, so that a person who removed it does not get it back.
An import already in the source, commented or not, is not added again.

# `app_css_manual`

```elixir
@spec app_css_manual([{String.t(), :import | :comment}]) :: String.t()
```

The lines to add to `app.css` by hand.

# `app_js`

```elixir
@spec app_js(String.t(), String.t(), String.t()) :: result()
```

Adds `import { hook } from "package"` to the source of `app.js`, and
`hook` to the hooks of its `new LiveSocket(...)`.

Returns `{:changed, source}`, `:unchanged` when both are there, or
`{:manual, text}` when the hooks cannot be edited safely (they are a
computed value, or the call is not found): `text` tells the person what
to add.

# `app_js_manual`

```elixir
@spec app_js_manual(String.t(), String.t(), boolean()) :: String.t()
```

The lines to add to `app.js` by hand.

# `node_path?`

```elixir
@spec node_path?(String.t()) :: boolean()
```

Whether the esbuild config of the host resolves packages from `deps/`
(`"NODE_PATH" => [... "../deps" ...]`), as a generated Phoenix app does.

# `relative`

```elixir
@spec relative(Path.t(), Path.t()) :: String.t()
```

The path from the directory `from` to `path`, with `..` where it must go
up: the form an `@import` of `assets/css/app.css` needs.

    iex> PhoenixMountable.Igniter.HostAssets.relative("deps/my_lib", "assets/css")
    "../../deps/my_lib"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
