primer_view_components 0.0.35 → 0.0.40

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +178 -22
  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} +12 -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 +6 -3
  15. data/app/components/primer/base_button.rb +47 -0
  16. data/app/components/primer/base_component.rb +9 -8
  17. data/app/components/primer/blankslate_component.rb +5 -2
  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 +58 -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 +21 -2
  33. data/app/components/primer/counter_component.rb +6 -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 +1 -1
  37. data/app/components/primer/flash_component.rb +1 -1
  38. data/app/components/primer/flex_component.rb +28 -1
  39. data/app/components/primer/flex_item_component.rb +20 -1
  40. data/app/components/primer/heading_component.rb +25 -4
  41. data/app/components/primer/hidden_text_expander.rb +41 -0
  42. data/app/components/primer/icon_button.rb +65 -0
  43. data/app/components/primer/image_crop.d.ts +1 -0
  44. data/app/components/primer/image_crop.html.erb +12 -0
  45. data/app/components/primer/image_crop.js +1 -0
  46. data/app/components/primer/image_crop.rb +36 -0
  47. data/app/components/primer/image_crop.ts +1 -0
  48. data/app/components/primer/label_component.rb +1 -1
  49. data/app/components/primer/layout_component.rb +1 -1
  50. data/app/components/primer/link_component.rb +1 -1
  51. data/app/components/primer/{markdown_component.rb → markdown.rb} +6 -5
  52. data/app/components/primer/menu_component.rb +1 -1
  53. data/app/components/primer/octicon_component.html.erb +7 -0
  54. data/app/components/primer/octicon_component.rb +46 -14
  55. data/app/components/primer/octicon_symbols_component.html.erb +3 -0
  56. data/app/components/primer/octicon_symbols_component.rb +61 -0
  57. data/app/components/primer/popover_component.rb +1 -1
  58. data/app/components/primer/primer.d.ts +3 -1
  59. data/app/components/primer/primer.js +3 -1
  60. data/app/components/primer/primer.ts +3 -1
  61. data/app/components/primer/progress_bar_component.rb +1 -1
  62. data/app/components/primer/spinner_component.rb +3 -3
  63. data/app/components/primer/state_component.rb +2 -2
  64. data/app/components/primer/subhead_component.rb +34 -4
  65. data/app/components/primer/tab_container_component.rb +1 -1
  66. data/app/components/primer/tab_nav_component.rb +1 -1
  67. data/app/components/primer/text_component.rb +6 -3
  68. data/app/components/primer/time_ago_component.rb +1 -1
  69. data/app/components/primer/timeline_item_component.rb +1 -1
  70. data/app/components/primer/tooltip_component.rb +1 -1
  71. data/app/components/primer/{truncate_component.rb → truncate.rb} +8 -6
  72. data/app/components/primer/underline_nav_component.rb +1 -1
  73. data/app/lib/primer/classify.rb +9 -34
  74. data/app/lib/primer/classify/cache.rb +20 -15
  75. data/app/lib/primer/classify/flex.rb +111 -0
  76. data/app/lib/primer/classify/functional_border_colors.rb +1 -2
  77. data/app/lib/primer/fetch_or_fallback_helper.rb +2 -2
  78. data/app/lib/primer/octicon/cache.rb +42 -0
  79. data/lib/primer/view_components.rb +1 -1
  80. data/lib/primer/view_components/version.rb +1 -1
  81. data/lib/tasks/coverage.rake +14 -0
  82. data/lib/tasks/docs.rake +312 -0
  83. data/lib/tasks/statuses.rake +12 -0
  84. data/lib/yard/docs_helper.rb +57 -0
  85. data/static/statuses.json +52 -1
  86. metadata +53 -15
  87. data/app/assets/javascripts/primer_view_components.js.map.orig +0 -5
  88. data/app/assets/javascripts/primer_view_components.js.orig +0 -6
  89. data/app/components/primer/auto_complete_item_component.rb +0 -40
  90. data/app/components/primer/button_group_component.rb +0 -35
@@ -0,0 +1 @@
1
+ import '@github/image-crop-element';
@@ -0,0 +1,12 @@
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
+ <% if loading.present? %>
3
+ <%= loading %>
4
+ <% else %>
5
+ <%= render(Primer::SpinnerComponent.new(size: :large, flex: 1, "data-loading-slot": true)) %>
6
+ <% end %>
7
+
8
+ <input type="hidden" data-image-crop-input="x" name="cropped_x">
9
+ <input type="hidden" data-image-crop-input="y" name="cropped_y">
10
+ <input type="hidden" data-image-crop-input="width" name="cropped_width">
11
+ <input type="hidden" data-image-crop-input="height" name="cropped_height">
12
+ <% end %>
@@ -0,0 +1 @@
1
+ import '@github/image-crop-element';
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # A client-side mechanism to crop images.
5
+ class ImageCrop < Primer::Component
6
+ # A loading indicator that is shown while the image is loading.
7
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
8
+ renders_one :loading, lambda { |**system_arguments|
9
+ system_arguments[:tag] ||= :div
10
+ system_arguments[:"data-loading-slot"] = true
11
+
12
+ Primer::BaseComponent.new(**system_arguments)
13
+ }
14
+
15
+ # @example Simple cropper
16
+ # <%= render(Primer::ImageCrop.new(src: "https://github.com/koddsson.png")) %>
17
+ #
18
+ # @example Square cropper
19
+ # <%= render(Primer::ImageCrop.new(src: "https://github.com/koddsson.png", rounded: false)) %>
20
+ #
21
+ # @example Cropper with a custom loader
22
+ # <%= render(Primer::ImageCrop.new(src: "https://github.com/koddsson.png", rounded: false)) do |cropper| %>
23
+ # <% cropper.loading(style: "width: 120px", tag: :img, src: "spinner.gif") %>
24
+ # <% end %>
25
+ #
26
+ # @param src [String] The path of the image to crop.
27
+ # @param rounded [Boolean] If the crop mask should be a circle. Defaults to true.
28
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
29
+ def initialize(src:, rounded: true, **system_arguments)
30
+ @system_arguments = system_arguments
31
+ @system_arguments[:tag] = "image-crop"
32
+ @system_arguments[:src] = src
33
+ @system_arguments[:rounded] = rounded
34
+ end
35
+ end
36
+ end
@@ -0,0 +1 @@
1
+ import '@github/image-crop-element'
@@ -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,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use MarkdownComponent to wrap markdown content
5
- class MarkdownComponent < Primer::Component
4
+ # Use `Markdown` to wrap markdown content
5
+ class Markdown < Primer::Component
6
+ status :beta
6
7
  # @example Default
7
- # <%= render(Primer::MarkdownComponent.new) do %>
8
+ # <%= render(Primer::Markdown.new) do %>
8
9
  # <p>Text can be <b>bold</b>, <i>italic</i>, or <s>strikethrough</s>. <a href="https://github.com">Links </a> should be blue with no underlines (unless hovered over).</p>
9
10
  #
10
11
  # <p>There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs.</p>
@@ -235,11 +236,11 @@ module Primer
235
236
  #
236
237
  # <p>Code can also use syntax highlighting.</p>
237
238
  #
238
- # <pre><code class="prism-code language-javascript">var foo = "bar";</code></pre>
239
+ # <pre><code>var foo = "bar";</code></pre>
239
240
  #
240
241
  # <pre><code>Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.</code></pre>
241
242
  #
242
- # <pre><code class="prism-code language-javascript">var foo = "The same thing is true for code with syntax highlighting. A single line of code should horizontally scroll if it is really long.";</code></pre>
243
+ # <pre><code>var foo = "The same thing is true for code with syntax highlighting. A single line of code should horizontally scroll if it is really long.";</code></pre>
243
244
  #
244
245
  # <p>Inline code inside table cells should still be distinguishable.</p>
245
246
  #
@@ -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
  #
@@ -0,0 +1,7 @@
1
+ <%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
2
+ <% if @use_symbol %>
3
+ <use href="#octicon_<%= [@icon.symbol, @icon.height].join("_") %>"></use>
4
+ <% else %>
5
+ <%= @icon.path.html_safe %>
6
+ <% end %>
7
+ <% end %>
@@ -1,15 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "octicons"
4
+
3
5
  module Primer
4
- # Renders an [Octicon](https://primer.style/octicons/) with <%= link_to_system_arguments_docs %>.
6
+ # `Octicon` renders an <%= link_to_octicons %> with <%= link_to_system_arguments_docs %>.
7
+ # `Octicon` can also be rendered with the `primer_octicon` helper, which accepts the same arguments.
5
8
  class OcticonComponent < Primer::Component
6
9
  status :beta
7
10
 
8
11
  SIZE_DEFAULT = :small
12
+ SIZE_MEDIUM = :medium
13
+ SIZE_LARGE = :large
14
+
9
15
  SIZE_MAPPINGS = {
10
16
  SIZE_DEFAULT => 16,
11
- :medium => 32,
12
- :large => 64
17
+ SIZE_MEDIUM => 32,
18
+ SIZE_LARGE => 64
13
19
  }.freeze
14
20
  SIZE_OPTIONS = SIZE_MAPPINGS.keys
15
21
 
@@ -23,24 +29,50 @@ module Primer
23
29
  # @example Large
24
30
  # <%= render(Primer::OcticonComponent.new("x", size: :large)) %>
25
31
  #
26
- # @param icon [String] Name of [Octicon](https://primer.style/octicons/) to use.
32
+ # @example Helper
33
+ # <%= primer_octicon("check") %>
34
+ #
35
+ # @param icon [String] Name of <%= link_to_octicons %> to use.
27
36
  # @param size [Symbol] <%= one_of(Primer::OcticonComponent::SIZE_MAPPINGS) %>
37
+ # @param use_symbol [Boolean] EXPERIMENTAL (May change or be removed) - Set to true when using with <%= link_to_component(Primer::OcticonSymbolsComponent) %>.
28
38
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
29
- def initialize(icon_name = nil, icon: nil, size: SIZE_DEFAULT, **system_arguments)
30
- @icon = icon_name || icon
39
+ def initialize(icon_name = nil, icon: nil, size: SIZE_DEFAULT, use_symbol: false, **system_arguments)
40
+ icon_key = icon_name || icon
41
+ cache_key = Primer::Octicon::Cache.get_key(symbol: icon_key, size: size, **system_arguments.slice(:height, :width))
42
+
31
43
  @system_arguments = system_arguments
44
+ @system_arguments[:tag] = :svg
45
+ @system_arguments[:aria] ||= {}
46
+ @use_symbol = use_symbol
47
+
48
+ if @system_arguments[:aria][:label] || @system_arguments[:"aria-label"]
49
+ @system_arguments[:role] = "img"
50
+ else
51
+ @system_arguments[:aria][:hidden] = true
52
+ end
53
+
54
+ if (cache_icon = Primer::Octicon::Cache.read(cache_key))
55
+ @icon = cache_icon
56
+ else
57
+ # Filter out classify options to prevent them from becoming invalid html attributes.
58
+ # Note height and width are both classify options and valid html attributes.
59
+ octicon_options = {
60
+ height: SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, SIZE_DEFAULT)]
61
+ }.merge(@system_arguments.slice(:height, :width))
32
62
 
33
- @system_arguments[:class] = Primer::Classify.call(**@system_arguments)[:class]
34
- @system_arguments[:height] ||= SIZE_MAPPINGS[size]
63
+ @icon = Octicons::Octicon.new(icon_key, octicon_options)
64
+ Primer::Octicon::Cache.set(cache_key, @icon)
65
+ end
35
66
 
36
- # Filter out classify options to prevent them from becoming invalid html attributes.
37
- # Note height and width are both classify options and valid html attributes.
38
- octicon_helper_options = @system_arguments.slice(:height, :width)
39
- @system_arguments = add_test_selector(@system_arguments).except(*Primer::Classify::VALID_KEYS, :classes).merge(octicon_helper_options)
67
+ @system_arguments[:classes] = class_names(
68
+ @icon.options[:class],
69
+ @system_arguments[:classes]
70
+ )
71
+ @system_arguments.merge!(@icon.options.except(:class, :'aria-hidden'))
40
72
  end
41
73
 
42
- def call
43
- octicon(@icon, { **@system_arguments })
74
+ def self._after_compile
75
+ Primer::Octicon::Cache.preload!
44
76
  end
45
77
  end
46
78
  end
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" hidden>
2
+ <%= symbol_tags %>
3
+ </svg>
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "octicons"
4
+
5
+ module Primer
6
+ # OcticonSymbols renders a symbol dictionary using a list of <%= link_to_octicons %>.
7
+ class OcticonSymbolsComponent < Primer::Component
8
+ # @example Symbol dictionary
9
+ # <%= render(Primer::OcticonComponent.new(icon: :check, use_symbol: true, color: :icon_success)) %>
10
+ # <%= render(Primer::OcticonComponent.new(icon: :check, use_symbol: true, color: :text_danger)) %>
11
+ # <%= render(Primer::OcticonComponent.new(icon: :check, use_symbol: true, size: :medium)) %>
12
+ # <%= render(Primer::OcticonSymbolsComponent.new(icons: [{ symbol: :check }, { symbol: :check, size: :medium }])) %>
13
+ #
14
+ # @param icons [Array<Hash>] List of icons to render, in the format { symbol: :icon_name, size: :small }
15
+ def initialize(icons: [])
16
+ @icons = {}
17
+ icons.each do |icon|
18
+ symbol = icon[:symbol]
19
+ size = Primer::OcticonComponent::SIZE_MAPPINGS[
20
+ fetch_or_fallback(Primer::OcticonComponent::SIZE_OPTIONS, icon[:size] || Primer::OcticonComponent::SIZE_DEFAULT, Primer::OcticonComponent::SIZE_DEFAULT)
21
+ ]
22
+
23
+ cache_key = Primer::Octicon::Cache.get_key(symbol: symbol, size: size)
24
+
25
+ if (cache_icon = Primer::Octicon::Cache.read(cache_key))
26
+ icon_instance = cache_icon
27
+ else
28
+ icon_instance = Octicons::Octicon.new(symbol, height: size)
29
+
30
+ Primer::Octicon::Cache.set(cache_key, icon_instance)
31
+ end
32
+
33
+ # Don't put the same icon twice
34
+ @icons[[symbol, icon_instance.height]] = icon_instance if @icons[[symbol, icon_instance.height]].nil?
35
+ end
36
+ end
37
+
38
+ def render?
39
+ @icons.any?
40
+ end
41
+
42
+ def self._after_compile
43
+ Primer::Octicon::Cache.preload!
44
+ end
45
+
46
+ def symbol_tags
47
+ safe_join(
48
+ @icons.values.map do |icon|
49
+ content_tag(
50
+ :symbol,
51
+ icon.path.html_safe, # rubocop:disable Rails/OutputSafety
52
+ id: "octicon_#{icon.symbol}_#{icon.height}",
53
+ viewBox: icon.options[:viewBox],
54
+ width: icon.width,
55
+ height: icon.height
56
+ )
57
+ end
58
+ )
59
+ end
60
+ end
61
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use popovers to bring attention to specific user interface elements, typically to suggest an action or to guide users through a new experience.
4
+ # Use `Popover` to bring attention to specific user interface elements, typically to suggest an action or to guide users through a new experience.
5
5
  #
6
6
  # By default, the popover renders with absolute positioning, meaning it should usually be wrapped in an element with a relative position in order to be positioned properly. To render the popover with relative positioning, use the relative property.
7
7
  class PopoverComponent < Primer::Component
@@ -1,3 +1,5 @@
1
- import './auto_complete_component';
1
+ import './auto_complete/auto_complete';
2
+ import './clipboard_copy_component';
2
3
  import './tab_container_component';
3
4
  import './time_ago_component';
5
+ import './image_crop';
@@ -1,3 +1,5 @@
1
- import './auto_complete_component';
1
+ import './auto_complete/auto_complete';
2
+ import './clipboard_copy_component';
2
3
  import './tab_container_component';
3
4
  import './time_ago_component';
5
+ import './image_crop';
@@ -1,3 +1,5 @@
1
- import './auto_complete_component'
1
+ import './auto_complete/auto_complete'
2
+ import './clipboard_copy_component'
2
3
  import './tab_container_component'
3
4
  import './time_ago_component'
5
+ import './image_crop'
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use ProgressBar to visualize task completion.
4
+ # Use `ProgressBar` to visualize task completion.
5
5
  class ProgressBarComponent < 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 Primer::SpinnerComponent to let users know that content is being loaded.
4
+ # Use `Spinner` to let users know that content is being loaded.
5
5
  class SpinnerComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -27,10 +27,10 @@ module Primer
27
27
  # <%= render(Primer::SpinnerComponent.new(size: :large)) %>
28
28
  #
29
29
  # @param size [Symbol] <%= one_of(Primer::SpinnerComponent::SIZE_MAPPINGS) %>
30
- def initialize(size: DEFAULT_SIZE, **system_arguments)
30
+ def initialize(size: DEFAULT_SIZE, style: DEFAULT_STYLE, **system_arguments)
31
31
  @system_arguments = system_arguments
32
32
  @system_arguments[:tag] = :svg
33
- @system_arguments[:style] ||= DEFAULT_STYLE
33
+ @system_arguments[:style] ||= style
34
34
  @system_arguments[:animation] = :rotate
35
35
  @system_arguments[:width] = SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)]
36
36
  @system_arguments[:height] = SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)]
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Component for rendering the status of an item.
4
+ # Use `State` for rendering the status of an item.
5
5
  class StateComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -29,7 +29,7 @@ module Primer
29
29
  SIZE_OPTIONS = SIZE_MAPPINGS.keys
30
30
 
31
31
  TAG_DEFAULT = :span
32
- TAG_OPTIONS = [TAG_DEFAULT, :div, :a].freeze
32
+ TAG_OPTIONS = [TAG_DEFAULT, :div].freeze
33
33
 
34
34
  # @example Default
35
35
  # <%= render(Primer::StateComponent.new(title: "title")) { "State" } %>
@@ -1,16 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use the Subhead component for page headings.
4
+ # Use `Subhead` as the start of a section. The `:heading` slot will render an `<h2>` font-sized text.
5
+ #
6
+ # - Optionally set the `:description` slot to render a short description and the `:actions` slot for a related action.
7
+ # - Use a succint, one-line description for the `:description` slot. For longer descriptions, omit the description slot and render a paragraph below the `Subhead`.
8
+ # - Use the actions slot to render a related action to the right of the heading. Use <%= link_to_component(Primer::ButtonComponent) %> or <%= link_to_component(Primer::LinkComponent) %>.
9
+ #
10
+ # @accessibility
11
+ # The `:heading` slot defaults to rendering a `<div>`. Update the tag to a heading element with the appropriate level to improve page navigation for assistive technologies.
12
+ # <%= link_to_heading_practices %>
5
13
  class SubheadComponent < Primer::Component
6
14
  status :beta
7
15
 
16
+ DEFAULT_HEADING_TAG = :div
17
+ HEADING_TAG_OPTIONS = [DEFAULT_HEADING_TAG, :h1, :h2, :h3, :h4, :h5, :h6].freeze
18
+
8
19
  # The heading
9
20
  #
21
+ # @param tag [Symbol] <%= one_of(Primer::SubheadComponent::HEADING_TAG_OPTIONS)%>
10
22
  # @param danger [Boolean] Whether to style the heading as dangerous.
11
23
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
12
- renders_one :heading, lambda { |danger: false, **system_arguments|
13
- system_arguments[:tag] ||= :div
24
+ renders_one :heading, lambda { |tag: DEFAULT_HEADING_TAG, danger: false, **system_arguments|
25
+ system_arguments[:tag] = fetch_or_fallback(HEADING_TAG_OPTIONS, tag, DEFAULT_HEADING_TAG)
14
26
  system_arguments[:classes] = class_names(
15
27
  system_arguments[:classes],
16
28
  "Subhead-heading",
@@ -42,7 +54,7 @@ module Primer
42
54
 
43
55
  # @example Default
44
56
  # <%= render(Primer::SubheadComponent.new) do |component| %>
45
- # <% component.heading do %>
57
+ # <% component.heading(tag: :h3) do %>
46
58
  # My Heading
47
59
  # <% end %>
48
60
  # <% component.description do %>
@@ -50,6 +62,24 @@ module Primer
50
62
  # <% end %>
51
63
  # <% end %>
52
64
  #
65
+ # @example With dangerous heading
66
+ # <%= render(Primer::SubheadComponent.new) do |component| %>
67
+ # <% component.heading(tag: :h3, danger: true) do %>
68
+ # My Heading
69
+ # <% end %>
70
+ # <% component.description do %>
71
+ # My Description
72
+ # <% end %>
73
+ # <% end %>
74
+ #
75
+ # @example With long description
76
+ # <%= render(Primer::SubheadComponent.new) do |component| %>
77
+ # <% component.heading(tag: :h3) do %>
78
+ # My Heading
79
+ # <% end %>
80
+ # <% end %>
81
+ # <p> This is a longer description that is sitting below the Subhead. It's much longer than a description that could sit comfortably in the Subhead. </p>
82
+ #
53
83
  # @example Without border
54
84
  # <%= render(Primer::SubheadComponent.new(hide_border: true)) do |component| %>
55
85
  # <% component.heading do %>