Module: Protege::Components::ButtonsHelper

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

Overview

Clickable actions: the primary/danger button, the solid form-submitting action_button (its button_to counterpart, sharing the same look via button_class), the amber text ui_link, and the two link-styled form buttons (+inline_button+, destructive_link) for subtler POST/DELETE actions. Variant styling is resolved by button_variant_style, defined alongside them here.

Instance Method Summary collapse

Instance Method Details

#action_button(text, href, method: :post, variant: :primary, **attrs) ⇒ ActiveSupport::SafeBuffer

Render a solid, button-styled action that submits a form — a button_to (so it POSTs, unlike the formless #button) wearing the same styling as #button. Use this for actions that mutate state from a plain click (e.g. "Sync now"); the link-styled #inline_button/#destructive_link are the subtler variants.

Parameters:

  • text (String)

    the button label

  • href (String)

    the form action target

  • method (Symbol) (defaults to: :post)

    the HTTP verb the button submits (default :post)

  • variant (Symbol) (defaults to: :primary)

    the visual variant (see button_variant_style)

  • attrs (Hash)

    extra HTML attributes forwarded to the button

Returns:

  • (ActiveSupport::SafeBuffer)

    the button-to markup



34
35
36
37
38
39
40
41
# File 'app/helpers/protege/components/buttons_helper.rb', line 34

def action_button(text, href, method: :post, variant: :primary, **attrs)
  button_to text, href,
            method:,
            class:  button_class(variant, attrs.delete(:class)),
            style:  button_variant_style(variant),
            form:   { class: 'inline' },
            **attrs
end

#button(text, variant: :primary, **attrs) ⇒ ActiveSupport::SafeBuffer

Render a styled button. The :danger variant uses the danger hover style.

Parameters:

  • text (String)

    the button label

  • variant (Symbol) (defaults to: :primary)

    the visual variant (see button_variant_style)

  • attrs (Hash)

    extra HTML attributes forwarded to the button

Returns:

  • (ActiveSupport::SafeBuffer)

    the button markup



16
17
18
19
20
21
# File 'app/helpers/protege/components/buttons_helper.rb', line 16

def button(text, variant: :primary, **attrs)
  tag.button(text,
             class: button_class(variant, attrs.delete(:class)),
             style: button_variant_style(variant),
             **attrs)
end

#button_class(variant, extra = nil) ⇒ String

The shared class list for the solid button look, worn by both #button and #action_button.

Parameters:

  • variant (Symbol)

    the button variant (only :danger changes the hover treatment)

  • extra (String, nil) (defaults to: nil)

    caller-supplied extra classes

Returns:

  • (String)

    the combined class string



121
122
123
124
125
126
# File 'app/helpers/protege/components/buttons_helper.rb', line 121

def button_class(variant, extra = nil)
  hover_class = variant == :danger ? 'btn-danger' : 'btn-outline'
  base_class  = 'inline-flex items-center justify-center rounded-sm px-2.5 py-1 text-xs ' \
                'font-semibold uppercase tracking-wide transition-colors cursor-pointer'
  class_names(hover_class, base_class, extra)
end

#button_variant_style(variant) ⇒ String

Map a button variant to its inline style string.

Parameters:

  • variant (Symbol)

    the button variant

Returns:

  • (String)

    the variant's CSS style string



132
133
134
135
136
137
138
# File 'app/helpers/protege/components/buttons_helper.rb', line 132

def button_variant_style(variant)
  case variant
  when :secondary then 'background: transparent; border: 1px solid var(--border); color: var(--text-muted)'
  when :danger    then 'background: transparent; border: 1px solid #ef4444; color: #ef4444'
  else                 'background: transparent; border: 1px solid var(--border); color: var(--text)'
  end
end

Render a destructive action as an inline form button with optional confirm.

Parameters:

  • text (String)

    the link text

  • href (String)

    the action target

  • confirm (String, nil) (defaults to: nil)

    optional Turbo confirmation prompt

  • method (Symbol) (defaults to: :delete)

    the HTTP verb the button submits

  • attrs (Hash{Symbol => Object})

Returns:

  • (ActiveSupport::SafeBuffer)

    the button-to markup



87
88
89
90
91
92
93
94
95
96
97
# File 'app/helpers/protege/components/buttons_helper.rb', line 87

def destructive_link(text, href, confirm: nil, method: :delete, **attrs)
  classes = 'text-sm text-red-500 hover:text-red-700 cursor-pointer ' \
            "bg-transparent border-0 p-0 #{attrs.delete(:class)}"

  button_to text, href,
            method:,
            class:  classes,
            form:   { class: 'inline' },
            data:   confirm ? { turbo_confirm: confirm } : {},
            **attrs
end

#icon_button(name, label:, **attrs) ⇒ ActiveSupport::SafeBuffer

Render an icon-only button — a muted glyph that brightens on hover (e.g. a composer's attach control). label is both the tooltip and the accessible name, since there is no visible text.

Parameters:

  • name (Symbol)

    the icon to render (see IconsHelper#icon)

  • label (String)

    the tooltip / accessible label

  • attrs (Hash)

    extra HTML attributes forwarded to the button (e.g. data:)

Returns:

  • (ActiveSupport::SafeBuffer)

    the icon-button markup



106
107
108
109
110
111
112
113
114
# File 'app/helpers/protege/components/buttons_helper.rb', line 106

def icon_button(name, label:, **attrs)
  tag.button(icon(name),
             type:         'button',
             title:        label,
             'aria-label': label,
             class:        'rounded p-1.5 opacity-70 transition-opacity hover:opacity-100 cursor-pointer',
             style:        'color: var(--text-muted)',
             **attrs)
end

#inline_button(text, href, method: :post, **attrs) ⇒ ActiveSupport::SafeBuffer

Render a form button as a link-styled element, for use in inline forms (e.g. button_to with +form: { class: "inline" }).

Parameters:

  • text (String)

    the button text

  • href (String)

    the form action target

  • method (Symbol) (defaults to: :post)

    the HTTP verb the button submits

  • attrs (Hash)

    extra HTML attributes forwarded to the button

Returns:

  • (ActiveSupport::SafeBuffer)

    the button markup



51
52
53
54
55
56
57
58
59
60
# File 'app/helpers/protege/components/buttons_helper.rb', line 51

def inline_button(text, href, method: :post, **attrs)
  classes = 'text-sm text-amber-600 hover:text-amber-700 cursor-pointer ' \
            "bg-transparent border-0 p-0 #{attrs.delete(:class)}"

  button_to text, href,
            method:,
            class:  classes,
            form:   { class: 'inline' },
            **attrs
end

Render an amber text link, dimmed when muted.

Parameters:

  • text (String)

    the link text

  • href (String)

    the link target

  • muted (Boolean) (defaults to: false)

    whether to render the dimmed variant

  • attrs (Hash)

    extra HTML attributes forwarded to the link

Returns:

  • (ActiveSupport::SafeBuffer)

    the link markup



69
70
71
72
73
74
75
76
77
# File 'app/helpers/protege/components/buttons_helper.rb', line 69

def ui_link(text, href, muted: false, **attrs)
  classes = if muted
              'text-sm text-amber-400 hover:text-amber-600'
            else
              'text-sm text-amber-600 hover:text-amber-700'
            end

  link_to(text, href, class: "#{classes} #{attrs.delete(:class)}", **attrs)
end