Packages
petal_components
4.4.0
4.6.2
4.6.1
4.6.0
4.5.0
4.4.0
4.3.0
4.2.1
4.2.0
4.1.2
4.1.1
4.1.0
4.0.12
4.0.11
4.0.10
4.0.6
4.0.5
4.0.4
4.0.3
4.0.1
3.2.2
3.2.1
3.2.0
3.1.0
3.0.2
3.0.1
3.0.0
2.9.3
2.9.2
retired
2.9.1
retired
2.9.0
retired
2.8.4
2.8.3
2.8.2
2.8.1
2.8.0
2.7.4
2.7.3
2.7.2
2.7.1
2.7.0
2.6.1
2.6.0
2.5.2
2.5.1
2.5.0
2.4.3
2.4.2
2.4.1
2.4.0
2.3.0
2.2.1
2.2.0
2.1.2
2.1.1
2.1.0
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.9.3
1.9.2
1.9.1
1.9.0
1.8.0
1.7.1
1.7.0
1.6.2
1.6.1
1.6.0
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.0
1.2.14
1.2.13
1.2.12
1.2.11
1.2.10
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.19.10
0.19.9
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.7
0.17.6
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.0
0.15.0
0.14.1
0.14.0
0.13.7
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.8
0.10.7
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.0
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.2
0.2.1
0.2.0
0.1.0
Shadcn-style Phoenix LiveView components that AI assistants can actually use. Pair with the MCP server so AI coding tools can inspect the real component API.
Current section
Files
Jump to
Current section
Files
petal_components
rules.md
rules.md
# petal_components - rules for AI coding assistants
petal_components is a shadcn-style component library for Phoenix LiveView. Components live in modules under `PetalComponents.*` and are called as plain HEEx tags (`<.button>`, `<.modal>`, `<.table>`) once you `use PetalComponents`. CSS classes use a `pc-` prefix for styling overrides (`pc-button`, `pc-button--primary`). Use these rules to write idiomatic Phoenix UI instead of inventing raw Tailwind markup.
Drop this file into your AI coding tool's rules system (Cursor `.cursorrules`, Claude Code `CLAUDE.md`, Codex `AGENTS.md`, Continue rules, etc.) when working in a Phoenix project that has `petal_components` installed.
## Installing petal_components
When the user says "install petal_components" (or you're starting in a Phoenix project that doesn't have it yet), follow these steps. They are idempotent - safe to re-run if any step is partially done.
### 1. Add the dependency
Open `mix.exs`. In the `deps/0` function, add this line if it's not already there:
```elixir
{:petal_components, "~> 4.0"}
```
If the user wants the chat components (`PetalComponents.Chat` — `<Chat.conversation>`, `<Chat.markdown>`, `<Chat.rich_text>`, …), also add the optional `{:mdex, "~> 0.12"}`. The rest of the library needs no extra deps. Note the `Chat` family is not pulled in by `use PetalComponents` — `alias PetalComponents.Chat` and call it namespaced.
### 2. Fetch dependencies
```sh
mix deps.get
```
### 3. Configure Tailwind CSS
Open `assets/css/app.css`. Find the `@import "tailwindcss";` line and add the two lines below it:
```css
@import "tailwindcss";
@source "../deps/petal_components/**/*.*ex";
@import "../deps/petal_components/assets/default.css";
```
The `@source` line tells Tailwind to scan petal_components source for class usage. The `@import` line brings in the default component styles (the `pc-*` CSS prefix).
If `@import "tailwindcss";` is missing, the project is on Tailwind v3 and petal_components 4.x will not work. Tell the user to upgrade to Tailwind v4, or pin to `petal_components ~> 1.0` for Tailwind v3 support.
### 4. Import the components in your web module
Find `lib/<your_app>_web.ex`. In umbrella apps it lives at `apps/<your_app>_web/lib/<your_app>_web.ex`. The file defines macros like `def html`, `def controller`, `def live_view`.
Inside `def html`, locate the `quote do` block and add `use PetalComponents`:
```elixir
def html do
quote do
use Phoenix.Component
use PetalComponents
# ... existing imports
end
end
```
`use PetalComponents` imports every component so you can call them as `<.button>`, `<.modal>`, etc. without explicit aliases. If a `use PetalComponents` line is already present, skip this step.
### 5. Register the JS hooks
petal_components v4 ships JS hooks for the password/copyable/clearable inputs and the chat components (everything else is CSS + LiveView.JS only). Open `assets/js/app.js`, import the hooks, and merge them into your `LiveSocket`:
```js
import PetalComponents from "../../deps/petal_components/assets/js/petal_components"
const liveSocket = new LiveSocket("/live", Socket, {
params: { _csrf_token: csrfToken },
hooks: { ...PetalComponents }, // merge with existing hooks: { ...MyHooks, ...PetalComponents }
})
```
If the project has no `assets/js/app.js` (an API-only or minimal app), skip this — the hooks are only needed for those interactive components.
### 6. Verify
```sh
mix compile
```
Should compile cleanly. To smoke test, drop `<.button>Hello</.button>` in any HEEx template.
### 7. Brand colours (optional)
Components work out of the box: petal_components ships default colour ramps (blue `primary`, pink `secondary`, semantic hues, zinc `gray`). To use the project's brand colours instead, define the same variables AFTER the petal_components import in `app.css` - later definitions win:
```css
@theme inline {
--color-primary-50: var(--color-violet-50);
--color-primary-100: var(--color-violet-100);
/* ...one line per stop, 50-950, for any ramp you want to change... */
--color-primary-950: var(--color-violet-950);
}
```
The roles: `primary` is the base action colour and tints every variant of every component (solid fills, outline borders, ghost text); `secondary` is a second brand accent with the same rule; `info`/`success`/`warning`/`danger` carry meaning and should stay recognisable; `gray` is the neutral chrome. Map a role to any Tailwind hue by referencing that hue's variables, or use literal values.
### Installation rules of thumb for AI agents
- Read each file before editing. Do not blind-patch.
- If the project already uses `petal_components`, skip the steps that are already done. Report what was already in place.
- After installing, suggest calling `list_components` to see what's available.
## Hard rules
1. **Prefer a petal_components tag over raw HTML.** If you would reach for a `<button>`, `<table>`, `<input>`, `<div role="dialog">`, `<select>`, or any other common UI primitive, check for a petal_components equivalent first (`<.button>`, `<.table>`, `<.text_input>`, `<.modal>`, `<.select>`).
2. **Do not invent Tailwind soup for things petal_components already does.** No hand-rolled modal divs, no manual dropdown JS, no DIY form labels. There is almost certainly an existing component for it.
3. **Look up the schema before guessing attrs.** Do not assume attr names from memory. Call `list_components` and `get_component` (see below) to get the real attr/slot signature before writing HEEx.
4. **Call components as plain HEEx tags after `use PetalComponents`.** `<.button>`, `<.modal>`, `<.table>`, `<.card>`, etc. If you have not imported, qualify with the module: `<PetalComponents.Button.button />`. Note: the `pc-*` prefix you see in source is the CSS class prefix for styling, not part of the function name.
5. **Components work in both live and dead views.** Interactivity is Phoenix.LiveView.JS only (no Alpine.js as of v4). Some components (password/copyable/clearable inputs and the Chat family) use bundled JS hooks — register them once in your LiveSocket: `import PetalComponents from "../../deps/petal_components/assets/js/petal_components"` then `hooks: { ...PetalComponents }`.
6. **Form inputs come in two layers, pick deliberately.** Use `<.field type="..." />` when you want label + input + error + help text bundled (the common case in form contexts). Use the standalone primitives (`<.text_input>`, `<.select>`, `<.checkbox>`, etc.) when composing your own field layout.
## Discovering components
### Recommended: the MCP server
Install once:
```sh
claude mcp add petal --transport http https://mcp.petal.build/mcp
```
Then call:
- `list_components` returns every component with a one-line summary
- `get_component <name>` returns the full schema (attrs, slots, defaults, allowed values) plus a usage example
Equivalent installs exist for Cursor, Windsurf, Continue, Codex, and Cline. See https://petal.build/petal-components for setup snippets.
### Fallback: static reference
If the MCP is unavailable, the source of truth is https://hexdocs.pm/petal_components. Each `lib/petal_components/*.ex` module documents its component with `attr` and `slot` declarations you can read directly.
## Naming conventions
- **HEEx tags**: plain component name with a leading dot, e.g. `<.button>`, `<.modal>`, `<.breadcrumbs>`. No `pc_` prefix on the function name.
- **Modules**: `PetalComponents.Button`, `PetalComponents.Modal`, `PetalComponents.Breadcrumbs`. Importing via `use PetalComponents` is the common path.
- **Form primitives**: `<.text_input>`, `<.email_input>`, `<.select>`, `<.checkbox>`, `<.switch>`, `<.textarea>`, etc. (all defined in `PetalComponents.Form`).
- **Field wrapper**: `<.field type="text" | "email" | "select" | "checkbox" | "switch" | "radio-group" | ...>`
- **CSS classes**: use the `pc-` prefix for styling overrides (e.g. `pc-button`, `pc-button--primary`, `pc-modal`). This is the only place `pc-` appears.
## Common patterns
### Form in card
```heex
<.card>
<.card_content>
<.form for={@form} phx-submit="save">
<.field field={@form[:name]} label="Name" />
<.field field={@form[:email]} type="email" label="Email" />
<.button type="submit">Save</.button>
</.form>
</.card_content>
</.card>
```
### Modal with form
```heex
<.modal title="Edit user" max_width="md">
<.form for={@form} phx-submit="save">
<.field field={@form[:name]} label="Name" />
<.button type="submit">Save</.button>
</.form>
</.modal>
```
### Table with row actions
```heex
<.table>
<:col :let={user} label="Name">{user.name}</:col>
<:col :let={user} label="Email">{user.email}</:col>
<:col :let={user} label="">
<.button size="xs" variant="outline" phx-click="edit" phx-value-id={user.id}>
Edit
</.button>
</:col>
</.table>
```
### Alert / inline feedback
```heex
<.alert color="success" heading="Saved">
Your changes have been saved.
</.alert>
```
### Loading state on a button
```heex
<.button loading={@saving} phx-click="save">Save</.button>
```
## When in doubt
Stop guessing. Call `list_components` to see the full catalogue, then `get_component <name>` for the exact schema before writing HEEx. The MCP exists so you never have to invent component APIs from training data.
## Companion libraries
- **petal_pro** is the production Phoenix SaaS boilerplate built on petal_components. Use it as a reference for real-world composition (auth pages, dashboards, billing UI, tables with filters, etc.).
- **petal-components-mcp** is this rules file's companion - the MCP server that exposes schemas. Source: https://github.com/petalframework/petal-components-mcp.