primer_view_components 0.0.39 → 0.0.44

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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +269 -3
  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/alpha/button_marketing.rb +70 -0
  6. data/app/components/primer/auto_complete.rb +99 -41
  7. data/app/components/primer/auto_complete/auto_complete.html.erb +1 -0
  8. data/app/components/primer/avatar_stack_component.rb +7 -4
  9. data/app/components/primer/base_component.rb +17 -7
  10. data/app/components/primer/beta/text.rb +27 -0
  11. data/app/components/primer/blankslate_component.html.erb +1 -0
  12. data/app/components/primer/blankslate_component.rb +68 -49
  13. data/app/components/primer/button_component.rb +3 -2
  14. data/app/components/primer/button_group.rb +2 -2
  15. data/app/components/primer/clipboard_copy_component.js +13 -2
  16. data/app/components/primer/clipboard_copy_component.ts +15 -2
  17. data/app/components/primer/component.rb +6 -1
  18. data/app/components/primer/counter_component.rb +6 -1
  19. data/app/components/primer/details_component.rb +12 -1
  20. data/app/components/primer/dropdown.d.ts +1 -0
  21. data/app/components/primer/{dropdown_component.html.erb → dropdown.html.erb} +2 -1
  22. data/app/components/primer/dropdown.js +1 -0
  23. data/app/components/primer/dropdown.rb +149 -0
  24. data/app/components/primer/dropdown.ts +1 -0
  25. data/app/components/primer/dropdown/menu.d.ts +1 -0
  26. data/app/components/primer/dropdown/menu.html.erb +25 -0
  27. data/app/components/primer/dropdown/menu.js +1 -0
  28. data/app/components/primer/dropdown/menu.rb +99 -0
  29. data/app/components/primer/dropdown/menu.ts +1 -0
  30. data/app/components/primer/flash_component.rb +2 -2
  31. data/app/components/primer/flex_component.rb +27 -0
  32. data/app/components/primer/flex_item_component.rb +1 -1
  33. data/app/components/primer/heading_component.rb +11 -18
  34. data/app/components/primer/hidden_text_expander.rb +3 -3
  35. data/app/components/primer/icon_button.rb +20 -3
  36. data/app/components/primer/image.rb +46 -0
  37. data/app/components/primer/image_crop.d.ts +1 -0
  38. data/app/components/primer/image_crop.html.erb +12 -0
  39. data/app/components/primer/image_crop.js +1 -0
  40. data/app/components/primer/image_crop.rb +36 -0
  41. data/app/components/primer/image_crop.ts +1 -0
  42. data/app/components/primer/label_component.rb +6 -2
  43. data/app/components/primer/local_time.d.ts +1 -0
  44. data/app/components/primer/local_time.js +1 -0
  45. data/app/components/primer/local_time.rb +59 -0
  46. data/app/components/primer/local_time.ts +1 -0
  47. data/app/components/primer/{markdown_component.rb → markdown.rb} +11 -6
  48. data/app/components/primer/navigation/tab_component.rb +10 -3
  49. data/app/components/primer/octicon_component.html.erb +7 -0
  50. data/app/components/primer/octicon_component.rb +25 -15
  51. data/app/components/primer/octicon_symbols_component.html.erb +3 -0
  52. data/app/components/primer/octicon_symbols_component.rb +61 -0
  53. data/app/components/primer/primer.d.ts +3 -0
  54. data/app/components/primer/primer.js +3 -0
  55. data/app/components/primer/primer.ts +3 -0
  56. data/app/components/primer/spinner_component.rb +4 -2
  57. data/app/components/primer/subhead_component.rb +34 -4
  58. data/app/components/primer/tab_nav_component.html.erb +5 -1
  59. data/app/components/primer/tab_nav_component.rb +62 -9
  60. data/app/components/primer/{tooltip_component.rb → tooltip.rb} +10 -8
  61. data/app/components/primer/truncate.rb +6 -2
  62. data/app/components/primer/underline_nav_component.html.erb +1 -1
  63. data/app/components/primer/underline_nav_component.rb +17 -1
  64. data/app/lib/primer/classify.rb +21 -8
  65. data/app/lib/primer/classify/cache.rb +16 -1
  66. data/app/lib/primer/classify/grid.rb +45 -0
  67. data/app/lib/primer/octicon/cache.rb +4 -0
  68. data/app/lib/primer/tabbed_component_helper.rb +2 -2
  69. data/app/lib/primer/view_helper.rb +2 -1
  70. data/lib/primer/view_components.rb +1 -1
  71. data/lib/primer/view_components/engine.rb +2 -0
  72. data/lib/primer/view_components/linters.rb +3 -0
  73. data/lib/primer/view_components/linters/argument_mappers/button.rb +82 -0
  74. data/lib/primer/view_components/linters/argument_mappers/conversion_error.rb +10 -0
  75. data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +46 -0
  76. data/lib/primer/view_components/linters/button_component_migration_counter.rb +35 -0
  77. data/lib/primer/view_components/linters/flash_component_migration_counter.rb +16 -0
  78. data/lib/primer/view_components/linters/helpers.rb +93 -0
  79. data/lib/primer/view_components/version.rb +1 -1
  80. data/lib/tasks/coverage.rake +14 -0
  81. data/lib/tasks/docs.rake +387 -0
  82. data/lib/tasks/statuses.rake +12 -0
  83. data/lib/yard/docs_helper.rb +67 -0
  84. data/static/statuses.json +56 -1
  85. metadata +72 -13
  86. data/app/components/primer/button_marketing_component.rb +0 -68
  87. data/app/components/primer/dropdown/menu_component.html.erb +0 -12
  88. data/app/components/primer/dropdown/menu_component.rb +0 -46
  89. data/app/components/primer/dropdown_component.rb +0 -73
  90. data/app/components/primer/text_component.rb +0 -22
@@ -1,3 +1,4 @@
1
+ <%= label %>
1
2
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
3
  <%= input %>
3
4
  <%= icon %>
@@ -8,6 +8,8 @@ module Primer
8
8
  ALIGN_DEFAULT = :left
9
9
  ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
10
10
 
11
+ DEFAULT_TAG = :div
12
+ TAG_OPTIONS = [DEFAULT_TAG, :span].freeze
11
13
  # Required list of stacked avatars.
12
14
  #
13
15
  # @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::AvatarComponent) %>.
@@ -34,11 +36,12 @@ module Primer
34
36
  # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
35
37
  # <% end %>
36
38
  #
39
+ # @param tag [Symbol] <%= one_of(Primer::AvatarStackComponent::TAG_OPTIONS) %>
37
40
  # @param align [Symbol] <%= one_of(Primer::AvatarStackComponent::ALIGN_OPTIONS) %>
38
41
  # @param tooltipped [Boolean] Whether to add a tooltip to the stack or not.
39
- # @param body_arguments [Hash] Parameters to add to the Body. If `tooltipped` is set, has the same arguments as <%= link_to_component(Primer::TooltipComponent) %>.
42
+ # @param body_arguments [Hash] Parameters to add to the Body. If `tooltipped` is set, has the same arguments as <%= link_to_component(Primer::Tooltip) %>.
40
43
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
41
- def initialize(align: ALIGN_DEFAULT, tooltipped: false, body_arguments: {}, **system_arguments)
44
+ def initialize(tag: DEFAULT_TAG, align: ALIGN_DEFAULT, tooltipped: false, body_arguments: {}, **system_arguments)
42
45
  @align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
43
46
  @system_arguments = system_arguments
44
47
  @tooltipped = tooltipped
@@ -50,7 +53,7 @@ module Primer
50
53
  @body_arguments[:classes]
51
54
  )
52
55
 
53
- @system_arguments[:tag] ||= :div
56
+ @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
54
57
  @system_arguments[:classes] = class_names(
55
58
  "AvatarStack",
56
59
  system_arguments[:classes],
@@ -60,7 +63,7 @@ module Primer
60
63
 
61
64
  def body_component
62
65
  if @tooltipped
63
- Primer::TooltipComponent.new(**@body_arguments)
66
+ Primer::Tooltip.new(**@body_arguments)
64
67
  else
65
68
  Primer::BaseComponent.new(**@body_arguments)
66
69
  end
@@ -77,20 +77,22 @@ module Primer
77
77
  # | `flex_shrink` | Integer | To enable, set to `0`. |
78
78
  # | `flex_wrap` | Symbol | <%= one_of(Primer::Classify::Flex::WRAP_MAPPINGS.keys) %> |
79
79
  # | `justify_content` | Symbol | <%= one_of(Primer::Classify::Flex::JUSTIFY_CONTENT_VALUES) %> |
80
- # | `width` | Symbol | <%= one_of([:fit, :fill]) %> |
80
+ # | `width` | Symbol | <%= one_of([:fit]) %> |
81
81
  #
82
82
  # ## Grid
83
83
  #
84
84
  # | Name | Type | Description |
85
85
  # | :- | :- | :- |
86
- # | `col` | Integer | Number of columns. |
86
+ # | `clearfix` | Boolean | Wether to assign the `clearfix` class. |
87
+ # | `col` | Integer | Number of columns. <%= one_of(Primer::Classify::Grid::COL_VALUES) %> |
88
+ # | `container` | Symbol | Size of the container. <%= one_of(Primer::Classify::Grid::CONTAINER_VALUES) %> |
87
89
  #
88
90
  # ## Layout
89
91
  #
90
92
  # | Name | Type | Description |
91
93
  # | :- | :- | :- |
92
94
  # | `display` | Symbol | <%= one_of([:none, :block, :flex, :inline, :inline_block, :inline_flex, :table, :table_cell]) %> |
93
- # | `height` | Symbol | <%= one_of([:fit, :fill]) %> |
95
+ # | `height` | Symbol | <%= one_of([:fit]) %> |
94
96
  # | `hide` | Symbol | Hide the element at a specific breakpoint. <%= one_of([:sm, :md, :lg, :xl]) %> |
95
97
  # | `v` | Symbol | Visibility. <%= one_of([:hidden, :visible]) %> |
96
98
  # | `vertical_align` | Symbol | <%= one_of([:baseline, :top, :middle, :bottom, :text_top, :text_bottom]) %> |
@@ -129,9 +131,12 @@ module Primer
129
131
  #
130
132
  # | Name | Type | Description |
131
133
  # | :- | :- | :- |
132
- # | `font_size` | String, Integer | <%= one_of(["00", 0, 1, 2, 3, 4, 5, 6]) %> |
133
- # | `font_weight` | Symbol | Font weight. <%= one_of([:light, :normal, :bold]) %> |
134
+ # | `font_family` | Symbol | Font weight. <%= one_of([:mono]) %> |
135
+ # | `font_size` | String, Integer, Symbol | <%= one_of(["00", 0, 1, 2, 3, 4, 5, 6, :small, :normal]) %> |
136
+ # | `font_style` | Symbol | Font weight. <%= one_of([:italic]) %> |
137
+ # | `font_weight` | Symbol | Font weight. <%= one_of([:light, :normal, :bold, :emphasized]) %> |
134
138
  # | `text_align` | Symbol | Text alignment. <%= one_of([:left, :right, :center]) %> |
139
+ # | `text_transform` | Symbol | Text alignment. <%= one_of([:uppercase]) %> |
135
140
  # | `underline` | Boolean | Whether text should be underlined. |
136
141
  # | `word_break` | Symbol | Whether to break words on line breaks. Can only be `:break_all`. |
137
142
  #
@@ -143,10 +148,15 @@ module Primer
143
148
  # | test_selector | String | Adds `data-test-selector='given value'` in non-Production environments for testing purposes. |
144
149
  def initialize(tag:, classes: nil, **system_arguments)
145
150
  @tag = tag
146
- @result = Primer::Classify.call(**system_arguments.merge(classes: classes))
151
+ @system_arguments = system_arguments
147
152
 
153
+ raise ArgumentError, "`class` is an invalid argument. Use `classes` instead." if system_arguments.key?(:class) && !Rails.env.production?
154
+
155
+ @result = Primer::Classify.call(**@system_arguments.merge(classes: classes))
156
+
157
+ @system_arguments[:"data-view-component"] = true
148
158
  # Filter out Primer keys so they don't get assigned as HTML attributes
149
- @content_tag_args = add_test_selector(system_arguments).except(*Primer::Classify::VALID_KEYS)
159
+ @content_tag_args = add_test_selector(@system_arguments).except(*Primer::Classify::VALID_KEYS)
150
160
  end
151
161
 
152
162
  def call
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Beta
5
+ # `Text` is a wrapper component that will apply typography styles to the text inside.
6
+ class Text < Primer::Component
7
+ status :beta
8
+
9
+ DEFAULT_TAG = :span
10
+
11
+ # @example Default
12
+ # <%= render(Primer::Beta::Text.new(tag: :p, font_weight: :bold)) { "Bold Text" } %>
13
+ # <%= render(Primer::Beta::Text.new(tag: :p, color: :text_danger)) { "Danger Text" } %>
14
+ #
15
+ # @param tag [Symbol]
16
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
17
+ def initialize(tag: DEFAULT_TAG, **system_arguments)
18
+ @system_arguments = system_arguments
19
+ @system_arguments[:tag] = tag
20
+ end
21
+
22
+ def call
23
+ render(Primer::BaseComponent.new(**@system_arguments)) { content }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,4 @@
1
+ <%# erblint:counter ButtonComponentMigrationCounter 1 %>
1
2
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
3
  <% if spinner.present? %>
3
4
  <%= spinner %>
@@ -3,8 +3,8 @@
3
3
  module Primer
4
4
  # 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.
5
5
  # @accessibility
6
- # `BlankSlate` renders an `<h3>` element for the title by default. Update the heading level based on what is appropriate for your page hierarchy by setting `title_tag`.
7
- # [Learn more about best heading practices (WAI Headings)](https://www.w3.org/WAI/tutorials/page-structure/headings/)
6
+ # `Blankslate` renders an `<h3>` element for the title by default. Update the heading level based on what is appropriate for your page hierarchy by setting `title_tag`.
7
+ # <%= link_to_heading_practices %>
8
8
  class BlankslateComponent < Primer::Component
9
9
  status :beta
10
10
 
@@ -23,61 +23,79 @@ module Primer
23
23
  # description: "Description",
24
24
  # ) %>
25
25
  #
26
- # @example Icon|Add an `icon` to give additional context. Refer to the [Octicons](https://primer.style/octicons/) documentation to choose an icon.
27
- # <%= render Primer::BlankslateComponent.new(
28
- # icon: "octoface",
29
- # title: "Title",
30
- # description: "Description",
31
- # ) %>
26
+ # @example Icon
27
+ # @description
28
+ # Add an `icon` to give additional context. Refer to the [Octicons](https://primer.style/octicons/) documentation to choose an icon.
29
+ # @code
30
+ # <%= render Primer::BlankslateComponent.new(
31
+ # icon: :globe,
32
+ # title: "Title",
33
+ # description: "Description",
34
+ # ) %>
32
35
  #
33
- # @example Loading|Add a [SpinnerComponent](https://primer.style/view-components/components/spinner) to the blankslate in place of an icon.
34
- # <%= render Primer::BlankslateComponent.new(
35
- # title: "Title",
36
- # description: "Description",
37
- # ) do |component| %>
38
- # <% component.spinner(size: :large) %>
39
- # <% end %>
36
+ # @example Loading
37
+ # @description
38
+ # Add a [SpinnerComponent](https://primer.style/view-components/components/spinner) to the blankslate in place of an icon.
39
+ # @code
40
+ # <%= render Primer::BlankslateComponent.new(
41
+ # title: "Title",
42
+ # description: "Description",
43
+ # ) do |component| %>
44
+ # <% component.spinner(size: :large) %>
45
+ # <% end %>
40
46
  #
41
- # @example Custom content|Pass custom content as a block in place of `description`.
42
- # <%= render Primer::BlankslateComponent.new(
43
- # title: "Title",
44
- # ) do %>
45
- # <em>Your custom content here</em>
46
- # <% end %>
47
+ # @example Custom content
48
+ # @description
49
+ # Pass custom content as a block in place of `description`.
50
+ # @code
51
+ # <%= render Primer::BlankslateComponent.new(
52
+ # title: "Title",
53
+ # ) do %>
54
+ # <em>Your custom content here</em>
55
+ # <% end %>
47
56
  #
48
- # @example Action button|Provide a button to guide users to take action from the blankslate. The button appears below the description and custom content.
49
- # <%= render Primer::BlankslateComponent.new(
50
- # icon: "book",
51
- # title: "Welcome to the mona wiki!",
52
- # 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.",
57
+ # @example Action button
58
+ # @description
59
+ # Provide a button to guide users to take action from the blankslate. The button appears below the description and custom content.
60
+ # @code
61
+ # <%= render Primer::BlankslateComponent.new(
62
+ # icon: :book,
63
+ # title: "Welcome to the mona wiki!",
64
+ # 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.",
53
65
  #
54
- # button_text: "Create the first page",
55
- # button_url: "https://github.com/monalisa/mona/wiki/_new",
56
- # ) %>
66
+ # button_text: "Create the first page",
67
+ # button_url: "https://github.com/monalisa/mona/wiki/_new",
68
+ # ) %>
57
69
  #
58
- # @example Link|Add an additional link to help users learn more about a feature. The link will be shown at the very bottom:
59
- # <%= render Primer::BlankslateComponent.new(
60
- # icon: "book",
61
- # title: "Welcome to the mona wiki!",
62
- # 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.",
63
- # link_text: "Learn more about wikis",
64
- # link_url: "https://docs.github.com/en/github/building-a-strong-community/about-wikis",
65
- # ) %>
70
+ # @example Link
71
+ # @description
72
+ # Add an additional link to help users learn more about a feature. The link will be shown at the very bottom:
73
+ # @code
74
+ # <%= render Primer::BlankslateComponent.new(
75
+ # icon: :book,
76
+ # title: "Welcome to the mona wiki!",
77
+ # 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.",
78
+ # link_text: "Learn more about wikis",
79
+ # link_url: "https://docs.github.com/en/github/building-a-strong-community/about-wikis",
80
+ # ) %>
66
81
  #
67
- # @example Variations|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.
68
- # <%= render Primer::BlankslateComponent.new(
69
- # icon: "book",
70
- # title: "Welcome to the mona wiki!",
71
- # 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.",
72
- # narrow: true,
73
- # large: true,
74
- # spacious: true,
75
- # ) %>
82
+ # @example Variations
83
+ # @description
84
+ # 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.
85
+ # @code
86
+ # <%= render Primer::BlankslateComponent.new(
87
+ # icon: :book,
88
+ # title: "Welcome to the mona wiki!",
89
+ # 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.",
90
+ # narrow: true,
91
+ # large: true,
92
+ # spacious: true,
93
+ # ) %>
76
94
  #
77
95
  # @param title [String] Text that appears in a larger bold font.
78
96
  # @param title_tag [Symbol] HTML tag to use for title.
79
- # @param icon [String] Octicon icon to use at top of component.
80
- # @param icon_size [Symbol] <%= one_of(Primer::OcticonComponent::SIZE_MAPPINGS) %>
97
+ # @param icon [Symbol] Octicon icon to use at top of component.
98
+ # @param icon_size [Symbol] <%= one_of(Primer::OcticonComponent::SIZE_MAPPINGS, sort: false) %>
81
99
  # @param image_src [String] Image to display.
82
100
  # @param image_alt [String] Alt text for image.
83
101
  # @param description [String] Text that appears below the title. Typically a whole sentence.
@@ -89,6 +107,7 @@ module Primer
89
107
  # @param narrow [Boolean] Adds a maximum width.
90
108
  # @param large [Boolean] Increases the font size.
91
109
  # @param spacious [Boolean] Adds extra padding.
110
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
92
111
  def initialize(
93
112
  title: "",
94
113
  title_tag: :h3,
@@ -111,7 +130,7 @@ module Primer
111
130
  **system_arguments
112
131
  )
113
132
  @system_arguments = system_arguments
114
- @system_arguments[:tag] ||= :div
133
+ @system_arguments[:tag] = :div
115
134
  @system_arguments[:classes] = class_names(
116
135
  @system_arguments[:classes],
117
136
  "blankslate",
@@ -78,11 +78,12 @@ module Primer
78
78
  #
79
79
  # @param scheme [Symbol] <%= one_of(Primer::ButtonComponent::SCHEME_OPTIONS) %>
80
80
  # @param variant [Symbol] <%= one_of(Primer::ButtonComponent::VARIANT_OPTIONS) %>
81
- # @param tag [Symbol] <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
82
- # @param type [Symbol] <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
81
+ # @param tag [Symbol] (Primer::BaseButton::DEFAULT_TAG) <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
82
+ # @param type [Symbol] (Primer::BaseButton::DEFAULT_TYPE) <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
83
83
  # @param group_item [Boolean] Whether button is part of a ButtonGroup.
84
84
  # @param block [Boolean] Whether button is full-width with `display: block`.
85
85
  # @param caret [Boolean] Whether or not to render a caret.
86
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
86
87
  def initialize(
87
88
  scheme: DEFAULT_SCHEME,
88
89
  variant: DEFAULT_VARIANT,
@@ -22,7 +22,7 @@ module Primer
22
22
  # <% component.button(scheme: :primary) { "Primary" } %>
23
23
  # <% component.button(scheme: :danger) { "Danger" } %>
24
24
  # <% component.button(scheme: :outline) { "Outline" } %>
25
- # <% component.button(classes: "my-class") { "Custom class" } %>
25
+ # <% component.button(classes: "custom-class") { "Custom class" } %>
26
26
  # <% end %>
27
27
  #
28
28
  # @example Variants
@@ -46,7 +46,7 @@ module Primer
46
46
  def initialize(variant: Primer::ButtonComponent::DEFAULT_VARIANT, **system_arguments)
47
47
  @variant = variant
48
48
  @system_arguments = system_arguments
49
- @system_arguments[:tag] ||= :div
49
+ @system_arguments[:tag] = :div
50
50
 
51
51
  @system_arguments[:classes] = class_names(
52
52
  "BtnGroup",
@@ -1,4 +1,5 @@
1
1
  import '@github/clipboard-copy-element';
2
+ const CLIPBOARD_COPY_TIMER_DURATION = 2000;
2
3
  function toggleSVG(svg) {
3
4
  if (svg.style.display === '' || svg.style.display === 'block') {
4
5
  svg.style.display = 'none';
@@ -15,9 +16,19 @@ function toggleCopyButton(button) {
15
16
  toggleSVG(clippyIcon);
16
17
  toggleSVG(checkIcon);
17
18
  }
19
+ const clipboardCopyElementTimers = new WeakMap();
18
20
  document.addEventListener('clipboard-copy', function ({ target }) {
19
21
  if (!(target instanceof HTMLElement))
20
22
  return;
21
- toggleCopyButton(target);
22
- setTimeout(toggleCopyButton, 2000, target);
23
+ if (!target.hasAttribute('data-view-component'))
24
+ return;
25
+ const currentTimeout = clipboardCopyElementTimers.get(target);
26
+ if (currentTimeout) {
27
+ clearTimeout(currentTimeout);
28
+ clipboardCopyElementTimers.delete(target);
29
+ }
30
+ else {
31
+ toggleCopyButton(target);
32
+ }
33
+ clipboardCopyElementTimers.set(target, setTimeout(toggleCopyButton, CLIPBOARD_COPY_TIMER_DURATION, target));
23
34
  });
@@ -1,5 +1,7 @@
1
1
  import '@github/clipboard-copy-element'
2
2
 
3
+ const CLIPBOARD_COPY_TIMER_DURATION = 2000
4
+
3
5
  function toggleSVG(svg: SVGElement) {
4
6
  if (svg.style.display === '' || svg.style.display === 'block') {
5
7
  svg.style.display = 'none'
@@ -18,9 +20,20 @@ function toggleCopyButton(button: HTMLElement) {
18
20
  toggleSVG(checkIcon)
19
21
  }
20
22
 
23
+ const clipboardCopyElementTimers = new WeakMap<HTMLElement, number>()
24
+
21
25
  document.addEventListener('clipboard-copy', function ({target}) {
22
26
  if (!(target instanceof HTMLElement)) return
23
- toggleCopyButton(target)
27
+ if (!target.hasAttribute('data-view-component')) return
28
+
29
+ const currentTimeout = clipboardCopyElementTimers.get(target)
30
+
31
+ if (currentTimeout) {
32
+ clearTimeout(currentTimeout)
33
+ clipboardCopyElementTimers.delete(target)
34
+ } else {
35
+ toggleCopyButton(target)
36
+ }
24
37
 
25
- setTimeout(toggleCopyButton, 2000, target)
38
+ clipboardCopyElementTimers.set(target, setTimeout(toggleCopyButton, CLIPBOARD_COPY_TIMER_DURATION, target))
26
39
  })
@@ -5,7 +5,7 @@ require "view_component/version"
5
5
  module Primer
6
6
  # @private
7
7
  class Component < ViewComponent::Base
8
- include ViewComponent::SlotableV2 unless ViewComponent::VERSION::STRING.to_f >= 2.28
8
+ include ViewComponent::SlotableV2 unless ViewComponent::Base < ViewComponent::SlotableV2
9
9
  include ClassNameHelper
10
10
  include FetchOrFallbackHelper
11
11
  include TestSelectorHelper
@@ -25,6 +25,11 @@ module Primer
25
25
  ActiveSupport::Deprecation.warn(message)
26
26
  end
27
27
 
28
+ def validate_aria_label
29
+ aria_label = @system_arguments[:"aria-label"] || @system_arguments.dig(:aria, :label)
30
+ raise ArgumentError, "`aria-label` is required." if aria_label.nil? && !Rails.env.production?
31
+ end
32
+
28
33
  def silence_deprecations?
29
34
  Rails.application.config.primer_view_components.silence_deprecations
30
35
  end
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use `CounterComponent` to add a count to navigational elements and buttons.
4
+ # Use `Counter` to add a count to navigational elements and buttons.
5
+ #
6
+ # @accessibility
7
+ # Always use `Counter` with adjacent text that provides supplementary information regarding what the count is for. For instance, `Counter`
8
+ # should be accompanied with text such as `issues` or `pull requests`.
9
+ #
5
10
  class CounterComponent < Primer::Component
6
11
  status :beta
7
12
 
@@ -14,7 +14,7 @@ module Primer
14
14
 
15
15
  # Use the Summary slot as a trigger to reveal the content.
16
16
  #
17
- # @param button [Boolean] Whether to render the Summary as a button or not.
17
+ # @param button [Boolean] (true) Whether to render the Summary as a button or not.
18
18
  # @param kwargs [Hash] The same arguments as <%= link_to_system_arguments_docs %>.
19
19
  renders_one :summary, lambda { |button: true, **system_arguments|
20
20
  system_arguments[:tag] = :summary
@@ -33,6 +33,17 @@ module Primer
33
33
  Primer::BaseComponent.new(**system_arguments)
34
34
  }
35
35
 
36
+ # @example Default
37
+ #
38
+ # <%= render Primer::DetailsComponent.new do |c| %>
39
+ # component.summary do
40
+ # "Summary"
41
+ # end
42
+ # component.body do
43
+ # "Body"
44
+ # end
45
+ # <% end %>
46
+ #
36
47
  # @param overlay [Symbol] Dictates the type of overlay to render with. <%= one_of(Primer::DetailsComponent::OVERLAY_MAPPINGS.keys) %>
37
48
  # @param reset [Boolean] Defatuls to false. If set to true, it will remove the default caret and remove style from the summary element
38
49
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>