1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
# frozen_string_literal: true
module Pajamas
class ButtonComponent < Pajamas::Component
CATEGORY_OPTIONS = [:primary, :secondary, :tertiary].freeze
VARIANT_OPTIONS = [:default, :confirm, :danger, :dashed, :link, :reset].freeze
SIZE_OPTIONS = [:small, :medium].freeze
TYPE_OPTIONS = [:button, :reset, :submit].freeze
TARGET_OPTIONS = %w[_self _blank _parent _top].freeze
METHOD_OPTIONS = [:get, :post, :put, :delete, :patch].freeze
CATEGORY_CLASSES = {
primary: '',
secondary: 'secondary',
tertiary: 'tertiary'
}.freeze
VARIANT_CLASSES = {
default: 'btn-default',
confirm: 'btn-confirm',
danger: 'btn-danger',
dashed: 'btn-dashed',
link: 'btn-link',
reset: 'btn-gl-reset'
}.freeze
NON_CATEGORY_VARIANTS = [:dashed, :link, :reset].freeze
SIZE_CLASSES = {
small: 'btn-sm',
medium: 'btn-md'
}.freeze
# Below slot must be used as an exception to render custom icon image that is available from assets,
# configs, attachments, etc. For all other regular cases please use :icon param to add an icon.
renders_one :icon_content
# @param [Symbol] category
# @param [Symbol] variant
# @param [Symbol] size
# @param [Symbol] type
# @param [Boolean] disabled
# @param [Boolean] loading
# @param [Boolean] block
# @param [Boolean] selected
# @param [String] icon
# @param [String] href
# @param [Boolean] form
# @param [String] target
# @param [Symbol] method
# @param [Hash] button_options
# @param [String] button_text_classes
# @param [String] icon_classes
def initialize(
category: :primary,
variant: :default,
size: :medium,
type: :button,
disabled: false,
loading: false,
block: false,
selected: false,
icon: nil,
href: nil,
form: false,
target: nil,
method: nil,
button_options: {},
button_text_classes: nil,
icon_classes: nil
)
@category = filter_attribute(category.to_sym, CATEGORY_OPTIONS)
@variant = filter_attribute(variant.to_sym, VARIANT_OPTIONS)
@size = filter_attribute(size.to_sym, SIZE_OPTIONS)
@type = filter_attribute(type.to_sym, TYPE_OPTIONS, default: :button)
@disabled = disabled
@loading = loading
@block = block
@selected = selected
@icon = icon
@href = href
@form = form
@target = filter_attribute(target, TARGET_OPTIONS)
@method = filter_attribute(method, METHOD_OPTIONS)
@button_options = button_options
@button_text_classes = button_text_classes
@icon_classes = icon_classes
end
private
def button_class
classes = ['gl-button btn']
classes.push('disabled') if @disabled || @loading
classes.push('selected') if @selected
classes.push('btn-block') if @block
classes.push('btn-icon') if @icon && !content
classes.push(SIZE_CLASSES[@size])
classes.push(VARIANT_CLASSES[@variant])
unless NON_CATEGORY_VARIANTS.include?(@variant) || @category == :primary
classes.push("#{VARIANT_CLASSES[@variant]}-#{CATEGORY_CLASSES[@category]}")
end
classes.push(@button_options[:class])
classes.join(' ')
end
delegate :sprite_icon, to: :helpers
delegate :gl_loading_icon, to: :helpers
def link?
@href.present?
end
def form?
@href.present? && @form.present?
end
def base_attributes
attributes = {}
attributes['disabled'] = 'disabled' if @disabled || @loading
attributes['aria-disabled'] = true if @disabled || @loading
attributes['type'] = @type unless @href
attributes['rel'] = safe_rel_for_target_blank if link? && @target == '_blank'
attributes
end
def safe_rel_for_target_blank
(@button_options[:rel] || '').split(' ')
.concat(%w[noopener noreferrer])
.uniq.join(' ')
end
end
end
|