From 53a51f5d127b3adbb772964cbe8e27ab19d9675f Mon Sep 17 00:00:00 2001 From: Sascha Eggenberger <seggenberger@gitlab.com> Date: Thu, 1 Feb 2024 17:05:19 +0000 Subject: [PATCH] Add GlSingleStat to haml Adds the GlSingleStat component as a HAML component. Changelog: changed --- .../pajamas/single_stat_component.html.haml | 20 ++++++ .../pajamas/single_stat_component.rb | 56 ++++++++++++++++ .../pajamas/single_stat_component_spec.rb | 64 +++++++++++++++++++ .../pajamas/single_stat_component_preview.rb | 38 +++++++++++ 4 files changed, 178 insertions(+) create mode 100644 app/components/pajamas/single_stat_component.html.haml create mode 100644 app/components/pajamas/single_stat_component.rb create mode 100644 spec/components/pajamas/single_stat_component_spec.rb create mode 100644 spec/components/previews/pajamas/single_stat_component_preview.rb diff --git a/app/components/pajamas/single_stat_component.html.haml b/app/components/pajamas/single_stat_component.html.haml new file mode 100644 index 0000000000000..a5ee88fa476b9 --- /dev/null +++ b/app/components/pajamas/single_stat_component.html.haml @@ -0,0 +1,20 @@ +.gl-single-stat.gl-display-flex.gl-flex-direction-column.gl-p-2 + .gl-display-flex.gl-align-items-center.gl-text-gray-700.gl-mb-2 + - if title_icon? + = sprite_icon(@title_icon, css_class: 'gl-mr-2') + %span.gl-font-base.gl-font-weight-normal{ data: { testid: 'title-text' } } + = @title + .gl-single-stat-content.gl-display-flex.gl-align-items-baseline.gl-font-weight-bold.gl-text-gray-900 + %span.gl-single-stat-number.gl-line-height-1{ class: unit_class, data: { testid: 'displayValue' } } + %span{ data: { testid: 'non-animated-value' } } + = @stat_value + - if unit? + %span.gl-font-sm.gl-mx-2.gl-transition-medium.gl-opacity-10{ data: { testid: 'unit' } } + = @unit + - if meta_icon? && !meta_text? + = sprite_icon(@meta_icon, css_class: @text_color) + - elsif meta_text? + = render Pajamas::BadgeComponent.new(@meta_text, + variant: @variant, + icon: @meta_icon, + data: { testid: 'meta-badge' }) diff --git a/app/components/pajamas/single_stat_component.rb b/app/components/pajamas/single_stat_component.rb new file mode 100644 index 0000000000000..6c1a386eaaafe --- /dev/null +++ b/app/components/pajamas/single_stat_component.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Pajamas + class SingleStatComponent < Pajamas::Component + # @param [String] title + # @param [String] stat_value + # @param [String] unit + # @param [String] title_icon + # @param [String] meta_text + # @param [String] meta_icon + # @param [Symbol] variant + def initialize( + title: nil, + stat_value: nil, + unit: nil, + title_icon: nil, + meta_text: nil, + meta_icon: nil, + text_color: nil, + variant: :muted + ) + @title = title + @stat_value = stat_value + @unit = unit + @title_icon = title_icon.to_s.presence + @meta_text = meta_text + @meta_icon = meta_icon + @text_color = text_color + @variant = filter_attribute(variant.to_sym, Pajamas::BadgeComponent::VARIANT_OPTIONS, default: :muted) + end + + private + + delegate :sprite_icon, to: :helpers + + def unit_class + "gl-mr-2" unless unit? + end + + def unit? + @unit + end + + def title_icon? + @title_icon + end + + def meta_icon? + @meta_icon + end + + def meta_text? + @meta_text + end + end +end diff --git a/spec/components/pajamas/single_stat_component_spec.rb b/spec/components/pajamas/single_stat_component_spec.rb new file mode 100644 index 0000000000000..620cc8dedca9f --- /dev/null +++ b/spec/components/pajamas/single_stat_component_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Pajamas::SingleStatComponent, type: :component, feature_category: :shared do + let(:title) { "Single Stat" } + let(:stat_value) { "9,000" } + let(:title_icon) { nil } + let(:unit) { nil } + let(:meta_text) { nil } + let(:variant) { :success } + + before do + render_inline(described_class.new( + title: title, + title_icon: title_icon, + stat_value: stat_value, + unit: unit, + meta_text: meta_text + )) + end + + context "with default props" do + it 'shows title' do + expect(page).to have_css('[data-testid=title-text]', text: title) + end + + it 'shows stat_value' do + expect(page).to have_css('[data-testid=non-animated-value]', text: stat_value) + end + + it 'does not show unit' do + expect(page).not_to have_css('[data-testid=unit]') + end + + it 'does not show meta badge' do + expect(page).not_to have_css('[data-testid=meta-badge]') + end + end + + context "with title_icon" do + let(:title_icon) { :tanuki } + + it 'shows icon' do + expect(page).to have_css('svg[data-testid=tanuki-icon]') + end + end + + context 'with unit' do + let(:unit) { 'KB' } + + it 'shows unit' do + expect(page).to have_css('[data-testid=unit]', text: unit) + end + end + + context 'with meta_text' do + let(:meta_text) { "You're doing great!" } + + it 'shows badge with text' do + expect(page).to have_css('[data-testid=meta-badge]', text: meta_text) + end + end +end diff --git a/spec/components/previews/pajamas/single_stat_component_preview.rb b/spec/components/previews/pajamas/single_stat_component_preview.rb new file mode 100644 index 0000000000000..8519c96633f3a --- /dev/null +++ b/spec/components/previews/pajamas/single_stat_component_preview.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Pajamas + class SingleStatComponentPreview < ViewComponent::Preview + # SingleStat + # --- + # + # See its design reference [here](https://design.gitlab.com/data-visualization/single-stat). + # + # @param title text + # @param stat_value text + # @param unit text + # @param title_icon text + # @param meta_text text + # @param meta_icon text + # @param variant select {{ Pajamas::BadgeComponent::VARIANT_OPTIONS }} + # @param hide_units toggle + def default( + title: 'Single stat', + stat_value: '9,001', + unit: '', + title_icon: 'chart', + meta_text: '', + meta_icon: 'check-circle', + variant: :default + ) + render Pajamas::SingleStatComponent.new( + title: title, + stat_value: stat_value, + unit: unit, + title_icon: title_icon, + meta_text: meta_text, + meta_icon: meta_icon, + variant: variant + ) + end + end +end -- GitLab