Packages

shadcn/ui-inspired component library for Phoenix LiveView with eject-based distribution. CSS-first theme system, 829 components across 20+ categories — Calendar, Chart, Animation, DnD, Editor, Collaboration, Typography, Navigation, Background, Surface, and more.

Current section

Files

Jump to
phia_ui lib mix tasks phia.design.export.ex
Raw

lib/mix/tasks/phia.design.export.ex

defmodule Mix.Tasks.Phia.Design.Export do
@moduledoc """
Export a saved PhiaUI design to HEEx or LiveView source files.
Takes a `.phia.json` file (created by `mix phia.design` or the MCP server)
and generates production-ready Phoenix code.
## Usage
mix phia.design.export my_design.phia.json
mix phia.design.export my_design.phia.json --format liveview --output lib/my_app_web/live/page_live.ex
mix phia.design.export my_design.phia.json --format heex --output lib/my_app_web/templates/page.html.heex
## Options
- `--format` (`-f`) — Output format: `heex` (default) or `liveview`
- `--output` (`-o`) — Output file path (prints to stdout if omitted)
- `--module` (`-m`) — Module name for LiveView format (default: `MyAppWeb.DesignedLive`)
- `--web-module` — Phoenix web module (default: `MyAppWeb`)
## Examples
# Quick preview — print HEEx to terminal
mix phia.design.export priv/phiaui_design/projects/dashboard.phia.json
# Generate a LiveView module
mix phia.design.export dashboard.phia.json \\
-f liveview \\
-o lib/my_app_web/live/dashboard_live.ex \\
-m MyAppWeb.DashboardLive
## Related Tasks
- `mix phia.design` — visual editor
- `mix phia.design.mcp` — MCP server for Claude Code
- `mix phia.design.analyze` — analyze a design file
"""
@shortdoc "Export a .phia.json design to HEEx or LiveView code"
use Mix.Task
alias PhiaUiDesign.Canvas.Persistence
alias PhiaUiDesign.Codegen.{HeexEmitter, LiveviewEmitter}
@impl Mix.Task
def run(args) do
{opts, positional, _} =
OptionParser.parse(args,
strict: [
format: :string,
output: :string,
module: :string,
web_module: :string,
help: :boolean
],
aliases: [f: :format, o: :output, m: :module, h: :help]
)
if opts[:help] || positional == [] do
Mix.shell().info(@moduledoc)
return_or_halt()
end
Application.ensure_all_started(:phia_ui)
[input_path | _] = positional
format = Keyword.get(opts, :format, "heex")
output_path = opts[:output]
module_name = Keyword.get(opts, :module, "MyAppWeb.DesignedLive")
web_module = Keyword.get(opts, :web_module, "MyAppWeb")
unless File.exists?(input_path) do
Mix.raise("File not found: #{input_path}")
end
case Persistence.load(input_path) do
{:ok, scene, metadata} ->
Mix.shell().info("Loaded design '#{metadata.name}' from #{input_path}")
code =
case format do
"liveview" ->
LiveviewEmitter.emit(scene, module_name, web_module: web_module)
_ ->
HeexEmitter.emit(scene)
end
if output_path do
File.mkdir_p!(Path.dirname(output_path))
File.write!(output_path, code)
Mix.shell().info("Exported #{format} to #{output_path}")
else
Mix.shell().info(code)
end
{:error, reason} ->
Mix.raise("Failed to load #{input_path}: #{inspect(reason)}")
end
end
defp return_or_halt do
if function_exported?(System, :halt, 1), do: System.halt(0)
end
end