Skip to content

Commit

Permalink
Add Menu component
Browse files Browse the repository at this point in the history
  • Loading branch information
davidalejandroaguilar committed Aug 5, 2024
1 parent a2821e5 commit e981978
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/phlexy_ui.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module PhlexyUI
autoload :Tabs, "phlexy_ui/tabs"
autoload :Drawer, "phlexy_ui/drawer"
autoload :Dropdown, "phlexy_ui/dropdown"
autoload :Menu, "phlexy_ui/menu"
end

loader.eager_load
51 changes: 51 additions & 0 deletions lib/phlexy_ui/menu.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

module PhlexyUI
class Menu < Base
def view_template(&)
generate_classes!(
component_html_class: :menu,
modifiers_map: MENU_MODIFIERS_MAP,
base_modifiers:,
options:
).then do |classes|
ul(class: classes, **options, &)
end
end

def title(*, **, &)
li(class: "menu-title", **, &)
end

def item(*base_modifiers, **, &)
generate_classes!(
modifiers_map: MENU_ITEM_MODIFIERS_MAP,
base_modifiers:,
options:
).then do |classes|
li(class: classes, &)
end
end

def submenu(*, **, &)
render SubMenu.new(*, **, &)
end

private

MENU_MODIFIERS_MAP = {
xs: "menu-xs",
sm: "menu-sm",
md: "menu-md",
lg: "menu-lg",
vertical: "menu-vertical",
horizontal: "menu-horizontal"
}.freeze

MENU_ITEM_MODIFIERS_MAP = {
disabled: "disabled",
active: "active",
focus: "focus"
}
end
end
57 changes: 57 additions & 0 deletions lib/phlexy_ui/menu/sub_menu.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

module PhlexyUI
class Menu
# @private
class SubMenu < Base
include Phlex::DeferredRender

def initialize(*, **)
super
@items ||= []
end

def view_template(&)
attributes = ATTRIBUTES_MAP.select do |key|
base_modifiers.include?(key)
end

details(**attributes) do
if @subtitle
summary do
render @subtitle
end
end

if @items.any?
ul do
@items.each do |item|
li do
render item
end
end
end
end
end
end

def subtitle(&block)
@subtitle = block
end

def item(&block)
@items << block
end

def submenu(*, **, &)
@items << self.class.new(*, **, &)
end

private

ATTRIBUTES_MAP = {
open: true
}.freeze
end
end
end
92 changes: 92 additions & 0 deletions spec/lib/phlexy_ui/menu_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
require "spec_helper"

describe PhlexyUI::Dropdown do
subject(:output) { render described_class.new }

describe "rendering a full menu" do
let(:component) do
Class.new(Phlex::HTML) do
def view_template(&)
render PhlexyUI::Menu.new(:xs) do |menu|
menu.title do
"My Menu"
end

menu.item do
"Item 1"
end

menu.item(:disabled) do
"Item 2"
end

menu.item(:active) do
"Item 3"
end

menu.item(:focus) do
"Item 4"
end

menu.item do
menu.submenu do |submenu_1|
submenu_1.subtitle do
"Parent 1"
end

submenu_1.item do
"Child 1"
end

submenu_1.submenu(:open) do |submenu_2|
submenu_2.subtitle do
"Parent 2"
end

submenu_2.item do
"Child 2"
end
end
end
end
end
end
end
end

subject(:output) do
render component.new
end

it "is expected to match the formatted HTML" do
expected_html = html <<~HTML
<ul class="menu menu-xs">
<li class="menu-title">My Menu</li>
<li>Item 1</li>
<li class="disabled">Item 2</li>
<li class="active">Item 3</li>
<li class="focus">Item 4</li>
<li>
<details>
<summary>Parent 1</summary>
<ul>
<li>Child 1</li>
<li>
<details open>
<summary>Parent 2</summary>
<ul>
<li>Child 2</li>
</ul>
</details>
</li>
</ul>
</details>
</li>
</ul>
HTML

is_expected.to eq(expected_html)
end
end
end

0 comments on commit e981978

Please sign in to comment.