Class: UI::NavigationMenuLinkComponent

Inherits:
ViewComponent::Base
  • Object
show all
Includes:
NavigationMenuLinkBehavior, SharedAsChildBehavior
Defined in:
app/view_components/ui/navigation_menu_link_component.rb

Overview

LinkComponent - ViewComponent implementation

Navigation link component. Supports asChild pattern for composition with link_to.

Examples:

Basic usage

<%= render UI::LinkComponent.new(href: "/docs") do %>
  Documentation
<% end %>

With asChild for Rails link_to

<%= render UI::LinkComponent.new(as_child: true) do %>
  <%= link_to "Documentation", docs_path %>
<% end %>

As trigger style (for direct links without dropdown)

<%= render UI::LinkComponent.new(as_child: true, trigger_style: true) do %>
  <%= link_to "About", about_path %>
<% end %>

Instance Method Summary collapse

Methods included from SharedAsChildBehavior

#merge_attributes

Methods included from NavigationMenuLinkBehavior

#navigation_menu_link_classes, #navigation_menu_link_data_attributes, #navigation_menu_link_html_attributes, #navigation_menu_link_trigger_style_classes

Constructor Details

#initialize(href: nil, active: false, as_child: false, trigger_style: false, classes: "", **attributes) ⇒ NavigationMenuLinkComponent

Returns a new instance of NavigationMenuLinkComponent.

Parameters:

  • href (String) (defaults to: nil)

    URL for the link (ignored when as_child: true)

  • active (Boolean) (defaults to: false)

    Whether this link is currently active

  • as_child (Boolean) (defaults to: false)

    When true, injects attributes into child element

  • trigger_style (Boolean) (defaults to: false)

    When true, uses trigger styling (for direct links)

  • classes (String) (defaults to: "")

    Additional CSS classes to merge

  • attributes (Hash)

    Additional HTML attributes



33
34
35
36
37
38
39
40
# File 'app/view_components/ui/navigation_menu_link_component.rb', line 33

def initialize(href: nil, active: false, as_child: false, trigger_style: false, classes: "", **attributes)
  @href = href
  @active = active
  @as_child = as_child
  @trigger_style = trigger_style
  @classes = classes
  @attributes = attributes
end

Instance Method Details

#callObject



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'app/view_components/ui/navigation_menu_link_component.rb', line 42

def call
  link_attrs = build_link_attributes

  if @as_child
    # asChild mode: merge attributes into child element using Nokogiri
    rendered = content.to_s
    doc = Nokogiri::HTML::DocumentFragment.parse(rendered)
    first_element = doc.children.find { |node| node.element? }

    if first_element
      # Merge data attributes
      link_attrs.fetch(:data, {}).each do |key, value|
        next if value.nil?

        html_key = key.to_s.gsub("__", "--").tr("_", "-")
        first_element["data-#{html_key}"] = value.to_s
      end

      # Merge CSS classes with TailwindMerge
      if link_attrs[:class]
        existing_classes = first_element["class"] || ""
        merged_classes = TailwindMerge::Merger.new.merge([existing_classes, link_attrs[:class]].join(" "))
        first_element["class"] = merged_classes
      end

      # Merge other attributes (except data and class)
      link_attrs.except(:data, :class).each do |key, value|
        next if value.nil?

        first_element[key.to_s.tr("_", "-")] = value.to_s
      end

      doc.to_html.html_safe
    else
      content
    end
  else
    # Default mode: render as anchor
     :a, **link_attrs do
      content
    end
  end
end