Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: dropdown component #483

Merged
merged 16 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ let Hooks = {
StickyScroll: StickyScroll
};


Hooks.ScrollToTop = {
mounted() {
this.el.addEventListener("click", e => {
Expand All @@ -46,6 +47,23 @@ Hooks.ScrollToTop = {
}
}


Hooks.Dropdown = {
mounted() {
this.el.addEventListener("click", e => {
e.preventDefault()
if(this.el.nextElementSibling.classList.contains("hidden")) {
this.el.nextElementSibling.classList.remove("hidden")
this.el.classList.add("block")
}
else {
this.el.nextElementSibling.classList.add("hidden")
this.el.classList.remove("block")
}
})
}
}

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {
params: { _csrf_token: csrfToken },
Expand Down
23 changes: 15 additions & 8 deletions lib/atomic_web/components/calendar/calendar.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule AtomicWeb.Components.Calendar do
import AtomicWeb.CalendarUtils
import AtomicWeb.Components.CalendarMonth
import AtomicWeb.Components.CalendarWeek
import AtomicWeb.Components.Dropdown

alias Timex.Duration

Expand Down Expand Up @@ -85,14 +86,20 @@ defmodule AtomicWeb.Components.Calendar do
</div>
<div class="hidden md:ml-4 md:flex md:items-center">
<div class="relative">
<a @click="mode_view = !mode_view" class="flex cursor-pointer items-center py-2 pr-2 pl-3 text-sm font-medium text-zinc-700 hover:bg-zinc-50" id="menu-button" aria-expanded="false" aria-haspopup="true">
<%= if @mode == "month" do
gettext("Month view")
else
gettext("Week view")
end %>
<.icon name={:chevron_down} solid class="ml-2 h-5 w-5 text-zinc-400" />
</a>
<.dropdown
label={
if @mode == "month" do
gettext("Month view")
else
gettext("Week view")
end
}
type={:button}
items={[
%{name: gettext("Week view"), link: @current_week_path},
%{name: gettext("Month view"), link: @current_month_path}
]}
/>

<div x-bind:class="mode_view ?'block' : 'hidden'" class="absolute right-0 mt-3 w-36 origin-top-right overflow-hidden rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none" role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
<div class="py-1" role="none">
Expand Down
59 changes: 59 additions & 0 deletions lib/atomic_web/components/dropdown.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
defmodule AtomicWeb.Components.Dropdown do
@moduledoc false
use AtomicWeb, :component

import AtomicWeb.Components.Icon

attr :label, :string, required: true, doc: "The label of the dropdown."
attr :image, :string, default: "", doc: "The image of the dropdown."

attr :type, :atom,
default: :button,
values: [:button, :avatar],
doc: "The type of the dropdown."

attr :items, :list, default: [], doc: "The items to display in the dropdown."

def dropdown(%{type: :avatar} = assigns) do
~H"""
<div class="relative inline-block text-left">
<button id={"dropdown-#{assigns.label}"} type="button" phx-hook="Dropdown" class="inline-flex h-10 w-10 justify-center rounded-3xl border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50">
<%= if String.length(assigns.image) > 0 do %>
<img class="h-8 w-8 rounded-full" src={assigns.image} alt="" />
<% else %>
<%= extract_initials(assigns.label) %>
<% end %>
</button>
<div id="avatar" class="absolute right-0 mt-2 hidden w-56 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5">
<div class="py-1" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
<%= for item <- assigns.items do %>
<a href={item.link} class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900" role="menuitem">
<%= item.name %>
</a>
<% end %>
</div>
</div>
</div>
"""
end

def dropdown(%{type: :button} = assigns) do
~H"""
<div class="relative inline-block text-left">
<button id={"dropdown-#{assigns.label}"} type="button" phx-hook="Dropdown" class="inline-flex w-full justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50">
<%= assigns.label %>
<.icon name={:chevron_down} solid class="-mr-1 ml-2 h-5 w-5" />
</button>
<div id="button" class="absolute right-0 mt-2 hidden w-56 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5">
<div class="py-1" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
<%= for item <- assigns.items do %>
<a href={item.link} class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900" role="menuitem">
<%= item.name %>
</a>
<% end %>
</div>
</div>
</div>
"""
end
end
36 changes: 36 additions & 0 deletions storybook/components/dropdown.story.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule AtomicWeb.Storybook.Components.Dropdown do
use PhoenixStorybook.Story, :component

alias AtomicWeb.Components.Dropdown

def function, do: &Dropdown.dropdown/1

def variations do
[
%Variation{
id: :default,
attributes: %{
label: "Dropdown",
type: :button,
items: [
%{name: "Profile", link: "#"},
%{name: "Settings", link: "#"},
%{name: "Logout", link: "#"}
]
}
},
%Variation{
id: :avatar,
attributes: %{
label: "Dropdown",
type: :avatar,
items: [
%{name: "Profile", link: "#"},
%{name: "Settings", link: "#"},
%{name: "Logout", link: "#"}
]
}
}
]
end
end
Loading