Packages
corex
0.1.0-beta.3
0.1.2
0.1.1
0.1.0
0.1.0-rc.1
0.1.0-rc.0
0.1.0-beta.5
0.1.0-beta.4
0.1.0-beta.3
0.1.0-beta.2
0.1.0-beta.1
0.1.0-alpha.33
0.1.0-alpha.32
0.1.0-alpha.31
0.1.0-alpha.30
0.1.0-alpha.29
0.1.0-alpha.28
0.1.0-alpha.27
0.1.0-alpha.26
0.1.0-alpha.25
0.1.0-alpha.24
0.1.0-alpha.23
0.1.0-alpha.22
0.1.0-alpha.21
0.1.0-alpha.20
0.1.0-alpha.19
0.1.0-alpha.18
0.1.0-alpha.17
0.1.0-alpha.16
0.1.0-alpha.15
0.1.0-alpha.14
0.1.0-alpha.13
0.1.0-alpha.12
0.1.0-alpha.11
0.1.0-alpha.10
0.1.0-alpha.9
0.1.0-alpha.8
0.1.0-alpha.7
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
Accessible and unstyled UI components library written in Elixir and TypeScript that integrates Zag.js state machines into the Phoenix Framework.
Current section
Files
Jump to
Current section
Files
lib/components/code.ex
defmodule Corex.Code do
@moduledoc ~S'''
Displays syntax-highlighted code with Makeup.
## Installation
Add `makeup` and the lexer packages for each language you use:
```elixir
defp deps do
[
{:makeup, "~> 1.2"},
{:makeup_elixir, "~> 1.0.1 or ~> 1.1"},
{:makeup_html, "~> 1.0"},
{:makeup_css, "~> 1.0"},
{:makeup_js, "~> 1.0"}
]
end
```
Only `makeup` is required. Add the lexer packages you need; without a lexer, code renders as plain escaped text.
## Examples
### Basic Usage
```heex
<.code code="def hello, do: :world" />
```
### Multi-line with heredoc
Use `"""` heredoc for readable multi-line code in templates:
```heex
<.code code={"""
defmodule Hello do
def world, do: "Hello, World!"
end
"""} />
```
### Loading from a file
```heex
<.code code={File.read!("priv/code_examples/example.ex")} language={:elixir} />
```
Or in a controller, load the file and pass the contents:
```elixir
def my_page(conn, _params) do
code = File.read!("priv/code_examples/example.ex")
render(conn, :my_page, code: code)
end
```
```heex
<.code code={@code} language={:elixir} />
```
The `language` attribute maps to Makeup's registry (e.g. `:elixir` → `"elixir"`).
Add the corresponding lexer package to your deps for each language. Without it, code renders as plain escaped text.
## Styling
Use data attributes to target elements:
```css
[data-scope="code"][data-part="root"] {}
[data-scope="code"][data-part="content"] {}
```
With Corex Design, syntax highlighting styles are included in
`code.css`. Nothing else is required.
Without Corex Design, run `mix corex.code` to generate the Makeup stylesheet and
import it in your CSS:
```bash
mix corex.code
mix corex.code assets/styles/syntax.css
mix corex.code --force
```
```css
@import "./code_highlight.css";
```
'''
@doc type: :component
use Phoenix.Component
attr(:code, :string, required: true, doc: "The raw source code to display")
attr(:language, :atom,
default: :elixir,
doc:
"The language name in Makeup's registry (e.g. :elixir, :html). Add the lexer package to deps; otherwise renders as plain escaped text."
)
attr(:inline, :boolean, default: false, doc: "Whether to display the code inline")
attr(:rest, :global)
def code(assigns) do
makeup = Module.concat(["Elixir", "Makeup"])
unless Code.ensure_loaded?(makeup) do
raise """
Corex.Code requires makeup.
Add it to your mix.exs:
{:makeup, "~> 1.2"}
Add lexer packages for each language you use (e.g. makeup_elixir, makeup_html).
"""
end
assigns =
assigns
|> then(&assign(&1, :highlighted_html, highlight_code(&1)))
~H"""
<pre
:if={!@inline}
data-scope="code"
data-part="root"
tabindex="0"
{@rest}
>
<code data-scope="code" data-part="content">{Phoenix.HTML.raw(@highlighted_html)}</code>
</pre>
<code :if={@inline} data-scope="code" data-part="root" {@rest}>
<span data-scope="code" data-part="content">{Phoenix.HTML.raw(@highlighted_html)}</span>
</code>
"""
end
defp highlight_code(assigns) do
name = to_string(assigns.language)
registry = Module.concat(["Elixir", "Makeup", "Registry"])
makeup = Module.concat(["Elixir", "Makeup"])
case registry.fetch_lexer_by_name(name) do
{:ok, _} ->
makeup.highlight_inner_html(assigns.code, lexer: name)
:error ->
assigns.code
|> Phoenix.HTML.html_escape()
|> Phoenix.HTML.safe_to_string()
end
end
end