From 9a86d60b7244e0e5ff63f48d8012e3be70ebf972 Mon Sep 17 00:00:00 2001 From: Dzung Nguyen Date: Tue, 12 Nov 2024 22:48:21 +0700 Subject: [PATCH] Add helper for css style --- lib/salad_ui.ex | 9 + lib/salad_ui/helpers.ex | 23 ++- lib/salad_ui/{slidebar.ex => sidebar.ex} | 210 +++++++++++++++++++++-- 3 files changed, 221 insertions(+), 21 deletions(-) rename lib/salad_ui/{slidebar.ex => sidebar.ex} (72%) diff --git a/lib/salad_ui.ex b/lib/salad_ui.ex index 1c858f4..ae00544 100644 --- a/lib/salad_ui.ex +++ b/lib/salad_ui.ex @@ -49,6 +49,15 @@ defmodule SaladUI do import SaladUI.Tabs import SaladUI.Textarea import SaladUI.Tooltip + import SaladUI.Collapsible + import SaladUI.Chart + import SaladUI.AlertDialog + import SaladUI.Popover + import SaladUI.Accordion + import SaladUI.RadioGroup + import SaladUI.ToggleGroup + import SaladUI.Toggle + import SaladUI.Sidebar end end end diff --git a/lib/salad_ui/helpers.ex b/lib/salad_ui/helpers.ex index b61864d..958a5b2 100644 --- a/lib/salad_ui/helpers.ex +++ b/lib/salad_ui/helpers.ex @@ -162,8 +162,9 @@ defmodule SaladUI.Helpers do |> Map.keys() |> Enum.map(fn variant_key -> # Get the variant value from input or use default - variant_value = Map.get(class_input, variant_key) || - Map.get(default_variants, variant_key) + variant_value = + Map.get(class_input, variant_key) || + Map.get(default_variants, variant_key) # Get the variant options map variant_options = Map.get(variants, variant_key, %{}) @@ -175,8 +176,26 @@ defmodule SaladUI.Helpers do |> Enum.join(" ") end + @doc """ + This function build css style string from map of css style + + ## Examples + ```elixir + css_style = %{ + "background-color": "red", + "color": "white", + "font-size": "16px", + } + style(css_style) + + # => "background-color: red; color: white; font-size: 16px;" + ``` + """ + def style(css_map) do + Enum.map_join(css_map, "; ", fn {k, v} -> "#{k}: #{v}" end) <> ";" + end # Translate error message # borrowed from https://github.com/petalframework/petal_components/blob/main/lib/petal_components/field.ex#L414 diff --git a/lib/salad_ui/slidebar.ex b/lib/salad_ui/sidebar.ex similarity index 72% rename from lib/salad_ui/slidebar.ex rename to lib/salad_ui/sidebar.ex index e62e954..97c6f6d 100644 --- a/lib/salad_ui/slidebar.ex +++ b/lib/salad_ui/sidebar.ex @@ -6,12 +6,44 @@ defmodule SaladUI.Sidebar do import SaladUI.Input import SaladUI.Separator import SaladUI.Sheet + import SaladUI.Skeleton import SaladUI.Tooltip @sidebar_width "16rem" @sidebar_width_mobile "18rem" @sidebar_width_icon "3rem" + + @doc """ + Render + """ + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) + + def sidebar_provider(assigns) do + assigns = assign(assigns, %{sidebar_width: @sidebar_width, sidebar_width_icon: @sidebar_width_icon}) + ~H""" +
+ <%= render_slot(@inner_block) %> +
+ """ + end + @doc """ Render """ @@ -72,7 +104,6 @@ defmodule SaladUI.Sidebar do data-variant={@variant} data-side={@side} > - {/* This is what handles the sidebar gap on desktop */} """ end @@ -231,7 +264,7 @@ defmodule SaladUI.Sidebar do attr(:class, :string, default: nil) attr(:rest, :global) - def assigns do + def sidebar_footer(assigns) do ~H"""
""" @@ -313,6 +346,7 @@ defmodule SaladUI.Sidebar do @doc """ Render + TODO: class merge not work well here """ attr(:class, :string, default: nil) attr(:rest, :global) @@ -323,11 +357,11 @@ defmodule SaladUI.Sidebar do
svg]:size-4 [&>svg]:shrink-0", + Enum.join([ + "duration-200 flex h-8 shrink-0 items-center rounded-md px-2 font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0 text-xs", "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0", @class - ]) + ], " ") } {@rest} > @@ -440,38 +474,37 @@ defmodule SaladUI.Sidebar do attr :variant, :string, values: ~w(default outline), default: "default" attr :size, :string, values: ~w(default sm lg), default: "default" attr :is_active, :boolean, default: false - attr :tooltip, :map, default: nil attr(:class, :string, default: nil) attr :is_mobile, :boolean, default: false attr :state, :string, default: "expanded" attr(:rest, :global) slot(:inner_block, required: true) + slot :tooltip, required: true def sidebar_menu_button(assigns) do button = ~H""" """ + assigns = assign(assigns, :button, button) + if assigns[:tooltip] do ~H""" <.tooltip> <.tooltip_trigger> - <%= button %> + <%= @button %> - <.tooltip_content - side="right" - align="center" - hidden={state != "collapsed" || @is_mobile} - {@tooltip} - /> + <.tooltip_content side="right" align="center" hidden={@state != "collapsed" || @is_mobile}> + <%= render_slot(@tooltip) %> + """ else @@ -511,6 +544,145 @@ defmodule SaladUI.Sidebar do """ end + @doc """ + Render + """ + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) + + def sidebar_menu_badge(assigns) do + ~H""" +
+ <%= render_slot(@inner_block) %> +
+ """ + end + + @doc """ + Render + """ + attr(:class, :string, default: nil) + attr :show_icon, :boolean, default: false + attr(:rest, :global) + + def sidebar_menu_skeleton(assigns) do + width = :rand.uniform(40) + 50 + assigns = assign(assigns, :width, width) + + ~H""" +
+ <.skeleton :if={@show_icon} class="size-4 rounded-md" data-sidebar="menu-skeleton-icon" /> + <.skeleton + class="h-4 flex-1 max-w-[--skeleton-width]" + data-sidebar="menu-skeleton-text" + style={ + %{ + "--skeleton-width": @width + } + } + /> +
+ """ + end + + @doc """ + Render + """ + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) + + def sidebar_menu_sub(assigns) do + ~H""" +
    + <%= render_slot(@inner_block) %> +
+ """ + end + + @doc """ + Render + """ + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) + + def sidebar_menu_sub_item(assigns) do + ~H""" +
  • + <%= render_slot(@inner_block) %> +
  • + """ + end + + @doc """ + Render + """ + attr :size, :string, values: ~w(sm md), default: "md" + attr :is_active, :boolean, default: false + attr(:class, :string, default: nil) + attr(:rest, :global) + slot(:inner_block, required: true) + + def sidebar_menu_sub_button(assigns) do + ~H""" + span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground", + "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground", + @size == "sm" && "text-xs", + @size == "md" && "text-sm", + "group-data-[collapsible=icon]:hidden", + @class + ]) + } + {@rest} + > + <%= render_slot(@inner_block) %> + + """ + end + @variant_config %{ variants: %{ variant: %{