primer_view_components 0.1.9 → 0.2.0

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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -0
  3. data/README.md +1 -1
  4. data/app/assets/javascripts/primer_view_components.js +1 -1
  5. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  6. data/app/assets/styles/primer_view_components.css +1 -3
  7. data/app/assets/styles/primer_view_components.css.map +1 -1
  8. data/app/components/primer/alpha/action_list/item.rb +2 -2
  9. data/app/components/primer/alpha/action_list.css +1 -1
  10. data/app/components/primer/alpha/action_list.css.json +16 -16
  11. data/app/components/primer/alpha/action_list.css.map +1 -1
  12. data/app/components/primer/alpha/action_list.pcss +145 -145
  13. data/app/components/primer/alpha/action_list.rb +30 -15
  14. data/app/components/primer/alpha/action_menu/action_menu_element.d.ts +2 -1
  15. data/app/components/primer/alpha/action_menu/action_menu_element.js +44 -34
  16. data/app/components/primer/alpha/action_menu/action_menu_element.ts +32 -30
  17. data/app/components/primer/alpha/action_menu/list.rb +6 -1
  18. data/app/components/primer/alpha/auto_complete.css +1 -1
  19. data/app/components/primer/alpha/auto_complete.css.map +1 -1
  20. data/app/components/primer/alpha/auto_complete.pcss +3 -3
  21. data/app/components/primer/alpha/banner.css +1 -1
  22. data/app/components/primer/alpha/banner.css.map +1 -1
  23. data/app/components/primer/alpha/banner.pcss +11 -11
  24. data/app/components/primer/alpha/button_marketing.css.map +1 -1
  25. data/app/components/primer/alpha/button_marketing.pcss +5 -12
  26. data/app/components/primer/alpha/button_marketing.rb +3 -0
  27. data/app/components/primer/alpha/dialog.css +1 -1
  28. data/app/components/primer/alpha/dialog.css.map +1 -1
  29. data/app/components/primer/alpha/dialog.pcss +36 -36
  30. data/app/components/primer/alpha/dropdown.css +1 -1
  31. data/app/components/primer/alpha/dropdown.css.map +1 -1
  32. data/app/components/primer/alpha/dropdown.pcss +12 -12
  33. data/app/components/primer/alpha/form_control.html.erb +1 -1
  34. data/app/components/primer/alpha/hellip_button.rb +3 -1
  35. data/app/components/primer/alpha/layout.css +1 -1
  36. data/app/components/primer/alpha/layout.css.map +1 -1
  37. data/app/components/primer/alpha/layout.pcss +4 -4
  38. data/app/components/primer/alpha/menu.css +1 -1
  39. data/app/components/primer/alpha/menu.css.map +1 -1
  40. data/app/components/primer/alpha/menu.pcss +21 -21
  41. data/app/components/primer/alpha/modal_dialog.js +11 -4
  42. data/app/components/primer/alpha/modal_dialog.ts +11 -4
  43. data/app/components/primer/alpha/nav_list/item.rb +2 -0
  44. data/app/components/primer/alpha/nav_list.js +6 -0
  45. data/app/components/primer/alpha/nav_list.rb +55 -36
  46. data/app/components/primer/alpha/nav_list.ts +8 -0
  47. data/app/components/primer/alpha/octicon_symbols.html.erb +1 -1
  48. data/app/components/primer/alpha/overlay.css +1 -1
  49. data/app/components/primer/alpha/overlay.css.json +1 -2
  50. data/app/components/primer/alpha/overlay.css.map +1 -1
  51. data/app/components/primer/alpha/overlay.pcss +14 -4
  52. data/app/components/primer/alpha/segmented_control.css +1 -1
  53. data/app/components/primer/alpha/segmented_control.css.map +1 -1
  54. data/app/components/primer/alpha/segmented_control.pcss +24 -33
  55. data/app/components/primer/alpha/tab_nav.css +1 -1
  56. data/app/components/primer/alpha/tab_nav.css.map +1 -1
  57. data/app/components/primer/alpha/tab_nav.pcss +12 -12
  58. data/app/components/primer/alpha/text_field.css +1 -3
  59. data/app/components/primer/alpha/text_field.css.json +1 -0
  60. data/app/components/primer/alpha/text_field.css.map +1 -1
  61. data/app/components/primer/alpha/text_field.pcss +87 -83
  62. data/app/components/primer/alpha/toggle_switch.css +1 -1
  63. data/app/components/primer/alpha/toggle_switch.css.map +1 -1
  64. data/app/components/primer/alpha/toggle_switch.pcss +12 -12
  65. data/app/components/primer/alpha/underline_nav.css +1 -1
  66. data/app/components/primer/alpha/underline_nav.css.map +1 -1
  67. data/app/components/primer/alpha/underline_nav.pcss +11 -11
  68. data/app/components/primer/beta/avatar.css +1 -1
  69. data/app/components/primer/beta/avatar.css.map +1 -1
  70. data/app/components/primer/beta/avatar.pcss +18 -18
  71. data/app/components/primer/beta/avatar_stack.css +1 -1
  72. data/app/components/primer/beta/avatar_stack.css.map +1 -1
  73. data/app/components/primer/beta/avatar_stack.pcss +5 -5
  74. data/app/components/primer/beta/base_button.rb +11 -0
  75. data/app/components/primer/beta/blankslate.css +1 -1
  76. data/app/components/primer/beta/blankslate.css.map +1 -1
  77. data/app/components/primer/beta/blankslate.pcss +16 -16
  78. data/app/components/primer/beta/border_box.css +1 -1
  79. data/app/components/primer/beta/border_box.css.json +1 -1
  80. data/app/components/primer/beta/border_box.css.map +1 -1
  81. data/app/components/primer/beta/border_box.pcss +40 -42
  82. data/app/components/primer/beta/button.css +1 -1
  83. data/app/components/primer/beta/button.css.json +4 -0
  84. data/app/components/primer/beta/button.css.map +1 -1
  85. data/app/components/primer/beta/button.pcss +39 -24
  86. data/app/components/primer/beta/button.rb +3 -0
  87. data/app/components/primer/beta/button_group.css +1 -0
  88. data/app/components/primer/beta/button_group.css.json +14 -0
  89. data/app/components/primer/beta/button_group.css.map +1 -0
  90. data/app/components/primer/beta/button_group.pcss +27 -0
  91. data/app/components/primer/beta/button_group.rb +19 -19
  92. data/app/components/primer/beta/close_button.rb +3 -1
  93. data/app/components/primer/beta/counter.css +1 -1
  94. data/app/components/primer/beta/counter.css.map +1 -1
  95. data/app/components/primer/beta/counter.pcss +5 -5
  96. data/app/components/primer/beta/details.html.erb +6 -2
  97. data/app/components/primer/beta/details.rb +18 -10
  98. data/app/components/primer/beta/flash.css +1 -1
  99. data/app/components/primer/beta/flash.css.map +1 -1
  100. data/app/components/primer/beta/flash.pcss +12 -12
  101. data/app/components/primer/beta/icon_button.rb +7 -3
  102. data/app/components/primer/beta/label.css +1 -1
  103. data/app/components/primer/beta/label.css.map +1 -1
  104. data/app/components/primer/beta/label.pcss +3 -3
  105. data/app/components/primer/beta/popover.css +1 -1
  106. data/app/components/primer/beta/popover.css.map +1 -1
  107. data/app/components/primer/beta/popover.pcss +4 -4
  108. data/app/components/primer/beta/state.css +1 -1
  109. data/app/components/primer/beta/state.css.map +1 -1
  110. data/app/components/primer/beta/state.pcss +7 -7
  111. data/app/components/primer/beta/subhead.css +1 -1
  112. data/app/components/primer/beta/subhead.css.map +1 -1
  113. data/app/components/primer/beta/subhead.pcss +9 -9
  114. data/app/components/primer/beta/timeline_item.css +1 -1
  115. data/app/components/primer/beta/timeline_item.css.map +1 -1
  116. data/app/components/primer/beta/timeline_item.pcss +18 -18
  117. data/app/components/primer/beta/truncate.css +1 -1
  118. data/app/components/primer/beta/truncate.css.map +1 -1
  119. data/app/components/primer/beta/truncate.pcss +1 -1
  120. data/app/components/primer/focus_group.js +1 -10
  121. data/app/components/primer/focus_group.ts +1 -10
  122. data/app/components/primer/primer.d.ts +1 -0
  123. data/app/components/primer/primer.js +1 -0
  124. data/app/components/primer/primer.pcss +1 -0
  125. data/app/components/primer/primer.ts +1 -0
  126. data/lib/postcss_mixins/activeIndicatorLine.pcss +4 -4
  127. data/lib/primer/accessibility.rb +74 -0
  128. data/lib/primer/forms/form_control.html.erb +1 -1
  129. data/lib/primer/static/generate_previews.rb +15 -8
  130. data/lib/primer/view_components/linters/deprecated_components_counter.rb +37 -13
  131. data/lib/primer/view_components/version.rb +2 -2
  132. data/lib/primer/yard/lookbook_pages_backend.rb +3 -3
  133. data/previews/pages/forms/03_caption_templates.md.erb +1 -1
  134. data/previews/pages/forms/04_after_content.md.erb +1 -1
  135. data/previews/pages/forms/06_miscellaneous_inputs.md.erb +1 -1
  136. data/previews/pages/forms/07_toggle_switch_forms.md.erb +1 -1
  137. data/previews/primer/alpha/action_menu_preview/two_menus.html.erb +13 -0
  138. data/previews/primer/alpha/action_menu_preview/with_actions.html.erb +21 -0
  139. data/previews/primer/alpha/action_menu_preview.rb +5 -13
  140. data/previews/primer/alpha/button_marketing_preview.rb +3 -2
  141. data/previews/primer/alpha/dialog_preview.rb +4 -3
  142. data/previews/primer/alpha/hellip_button_preview.rb +3 -2
  143. data/previews/primer/alpha/nav_list_preview.rb +1 -1
  144. data/previews/primer/beta/base_button_preview.rb +9 -2
  145. data/previews/primer/beta/button_group_preview/action_menus.html.erb +8 -0
  146. data/previews/primer/beta/button_group_preview.rb +49 -11
  147. data/previews/primer/beta/button_preview/trailing_counter.html.erb +1 -1
  148. data/previews/primer/beta/button_preview.rb +5 -2
  149. data/previews/primer/beta/close_button_preview.rb +3 -2
  150. data/previews/primer/beta/details_preview.rb +11 -8
  151. data/previews/primer/forms_preview.rb +44 -0
  152. data/static/arguments.json +4 -4
  153. data/static/classes.json +378 -372
  154. data/static/constants.json +0 -1
  155. data/static/info_arch.json +5150 -1368
  156. data/static/previews.json +5197 -1433
  157. metadata +37 -29
  158. data/previews/primer/forms/forms_preview.rb +0 -48
  159. /data/previews/primer/{forms/forms_preview → forms_preview}/after_content_form.html.erb +0 -0
  160. /data/previews/primer/{forms/forms_preview → forms_preview}/array_check_box_group_form.html.erb +0 -0
  161. /data/previews/primer/{forms/forms_preview → forms_preview}/caption_template_form.html.erb +0 -0
  162. /data/previews/primer/{forms/forms_preview → forms_preview}/check_box_group_form.html.erb +0 -0
  163. /data/previews/primer/{forms/forms_preview → forms_preview}/check_box_with_nested_form.html.erb +0 -0
  164. /data/previews/primer/{forms/forms_preview → forms_preview}/composed_form.html.erb +0 -0
  165. /data/previews/primer/{forms/forms_preview → forms_preview}/example_toggle_switch_form.html.erb +0 -0
  166. /data/previews/primer/{forms/forms_preview → forms_preview}/horizontal_form.html.erb +0 -0
  167. /data/previews/primer/{forms/forms_preview → forms_preview}/immediate_validation_form.html.erb +0 -0
  168. /data/previews/primer/{forms/forms_preview → forms_preview}/invalid_form.html.erb +0 -0
  169. /data/previews/primer/{forms/forms_preview → forms_preview}/multi_input_form.html.erb +0 -0
  170. /data/previews/primer/{forms/forms_preview → forms_preview}/multi_text_field_form.html.erb +0 -0
  171. /data/previews/primer/{forms/forms_preview → forms_preview}/name_with_question_mark_form.html.erb +0 -0
  172. /data/previews/primer/{forms/forms_preview → forms_preview}/radio_button_group_form.html.erb +0 -0
  173. /data/previews/primer/{forms/forms_preview → forms_preview}/radio_button_with_nested_form.html.erb +0 -0
  174. /data/previews/primer/{forms/forms_preview → forms_preview}/select_form.html.erb +0 -0
  175. /data/previews/primer/{forms/forms_preview → forms_preview}/single_text_field_form.html.erb +0 -0
  176. /data/previews/primer/{forms/forms_preview → forms_preview}/submit_button_form.html.erb +0 -0
  177. /data/previews/primer/{forms/forms_preview → forms_preview}/text_field_and_checkbox_form.html.erb +0 -0
@@ -13,7 +13,7 @@
13
13
  white-space: nowrap;
14
14
 
15
15
  & + .Truncate-text {
16
- margin-left: var(--control-small-gap, 4px);
16
+ margin-left: var(--control-small-gap);
17
17
  }
18
18
 
19
19
  &.Truncate-text--primary {
@@ -12,15 +12,6 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  var _FocusGroupElement_instances, _FocusGroupElement_abortController, _FocusGroupElement_items_get;
13
13
  import '@oddbird/popover-polyfill';
14
14
  const menuItemSelector = '[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]';
15
- const popoverSelector = (() => {
16
- try {
17
- document.querySelector(':popover-open');
18
- return ':popover-open';
19
- }
20
- catch (_a) {
21
- return '.\\:popover-open';
22
- }
23
- })();
24
15
  const getMnemonicFor = (item) => { var _a; return (_a = item.textContent) === null || _a === void 0 ? void 0 : _a.trim()[0].toLowerCase(); };
25
16
  const printable = /^\S$/;
26
17
  export default class FocusGroupElement extends HTMLElement {
@@ -128,7 +119,7 @@ export default class FocusGroupElement extends HTMLElement {
128
119
  {
129
120
  let el = focusEl;
130
121
  do {
131
- el = el.closest(`[popover]:not(${popoverSelector})`);
122
+ el = el.closest(`[popover]:not(:popover-open)`);
132
123
  if ((el === null || el === void 0 ? void 0 : el.popover) === 'auto') {
133
124
  el.showPopover();
134
125
  }
@@ -2,15 +2,6 @@ import '@oddbird/popover-polyfill'
2
2
 
3
3
  const menuItemSelector = '[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]'
4
4
 
5
- const popoverSelector = (() => {
6
- try {
7
- document.querySelector(':popover-open')
8
- return ':popover-open'
9
- } catch {
10
- return '.\\:popover-open'
11
- }
12
- })()
13
-
14
5
  const getMnemonicFor = (item: Element) => item.textContent?.trim()[0].toLowerCase()
15
6
 
16
7
  const printable = /^\S$/
@@ -118,7 +109,7 @@ export default class FocusGroupElement extends HTMLElement {
118
109
  {
119
110
  let el: HTMLElement | null = focusEl
120
111
  do {
121
- el = el.closest(`[popover]:not(${popoverSelector})`)
112
+ el = el.closest(`[popover]:not(:popover-open)`)
122
113
  if (el?.popover === 'auto') {
123
114
  el.showPopover()
124
115
  }
@@ -1,3 +1,4 @@
1
+ import '@github/include-fragment-element';
1
2
  import '@oddbird/popover-polyfill';
2
3
  import './alpha/dropdown';
3
4
  import './anchored_position';
@@ -1,3 +1,4 @@
1
+ import '@github/include-fragment-element';
1
2
  import '@oddbird/popover-polyfill';
2
3
  import './alpha/dropdown';
3
4
  import './anchored_position';
@@ -25,6 +25,7 @@
25
25
  @import "./alpha/overlay.pcss";
26
26
  @import "./beta/breadcrumbs.pcss";
27
27
  @import "./beta/button.pcss";
28
+ @import "./beta/button_group.pcss";
28
29
  @import "./beta/counter.pcss";
29
30
  @import "./beta/flash.pcss";
30
31
  @import "./beta/label.pcss";
@@ -1,3 +1,4 @@
1
+ import '@github/include-fragment-element'
1
2
  import '@oddbird/popover-polyfill'
2
3
  import './alpha/dropdown'
3
4
  import './anchored_position'
@@ -1,11 +1,11 @@
1
1
  /* active indicator line for navlist items */
2
- @define-mixin activeIndicatorLine $padding-left: calc(-1 * var(--base-size-8, 8px)) {
2
+ @define-mixin activeIndicatorLine $padding-left: calc(-1 * var(--base-size-8)) {
3
3
  position: absolute;
4
4
  top: calc(50% - 12px);
5
5
  left: $padding-left;
6
- width: var(--base-size-4, 4px);
7
- height: var(--base-size-24, 24px);
6
+ width: var(--base-size-4);
7
+ height: var(--base-size-24);
8
8
  content: '';
9
9
  background: var(--color-accent-fg);
10
- border-radius: var(--borderRadius-medium, 6px);
10
+ border-radius: var(--borderRadius-medium);
11
11
  }
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+ module Primer
5
+ # :nodoc:
6
+ module Accessibility
7
+ # Skip axe checks for components that should be tested as part of a larger component.
8
+ # Do not add to this list for any other reason!
9
+ IGNORED_PREVIEWS = [
10
+ Primer::Beta::MarkdownPreview,
11
+ Primer::Beta::AutoCompleteItemPreview
12
+ ].freeze
13
+
14
+ # Skip `:region` which relates to preview page structure rather than individual component.
15
+ # Skip `:color-contrast` which requires primer design-level change.
16
+ AXE_RULES_TO_SKIP = {
17
+ # these will be skipped in CI but will still be tracked in Datadog
18
+ will_fix: {
19
+ global: %i[
20
+ color-contrast
21
+ ],
22
+
23
+ per_component: {}
24
+ },
25
+
26
+ # these will always be skipped
27
+ wont_fix: {
28
+ global: %i[
29
+ region
30
+ ],
31
+
32
+ per_component: {
33
+ Primer::Alpha::ToggleSwitch => {
34
+ all_scenarios: %i[button-name]
35
+ }
36
+ }
37
+ }
38
+ }.freeze
39
+
40
+ class << self
41
+ def ignore_preview?(preview_class)
42
+ preview_class.name.start_with?("Docs::") || IGNORED_PREVIEWS.include?(preview_class)
43
+ end
44
+
45
+ def axe_rules_to_skip(component: nil, scenario_name: nil, flatten: false)
46
+ to_skip = {
47
+ wont_fix: Set.new(AXE_RULES_TO_SKIP.dig(:wont_fix, :global) || []),
48
+ will_fix: Set.new(AXE_RULES_TO_SKIP.dig(:will_fix, :global) || [])
49
+ }
50
+
51
+ if component
52
+ to_skip[:wont_fix].merge(AXE_RULES_TO_SKIP.dig(:wont_fix, :per_component, component, :all_scenarios) || [])
53
+ to_skip[:will_fix].merge(AXE_RULES_TO_SKIP.dig(:will_fix, :per_component, component, :all_scenarios) || [])
54
+
55
+ if scenario_name
56
+ to_skip[:wont_fix].merge(AXE_RULES_TO_SKIP.dig(:wont_fix, :per_component, component, scenario_name) || [])
57
+ to_skip[:will_fix].merge(AXE_RULES_TO_SKIP.dig(:will_fix, :per_component, component, scenario_name) || [])
58
+ end
59
+ end
60
+
61
+ if flatten
62
+ flattened = to_skip.each_with_object(Set.new) do |(_, rule_set), memo|
63
+ memo.merge(rule_set)
64
+ end
65
+
66
+ return flattened.to_a
67
+ end
68
+
69
+ to_skip.transform_values(&:to_a)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ # :nocov:
@@ -10,7 +10,7 @@
10
10
  <% end %>
11
11
  <%= content %>
12
12
  <%= content_tag(:div, **@input.validation_arguments) do %>
13
- <%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %>
13
+ <span class="FormControl-inlineValidation--visual"><%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %></span>
14
14
  <%= content_tag(:span, @input.invalid? ? @input.validation_messages.first : "", **@input.validation_message_arguments) %>
15
15
  <% end %>
16
16
  <%= render(Caption.new(input: @input)) %>
@@ -11,8 +11,8 @@ module Primer
11
11
  class << self
12
12
  def call
13
13
  Lookbook.previews.filter_map do |preview|
14
- next if preview.preview_class.name.start_with?("Docs::")
15
- next if preview.preview_class == Primer::Forms::FormsPreview
14
+ next if preview.preview_class == Primer::FormsPreview
15
+ next if Primer::Accessibility.ignore_preview?(preview.preview_class)
16
16
 
17
17
  component = preview.components.first&.component_class
18
18
 
@@ -29,12 +29,19 @@ module Primer
29
29
  component: class_name,
30
30
  status: component.status.to_s,
31
31
  lookup_path: preview.lookup_path,
32
- examples: preview.examples.map do |example|
33
- {
34
- inspect_path: example.url_path,
35
- preview_path: example.url_path.sub("/inspect/", "/preview/"),
36
- name: example.name
37
- }
32
+ examples: preview.scenarios.flat_map do |parent_scenario|
33
+ scenarios = parent_scenario.type == :scenario_group ? parent_scenario.scenarios : [parent_scenario]
34
+
35
+ scenarios.map do |scenario|
36
+ {
37
+ preview_path: scenario.lookup_path,
38
+ name: scenario.name,
39
+ skip_rules: Primer::Accessibility.axe_rules_to_skip(
40
+ component: component,
41
+ scenario_name: scenario.name
42
+ )
43
+ }
44
+ end
38
45
  end
39
46
  }
40
47
  end
@@ -3,13 +3,10 @@
3
3
  require_relative "helpers/deprecated_components_helpers"
4
4
  require_relative "severity_schema"
5
5
 
6
- require "erblint-github/linters/custom_helpers"
7
-
8
6
  module ERBLint
9
7
  module Linters
10
8
  # Lints against deprecated components
11
- class DeprecatedComponentsCounter < Linter
12
- include CustomHelpers
9
+ class DeprecatedComponentsCounter < BaseLinter
13
10
  include ERBLint::LinterRegistry
14
11
  include Helpers::DeprecatedComponentsHelpers
15
12
 
@@ -25,7 +22,7 @@ module ERBLint
25
22
  deprecated_components.each do |component|
26
23
  next unless code.include?(component)
27
24
 
28
- add_offense(erb_node.loc, message(component))
25
+ add_offense_with_severity(erb_node.loc, message(component))
29
26
  end
30
27
  end
31
28
 
@@ -46,14 +43,41 @@ module ERBLint
46
43
  end
47
44
  end
48
45
 
49
- # this override is necessary because of the github/erblint-github `CustomHelpers`
50
- # module. `counter_correct?` is provided by this module, and calls `add_offense`
51
- # directly. there is no simple way to modify this without updating the gem and
52
- # creating what would likely be an API that is non-standard and/or difficult to use
53
- #
54
- # https://github.com/github/erblint-github/blob/main/lib/erblint-github/linters/custom_helpers.rb
55
- def add_offense(source_range, message, context = nil, severity = nil)
56
- super(source_range, message, context, severity || @config.severity)
46
+ def counter_correct?(processed_source)
47
+ comment_node = nil
48
+ expected_count = 0
49
+ rule_name = self.class.name.gsub("ERBLint::Linters::", "")
50
+ offenses_count = @offenses.length
51
+
52
+ processed_source.parser.ast.descendants(:erb).each do |node|
53
+ indicator_node, _, code_node, = *node
54
+ indicator = indicator_node&.loc&.source
55
+ comment = code_node&.loc&.source&.strip
56
+
57
+ if indicator == "#" && comment.start_with?("erblint:counter") && comment.match(rule_name)
58
+ comment_node = node
59
+ expected_count = comment.match(/\s(\d+)\s?$/)[1].to_i
60
+ end
61
+ end
62
+
63
+ if offenses_count.zero?
64
+ # have to adjust to get `\n` so we delete the whole line
65
+ add_offense_with_severity(processed_source.to_source_range(comment_node.loc.adjust(end_pos: 1)), "Unused erblint:counter comment for #{rule_name}", "") if comment_node
66
+ return
67
+ end
68
+
69
+ first_offense = @offenses[0]
70
+
71
+ if comment_node.nil?
72
+ add_offense_with_severity(processed_source.to_source_range(first_offense.source_range), "#{rule_name}: If you must, add <%# erblint:counter #{rule_name} #{offenses_count} %> to bypass this check.", "<%# erblint:counter #{rule_name} #{offenses_count} %>")
73
+ else
74
+ clear_offenses
75
+ add_offense_with_severity(processed_source.to_source_range(comment_node.loc), "Incorrect erblint:counter number for #{rule_name}. Expected: #{expected_count}, actual: #{offenses_count}.", "<%# erblint:counter #{rule_name} #{offenses_count} %>") if expected_count != offenses_count
76
+ end
77
+ end
78
+
79
+ def add_offense_with_severity(source_range, message, context = nil, severity = nil)
80
+ add_offense(source_range, message, context, severity || @config.severity)
57
81
  end
58
82
  end
59
83
  end
@@ -5,8 +5,8 @@ module Primer
5
5
  module ViewComponents
6
6
  module VERSION
7
7
  MAJOR = 0
8
- MINOR = 1
9
- PATCH = 9
8
+ MINOR = 2
9
+ PATCH = 0
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
12
12
  end
@@ -50,12 +50,12 @@ module Primer
50
50
  preview_methods = PREVIEW_MAP[component]
51
51
  preview_erbs = preview_methods.map do |preview_method|
52
52
  # rubocop:disable Style/IfUnlessModifier
53
- if Primer::Forms::FormsPreview.instance_methods.exclude?(preview_method)
54
- raise "Preview '#{preview_method}' does not exist in Primer::Forms::FormsPreview"
53
+ if Primer::FormsPreview.instance_methods.exclude?(preview_method)
54
+ raise "Preview '#{preview_method}' does not exist in Primer::FormsPreview"
55
55
  end
56
56
  # rubocop:enable Style/IfUnlessModifier
57
57
 
58
- "<%= embed Primer::Forms::FormsPreview, #{preview_method.inspect} %>"
58
+ "<%= embed Primer::FormsPreview, #{preview_method.inspect} %>"
59
59
  end
60
60
  # rubocop:enable Lint/UselessAssignment
61
61
 
@@ -27,4 +27,4 @@ In cases where the `caption:` argument _and_ a caption template are provided, th
27
27
 
28
28
  ## Example
29
29
 
30
- <%= embed Primer::Forms::FormsPreview, :caption_template_form %>
30
+ <%= embed Primer::FormsPreview, :caption_template_form %>
@@ -36,4 +36,4 @@ For such cases, Primer forms feature "after" content. Like [caption templates](<
36
36
 
37
37
  ## Example
38
38
 
39
- <%= embed Primer::Forms::FormsPreview, :after_content_form %>
39
+ <%= embed Primer::FormsPreview, :after_content_form %>
@@ -40,4 +40,4 @@ Occasionally it can be appealing to visually distinguish parts of a form from ea
40
40
 
41
41
  ### Example
42
42
 
43
- <%= embed Primer::Forms::FormsPreview, :multi_text_field_form %>
43
+ <%= embed Primer::FormsPreview, :multi_text_field_form %>
@@ -55,4 +55,4 @@ The server can indicate that an error occurred by responding with a non-2xx stat
55
55
 
56
56
  ## Example
57
57
 
58
- <%= embed Primer::Forms::FormsPreview, :example_toggle_switch_form %>
58
+ <%= embed Primer::FormsPreview, :example_toggle_switch_form %>
@@ -0,0 +1,13 @@
1
+ <%= render(Primer::Alpha::ActionMenu.new(menu_id: "menu-1")) do |menu| %>
2
+ <% menu.with_show_button { |button| button.with_trailing_action_icon(icon: :"triangle-down"); "Pac-Man" } %>
3
+ <% menu.with_item(label: "Eat a dot") %>
4
+ <% menu.with_item(label: "Avoid a ghost") %>
5
+ <% menu.with_item(label: "Eat a stunned ghost") %>
6
+ <% end %>
7
+
8
+ <%= render(Primer::Alpha::ActionMenu.new(menu_id: "menu-2")) do |menu| %>
9
+ <% menu.with_show_button { |button| button.with_trailing_action_icon(icon: :"triangle-down"); "Mario Bros" } %>
10
+ <% menu.with_item(label: "Stomp a turtle") %>
11
+ <% menu.with_item(label: "Collect a gold coin") %>
12
+ <% menu.with_item(label: "Save the princess") %>
13
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <script type="text/javascript">
2
+ window.addEventListener('load', function() {
3
+ document.querySelector('button#alert-item').addEventListener('click', (_e) => {
4
+ alert('Foo')
5
+ });
6
+ }, false);
7
+ </script>
8
+
9
+ <%= render(Primer::Alpha::ActionMenu.new) do |component| %>
10
+ <% component.with_show_button { "Trigger" } %>
11
+ <% component.with_item(label: "Alert", tag: :button, id: "alert-item") %>
12
+ <% component.with_item(label: "Navigate", tag: :a, content_arguments: { href: action_menu_landing_path }) %>
13
+ <% component.with_item(label: "Copy text", tag: :"clipboard-copy", content_arguments: { value: "Text to copy" }) %>
14
+ <% component.with_item(
15
+ label: "Submit form",
16
+ href: action_menu_form_action_path,
17
+ form_arguments: {
18
+ name: "foo", value: "bar", method: :post
19
+ }
20
+ ) %>
21
+ <% end %>
@@ -180,19 +180,6 @@ module Primer
180
180
  # @label With actions
181
181
  #
182
182
  def with_actions
183
- render(Primer::Alpha::ActionMenu.new) do |component|
184
- component.with_show_button { "Trigger" }
185
- component.with_item(label: "Alert", tag: :button, content_arguments: { onclick: "alert('Foo')", onkeydown: "if (event.key === 'Enter') { alert(event.key) }" })
186
- component.with_item(label: "Navigate", tag: :a, content_arguments: { href: UrlHelpers.action_menu_landing_path })
187
- component.with_item(label: "Copy text", tag: :"clipboard-copy", content_arguments: { value: "Text to copy" })
188
- component.with_item(
189
- label: "Submit form",
190
- href: UrlHelpers.action_menu_form_action_path,
191
- form_arguments: {
192
- name: "foo", value: "bar", method: :post
193
- }
194
- )
195
- end
196
183
  end
197
184
 
198
185
  # @label Single select form
@@ -284,6 +271,11 @@ module Primer
284
271
  end
285
272
  end
286
273
  end
274
+
275
+ # @label Two menus
276
+ #
277
+ def two_menus
278
+ end
287
279
  end
288
280
  end
289
281
  end
@@ -9,8 +9,9 @@ module Primer
9
9
  # @param variant [Symbol] select [default, large]
10
10
  # @param tag [Symbol] select [button, a]
11
11
  # @param type [Symbol] select [button, submit]
12
- def playground(tag: :button, type: :button, scheme: :default, variant: :default)
13
- render(Primer::Alpha::ButtonMarketing.new(tag: tag, type: type, scheme: scheme, variant: variant)) { "Default" }
12
+ # @param disabled [Boolean]
13
+ def playground(tag: :button, type: :button, scheme: :default, variant: :default, disabled: false)
14
+ render(Primer::Alpha::ButtonMarketing.new(tag: tag, type: type, scheme: scheme, variant: variant, disabled: disabled)) { "Default" }
14
15
  end
15
16
 
16
17
  # @label Default options
@@ -12,15 +12,16 @@ module Primer
12
12
  # @param position [Symbol] select [center, left, right]
13
13
  # @param position_narrow [Symbol] select [inherit, bottom, fullscreen, left, right]
14
14
  # @param visually_hide_title [Boolean] toggle
15
+ # @param disable_button [Boolean] toggle
15
16
  # @param button_text [String] text
16
17
  # @param body_text [String] text
17
18
  # @param icon [Symbol] octicon
18
- def playground(title: "Test Dialog", subtitle: nil, size: :medium, button_text: "Show Dialog", body_text: "Content", position: :center, position_narrow: :fullscreen, visually_hide_title: false, icon: nil)
19
+ def playground(title: "Test Dialog", subtitle: nil, size: :medium, button_text: "Show Dialog", body_text: "Content", position: :center, position_narrow: :fullscreen, visually_hide_title: false, icon: nil, disable_button: false)
19
20
  render(Primer::Alpha::Dialog.new(title: title, subtitle: subtitle, size: size, position: position, position_narrow: position_narrow, visually_hide_title: visually_hide_title)) do |d|
20
21
  if icon.present? && (icon != :none)
21
- d.with_show_button(icon: icon, "aria-label": icon.to_s)
22
+ d.with_show_button(icon: icon, "aria-label": icon.to_s, disabled: disable_button)
22
23
  else
23
- d.with_show_button { button_text }
24
+ d.with_show_button(disabled: disable_button) { button_text }
24
25
  end
25
26
  d.with_body { body_text }
26
27
  end
@@ -16,8 +16,9 @@ module Primer
16
16
  #
17
17
  # @param aria_label [String]
18
18
  # @param inline [Boolean]
19
- def playground(inline: false, aria_label: "No effect")
20
- render(Primer::Alpha::HellipButton.new(inline: inline, "aria-label": aria_label))
19
+ # @param disabled [Boolean]
20
+ def playground(inline: false, aria_label: "No effect", disabled: false)
21
+ render(Primer::Alpha::HellipButton.new(inline: inline, "aria-label": aria_label, disabled: disabled))
21
22
  end
22
23
  end
23
24
  end
@@ -6,7 +6,7 @@ module Primer
6
6
  class NavListPreview < ViewComponent::Preview
7
7
  # @label Playground
8
8
  def playground
9
- render(Primer::Alpha::NavList.new(aria: { label: "Repository settings" }, selected_item_id: :code_review_limits)) do |list|
9
+ render(Primer::Alpha::NavList.new(aria: { label: "Repository settings" }, selected_item_id: :collaborators)) do |list|
10
10
  list.with_heading(title: "Repository settings")
11
11
 
12
12
  list.with_item(label: "General", href: "/general") do |item|
@@ -9,8 +9,9 @@ module Primer
9
9
  # @param type [Symbol] select [button, submit]
10
10
  # @param tag [Symbol] select [button, a, summary]
11
11
  # @param block [Boolean] toggle
12
- def playground(tag: :button, block: false, type: :button)
13
- render(Primer::Beta::BaseButton.new(tag: tag, block: block, type: type)) { "Button" }
12
+ # @param disabled [Boolean]
13
+ def playground(tag: :button, block: false, type: :button, disabled: false)
14
+ render(Primer::Beta::BaseButton.new(tag: tag, block: block, type: type, disabled: disabled)) { "Button" }
14
15
  end
15
16
 
16
17
  # @label Default options
@@ -21,6 +22,12 @@ module Primer
21
22
  def default(tag: :button, block: false, type: :button)
22
23
  render(Primer::Beta::BaseButton.new(tag: tag, block: block, type: type)) { "Button" }
23
24
  end
25
+
26
+ # @label Disabled
27
+ #
28
+ def disabled
29
+ render(Primer::Beta::BaseButton.new(disabled: true)) { "Button" }
30
+ end
24
31
  end
25
32
  end
26
33
  end
@@ -0,0 +1,8 @@
1
+ <%= render(Primer::Beta::ButtonGroup.new) do |component| %>
2
+ <% component.with_button() { "Main menu" } %>
3
+ <% component.with_button(icon: "triangle-down", "aria-label": "secondary menu", data: { "menu-id": "my-id" }) %>
4
+ <% end %>
5
+
6
+ <%= render(Primer::Alpha::ActionMenu.new(anchor_align: :end, menu_id: "my-id")) do |component| %>
7
+ <% component.with_item(label: "Item", tag: :button, value: "") %>
8
+ <% end %>
@@ -6,13 +6,13 @@ module Primer
6
6
  class ButtonGroupPreview < ViewComponent::Preview
7
7
  # @label Playground
8
8
  #
9
- # @param size [Symbol] select [medium, small]
10
- def playground(size: :medium)
11
- render(Primer::Beta::ButtonGroup.new(size: size)) do |component|
12
- component.with_button { "Button" }
13
- component.with_button(scheme: :primary) { "Primary" }
14
- component.with_button(scheme: :danger) { "Danger" }
15
- component.with_button(scheme: :outline) { "Outline" }
9
+ # @param size [Symbol] select [small, medium, large]
10
+ # @param scheme [Symbol] select [default, primary, secondary, danger, invisible]
11
+ def playground(size: :medium, scheme: :default)
12
+ render(Primer::Beta::ButtonGroup.new(size: size, scheme: scheme)) do |component|
13
+ component.with_button { "Button 1" }
14
+ component.with_button { "Button 2" }
15
+ component.with_button { "Button 3" }
16
16
  end
17
17
  end
18
18
 
@@ -21,10 +21,48 @@ module Primer
21
21
  # @param size [Symbol] select [medium, small]
22
22
  def default(size: :medium)
23
23
  render(Primer::Beta::ButtonGroup.new(size: size)) do |component|
24
- component.with_button { "Button" }
25
- component.with_button(scheme: :primary) { "Primary" }
26
- component.with_button(scheme: :danger) { "Danger" }
27
- component.with_button(scheme: :outline) { "Outline" }
24
+ component.with_button { "Button 1" }
25
+ component.with_button { "Button 2" }
26
+ component.with_button { "Button 3" }
27
+ end
28
+ end
29
+
30
+ # @label Split button
31
+ #
32
+ # @param size [Symbol] select [medium, small]
33
+ def split_button(size: :medium)
34
+ render(Primer::Beta::ButtonGroup.new(size: size)) do |component|
35
+ component.with_button { "Button 1" }
36
+ component.with_button(icon: "triangle-down", "aria-label": "menu")
37
+ end
38
+ end
39
+
40
+ # @label Icon buttons
41
+ #
42
+ # @param size [Symbol] select [medium, small]
43
+ def icon_buttons(size: :medium)
44
+ render(Primer::Beta::ButtonGroup.new(size: size)) do |component|
45
+ component.with_button(icon: :note, "aria-label": "button 1")
46
+ component.with_button(icon: :rows, "aria-label": "button 2")
47
+ component.with_button(icon: "sort-desc", "aria-label": "button 3")
48
+ end
49
+ end
50
+
51
+ # @label Button group with all tags
52
+ def all_tags
53
+ render(Primer::Beta::ButtonGroup.new) do |component|
54
+ component.with_button(id: "button-1", tag: :button) do |component|
55
+ component.with_tooltip(text: "Button Tooltip")
56
+ "Button 1"
57
+ end
58
+ component.with_button(id: "button-2", tag: :a) do |component|
59
+ component.with_tooltip(text: "Button Tooltip")
60
+ "Button 2"
61
+ end
62
+ component.with_button(id: "button-3", tag: :summary) do |component|
63
+ component.with_tooltip(text: "Button Tooltip")
64
+ "Button 3"
65
+ end
28
66
  end
29
67
  end
30
68
  end
@@ -1,5 +1,5 @@
1
1
  <%= render(Primer::Beta::Button.new(
2
- scheme: :primary,
2
+ scheme: scheme,
3
3
  size: :medium,
4
4
  block: block,
5
5
  id: id,
@@ -269,15 +269,18 @@ module Primer
269
269
  # @label Trailing Counter
270
270
  # @param block toggle
271
271
  # @param align_content select [center, start]
272
+ # @param scheme select [default, primary, danger, invisible]
272
273
  def trailing_counter(
273
274
  block: false,
274
275
  id: "button-preview",
275
- align_content: :center
276
+ align_content: :center,
277
+ scheme: :primary
276
278
  )
277
279
  render_with_template(locals: {
278
280
  block: block,
279
281
  id: id,
280
- align_content: align_content
282
+ align_content: align_content,
283
+ scheme: scheme
281
284
  })
282
285
  end
283
286
 
@@ -7,8 +7,9 @@ module Primer
7
7
  # @label Playground
8
8
  #
9
9
  # @param type [Symbol] select [button, submit]
10
- def playground(type: :button)
11
- render(Primer::Beta::CloseButton.new(type: type))
10
+ # @param disabled toggle
11
+ def playground(type: :button, disabled: false)
12
+ render(Primer::Beta::CloseButton.new(type: type, disabled: disabled))
12
13
  end
13
14
 
14
15
  # @label Default options