From f38517acf1aed43b27f2c6b94634d70b124883e6 Mon Sep 17 00:00:00 2001 From: Cameron Dutro Date: Wed, 3 Aug 2022 16:02:09 -0700 Subject: [PATCH] Revert removal of BlankslateComponent (#1273) --- .changeset/four-adults-guess.md | 5 + .../primer/blankslate_component.html.erb | 25 +++ app/components/primer/blankslate_component.rb | 152 +++++++++++++++++- .../primer/blankslate_component_stories.rb | 55 +++++++ test/components/blankslate_component_test.rb | 133 +++++++++++++++ test/components/component_test.rb | 2 +- 6 files changed, 369 insertions(+), 3 deletions(-) create mode 100644 .changeset/four-adults-guess.md create mode 100644 app/components/primer/blankslate_component.html.erb create mode 100644 stories/primer/blankslate_component_stories.rb create mode 100644 test/components/blankslate_component_test.rb diff --git a/.changeset/four-adults-guess.md b/.changeset/four-adults-guess.md new file mode 100644 index 0000000000..7fc9966f33 --- /dev/null +++ b/.changeset/four-adults-guess.md @@ -0,0 +1,5 @@ +--- +'@primer/view-components': patch +--- + +Revert removal of BlankslateComponent diff --git a/app/components/primer/blankslate_component.html.erb b/app/components/primer/blankslate_component.html.erb new file mode 100644 index 0000000000..bad71bca7d --- /dev/null +++ b/app/components/primer/blankslate_component.html.erb @@ -0,0 +1,25 @@ +<%# erblint:counter ButtonComponentMigrationCounter 1 %> +<%= render Primer::BaseComponent.new(**@system_arguments) do %> + <% if spinner.present? %> + <%= spinner %> + <% elsif @icon.present? %> + <%= primer_octicon @icon, size: @icon_size, classes: "blankslate-icon" %> + <% elsif @image_src.present? && @image_alt.present? %> + <%= image_tag @image_src.to_s, class: "mb-3", size: "56x56", alt: @image_alt.to_s %> + <% end %> + <% if @title.present? %> + <%= render Primer::BaseComponent.new(tag: @title_tag, mb: 1) do %><%= @title %><% end %> + <% end %> + <% if @description.present? %> +

<%= @description %>

+ <% end %> + <%= content %> + <% if @button_text.present? && @button_url.present? %> + <%= @button_text %> + <% end %> + <% if @link_text.present? && @link_url.present? %> +

+ <%= link_to @link_url.to_s do %><%= @link_text %><% end %> +

+ <% end %> +<% end %> diff --git a/app/components/primer/blankslate_component.rb b/app/components/primer/blankslate_component.rb index ea35d57bba..3500a719b9 100644 --- a/app/components/primer/blankslate_component.rb +++ b/app/components/primer/blankslate_component.rb @@ -1,8 +1,156 @@ # frozen_string_literal: true module Primer - # BlankslateComponent is deprecated. Please use `Primer::Beta::Blankslate` instead. - class BlankslateComponent < Primer::Beta::Blankslate + # Use `Blankslate` when there is a lack of content within a page or section. Use as placeholder to tell users why something isn't there. + # @accessibility + # `Blankslate` renders an `

` element for the title by default. Update the heading level based on what is appropriate for your page hierarchy by setting `title_tag`. + # <%= link_to_heading_practices %> + class BlankslateComponent < Primer::Component status :deprecated + + # Optional Spinner. + # + # @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::SpinnerComponent) %>. + renders_one :spinner, lambda { |**system_arguments| + system_arguments[:mb] ||= 3 + Primer::SpinnerComponent.new(**system_arguments) + } + + # + # @example Basic + # <%= render Primer::BlankslateComponent.new( + # title: "Title", + # description: "Description", + # ) %> + # + # @example Icon + # @description + # Add an `icon` to give additional context. Refer to the [Octicons](https://primer.style/octicons/) documentation to choose an icon. + # @code + # <%= render Primer::BlankslateComponent.new( + # icon: :globe, + # title: "Title", + # description: "Description", + # ) %> + # + # @example Loading + # @description + # Add a [SpinnerComponent](https://primer.style/view-components/components/spinner) to the blankslate in place of an icon. + # @code + # <%= render Primer::BlankslateComponent.new( + # title: "Title", + # description: "Description", + # ) do |component| %> + # <% component.spinner(size: :large) %> + # <% end %> + # + # @example Custom content + # @description + # Pass custom content as a block in place of `description`. + # @code + # <%= render Primer::BlankslateComponent.new( + # title: "Title", + # ) do %> + # Your custom content here + # <% end %> + # + # @example Action button + # @description + # Provide a button to guide users to take action from the blankslate. The button appears below the description and custom content. + # @code + # <%= render Primer::BlankslateComponent.new( + # icon: :book, + # title: "Welcome to the mona wiki!", + # description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.", + # + # button_text: "Create the first page", + # button_url: "https://github.com/monalisa/mona/wiki/_new", + # ) %> + # + # @example Link + # @description + # Add an additional link to help users learn more about a feature. The link will be shown at the very bottom: + # @code + # <%= render Primer::BlankslateComponent.new( + # icon: :book, + # title: "Welcome to the mona wiki!", + # description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.", + # link_text: "Learn more about wikis", + # link_url: "https://docs.github.com/en/github/building-a-strong-community/about-wikis", + # ) %> + # + # @example Variations + # @description + # There are a few variations of how the Blankslate appears: `narrow` adds a maximum width, `large` increases the font size, and `spacious` adds extra padding. + # @code + # <%= render Primer::BlankslateComponent.new( + # icon: :book, + # title: "Welcome to the mona wiki!", + # description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.", + # narrow: true, + # large: true, + # spacious: true, + # ) %> + # + # @param title [String] Text that appears in a larger bold font. + # @param title_tag [Symbol] HTML tag to use for title. + # @param icon [Symbol] Octicon icon to use at top of component. + # @param icon_size [Symbol] <%= one_of(Primer::OcticonComponent::SIZE_MAPPINGS, sort: false) %> + # @param image_src [String] Image to display. + # @param image_alt [String] Alt text for image. + # @param description [String] Text that appears below the title. Typically a whole sentence. + # @param button_text [String] The text of the button. + # @param button_url [String] The URL where the user will be taken after clicking the button. + # @param button_classes [String] Classes to apply to action button + # @param link_text [String] The text of the link. + # @param link_url [String] The URL where the user will be taken after clicking the link. + # @param narrow [Boolean] Adds a maximum width. + # @param large [Boolean] Increases the font size. + # @param spacious [Boolean] Adds extra padding. + # @param system_arguments [Hash] <%= link_to_system_arguments_docs %> + def initialize( + title: "", + title_tag: :h3, + icon: "", + icon_size: :medium, + image_src: "", + image_alt: " ", + description: "", + button_text: "", + button_url: "", + button_classes: "btn-primary my-3", + link_text: "", + link_url: "", + + # variations + narrow: false, + large: false, + spacious: false, + + **system_arguments + ) + @system_arguments = system_arguments + @system_arguments[:tag] = :div + @system_arguments[:classes] = class_names( + @system_arguments[:classes], + "blankslate", + "blankslate-narrow": narrow, + "blankslate-large": large, + "blankslate-spacious": spacious + ) + + @title_tag = title_tag + @icon = icon + @icon_size = icon_size + @image_src = image_src + @image_alt = image_alt + @title = title + @description = description + @button_text = button_text + @button_url = button_url + @button_classes = button_classes + @link_text = link_text + @link_url = link_url + end end end diff --git a/stories/primer/blankslate_component_stories.rb b/stories/primer/blankslate_component_stories.rb new file mode 100644 index 0000000000..18f5224b5f --- /dev/null +++ b/stories/primer/blankslate_component_stories.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +class Primer::BlankslateComponentStories < ViewComponent::Storybook::Stories + layout "storybook_preview" + + story(:icon) do + controls do + icon "shield" + title "It looks like we have discovered a vulnerability" + select(:icon_size, Primer::OcticonComponent::SIZE_MAPPINGS.keys, :medium) + end + end + + story(:image_src) do + controls do + image_src "https://github.githubassets.com/images/modules/site/features/security-icon.svg" + image_alt "Security - secure vault" + title "Millions of teams trust GitHub to keep their work safe" + end + end + + story(:loading) do + controls do + title "Mirroring your repository" + description "We’re currently mirroring this repository. It should take anywhere from a few minutes to a couple of hours depending on the size of the repository." + end + + content do |c| + c.spinner(size: :large) + end + end + + story(:description) do + controls do + title "It looks like we have discovered a vulnerability" + description "Millions of teams trust GitHub to keep their work safe" + end + end + + story(:button) do + controls do + title "It looks like we have discovered a vulnerability" + button_text "Fix issue" + button_url "#" + end + end + + story(:link) do + controls do + title "It looks like we have discovered a vulnerability" + link_text "Fix issue" + link_url "#" + end + end +end diff --git a/test/components/blankslate_component_test.rb b/test/components/blankslate_component_test.rb new file mode 100644 index 0000000000..90550fe933 --- /dev/null +++ b/test/components/blankslate_component_test.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +require "test_helper" + +class BlankslateComponentTest < Minitest::Test + include Primer::ComponentTestHelpers + + def test_renders_a_basic_blankslate_component_with_a_title + render_inline(Primer::BlankslateComponent.new( + title: "Title", + description: "Description" + )) + + assert_selector("div.blankslate") + assert_selector("h3", text: "Title") + refute_selector(".blankslate-narrow") + refute_selector(".blankslate-large") + refute_selector(".blankslate-spacious") + end + + def test_renders_a_blankslate_component_with_a_title_and_custom_tag + render_inline(Primer::BlankslateComponent.new( + title: "Title", + title_tag: :h5 + )) + + assert_selector("h5", text: "Title") + end + + def test_renders_a_blankslate_component_with_a_spinner_component + render_inline(Primer::BlankslateComponent.new(title: "Title")) do |component| + component.spinner(test_selector: "blankslate-spinner") + end + + assert_selector(".blankslate [data-test-selector='blankslate-spinner']") + end + + def test_renders_a_narrow_large_and_spacious_blankslate_component + render_inline(Primer::BlankslateComponent.new( + title: "Title", + narrow: true, + large: true, + spacious: true + )) + + assert_selector(".blankslate.blankslate-narrow") + assert_selector(".blankslate.blankslate-large") + assert_selector(".blankslate.blankslate-spacious") + end + + def test_renders_a_blankslate_component_with_an_icon + render_inline(Primer::BlankslateComponent.new( + icon: :star, + title: "Title" + )) + + assert_selector(".blankslate-icon[height=24]") + end + + def test_renders_a_blankslate_component_with_an_icon_with_a_custom_size + render_inline(Primer::BlankslateComponent.new( + icon: :star, + icon_size: :medium, + title: "Title" + )) + + assert_selector(".blankslate-icon[height=24]") + end + + def test_renders_a_blankslate_component_with_an_image + render_inline(Primer::BlankslateComponent.new( + image_src: "/some_image", + image_alt: "Alt text", + title: "Title" + )) + + assert_selector(".blankslate > img[src$='/some_image']") + assert_selector(".blankslate > img[alt='Alt text']") + end + + def test_renders_a_blankslate_component_with_a_description + render_inline(Primer::BlankslateComponent.new( + title: "Title", + description: "Description" + )) + + assert_selector("p", text: "Description") + end + + def test_renders_a_blankslate_component_with_custom_content + render_inline(Primer::BlankslateComponent.new( + icon: :star, + title: "Title" + )) { "Custom content" } + + assert_text("Custom content") + end + + def test_renders_a_blankslate_component_with_a_button + render_inline(Primer::BlankslateComponent.new( + title: "Title", + button_text: "Button", + button_url: "https://github.com" + )) + + assert_selector("a.btn[href='https://github.com']", text: "Button") + end + + def test_renders_a_blankslate_component_with_a_button_with_custom_classes + render_inline(Primer::BlankslateComponent.new( + title: "Title", + button_text: "Button", + button_url: "https://github.com", + button_classes: "btn-outline" + )) + + assert_selector("a.btn.btn-outline[href='https://github.com']", text: "Button") + end + + def test_renders_a_blankslate_component_with_a_link + render_inline(Primer::BlankslateComponent.new( + title: "Title", + link_text: "Link", + link_url: "https://docs.github.com" + )) + + assert_selector("a[href='https://docs.github.com']", text: "Link") + end + + def test_status + assert_component_state(Primer::BlankslateComponent, :deprecated) + end +end diff --git a/test/components/component_test.rb b/test/components/component_test.rb index 8589115230..da1d8f9440 100644 --- a/test/components/component_test.rb +++ b/test/components/component_test.rb @@ -34,6 +34,7 @@ class PrimerComponentTest < Minitest::Test }], [Primer::Beta::BorderBox, {}, proc { |component| component.header { "Foo" } }], [Primer::Beta::BorderBox::Header, {}], + [Primer::BlankslateComponent, { title: "Foo" }], [Primer::BoxComponent, {}], [Primer::Beta::Breadcrumbs, {}, proc { |component| component.item(href: "/") { "Foo" } }], [Primer::ButtonComponent, {}, proc { "Button" }], @@ -89,7 +90,6 @@ def test_registered_components "Primer::Component", "Primer::OcticonsSymbolComponent", "Primer::Content", - "Primer::BlankslateComponent", "Primer::BorderBoxComponent" ]