Skip to content

Commit

Permalink
add menu group component
Browse files Browse the repository at this point in the history
  • Loading branch information
woylie committed Feb 11, 2024
1 parent 24e37ff commit ec3d36b
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- New component: `Doggo.menu/1`.
- New component: `Doggo.menu_bar/1`.
- New component: `Doggo.menu_button/1`.
- New component: `Doggo.menu_group/1`.
- New component: `Doggo.menu_item/1`.
- New component: `Doggo.radio_group/1`.
- New component: `Doggo.split_pane/1`.
Expand Down
89 changes: 86 additions & 3 deletions lib/doggo.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3430,7 +3430,7 @@ defmodule Doggo do
This component is meant for organizing actions within an application, rather
than for navigating between different pages or sections of a website.
See also `menu_bar/1` and `menu_button/1`.
See also `menu_bar/1`, `menu_button/1`, and `menu_group/1`.
> #### In Development {: .warning}
>
Expand Down Expand Up @@ -3540,7 +3540,7 @@ defmodule Doggo do
This component is meant for organizing actions within an application, rather
than for navigating between different pages or sections of a website.
See also `menu/1`, `menu_button/1`, and `menu_item/1`.
See also `menu/1`, `menu_button/1`, `menu_item/1`, and `menu_group/1`.
> #### In Development {: .warning}
>
Expand Down Expand Up @@ -3657,7 +3657,7 @@ defmodule Doggo do
Renders a button that toggles an actions menu.
This component can be used on its own or as part of a `menu_bar/1` or `menu/1`.
See also `menu_item/1`.
See also `menu_item/1` and `menu_group/1`.
For a button that toggles the visibility of an element that is not a menu, use
`disclosure_button/1`. For a button that toggles other states, use
Expand Down Expand Up @@ -3759,6 +3759,89 @@ defmodule Doggo do
"""
end

@doc """
This component can be used to group items within a `menu/1` or `menu_bar/1`.
See also `menu_button/1` and `menu_item/1`.
> #### In Development {: .warning}
>
> The necessary JavaScript for making this component fully functional and
> accessible will be added in a future version.
>
> **Missing features**
>
> - Focus management
> - Keyboard support
## Example
```heex
<Doggo.menu id="actions-menu" labelledby="actions-button" hidden>
<:item>
<Doggo.menu_group label="Dog actions">
<:item>
<Doggo.menu_item on_click={JS.push("view-dog-profiles")}>
View Dog Profiles
</Doggo.menu_item>
</:item>
<:item>
<Doggo.menu_item on_click={JS.push("add-dog-profile")}>
Add Dog Profile
</Doggo.menu_item>
</:item>
<:item>
<Doggo.menu_item on_click={JS.push("dog-care-tips")}>
Dog Care Tips
</Doggo.menu_item>
</:item>
</Doggo.menu_group>
</:item>
<:item role="separator" />
<:item>
<Doggo.menu_item on_click={JS.push("help")}>Help</Doggo.menu_item>
</:item>
</Doggo.menu>
```
"""
@doc type: :component
@doc since: "0.5.0"

attr :label, :string,
required: true,
doc: """
A accessibility label for the group. Set as `aria-label` attribute.
"""

attr :class, :any,
default: [],
doc: "Additional CSS classes. Can be a string or a list of strings."

attr :rest, :global, doc: "Any additional HTML attributes."

slot :item, required: true do
attr :role, :string,
values: ["none", "separator"],
doc: """
Sets the role of the list item. If the item has a menu item, menu
item radio group or menu item checkbox as a child, use `"none"`. If you
want to render a visual separator, use `"separator"`. The default is
`"none"`.
"""
end

def menu_group(assigns) do
~H"""
<ul class={@class} role="group" aria-label={@label} {@rest}>
<li :for={item <- @item} role={Map.get(item, :role, "none")}>
<%= if item[:role] != "separator" do %>
<%= render_slot(item) %>
<% end %>
</li>
</ul>
"""
end

@doc """
Renders a button that acts as a menu item within a `menu/1` or `menu_bar/1`.
Expand Down
75 changes: 75 additions & 0 deletions test/doggo_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3949,6 +3949,81 @@ defmodule DoggoTest do
end
end

describe "menu_group/1" do
test "default" do
assigns = %{}

html =
parse_heex(~H"""
<Doggo.menu_group label="Dog actions">
<:item>A</:item>
</Doggo.menu_group>
""")

ul = find_one(html, "ul:root")
assert attribute(ul, "role") == "group"
assert attribute(ul, "aria-label") == "Dog actions"

assert li = find_one(html, "ul > li")
assert attribute(li, "role") == "none"
assert text(li) == "A"
end

test "with separator" do
assigns = %{}

html =
parse_heex(~H"""
<Doggo.menu_group label="Dog actions">
<:item role="separator">A</:item>
</Doggo.menu_group>
""")

assert li = find_one(html, "ul > li")
assert attribute(li, "role") == "separator"
assert text(li) == ""
end

test "with additional class as string" do
assigns = %{}

html =
parse_heex(~H"""
<Doggo.menu_group label="Dog actions" class="is-rad">
<:item>A</:item>
</Doggo.menu_group>
""")

assert attribute(html, ":root", "class") == "is-rad"
end

test "with additional classes as list" do
assigns = %{}

html =
parse_heex(~H"""
<Doggo.menu_group label="Dog Carousel" class={["is-rad", "is-good"]}>
<:item>A</:item>
</Doggo.menu_group>
""")

assert attribute(html, ":root", "class") == "is-rad is-good"
end

test "with global attribute" do
assigns = %{}

html =
parse_heex(~H"""
<Doggo.menu_group label="Dog actions" data-test="hello">
<:item>A</:item>
</Doggo.menu_group>
""")

assert attribute(html, ":root", "data-test") == "hello"
end
end

describe "menu_item/1" do
test "default" do
assigns = %{}
Expand Down

0 comments on commit ec3d36b

Please sign in to comment.