diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-20 11:10:13 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-20 11:10:13 +0000 |
commit | 0ea3fcec397b69815975647f5e2aa5fe944a8486 (patch) | |
tree | 7979381b89d26011bcf9bdc989a40fcc2f1ed4ff /app/components/pajamas | |
parent | 72123183a20411a36d607d70b12d57c484394c8e (diff) | |
download | gitlab-ce-0ea3fcec397b69815975647f5e2aa5fe944a8486.tar.gz |
Add latest changes from gitlab-org/gitlab@15-1-stable-eev15.1.0-rc42
Diffstat (limited to 'app/components/pajamas')
-rw-r--r-- | app/components/pajamas/alert_component.html.haml | 9 | ||||
-rw-r--r-- | app/components/pajamas/alert_component.rb | 14 | ||||
-rw-r--r-- | app/components/pajamas/banner_component.html.haml | 23 | ||||
-rw-r--r-- | app/components/pajamas/banner_component.rb | 61 | ||||
-rw-r--r-- | app/components/pajamas/button_component.html.haml | 8 | ||||
-rw-r--r-- | app/components/pajamas/button_component.rb | 118 | ||||
-rw-r--r-- | app/components/pajamas/card_component.html.haml | 9 | ||||
-rw-r--r-- | app/components/pajamas/card_component.rb | 21 | ||||
-rw-r--r-- | app/components/pajamas/checkbox_component.html.haml | 6 | ||||
-rw-r--r-- | app/components/pajamas/checkbox_component.rb | 56 | ||||
-rw-r--r-- | app/components/pajamas/component.rb | 12 | ||||
-rw-r--r-- | app/components/pajamas/concerns/checkbox_radio_label_with_help_text.rb | 30 | ||||
-rw-r--r-- | app/components/pajamas/concerns/checkbox_radio_options.rb | 11 | ||||
-rw-r--r-- | app/components/pajamas/radio_component.html.haml | 5 | ||||
-rw-r--r-- | app/components/pajamas/radio_component.rb | 51 |
15 files changed, 417 insertions, 17 deletions
diff --git a/app/components/pajamas/alert_component.html.haml b/app/components/pajamas/alert_component.html.haml index 782ac8b9ca2..13c458f05e9 100644 --- a/app/components/pajamas/alert_component.html.haml +++ b/app/components/pajamas/alert_component.html.haml @@ -1,11 +1,10 @@ -.gl-alert{ role: 'alert', class: [base_class, @alert_class], data: @alert_data } +.gl-alert{ @alert_options, role: 'alert', class: base_class } - if @show_icon = sprite_icon(icon, css_class: icon_classes) - if @dismissible - %button.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon.js-close{ type: 'button', - aria: { label: _('Dismiss') }, - class: @close_button_class, - data: @close_button_data } + %button.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon.js-close{ @close_button_options, + type: 'button', + aria: { label: _('Dismiss') } } = sprite_icon('close') .gl-alert-content{ role: 'alert' } - if @title diff --git a/app/components/pajamas/alert_component.rb b/app/components/pajamas/alert_component.rb index c1b2132da29..cfab34f537e 100644 --- a/app/components/pajamas/alert_component.rb +++ b/app/components/pajamas/alert_component.rb @@ -7,21 +7,17 @@ module Pajamas # @param [Symbol] variant # @param [Boolean] dismissible # @param [Boolean] show_icon - # @param [String] alert_class - # @param [Hash] alert_data - # @param [String] close_button_class - # @param [Hash] close_button_data + # @param [Hash] alert_options + # @param [Hash] close_button_options def initialize( title: nil, variant: :info, dismissible: true, show_icon: true, - alert_class: nil, alert_data: {}, close_button_class: nil, close_button_data: {}) + alert_options: {}, close_button_options: {}) @title = title @variant = variant @dismissible = dismissible @show_icon = show_icon - @alert_class = alert_class - @alert_data = alert_data - @close_button_class = close_button_class - @close_button_data = close_button_data + @alert_options = alert_options + @close_button_options = close_button_options end def base_class diff --git a/app/components/pajamas/banner_component.html.haml b/app/components/pajamas/banner_component.html.haml new file mode 100644 index 00000000000..4fa2ed09cd3 --- /dev/null +++ b/app/components/pajamas/banner_component.html.haml @@ -0,0 +1,23 @@ +%section.gl-banner{ @banner_options, class: banner_class } + - if illustration? + .gl-banner-illustration + = illustration + - elsif @svg_path.present? + .gl-banner-illustration + = image_tag @svg_path, alt: "" + + .gl-banner-content + %h1.gl-banner-title= title + + = content + + - if primary_action? + = primary_action + - else + = link_to @button_text, @button_link, { **@button_options, class: 'btn btn-md btn-confirm gl-button js-close-callout' } + + - actions.each do |action| + = action + + %button.gl-button.gl-banner-close.btn-sm.btn-icon.js-close{ @close_options, class: close_class, type: 'button' } + = sprite_icon('close', size: 16, css_class: 'dismiss-icon') diff --git a/app/components/pajamas/banner_component.rb b/app/components/pajamas/banner_component.rb new file mode 100644 index 00000000000..9b6343b47c9 --- /dev/null +++ b/app/components/pajamas/banner_component.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module Pajamas + class BannerComponent < Pajamas::Component + # @param [String] button_text + # @param [String] button_link + # @param [Boolean] embedded + # @param [Symbol] variant + # @param [String] svg_path + # @param [Hash] banner_options + # @param [Hash] button_options + # @param [Hash] close_options + def initialize( + button_text: 'OK', + button_link: '#', + embedded: false, + variant: :promotion, + svg_path: nil, + banner_options: {}, + button_options: {}, + close_options: {} + ) + @button_text = button_text + @button_link = button_link + @embedded = embedded + @variant = variant.to_sym + @svg_path = svg_path.to_s + @banner_options = banner_options + @button_options = button_options + @close_options = close_options + end + + private + + def banner_class + classes = [] + classes.push('gl-border-none') if @embedded + classes.push('gl-banner-introduction') if introduction? + classes.join(' ') + end + + def close_class + if introduction? + 'btn-confirm btn-confirm-tertiary' + else + 'btn-default btn-default-tertiary' + end + end + + delegate :sprite_icon, to: :helpers + + renders_one :title + renders_one :illustration + renders_one :primary_action + renders_many :actions + + def introduction? + @variant == :introduction + end + end +end diff --git a/app/components/pajamas/button_component.html.haml b/app/components/pajamas/button_component.html.haml new file mode 100644 index 00000000000..8ce7d9e0315 --- /dev/null +++ b/app/components/pajamas/button_component.html.haml @@ -0,0 +1,8 @@ += content_tag tag, {**@button_options, **base_attributes, class: button_class, href: @href, target: @target } do + - if @loading + = gl_loading_icon(inline: true, css_class: 'gl-button-icon gl-button-loading-indicator') + - if @icon && (!@loading || content) + = sprite_icon(@icon, css_class: "gl-icon gl-button-icon #{@icon_classes}") + - if content + %span.gl-button-text{ class: @button_text_classes } + = content diff --git a/app/components/pajamas/button_component.rb b/app/components/pajamas/button_component.rb new file mode 100644 index 00000000000..c6193d1ae05 --- /dev/null +++ b/app/components/pajamas/button_component.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +module Pajamas + class ButtonComponent < Pajamas::Component + # @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 [String] target + # @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, + target: 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 + @target = filter_attribute(target, TARGET_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 + + 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 + + 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 + + delegate :sprite_icon, to: :helpers + delegate :gl_loading_icon, to: :helpers + + def tag + @href ? 'a' : 'button' + end + + def base_attributes + attributes = {} + + attributes['disabled'] = '' if @disabled || @loading + attributes['aria-disabled'] = true if @disabled || @loading + attributes['type'] = @type unless @href + + attributes + end + end +end diff --git a/app/components/pajamas/card_component.html.haml b/app/components/pajamas/card_component.html.haml new file mode 100644 index 00000000000..007229cc69f --- /dev/null +++ b/app/components/pajamas/card_component.html.haml @@ -0,0 +1,9 @@ +.gl-card{ @card_options } + - if header? + .gl-card-header{ @header_options } + = header + .gl-card-body{ @body_options } + = body + - if footer? + .gl-card-footer{ @footer_options } + = footer diff --git a/app/components/pajamas/card_component.rb b/app/components/pajamas/card_component.rb new file mode 100644 index 00000000000..bcc71db1c34 --- /dev/null +++ b/app/components/pajamas/card_component.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# Renders a GlCard root element +module Pajamas + class CardComponent < Pajamas::Component + # @param [Hash] card_options + # @param [Hash] header_options + # @param [Hash] body_options + # @param [Hash] footer_options + def initialize(card_options: {}, header_options: {}, body_options: {}, footer_options: {}) + @card_options = card_options + @header_options = header_options + @body_options = body_options + @footer_options = footer_options + end + + renders_one :header + renders_one :body + renders_one :footer + end +end diff --git a/app/components/pajamas/checkbox_component.html.haml b/app/components/pajamas/checkbox_component.html.haml new file mode 100644 index 00000000000..9e3d4e68a42 --- /dev/null +++ b/app/components/pajamas/checkbox_component.html.haml @@ -0,0 +1,6 @@ +.gl-form-checkbox.custom-control.custom-checkbox + = form.check_box(method, + formatted_input_options, + checked_value, + unchecked_value) + = render_label_with_help_text diff --git a/app/components/pajamas/checkbox_component.rb b/app/components/pajamas/checkbox_component.rb new file mode 100644 index 00000000000..ae78d0453f8 --- /dev/null +++ b/app/components/pajamas/checkbox_component.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +# Renders a Pajamas compliant checkbox element +# Must be used in an instance of `ActionView::Helpers::FormBuilder` +module Pajamas + class CheckboxComponent < Pajamas::Component + include Pajamas::Concerns::CheckboxRadioLabelWithHelpText + include Pajamas::Concerns::CheckboxRadioOptions + + renders_one :label + renders_one :help_text + + def initialize( + form:, + method:, + label: nil, + help_text: nil, + label_options: {}, + checkbox_options: {}, + checked_value: '1', + unchecked_value: '0' + ) + @form = form + @method = method + @label_argument = label + @help_text_argument = help_text + @label_options = label_options + @input_options = checkbox_options + @checked_value = checked_value + @unchecked_value = unchecked_value + @value = checked_value if checkbox_options[:multiple] + end + + attr_reader( + :form, + :method, + :label_argument, + :help_text_argument, + :label_options, + :input_options, + :checked_value, + :unchecked_value, + :value + ) + + private + + def label_content + label? ? label : label_argument + end + + def help_text_content + help_text? ? help_text : help_text_argument + end + end +end diff --git a/app/components/pajamas/component.rb b/app/components/pajamas/component.rb index b05d93b680e..3b1826a646c 100644 --- a/app/components/pajamas/component.rb +++ b/app/components/pajamas/component.rb @@ -4,8 +4,6 @@ module Pajamas class Component < ViewComponent::Base private - # :nocov: - # Filter a given a value against a list of allowed values # If no value is given or value is not allowed return default one # @@ -18,6 +16,14 @@ module Pajamas default end - # :nocov: + + # Add CSS classes and additional options to an existing options hash + # + # @param [Hash] options + # @param [Array] css_classes + # @param [Hash] additional_option + def format_options(options:, css_classes: [], additional_options: {}) + options.merge({ class: [*css_classes, options[:class]].flatten.compact }, additional_options) + end end end diff --git a/app/components/pajamas/concerns/checkbox_radio_label_with_help_text.rb b/app/components/pajamas/concerns/checkbox_radio_label_with_help_text.rb new file mode 100644 index 00000000000..4ece904fb85 --- /dev/null +++ b/app/components/pajamas/concerns/checkbox_radio_label_with_help_text.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Pajamas + module Concerns + module CheckboxRadioLabelWithHelpText + def render_label_with_help_text + form.label(method, formatted_label_options) { label_entry } + end + + private + + def label_entry + if help_text_content + content_tag(:span, label_content) + + content_tag(:p, help_text_content, class: 'help-text', data: { testid: 'pajamas-component-help-text' }) + else + content_tag(:span, label_content) + end + end + + def formatted_label_options + format_options( + options: label_options, + css_classes: ['custom-control-label'], + additional_options: { value: value } + ) + end + end + end +end diff --git a/app/components/pajamas/concerns/checkbox_radio_options.rb b/app/components/pajamas/concerns/checkbox_radio_options.rb new file mode 100644 index 00000000000..e79fdb7b601 --- /dev/null +++ b/app/components/pajamas/concerns/checkbox_radio_options.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Pajamas + module Concerns + module CheckboxRadioOptions + def formatted_input_options + format_options(options: input_options, css_classes: ['custom-control-input']) + end + end + end +end diff --git a/app/components/pajamas/radio_component.html.haml b/app/components/pajamas/radio_component.html.haml new file mode 100644 index 00000000000..6bf57b0b187 --- /dev/null +++ b/app/components/pajamas/radio_component.html.haml @@ -0,0 +1,5 @@ +.gl-form-radio.custom-control.custom-radio + = form.radio_button(method, + value, + formatted_input_options) + = render_label_with_help_text diff --git a/app/components/pajamas/radio_component.rb b/app/components/pajamas/radio_component.rb new file mode 100644 index 00000000000..52a761b9d7d --- /dev/null +++ b/app/components/pajamas/radio_component.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +# Renders a Pajamas compliant radio button element +# Must be used in an instance of `ActionView::Helpers::FormBuilder` +module Pajamas + class RadioComponent < Pajamas::Component + include Pajamas::Concerns::CheckboxRadioLabelWithHelpText + include Pajamas::Concerns::CheckboxRadioOptions + + renders_one :label + renders_one :help_text + + def initialize( + form:, + method:, + label: nil, + help_text: nil, + label_options: {}, + radio_options: {}, + value: nil + ) + @form = form + @method = method + @label_argument = label + @help_text_argument = help_text + @label_options = label_options + @input_options = radio_options + @value = value + end + + attr_reader( + :form, + :method, + :label_argument, + :help_text_argument, + :label_options, + :input_options, + :value + ) + + private + + def label_content + label? ? label : label_argument + end + + def help_text_content + help_text? ? help_text : help_text_argument + end + end +end |