primer_view_components 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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