Class: Avo::Sidebar::LinkComponent

Inherits:
BaseComponent
  • Object
show all
Defined in:
app/components/avo/sidebar/link_component.rb

Overview

A single sidebar link (leaf). variant: :default or :subitem. Knows nothing about menus; callers pass the path, label and resolved active (a match mode like :inclusive, or a boolean to force it).

Constant Summary collapse

PALETTE_COLORS =

The raw Tailwind palette names accepted for the tinted sidebar icon. Each has a matching .sidebar-link--color-<name> rule in css/sidebar.css.

(Avo::UI::BadgeComponent::VALID_COLORS - %i[neutral success info warning danger]).freeze

Instance Method Summary collapse

Instance Method Details

#color_classObject



47
48
49
# File 'app/components/avo/sidebar/link_component.rb', line 47

def color_class
  "sidebar-link--color-#{@color}" if @color.present?
end

#is_external?Boolean

Returns:

  • (Boolean)


64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/components/avo/sidebar/link_component.rb', line 64

def is_external?
  uri = URI(@path)
  # Paths without a scheme are always internal (relative app paths).
  return false if uri.scheme.blank?

  # A link with a scheme is internal only when its path is mounted under Avo.
  # Compare against the URI path component, not the whole URL string, otherwise
  # hosts like "avohq.io" falsely match a "/avo" mount path (via "//avohq.io").
  # Use root_path_without_url so prefix_path + mount_path setups are recognized.
  !uri.path.start_with?(helpers.root_path_without_url)
rescue URI::InvalidURIError
  true
end

Backwards compatibility with ViewComponent 3.x



84
85
86
87
88
89
90
# File 'app/components/avo/sidebar/link_component.rb', line 84

def link_caller
  if Gem::Version.new(ViewComponent::VERSION::STRING) >= Gem::Version.new("4.0.0")
    helpers
  else
    self
  end
end


58
59
60
61
62
# File 'app/components/avo/sidebar/link_component.rb', line 58

def link_data
  return @data if @hotkey.blank?

  @data.merge(hotkey: @hotkey)
end


92
93
94
# File 'app/components/avo/sidebar/link_component.rb', line 92

def link_icon
  @icon
end

For external links active_link_to marks them all as active.



79
80
81
# File 'app/components/avo/sidebar/link_component.rb', line 79

def link_method
  is_external? ? :link_to : :active_link_to
end

#resolved_activeObject

A link pointing at the root path would stay active on every page under :inclusive matching (root is a prefix of all of them). Fall back to :exclusive so it only lights up on the root page itself. Only kicks in for the default mode — an explicit active: from the caller wins.



100
101
102
103
104
# File 'app/components/avo/sidebar/link_component.rb', line 100

def resolved_active
  return @active unless @active == :inclusive && root_link?

  :exclusive
end

#root_css_classObject



41
42
43
44
45
# File 'app/components/avo/sidebar/link_component.rb', line 41

def root_css_class
  return ["sidebar-link", color_class].reject(&:blank?).join(" ") unless subitem?

  ["sidebar-subitem", @bar_class].reject(&:blank?).join(" ")
end

#root_link?Boolean

Returns:

  • (Boolean)


106
107
108
109
110
111
112
# File 'app/components/avo/sidebar/link_component.rb', line 106

def root_link?
  return false if @path.blank?

  URI(@path).path.chomp("/") == helpers.root_path_without_url.chomp("/")
rescue URI::InvalidURIError
  false
end

#show_icon?Boolean

Sub-items don't show icons (for now); top-level links do.

Returns:

  • (Boolean)


52
53
54
55
56
# File 'app/components/avo/sidebar/link_component.rb', line 52

def show_icon?
  return false if subitem?

  @reserve_icon_space || link_icon.present?
end

#subitem?Boolean

Returns:

  • (Boolean)


37
38
39
# File 'app/components/avo/sidebar/link_component.rb', line 37

def subitem?
  @variant == :subitem
end