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.ex
Raw

lib/mix/tasks/phia.design.ex

defmodule Mix.Tasks.Phia.Design do
@moduledoc """
Starts the PhiaUI Design tool — a visual component editor.
## Usage
mix phia.design # Start on port 4200
mix phia.design --port 4201 # Custom port
mix phia.design --no-open # Don't auto-open browser
The design tool runs alongside your existing Phoenix application.
It starts its own HTTP server on a separate port (default: 4200)
using Bandit, with its own Endpoint, Router, and LiveView.
## Features
- **Component browser** — search and insert any of 623 PhiaUI components
- **Live canvas** — real component rendering (not placeholders)
- **Properties panel** — edit attributes and slots visually
- **Code panel** — live HEEx preview of your design
- **Page templates** — start from 9 pre-built layouts (dashboard, auth, landing, etc.)
- **Responsive preview** — desktop, tablet, and mobile viewports
- **Save/load** — persist designs as `.phia.json` files
## Claude Code Integration
For AI-assisted design, use the MCP server instead:
mix phia.design.mcp
See `Mix.Tasks.Phia.Design.Mcp` for setup instructions, or the
[PhiaUI Design tutorial](docs/guides/tutorial-design.md) for a full walkthrough.
## Related Tasks
- `mix phia.design.mcp` — MCP server for Claude Code integration
- `mix phia.design.export` — export designs to HEEx/LiveView code
- `mix phia.design.analyze` — analyze designs for dependencies
## Requirements
- Bandit (`{:bandit, "~> 1.6"}`) must be in your deps.
- The `:phia_ui` application must be startable (it is started
automatically by this task).
"""
@shortdoc "Starts the PhiaUI Design visual editor"
use Mix.Task
@impl Mix.Task
def run(args) do
{opts, _, _} =
OptionParser.parse(args,
strict: [port: :integer, open: :boolean, help: :boolean],
aliases: [p: :port, h: :help]
)
if opts[:help] do
Mix.shell().info(@moduledoc)
return_or_halt()
end
port = Keyword.get(opts, :port, 4200)
open? = Keyword.get(opts, :open, true)
unless Code.ensure_loaded?(Bandit) do
Mix.raise("""
Bandit is required to run PhiaUI Design.
Add {:bandit, "~> 1.6"} to your deps in mix.exs and run:
mix deps.get
""")
end
Mix.shell().info("Starting PhiaUI Design on http://localhost:#{port}")
# Ensure the application and its dependencies are started
Application.ensure_all_started(:phoenix)
Application.ensure_all_started(:phoenix_live_view)
Application.ensure_all_started(:phia_ui)
# Generate a stable-for-this-session secret key base
secret_key_base =
:crypto.strong_rand_bytes(64)
|> Base.url_encode64()
|> binary_part(0, 64)
# Configure the endpoint programmatically
design_config = [
http: [port: port],
server: true,
secret_key_base: secret_key_base,
live_view: [signing_salt: "phiaui_design_lv"],
pubsub_server: PhiaUiDesign.PubSub,
adapter: Bandit.PhoenixAdapter
]
Application.put_env(:phia_ui, PhiaUiDesign.Web.Endpoint, design_config)
# Start supporting processes under a dedicated supervisor
children = [
{Phoenix.PubSub, name: PhiaUiDesign.PubSub},
PhiaUiDesign.Catalog.CatalogServer
]
{:ok, _} =
Supervisor.start_link(children,
strategy: :one_for_one,
name: PhiaUiDesign.Supervisor
)
# Start the endpoint (HTTP server + LiveView socket)
{:ok, _} = PhiaUiDesign.Web.Endpoint.start_link()
Mix.shell().info("""
PhiaUI Design is running!
Open: http://localhost:#{port}
Press Ctrl+C to stop.
""")
if open? do
open_browser("http://localhost:#{port}")
end
# Keep the task alive
Process.sleep(:infinity)
end
defp open_browser(url) do
Task.start(fn ->
Process.sleep(500)
case :os.type() do
{:unix, :darwin} -> System.cmd("open", [url])
{:unix, _} -> System.cmd("xdg-open", [url])
{:win32, _} -> System.cmd("cmd", ["/c", "start", url])
end
end)
end
defp return_or_halt do
if function_exported?(System, :halt, 1) do
System.halt(0)
end
end
end