Module: Protege::Components::MenusHelper

Included in:
ComponentsHelper
Defined in:
app/helpers/protege/components/menus_helper.rb

Overview

The +

+-based dropdown menu: dropdown_menu renders the trigger + panel (with a backdrop that closes it), and dropdown_item renders each entry as a link or form button, with an active variant for filter-style menus.

Instance Method Summary collapse

Instance Method Details

Render a single dropdown entry, either a link or a form button. Pass active: true to mark the current selection — the entry is emphasized and gets a trailing check (for filter-style menus).

Parameters:

  • text (String)

    the entry label

  • href (String)

    the entry target

  • method (Symbol, nil) (defaults to: nil)

    when set, render a form button using this verb

  • active (Boolean) (defaults to: false)

    whether this entry is the current selection

  • destructive (Boolean) (defaults to: false)

    whether to apply destructive (red) styling

Returns:

  • (ActiveSupport::SafeBuffer)

    the entry markup



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'app/helpers/protege/components/menus_helper.rb', line 33

def dropdown_item(text, href, method: nil, active: false, destructive: false)
  text_class = destructive ? 'text-red-500 hover:text-red-700' : ''
  weight     = active ? 'font-semibold' : ''
  base_class = 'flex w-full items-center justify-between gap-2 text-left text-sm px-3 py-1.5 ' \
               "cursor-pointer #{text_class} #{weight}".squish
  content    = active ? safe_join([text, tag.span('', style: 'color: var(--color-amber-500, #f59e0b)')]) : text

  if method
    button_to content, href,
              method:,
              class:  "#{base_class} bg-transparent border-0",
              form:   { class: 'w-full' }
  else
    link_to content, href, class: base_class
  end
end

Render a +

+-based dropdown menu with a backdrop that closes it.

Parameters:

  • label (String) (defaults to: '···')

    the trigger text (defaults to a kebab ···)

Yields:

  • the menu items, rendered inside the dropdown panel

Returns:

  • (ActiveSupport::SafeBuffer)

    the dropdown markup



14
15
16
17
18
19
20
21
22
# File 'app/helpers/protege/components/menus_helper.rb', line 14

def dropdown_menu(label: '···', &block)
  tag.details(class: 'relative') do
    tag.summary(label, class: 'cursor-pointer list-none text-base font-bold select-none',
                       style: 'color: var(--text-faint)') +
      tag.div(class: 'fixed inset-0 z-10', onclick: "this.closest('details').removeAttribute('open')") +
      tag.div(class: 'absolute right-0 mt-1 w-36 rounded-lg py-1 shadow-lg z-20',
              style: 'background: var(--surface); border: 1px solid var(--border)') { capture(&block) }
  end
end

Render a navigation link, highlighted when the current path is under it.

Parameters:

  • text (String)

    the link text

  • href (String)

    the link target

  • current_path (String)

    the request path used to compute the active state

Returns:

  • (ActiveSupport::SafeBuffer)

    the nav-item markup



56
57
58
59
60
61
62
63
64
65
# File 'app/helpers/protege/components/menus_helper.rb', line 56

def nav_item(text, href, current_path)
  active  = current_path.start_with?(href)
  classes = 'rounded-sm px-2.5 py-1 text-xs font-medium transition-colors'
  style   = if active
              'background: var(--surface-subtle); color: var(--text)'
            else
              'color: var(--text-muted)'
            end
  link_to(text, href, class: classes, style:)
end