Skip to content

Instantly share code, notes, and snippets.

@mazz
Created June 3, 2024 18:41
Show Gist options
  • Save mazz/f228b44a68918a856a964a3280685f6d to your computer and use it in GitHub Desktop.
Save mazz/f228b44a68918a856a964a3280685f6d to your computer and use it in GitHub Desktop.
defmodule WordWeb.Components.ChannelRow do
use Surface.LiveComponent
alias Surface.Components.{
LiveRedirect
}
alias WordWeb.Components.{
Button,
Card
}
@doc "The post data"
prop channel, :map, required: true
@doc "On join click"
prop join_click, :event
@doc "On leave click"
prop leave_click, :event
def render(assigns) do
~F"""
<Card>
<div id={@id} class={"flex flex-row justify-between flex-initial w-full min-h-[4rem]"}>
<div class="flex flex-col justify-between items-start pr-2 space-y-2">
<LiveRedirect class="text-sm font-bold text-gray-300 sp-underline primary hover:text-gray-100" to={"/c/#{@channel.readable_id}"}>
{"#{@channel.name}"}
</LiveRedirect>
<div class="flex flex-col space-y-2">
<div class={"text-sm text-gray-400 line-clamp-2 overflow-ellipsis overflow-hidden"}>
{@channel.description}
</div>
<div class="flex flex-row space-x-2">
<div class={"text-xs text-gray-200 bg-gray-600 rounded-lg px-2"}>
Posts {@channel.total_posts}
</div>
<div class={"text-xs text-gray-200 bg-gray-600 rounded-lg px-2"}>
Members {@channel.total_users}
</div>
</div>
</div>
</div>
<div>
<Button :if={!@channel.joined} click={@join_click} value={@channel.id} class="bg-secondary-600">Join</Button>
<Button :if={@channel.joined} click={@leave_click} value={@channel.id} class="bg-opacity-0 border-2 border-secondary-600 hover:bg-secondary-600 hover:bg-opacity-100">Leave</Button>
</div>
</div>
</Card>
"""
end
end
@mazz
Copy link
Author

mazz commented Jun 3, 2024

defmodule WordWeb.Components.Button do
  use Surface.Component

  @doc """
  The button type, defaults to "button", mainly used for instances like modal X to close style buttons
  where you don't want to set a type at all. Setting to nil makes button have no type.
  """
  prop type, :string, default: "button"

  @doc "The label of the button, when no content (default slot) is provided"
  prop label, :string

  @doc "The aria label for the button"
  prop aria_label, :string

  @doc "The color of the button"
  prop color, :string, values: ~w(primary secondary link info success warning danger)

  @doc "The value for the button"
  prop value, :string

  @doc "Button is expanded (full-width)"
  prop expand, :boolean

  @doc "Set the button as disabled preventing the user from interacting with the control"
  prop disabled, :boolean

  @doc "Outlined style"
  prop outlined, :boolean

  @doc "Rounded style"
  prop rounded, :boolean

  @doc "Hovered style"
  prop hovered, :boolean

  @doc "Focused style"
  prop focused, :boolean

  @doc "Active style"
  prop active, :boolean

  @doc "Selected style"
  prop selected, :boolean

  @doc "Loading state"
  prop loading, :boolean

  @doc "Triggered on click"
  prop click, :event

  @doc "Css classes to propagate down to button. Default class if no class supplied is simply _button_"
  prop class, :css_class, default: []

  @doc """
  The content of the generated `<button>` element. If no content is provided,
  the value of property `label` is used instead.
  """
  slot default

  defp base_style() do
    classes = [
      "font-bold",
      "cursor-pointer",
      "px-4",
      "py-3",
      "text-sm",
      "text-white",
      "rounded-md",
      "group",
      "hover:bg-opacity-60",
      "focus:outline-none",
      "focus:ring-0",
      "transition-colors"
    ]

    Enum.join(classes, " ")
  end

  def render(assigns) do
    ~F"""
    <button
      type={@type}
      aria-label={@aria_label}
      :on-click={@click}
      disabled={@disabled}
      value={@value}
      class={[
        base_style(),
        "bg-primary-500": @color == "primary",
        "bg-rose-500": @color == "danger",
        "bg-gray-600": @color == "secondary",
        "w-full": @expand,
        "cursor-not-allowed opacity-50": @disabled
      ] ++ @class}>
      <#slot>{@label}</#slot>
    </button>
    """
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment