View Source

Petal Components

About 🌺

Petal stands for:

Petal is a set of HEEX components that makes it easy for Phoenix developers to start building beautiful web apps.

Docs 📄

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 to install Tailwind and Alpine.

2 - Add Petal to your deps:

mix.exs

defp deps do
  [
    {:petal_components, "~> 0.1.0"},
  ]
end

3 - Modify your tailwind.config.js file to include these settings:

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")],
};

New projects

We recommend using 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

  • [ ] menu dropdown
  • [ ] tooltips
  • [ ] avatar
  • [x] alerts
  • [ ] tables
  • [ ] cards
  • [ ] breadcrumbs
  • [ ] modal
  • [ ] slide over
  • [ ] spinners
  • [ ] accordian
  • [ ] pagination
  • [x] badges

Examples

Containers

<Container.container max_width="full | lg | md | sm">

Buttons

Button types

<Button.button label="Button">
<Button.a href="/" label="a">
<Button.patch href="/" label="Live Patch">
<Button.redirect href="/" label="Live Redirect">

Button colors

<Button.button color="primary | secondary | white | success | danger" label="Primary" />

Button colors (outline)

<Button.button color="primary | secondary | white | success | danger" label="Primary" variant="outline" />

Button sizes

<Button.button size="sm | md | lg | xl">

Button states

Disabled
<Button.button disabled type="a" href="/" label="a Disabled" />
<Button.button disabled color="primary" label="Button Disabled" />
<Button.patch disabled href="/" label="Live Patch Disabled" />
<Button.redirect disabled href="/" label="Live Redirect" />
Loading
<Button.button loading type="a" href="/" label="a Loading" />
<Button.button loading label="Button Loading" />
<Button.patch loading href="/" label="Live Patch Loading" />
<Button.redirect loading href="/" label="Live Redirect Loading" />

Button with icon

<Button.button icon type="a" href="/">
  <Heroicons.Solid.home class="w-5 h-5" />
  a with label
</Button.button>

Typography

<Typography.h1>Heading 1</Typography.h1>
<Typography.h2>Heading 2</Typography.h2>
<Typography.h3>Heading 3</Typography.h3>
<Typography.h4>Heading 4</Typography.h4>
<Typography.h5>Heading 5</Typography.h5>

Heroicons

Heroicons solid

<Heroicons.Solid.home class="w-6 h-6 text-blue-500" />

Heroicons outline

<Heroicons.Outline.home class="w-6 h-6 text-blue-500" />

Badges

<Badge.badge color="primary | secondary | White | Black | Green | Red | Blue | Gray | Light Gray | Pink | Purple | Orange | Yellow" label="Primary" />

Alerts

Info alert

<Alert.alert state="info">
  This is an info state
</Alert.alert>

Success alert

<Alert.alert state="success" label="This is a success state" />

Warning alert

<Alert.alert state="warning" label="This is a warning state" />

Danger alert

<Alert.alert state="danger" label="This is a danger state" />

Forms

Text input

<Form.text_input form={:user} field={:name} placeholder="eg. John" />

Text area

<Form.textarea form={:user} field={:description} />

Select

<Form.select
  options={["Admin": "admin", "User": "user"]}
  form={:user}
  field={:role}
/>

Radios

<Form.radios
  form={:user}
  field={:eye_color}
  options={["Green": "green", "Blue": "blue", "Gray": "gray"]}
/>
<Dropdown.dropdown label="Dropdown">
  <Dropdown.dropdown_menu_item type="button">
    <Heroicons.Outline.home class="w-5 h-5 text-gray-500" />
    Option with icon
  </Dropdown.dropdown_menu_item>
  <Dropdown.dropdown_menu_item type="button" label="Option 2" />
  <Dropdown.dropdown_menu_item type="button" label="Option 3" />
</Dropdown.dropdown>