sloanelybutsurely.com/lib/web/components/core_components.ex

149 lines
3.7 KiB
Elixir
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

defmodule Web.CoreComponents do
@moduledoc """
Provides core UI components.
"""
use Phoenix.Component
attr :class, :string, default: nil
attr :global, :global
slot :inner_block
def title(assigns) do
~H"""
<h1 class={["font-bold text-xl mb-3", @class]} {@global}>{render_slot(@inner_block)}</h1>
"""
end
attr :class, :string, default: nil
attr :global, :global
slot :inner_block
def subtitle(assigns) do
~H"""
<h2 class={["font-bold text-lg mb-2", @class]} {@global}>{render_slot(@inner_block)}</h2>
"""
end
attr :class, :string, default: nil
attr :global, :global,
include: ~w[navigate patch href replace method csrf_token download hreflang referrerpolicy rel target type]
slot :inner_block
def a(assigns) do
~H"""
<.link class={["hover:underline", @class]} {@global}>{render_slot(@inner_block)}</.link>
"""
end
attr :class, :string, default: nil
attr :type, :string, default: "button"
attr :global, :global
slot :inner_block
def button(assigns) do
~H"""
<button type={@type} class={["hover:underline", @class]} {@global}>
{render_slot(@inner_block)}
</button>
"""
end
attr :class, :string, default: nil
attr :field, Phoenix.HTML.FormField, required: true
attr :type, :string, default: "text"
attr :global, :global, include: ~w[required placeholder]
def input(%{type: "textarea"} = assigns) do
~H"""
<textarea
class={["px-2 py-1 border border-gray-400 rounded", @class]}
id={@field.id}
name={@field.name}
{@global}
>{@field.value}</textarea>
"""
end
def input(assigns) do
~H"""
<input
class={["px-2 py-1 border border-gray-400 rounded", @class]}
type={@type}
id={@field.id}
name={@field.name}
value={@field.value}
{@global}
/>
"""
end
@doc """
Renders a [Heroicon](https://heroicons.com).
Heroicons come in three styles outline, solid, and mini.
By default, the outline style is used, but solid and mini may
be applied by using the `-solid` and `-mini` suffix.
You can customize the size and colors of the icons by setting
width, height, and background color classes.
Icons are extracted from the `deps/heroicons` directory and bundled within
your compiled app.css by the plugin in your `assets/tailwind.config.js`.
## Examples
<.icon name="hero-x-mark-solid" />
<.icon name="hero-arrow-path" class="ml-1 w-3 h-3 animate-spin" />
"""
attr :name, :string, required: true
attr :class, :string, default: nil
def icon(%{name: "hero-" <> _} = assigns) do
~H"""
<span class={[@name, @class]} />
"""
end
attr :format, :string, required: true
attr :value, :any, default: nil
attr :formatter, :atom, default: :default
attr :timezone, :string, default: "America/New_York"
attr :global, :global
def timex(%{value: nil} = assigns) do
~H"""
<time datetime="">--</time>
"""
end
def timex(%{value: value, timezone: timezone} = assigns) do
assigns =
assign_new(assigns, :local_value, fn ->
case value do
%DateTime{} = datetime ->
datetime
%NaiveDateTime{} = naive ->
naive
|> DateTime.from_naive!("Etc/UTC")
|> DateTime.shift_zone!(timezone)
end
end)
~H"""
<time
datetime={Timex.format!(@local_value, "{ISO:Extended}")}
title={Timex.format!(@local_value, "{Mshort} {D}, {YYYY}, {h12}:{m} {AM} {Zabbr}")}
{@global}
>
{Timex.format!(@local_value, @format, timex_formatter(@formatter))}
</time>
"""
end
defp timex_formatter(formatter) do
Module.concat(Timex.Format.DateTime.Formatters, :string.titlecase("#{formatter}"))
end
end