Packages
petal_components
0.3.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
README.md
README.md
<p align="center">
<img src="https://res.cloudinary.com/wickedsites/image/upload/v1635752721/petal/logo_rh2ras.png" height="128">
<h1 align="center">Petal Components</h1>
</p>
## About 🌺
Petal stands for:
* [Phoenix](https://www.phoenixframework.org/)
* [Elixir](https://elixir-lang.org/)
* [Tailwind CSS](https://tailwindcss.com/)
* [Alpine JS](https://alpinejs.dev/)
* [Live View (HEEX)](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html)
Petal is a set of HEEX components that makes it easy for Phoenix developers to start building beautiful web apps.
<p align="center">
<img src="https://res.cloudinary.com/wickedsites/image/upload/v1635752726/petal/screenshot_tti5my.png" height="1200">
</p>
## Docs 📄
- [Install](#install)
- [Existing projects](#existing-projects)
- [New projects](#new-projects)
- [Roadmap](#roadmap)
- [Layout](#layout)
- [Form components](#form-components)
- [Buttons](#buttons)
- [Misc](#misc)
- [Examples](#examples)
- [Buttons](#buttons)
- [Button types](#button-types)
- [Button colors](#button-colors)
- [Button colors (outline)](#button-colors-(outline))
- [Button sizes](#button-sizes)
- [Button states](#button-states)
- [Disabled](#disabled)
- [Loading](#loading)
- [Button with icon](#button-with-icon)
- [Typography](#typography)
- [Heroicons](#heroicons)
- [Heroicons solid](#heroicons-solid)
- [Heroicons outline](#heroicons-outline)
- [Badges](#badges)
- [Alerts](#alerts)
- [Info alert](#info-alert)
- [Success alert](#success-alert)
- [Warning alert](#warning-alert)
- [Danger alert](#danger-alert)
- [Forms](#forms)
- [Text input](#text-input)
- [Text area](#text-area)
- [Select](#select)
- [Radios](#radios)
- [Dropdowns](#dropdowns)
- [Loading indicators](#loading-indicators)
## Install
For Petal to work you simply need Tailwind CSS and Alpine JS installed along with with some Tailwind configuration.
### Existing projects
1 - Follow [this guide](https://sergiotapia.com/phoenix-160-liveview-esbuild-tailwind-jit-alpinejs-a-brief-tutorial) to install Tailwind and Alpine.
2 - Add Petal to your deps:
`mix.exs`
```elixir
defp deps do
[
{:petal_components, "~> 0.3.0"},
]
end
```
3 - Modify your `tailwind.config.js` file to include these settings:
```js
const colors = require("tailwindcss/colors");
module.exports = {
mode: "jit",
purge: [
"../lib/*_web/**/*.*ex",
"./js/**/*.js",
// We need to include the Petal dependency so the classes get picked up by JIT.
"../deps/petal_components/**/*.*ex"
],
darkMode: false,
theme: {
extend: {
// Set these to your brand colors
colors: {
primary: colors.blue,
secondary: colors.pink,
},
},
},
plugins: [require("@tailwindcss/forms")],
};
```
4 - Alias the components in your `<your_project>_web.ex` file
```elixir
defmodule YourProjectWeb
...
defp view_helpers do
quote do
...
use PetalComponents
end
end
```
This will import the functions so you can go `<.button />` in your templates / live views.
If the function names clash with yours (eg. you already have a `.button` function) you can opt to alias the modules instead:
```elixir
defmodule YourProjectWeb
...
defp view_helpers do
quote do
...
alias PetalComponents.{
Heroicons,
Alert,
Badge,
Button,
Container,
Dropdown,
Form,
Loading,
Typography
}
end
end
```
### New projects
We recommend using [Petal boilerplate](https://github.com/petalframework/petal_boilerplate), which is a fresh Phoenix install with Tailwind + Alpine installed. It comes with a project renaming script so you can still rename your project to whatever you like.
## Roadmap
### Layout
- [x] container
### Form components
- [x] text input
- [x] select dropdown
- [x] textarea
- [x] checkbox
- [ ] multiple select
- [x] radios
- [ ] file upload
- [ ] switch
### Buttons
- [x] basic button
- [x] change size
- [x] change color
- [x] loading state (with spinner)
- [x] filled vs outline
- [ ] button group
### Misc
- [x] menu dropdown
- [ ] tooltips
- [ ] avatar
- [x] alerts
- [ ] tables
- [ ] cards
- [ ] breadcrumbs
- [ ] modal
- [ ] slide over
- [ ] spinners
- [ ] accordian
- [ ] pagination
- [x] badges
## Examples
### Containers
```elixir
<Container.container max_width="full | lg | md | sm">
```
### Buttons
#### Button types
```elixir
<.button label="Button">
<.a href="/" label="a">
<.patch href="/" label="Live Patch">
<.redirect href="/" label="Live Redirect">
```
#### Button colors
```elixir
<.button color="primary | secondary | white | success | danger" label="Primary" />
```
#### Button colors (outline)
```elixir
<.button color="primary | secondary | white | success | danger" label="Primary" variant="outline" />
```
#### Button sizes
```elixir
<.button size="sm | md | lg | xl">
```
#### Button states
##### Disabled
```elixir
<.button disabled type="a" href="/" label="a Disabled" />
<.button disabled color="primary" label="Button Disabled" />
<.patch disabled href="/" label="Live Patch Disabled" />
<.redirect disabled href="/" label="Live Redirect" />
```
##### Loading
```elixir
<.button loading type="a" href="/" label="a Loading" />
<.button loading label="Button Loading" />
<.patch loading href="/" label="Live Patch Loading" />
<.redirect loading href="/" label="Live Redirect Loading" />
```
#### Button with icon
```elixir
<.button icon type="a" href="/">
<Heroicons.Solid.home class="w-5 h-5" />
a with label
</.button>
```
### Typography
```elixir
<.h1>Heading 1</.h1>
<.h2>Heading 2</.h2>
<.h3>Heading 3</.h3>
<.h4>Heading 4</.h4>
<.h5>Heading 5</.h5>
```
### Heroicons
#### Heroicons solid
```elixir
<Heroicons.Solid.home class="w-6 h-6 text-blue-500" />
<Heroicons.Solid.render icon={:home} />
```
#### Heroicons outline
```elixir
<Heroicons.Outline.home class="w-6 h-6 text-blue-500" />
<Heroicons.Outline.render icon={:home} />
```
### Badges
```elixir
<.badge color="primary | secondary | White | Black | Green | Red | Blue | Gray | Light Gray | Pink | Purple | Orange | Yellow" label="Primary" />
```
### Alerts
#### Info alert
```elixir
<.alert state="info">
This is an info state
</.alert>
```
#### Success alert
```elixir
<.alert state="success" label="This is a success state" />
```
#### Warning alert
```elixir
<.alert state="warning" label="This is a warning state" />
```
#### Danger alert
```elixir
<.alert state="danger" label="This is a danger state" />
```
### Forms
#### Text input
```html
<.text_input form={:user} field={:name} placeholder="eg. John" />
<!-- With a label and bottom margin -->
<div class="mb-6">
<.form_label form={:user} field={:last_name} />
<.text_input form={:user} field={:last_name} placeholder="eg. Smith" />
</div>
<!-- Includes label and bottom margin -->
<.form_field
type="text_input"
form={:user}
field={:first_name}
/>
```
#### Text area
```html
<.textarea form={:user} field={:description} />
<!-- With a label and bottom margin -->
<div class="mb-6">
<.form_label form={:user} field={:description} />
<.textarea form={:user} field={:description} />
</div>
<!-- Includes label and bottom margin -->
<.form_field
type="textarea"
form={:user}
field={:description}
/>
```
#### Select
```html
<.select
options={["Admin": "admin", "User": "user"]}
form={:user}
field={:role}
/>
<!-- With a label and bottom margin -->
<div class="mb-6">
<.form_label form={:user} field={:role} />
<.select
options={["Admin": "admin", "User": "user"]}
form={:user}
field={:role}
/>
</div>
<!-- Includes label and bottom margin -->
<.form_field
type="select"
form={:user}
field={:first_name}
options={["Admin": "admin", "User": "user"]}
/>
```
#### Checkbox
```html
<!-- Includes the label and margin automatically -->
<.checkbox
form={:user}
field={:read_terms}
label="I accept"
/>
```
#### Radios
```html
<!-- A collection of radios - provide options like a select dropdown -->
<.radios
form={:user}
field={:eye_color}
options={["Green": "green", "Blue": "blue", "Gray": "gray"]}
/>
```
### Dropdowns
```elixir
<.dropdown label="Dropdown">
<.dropdown_menu_item type="button">
<Heroicons.Outline.home class="w-5 h-5 text-gray-500" />
Button item with icon
</.dropdown_menu_item>
<.dropdown_menu_item type="a" href="/" label="a item" />
<.dropdown_menu_item type="live_patch" href="/" label="Live Patch item" />
<.dropdown_menu_item type="live_redirect" href="/" label="Live Redirect item" />
</.dropdown>
```
### Loading indicators
```
<.spinner show={false} />
<.spinner show={true} size="sm" />
<.spinner show={true} size="md" class="text-green-500" />
<.spinner show={true} size="lg" class="text-red-500" />
```