Current section

Files

Jump to
oban_web lib oban web components sidebar_components.ex
Raw

lib/oban/web/components/sidebar_components.ex

defmodule Oban.Web.SidebarComponents do
use Oban.Web, :html
attr :csp_nonces, :map
attr :width, :integer, default: 320
slot :inner_block
def sidebar(assigns) do
~H"""
<style nonce={@csp_nonces.style}>
#sidebar {
width: var(--sidebar-width, <%= @width %>px);
}
</style>
<div id="sidebar" class="relative flex-none mr-2 pr-3" phx-hook="SidebarResizer">
{render_slot(@inner_block)}
<div
data-resize-handle
class="absolute top-0 right-0 bottom-0 w-1 cursor-col-resize group hover:bg-violet-400 transition-colors"
>
<div class="absolute top-8 right-0 w-1 h-12 bg-gray-300 dark:bg-gray-600 group-hover:bg-violet-500 rounded-full transition-colors">
</div>
</div>
</div>
"""
end
attr :name, :string, required: true
attr :headers, :list, required: true
slot :inner_block
def section(assigns) do
~H"""
<div id={@name} class="bg-transparent dark:bg-transparent w-full mb-3 overflow-hidden">
<header class="flex justify-between items-center py-3">
<button
id={"#{@name}-toggle"}
class="text-gray-400 hover:text-violet-500 dark:text-gray-500 dark:hover:text-violet-500"
data-title={"Toggle #{@name}"}
phx-click={toggle(@name)}
phx-hook="Tippy"
>
<Icons.icon
name="icon-chevron-right"
class="w-4 h-4 mt-1 mr-1 transition-transform rotate-90"
/>
</button>
<h3 class="dark:text-gray-200 font-bold">{String.capitalize(@name)}</h3>
<div class="ml-auto flex space-x-2 text-right text-xs tracking-tight text-gray-600 dark:text-gray-400 uppercase">
<span :for={header <- @headers} class="w-12">{header}</span>
</div>
</header>
<div id={"#{@name}-rows"}>{render_slot(@inner_block)}</div>
</div>
"""
end
attr :name, :string, required: true
attr :values, :list, required: true
attr :patch, :any, required: true
attr :active, :boolean, default: false
attr :exclusive, :boolean, default: false
slot :statuses
def filter_row(assigns) do
class =
cond do
assigns.exclusive and assigns.active ->
"rounded-md bg-white hover:bg-white dark:bg-gray-800 dark:hover:bg-gray-800"
assigns.exclusive ->
"rounded-md hover:bg-gray-100 dark:hover:bg-gray-800"
assigns.active ->
"border-violet-500 hover:border-violet-500 focus:border-violet-500"
true ->
"hover:border-violet-400 focus:border-violet-200"
end
assigns = assign(assigns, :class, class)
~H"""
<.link
class={["flex justify-between pr-2 py-2 ml-2 my-0.5 border-l-4 border-transparent", @class]}
id={"filter-#{@name}"}
patch={@patch}
replace={true}
>
<span class={[
"pl-2 text-sm text-gray-700 dark:text-gray-300 text-left tabular font-medium truncate",
if(@active, do: "font-semibold")
]}>
{String.downcase(@name)}
</span>
<div class="flex-none flex items-center space-x-2">
<div
:if={@statuses}
class="flex items-center text-right space-x-1 text-gray-600 dark:text-gray-400"
>
{render_slot(@statuses)}
</div>
<span
:for={value <- @values}
class="block w-10 text-sm text-right tabular text-gray-600 dark:text-gray-400"
>
{integer_to_estimate(value)}
</span>
</div>
</.link>
"""
end
defp toggle(prefix) do
%JS{}
|> JS.toggle(in: "fade-in-scale", out: "fade-out-scale", to: "##{prefix}-rows")
|> JS.add_class("rotate-90", to: "##{prefix}-toggle svg:not(.rotate-90)")
|> JS.remove_class("rotate-90", to: "##{prefix}-toggle svg.rotate-90")
end
end