primer_view_components 0.0.34 → 0.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +131 -21
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/components/primer/{auto_complete_component.rb → auto_complete.rb} +14 -12
  6. data/app/components/primer/{auto_complete_component.d.ts → auto_complete/auto_complete.d.ts} +0 -0
  7. data/app/components/primer/{auto_complete_component.html.erb → auto_complete/auto_complete.html.erb} +0 -0
  8. data/app/components/primer/{auto_complete_component.js → auto_complete/auto_complete.js} +0 -0
  9. data/app/components/primer/{auto_complete_component.ts → auto_complete/auto_complete.ts} +0 -0
  10. data/app/components/primer/auto_complete/auto_component.d.ts +1 -0
  11. data/app/components/primer/auto_complete/auto_component.js +1 -0
  12. data/app/components/primer/auto_complete/item.rb +42 -0
  13. data/app/components/primer/avatar_component.rb +22 -3
  14. data/app/components/primer/avatar_stack_component.rb +3 -1
  15. data/app/components/primer/base_button.rb +47 -0
  16. data/app/components/primer/base_component.rb +7 -8
  17. data/app/components/primer/blankslate_component.rb +4 -1
  18. data/app/components/primer/border_box_component.rb +1 -1
  19. data/app/components/primer/box_component.rb +1 -1
  20. data/app/components/primer/breadcrumb_component.rb +1 -1
  21. data/app/components/primer/button_component.html.erb +9 -0
  22. data/app/components/primer/button_component.rb +60 -21
  23. data/app/components/primer/{button_group_component.html.erb → button_group.html.erb} +0 -0
  24. data/app/components/primer/button_group.rb +61 -0
  25. data/app/components/primer/button_marketing_component.rb +4 -9
  26. data/app/components/primer/clipboard_copy.html.erb +8 -0
  27. data/app/components/primer/clipboard_copy.rb +26 -0
  28. data/app/components/primer/clipboard_copy_component.d.ts +1 -0
  29. data/app/components/primer/clipboard_copy_component.js +23 -0
  30. data/app/components/primer/clipboard_copy_component.ts +26 -0
  31. data/app/components/primer/close_button.rb +39 -0
  32. data/app/components/primer/component.rb +17 -2
  33. data/app/components/primer/counter_component.rb +1 -1
  34. data/app/components/primer/details_component.rb +1 -1
  35. data/app/components/primer/dropdown/menu_component.rb +1 -1
  36. data/app/components/primer/dropdown_component.rb +2 -2
  37. data/app/components/primer/dropdown_menu_component.rb +1 -1
  38. data/app/components/primer/flash_component.rb +1 -1
  39. data/app/components/primer/flex_component.rb +1 -1
  40. data/app/components/primer/flex_item_component.rb +20 -1
  41. data/app/components/primer/heading_component.rb +32 -4
  42. data/app/components/primer/hidden_text_expander.rb +41 -0
  43. data/app/components/primer/icon_button.rb +48 -0
  44. data/app/components/primer/label_component.rb +1 -1
  45. data/app/components/primer/layout_component.rb +1 -1
  46. data/app/components/primer/link_component.rb +1 -1
  47. data/app/components/primer/markdown_component.rb +1 -1
  48. data/app/components/primer/menu_component.rb +1 -1
  49. data/app/components/primer/navigation/tab_component.html.erb +9 -7
  50. data/app/components/primer/navigation/tab_component.rb +27 -3
  51. data/app/components/primer/octicon_component.rb +35 -14
  52. data/app/components/primer/popover_component.rb +1 -1
  53. data/app/components/primer/primer.d.ts +2 -1
  54. data/app/components/primer/primer.js +2 -1
  55. data/app/components/primer/primer.ts +2 -1
  56. data/app/components/primer/progress_bar_component.rb +1 -1
  57. data/app/components/primer/spinner_component.rb +1 -1
  58. data/app/components/primer/state_component.rb +2 -2
  59. data/app/components/primer/subhead_component.rb +1 -1
  60. data/app/components/primer/tab_container_component.rb +1 -1
  61. data/app/components/primer/tab_nav_component.html.erb +2 -2
  62. data/app/components/primer/tab_nav_component.rb +23 -9
  63. data/app/components/primer/text_component.rb +1 -1
  64. data/app/components/primer/time_ago_component.rb +1 -1
  65. data/app/components/primer/timeline_item_component.rb +1 -1
  66. data/app/components/primer/tooltip_component.rb +1 -1
  67. data/app/components/primer/{truncate_component.rb → truncate.rb} +8 -6
  68. data/app/components/primer/underline_nav_component.rb +47 -15
  69. data/app/lib/primer/classify.rb +8 -33
  70. data/app/lib/primer/classify/cache.rb +19 -14
  71. data/app/lib/primer/classify/flex.rb +111 -0
  72. data/app/lib/primer/classify/functional_border_colors.rb +1 -2
  73. data/app/lib/primer/fetch_or_fallback_helper.rb +2 -2
  74. data/app/lib/primer/octicon/cache.rb +38 -0
  75. data/app/lib/primer/tabbed_component_helper.rb +4 -0
  76. data/lib/primer/view_components/version.rb +1 -1
  77. data/static/statuses.json +1 -1
  78. metadata +116 -32
  79. data/app/assets/javascripts/primer_view_components.js.map.orig +0 -5
  80. data/app/assets/javascripts/primer_view_components.js.orig +0 -6
  81. data/app/components/primer/auto_complete_item_component.rb +0 -38
  82. data/app/components/primer/button_group_component.rb +0 -35
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use `CloseButton` to render an `×` without default button styles.
5
+ #
6
+ # @accessibility
7
+ # `CloseButton` has a default `aria-label` of "Close" to provides assistive technologies with an accessible label.
8
+ # You may choose to override this label with something more descriptive via [system_arguments][0].
9
+ # [0]: https://primer.style/view-components/system-arguments#html-attributes
10
+ class CloseButton < Primer::Component
11
+ status :beta
12
+
13
+ DEFAULT_TYPE = :button
14
+ TYPE_OPTIONS = [DEFAULT_TYPE, :submit].freeze
15
+
16
+ # @example Default
17
+ # <%= render(Primer::CloseButton.new) %>
18
+ #
19
+ # @param type [Symbol] <%= one_of(Primer::CloseButton::TYPE_OPTIONS) %>
20
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
21
+ def initialize(type: DEFAULT_TYPE, **system_arguments)
22
+ @system_arguments = system_arguments
23
+ @system_arguments[:tag] = :button
24
+ @system_arguments[:block] = false
25
+ @system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
26
+ @system_arguments[:classes] = class_names(
27
+ "close-button",
28
+ system_arguments[:classes]
29
+ )
30
+ @system_arguments[:"aria-label"] ||= "Close"
31
+ end
32
+
33
+ def call
34
+ render(Primer::BaseButton.new(**@system_arguments)) do
35
+ render(Primer::OcticonComponent.new("x"))
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "octicons_helper/helper"
4
3
  require "view_component/version"
5
4
 
6
5
  module Primer
@@ -9,9 +8,25 @@ module Primer
9
8
  include ViewComponent::SlotableV2 unless ViewComponent::VERSION::STRING.to_f >= 2.28
10
9
  include ClassNameHelper
11
10
  include FetchOrFallbackHelper
12
- include OcticonsHelper
11
+ include TestSelectorHelper
13
12
  include JoinStyleArgumentsHelper
14
13
  include ViewHelper
15
14
  include Status::Dsl
15
+
16
+ private
17
+
18
+ def deprecated_component_warning(new_class: nil, version: nil)
19
+ return if Rails.env.production? || silence_deprecations?
20
+
21
+ message = "#{self.class.name} is deprecated"
22
+ message += " and will be removed in v#{version}." if version
23
+ message += " Use #{new_class.name} instead." if new_class
24
+
25
+ ActiveSupport::Deprecation.warn(message)
26
+ end
27
+
28
+ def silence_deprecations?
29
+ Rails.application.config.primer_view_components.silence_deprecations
30
+ end
16
31
  end
17
32
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use Primer::CounterComponent to add a count to navigational elements and buttons.
4
+ # Use `CounterComponent` to add a count to navigational elements and buttons.
5
5
  class CounterComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use DetailsComponent to reveal content after clicking a button.
4
+ # Use `DetailsComponent` to reveal content after clicking a button.
5
5
  class DetailsComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Primer
4
4
  module Dropdown
5
- # This component is part of `Primer::DropdownComponent` and should not be
5
+ # This component is part of `Dropdown` and should not be
6
6
  # used as a standalone component.
7
7
  class MenuComponent < Primer::Component
8
8
  SCHEME_DEFAULT = :default
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Dropdowns are lightweight context menus for housing navigation and actions.
4
+ # `Dropdown` is a lightweight context menu for housing navigation and actions.
5
5
  # They're great for instances where you don't need the full power (and code) of the select menu.
6
6
  class DropdownComponent < Primer::Component
7
7
  # Required trigger for the dropdown. Only accepts a content.
@@ -11,7 +11,7 @@ module Primer
11
11
  # Required context menu for the dropdown
12
12
  #
13
13
  # @param direction [Symbol] <%= one_of(Primer::Dropdown::MenuComponent::DIRECTION_OPTIONS) %>
14
- # @param scheme [Symbol] Pass :dark for dark mode theming
14
+ # @param scheme [Symbol] Pass `:dark` for dark mode theming
15
15
  # @param header [String] Optional string to display as the header
16
16
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
17
17
  renders_one :menu, Primer::Dropdown::MenuComponent
@@ -36,7 +36,7 @@ module Primer
36
36
  # </div>
37
37
  #
38
38
  # @param direction [Symbol] <%= one_of(Primer::DropdownMenuComponent::DIRECTION_OPTIONS) %>
39
- # @param scheme [Symbol] Pass :dark for dark mode theming
39
+ # @param scheme [Symbol] Pass `:dark` for dark mode theming
40
40
  # @param header [String] Optional string to display as the header
41
41
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
42
42
  def initialize(direction: DIRECTION_DEFAULT, scheme: SCHEME_DEFAULT, header: nil, **system_arguments)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use the Flash component to inform users of successful or pending actions.
4
+ # Use `Flash` to inform users of successful or pending actions.
5
5
  class FlashComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use FlexComponent to make an element lay out its content using the flexbox model.
4
+ # Use `Flex` to make an element lay out its content using the flexbox model.
5
5
  # Before using these utilities, you should be familiar with CSS3 Flexible Box
6
6
  # spec. If you are not, check out MDN's guide [Using CSS Flexible
7
7
  # Boxes](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox).
@@ -1,9 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use FlexItemComponent to specify the ability of a flex item to alter its
4
+ # Use `FlexItem` to specify the ability of a flex item to alter its
5
5
  # dimensions to fill available space
6
+ #
7
+ # @deprecated
8
+ # Use <%= link_to_component(Primer::BoxComponent) %> instead.
9
+ #
10
+ # **Before**:
11
+ #
12
+ # ```erb
13
+ # <%%= render Primer::FlexItemComponent.new(flex_auto: :auto) %>
14
+ # ```
15
+ #
16
+ # **After**:
17
+ #
18
+ # ```erb
19
+ # <%%= render Primer::BoxComponent.new(flex: :auto) %>
20
+ # ```
6
21
  class FlexItemComponent < Primer::Component
22
+ status :deprecated
23
+
7
24
  FLEX_AUTO_DEFAULT = false
8
25
  FLEX_AUTO_ALLOWED_VALUES = [FLEX_AUTO_DEFAULT, true].freeze
9
26
 
@@ -21,6 +38,8 @@ module Primer
21
38
  # @param flex_auto [Boolean] Fills available space and auto-sizes based on the content. Defaults to <%= Primer::FlexItemComponent::FLEX_AUTO_DEFAULT %>
22
39
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
23
40
  def initialize(flex_auto: FLEX_AUTO_DEFAULT, **system_arguments)
41
+ deprecated_component_warning(new_class: Primer::BoxComponent, version: "0.0.39")
42
+
24
43
  @system_arguments = system_arguments
25
44
  @system_arguments[:classes] =
26
45
  class_names(
@@ -1,19 +1,47 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use the Heading component to wrap a component that will create a heading element
4
+ # `Heading` can be used to communicate page organization and hierarchy.
5
+ #
6
+ # - Set tag to one of `:h1`, `:h2`, `:h3`, `:h4`, `:h5`, `:h6` based on what is
7
+ # appropriate for the page context.
8
+ # - Use `Heading` as the title of a section or sub section.
9
+ # - Do not use `Heading` for styling alone. To style text without conveying heading semantics,
10
+ # consider using <%= link_to_component(Primer::TextComponent) %> with relevant <%= link_to_typography_docs %>.
11
+ # - Do not jump heading levels. For instance, do not follow a `<h1>` with an `<h3>`. Heading levels should
12
+ # increase by one in ascending order.
13
+ #
14
+ # @accessibility
15
+ # Headings convey semantic meaning. Assistive technology users rely on headings to quickly navigate and scan information on a page.
16
+ # Inappropriate use of headings can lead to a confusing experience.
17
+ # [Learn more about best heading practices (WAI Headings)](https://www.w3.org/WAI/tutorials/page-structure/headings/)
5
18
  class HeadingComponent < Primer::Component
6
19
  status :beta
7
20
 
21
+ TAG_FALLBACK = :h2
22
+ TAG_OPTIONS = [:h1, TAG_FALLBACK, :h3, :h4, :h5, :h6].freeze
23
+
8
24
  # @example Default
9
- # <%= render(Primer::HeadingComponent.new) { "H1 Text" } %>
25
+ # <%= render(Primer::HeadingComponent.new(tag: :h1)) { "H1 Text" } %>
10
26
  # <%= render(Primer::HeadingComponent.new(tag: :h2)) { "H2 Text" } %>
11
27
  # <%= render(Primer::HeadingComponent.new(tag: :h3)) { "H3 Text" } %>
28
+ # <%= render(Primer::HeadingComponent.new(tag: :h4)) { "H4 Text" } %>
29
+ # <%= render(Primer::HeadingComponent.new(tag: :h5)) { "H5 Text" } %>
30
+ # <%= render(Primer::HeadingComponent.new(tag: :h6)) { "H6 Text" } %>
31
+ #
32
+ # @example With `font_size`
33
+ # <%= render(Primer::HeadingComponent.new(tag: :h1, font_size: 6)) { "h1 tag, font_size 6" } %>
34
+ # <%= render(Primer::HeadingComponent.new(tag: :h2, font_size: 3)) { "h2 tag, font_size 3" } %>
35
+ # <%= render(Primer::HeadingComponent.new(tag: :h3, font_size: 2)) { "h3 tag, font_size 2" } %>
36
+ # <%= render(Primer::HeadingComponent.new(tag: :h4, font_size: 0)) { "h4 tag, font_size 0" } %>
37
+ # <%= render(Primer::HeadingComponent.new(tag: :h5, font_size: 1)) { "h5 tag, font_size 1" } %>
38
+ # <%= render(Primer::HeadingComponent.new(tag: :h6, font_size: 4)) { "h6 tag, font_size 4" } %>
12
39
  #
40
+ # @param tag [String] <%= one_of(Primer::HeadingComponent::TAG_OPTIONS) %>
13
41
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
14
- def initialize(**system_arguments)
42
+ def initialize(tag:, **system_arguments)
15
43
  @system_arguments = system_arguments
16
- @system_arguments[:tag] ||= :h1
44
+ @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, TAG_FALLBACK)
17
45
  end
18
46
 
19
47
  def call
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use `HiddenTextExpander` to indicate and toggle hidden text.
5
+ class HiddenTextExpander < Primer::Component
6
+ # @example Default
7
+ # <%= render(Primer::HiddenTextExpander.new) %>
8
+ #
9
+ # @example Inline
10
+ # <%= render(Primer::HiddenTextExpander.new(inline: true)) %>
11
+ #
12
+ # @example Styling the button
13
+ # <%= render(Primer::HiddenTextExpander.new(button_arguments: { p: 1, classes: "my-custom-class" })) %>
14
+ #
15
+ # @param inline [Boolean] Whether or not the expander is inline.
16
+ # @param button_arguments [Hash] <%= link_to_system_arguments_docs %> for the button element.
17
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
18
+ def initialize(inline: false, button_arguments: {}, **system_arguments)
19
+ @system_arguments = system_arguments
20
+ @system_arguments[:tag] ||= :span
21
+ @system_arguments[:classes] = class_names(
22
+ "hidden-text-expander",
23
+ @system_arguments[:classes],
24
+ "inline" => inline
25
+ )
26
+
27
+ @button_arguments = button_arguments
28
+ @button_arguments[:"aria-expanded"] = false
29
+ @button_arguments[:classes] = class_names(
30
+ "ellipsis-expander",
31
+ button_arguments[:classes]
32
+ )
33
+ end
34
+
35
+ def call
36
+ render(Primer::BaseComponent.new(**@system_arguments)) do
37
+ render(Primer::BaseButton.new(**@button_arguments)) { "&hellip;" }
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use `IconButton` to render Icon-only buttons without the default button styles.
5
+ #
6
+ # @accessibility
7
+ # `IconButton` requires an `aria-label`, which will provide assistive technologies with an accessible label.
8
+ class IconButton < Primer::Component
9
+ DEFAULT_SCHEME = :default
10
+ SCHEME_MAPPINGS = {
11
+ DEFAULT_SCHEME => "",
12
+ :danger => "btn-octicon-danger"
13
+ }.freeze
14
+ SCHEME_OPTIONS = SCHEME_MAPPINGS.keys
15
+ # @example Default
16
+ #
17
+ # <%= render(Primer::IconButton.new(icon: :search, "aria-label": "Search")) %>
18
+ #
19
+ # @example Schemes
20
+ #
21
+ # <%= render(Primer::IconButton.new(icon: :search, "aria-label": "Search")) %>
22
+ # <%= render(Primer::IconButton.new(icon: :trash, "aria-label": "Delete", scheme: :danger)) %>
23
+ #
24
+ # @param scheme [Symbol] <%= one_of(Primer::IconButton::SCHEME_OPTIONS) %>
25
+ # @param icon [String] Name of <%= link_to_octicons %> to use.
26
+ # @param tag [Symbol] <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
27
+ # @param type [Symbol] <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
28
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
29
+ def initialize(scheme: DEFAULT_SCHEME, icon:, **system_arguments)
30
+ @icon = icon
31
+
32
+ @system_arguments = system_arguments
33
+ @system_arguments[:classes] = class_names(
34
+ "btn-octicon",
35
+ SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)],
36
+ system_arguments[:classes]
37
+ )
38
+
39
+ raise ArgumentError, "`aria-label` is required." if @system_arguments[:"aria-label"].nil? && !Rails.env.production?
40
+ end
41
+
42
+ def call
43
+ render(Primer::BaseButton.new(**@system_arguments)) do
44
+ render(Primer::OcticonComponent.new(icon: @icon))
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use labels to add contextual metadata to a design.
4
+ # Use `Label` to add contextual metadata to a design.
5
5
  class LabelComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use Layout to build a main/sidebar layout.
4
+ # Use `Layout` to build a main/sidebar layout.
5
5
  class LayoutComponent < Primer::Component
6
6
  # The main content
7
7
  #
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use links for moving from one page to another. The Link component styles anchor tags with default blue styling and hover text-decoration.
4
+ # Use `Link` for navigating from one page to another. `Link` styles anchor tags with default blue styling and hover text-decoration.
5
5
  class LinkComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use MarkdownComponent to wrap markdown content
4
+ # Use `Markdown` to wrap markdown content
5
5
  class MarkdownComponent < Primer::Component
6
6
  # @example Default
7
7
  # <%= render(Primer::MarkdownComponent.new) do %>
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use menus to create vertical lists of navigational links.
4
+ # Use `Menu` to create vertical lists of navigational links.
5
5
  class MenuComponent < Primer::Component
6
6
  # Optional menu heading
7
7
  #
@@ -1,9 +1,11 @@
1
- <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
- <%= icon %>
3
- <% if text.present? %>
4
- <%= text %>
5
- <% else %>
6
- <%= content %>
1
+ <%= wrapper do %>
2
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
3
+ <%= icon %>
4
+ <% if text.present? %>
5
+ <%= text %>
6
+ <% else %>
7
+ <%= content %>
8
+ <% end %>
9
+ <%= counter %>
7
10
  <% end %>
8
- <%= counter %>
9
11
  <% end %>
@@ -65,30 +65,43 @@ module Primer
65
65
  # <% c.counter(count: 10) %>
66
66
  # <% end %>
67
67
  #
68
+ # @example Inside a list
69
+ # <%= render(Primer::Navigation::TabComponent.new(list: true)) do |c| %>
70
+ # <% c.text { "Tab" } %>
71
+ # <% end %>
72
+ #
68
73
  # @example With custom HTML
69
- # <%= render(Primer::Navigation::TabComponent.new) do |c| %>
74
+ # <%= render(Primer::Navigation::TabComponent.new) do %>
70
75
  # <div>
71
76
  # This is my <strong>custom HTML</strong>
72
77
  # </div>
73
78
  # <% end %>
74
79
  #
80
+ # @param list [Boolean] Whether the Tab is an item in a `<ul>` list.
75
81
  # @param selected [Boolean] Whether the Tab is selected or not.
76
82
  # @param with_panel [Boolean] Whether the Tab has an associated panel.
77
83
  # @param icon_classes [Boolean] Classes that must always be applied to icons.
84
+ # @param wrapper_arguments [Hash] <%= link_to_system_arguments_docs %> to be used in the `<li>` wrapper when the tab is an item in a list.
78
85
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
79
- def initialize(selected: false, with_panel: false, icon_classes: "", **system_arguments)
86
+ def initialize(list: false, selected: false, with_panel: false, icon_classes: "", wrapper_arguments: {}, **system_arguments)
80
87
  @selected = selected
81
88
  @icon_classes = icon_classes
89
+ @list = list
90
+
82
91
  @system_arguments = system_arguments
83
- @system_arguments[:role] = :tab
84
92
 
85
93
  if with_panel
86
94
  @system_arguments[:tag] ||= :button
87
95
  @system_arguments[:type] = :button
96
+ @system_arguments[:role] = :tab
88
97
  else
89
98
  @system_arguments[:tag] ||= :a
90
99
  end
91
100
 
101
+ @wrapper_arguments = wrapper_arguments
102
+ @wrapper_arguments[:tag] = :li
103
+ @wrapper_arguments[:display] ||= :flex
104
+
92
105
  return unless @selected
93
106
 
94
107
  if @system_arguments[:tag] == :a
@@ -97,6 +110,17 @@ module Primer
97
110
  @system_arguments[:"aria-selected"] = true
98
111
  end
99
112
  end
113
+
114
+ def wrapper
115
+ unless @list
116
+ yield
117
+ return # returning `yield` caused a double render
118
+ end
119
+
120
+ render(Primer::BaseComponent.new(**@wrapper_arguments)) do
121
+ yield
122
+ end
123
+ end
100
124
  end
101
125
  end
102
126
  end