README.md

# Tremorx
<p align="start">
  <a href="https://hex.pm/packages/tremorx">
    <img alt="Hex Version" src="https://img.shields.io/hexpm/v/tremorx.svg">
  </a>

  <a href="https://hexdocs.pm/tremorx">
    <img alt="Hex Docs" src="http://img.shields.io/badge/hex.pm-docs-green.svg?style=flat">
  </a>

  <a href="https://opensource.org/license/mit">
    <img alt="MIT License" src="https://img.shields.io/hexpm/l/tremorx">
  </a>

  <a href="https://tremorx.fly.dev/getting_started">
    <img alt="Phoenix Storybook" src="https://img.shields.io/badge/phoenix-storybook-purple">
  </a>
</p>

An Elixir Phoenix component library inspired by [Tremor](https://www.tremor.so/) - The react library to build dashboards fast.

> [!WARNING]
> The current version is an alpha version. Please report any bugs you find!

## Docs and Storybook

Preview the components and examples storybook available at [https://tremorx.fly.dev](https://tremorx.fly.dev/getting_started)

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `tremorx` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:tremorx, "~> 0.1.1"}
    
    # via git
    {:tremorx, git: "https://github.com/briankariuki/tremorx.git"}
  ]
end
```
Add tremorx to the dependecies section in `assets/package.json` like this:

If you don't have a `package.json` file, run `npm init -y`

```
{
  "dependencies": {
    #  Add this line
    "tremorx": "file:../deps/tremorx"
    
    # If in umbrella project
    "tremorx": "file:../../../deps/tremorx"
  } 
}
```

Then run `npm install` in the assets folder.

Then import the tremorx hooks in your `assets/js/app.js` file like this:
```
# Import the hooks
import { TremorHooks } from "tremorx";

# Add the hooks to the LiveSocket hooks option
let liveSocket = new LiveSocket("/live", Socket, {
  hooks: {...MyHooks, ...TremorxHooks},
});
```

Update your `*_web.ex` file like this:

```
defp html_helpers do
  quote do
    
    # Add this line
    use Tremorx

    # Routes generation with the ~p sigil
    unquote(verified_routes())
  end
end
```

Configure your `tailwind.config.js` file with the follwing:

Allow tailwind to find css classes defined in this library by adding the following lines to the `content` section in `tailwind.config.js`
```
content: [
  # Add these two lines.
  "../deps/tremorx/lib/components/**/*.ex",
  "../deps/tremorx/lib/js/*.js",

  # If in umbrella.
  "../../deps/tremorx/lib/components/**/*.ex",
  "../../deps/tremorx/lib/js/*.js",
]
```

Configure the tremorx theme tokens by adding these theme extensions in `theme` section in `tailwind.config.js`. You can read more about theming [Here](https://www.tremor.so/docs/getting-started/theming)

```
theme: {
  # Extend your theme with tremor's default config
  extend: {
    colors: {
      tremor: {
        brand: {
          faint: "#eff6ff",
          muted: "#bfdbfe",
          subtle: "#60a5fa",
          DEFAULT: "#3b82f6",
          emphasis: "#1d4ed8",
          inverted: "#ffffff",
        },
        background: {
          muted: "#f9fafb",
          subtle: "#f3f4f6",
          DEFAULT: "#ffffff",
          emphasis: "#374151",
        },
        border: {
          DEFAULT: "#e5e7eb",
        },
        ring: {
          DEFAULT: "#e5e7eb",
        },
        content: {
          subtle: "#9ca3af",
          DEFAULT: "#6b7280",
          emphasis: "#374151",
          strong: "#111827",
          inverted: "#ffffff",
        },
      },

      "dark-tremor": {
        brand: {
          faint: "#0B1229",
          muted: "#172554",
          subtle: "#1e40af",
          DEFAULT: "#3b82f6",
          emphasis: "#60a5fa",
          inverted: "#030712",
        },
        background: {
          muted: "#131A2B",
          subtle: "#1f2937",
          DEFAULT: "#111827",
          emphasis: "#d1d5db",
        },
        border: {
          DEFAULT: "#374151",
        },
        ring: {
          DEFAULT: "#1f2937",
        },
        content: {
          subtle: "#4b5563",
          DEFAULT: "#6b7280",
          emphasis: "#e5e7eb",
          strong: "#f9fafb",
          inverted: "#000000",
        },
      },
    },
    boxShadow: {
      # light
      "tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
      "tremor-card":
        "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
      "tremor-dropdown":
        "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
      # dark
      "dark-tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
      "dark-tremor-card":
        "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
      "dark-tremor-dropdown":
        "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
    },
    borderRadius: {
      "tremor-small": "0.375rem",
      "tremor-default": "0.5rem",
      "tremor-full": "9999px",
    },
    fontSize: {
      "tremor-label": ["0.75rem"],
      "tremor-default": ["0.875rem", { lineHeight: "1.25rem" }],
      "tremor-title": ["1.125rem", { lineHeight: "1.75rem" }],
      "tremor-metric": ["1.875rem", { lineHeight: "2.25rem" }],
    },
  },
}

```

Also safelist some css classes to prevent tailwind from purging them. To do this add the following to the `safelist` section in `tailwind.config.js`

```
safelist: [
  {
    pattern:
      /^(bg-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
    variants: ["hover", "ui-selected"],
  },
  {
    pattern:
      /^(text-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
    variants: ["hover", "ui-selected"],
  },
  {
    pattern:
      /^(border-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
    variants: ["hover", "ui-selected"],
  },
  {
    pattern:
      /^(ring-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
  },
  {
    pattern:
      /^(stroke-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
  },
  {
    pattern:
      /^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
  },
  { pattern: /^\-?m(\w?)-/ },
  { pattern: /^p(\w?)-/ },
  { pattern: /^text-/ },
  { pattern: /^bg-/ },
  { pattern: /^w-/ },
  { pattern: /^h-/ },
  { pattern: /^h(\w?)-/ },
  { pattern: /^grid-/ },
  { pattern: /^col-/ },
  { pattern: /^border-/ },
  { pattern: /^gap-/ },
  { pattern: /^min-/ },
],

```

## Usage
In your template import the component you need. For example,

```
alias Tremorx.Components.Input
alias Tremorx.Components.Layout
alias Tremorx.Components.Text
```

Then use like the following

```
<Layout.col class="space-y-1.5">
  <label for="name">
    <Text.text class="text-tremor-content">
      Name
    </Text.text>
  </label>

  <Input.text_input
    id="name"
    name="user[name]"
    placeholder="juma tano"
    type="text"
    field={f[:name]}
    value={f[:name].value}
    error={false}
    error_message={nil}
  />
</Layout.col>

```

## Components

#### UI Components
  - [ ] Accordion
  - [x] Badges
  - [x] Button
  - [x] Callout
  - [x] Card
  - [ ] Date range picker
  - [ ] Dialog
  - [x] Divider
  - [x] Icons
  - [x] Legend
  - [x] List
  - [ ] Number Input
  - [x] Select
  - [ ] Switch
  - [x] Table
  - [x] Tabs
  - [x] Text Input
  - [x] Textarea

#### Visualization Components
  - [x] Area Chart
  - [x] Bar Chart
  - [x] Donut Chart
  - [x] Line Chart
  - [ ] Scatter Chart
  - [ ] Funnel Chart
  - [ ] Bar List
  - [x] Progress Bar
  - [ ] Marker Bar
  - [ ] Delta Bar
  - [ ] Category Bar
  - [ ] Progress Circle
  - [ ] Spark Charts
  - [ ] Tracker

#### Extra Components
  - [x] Dropdown
  - [x] Tooltip
  - [ ] GeoJSON Map
  

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/tremorx>.