primer_view_components 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (209) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +79 -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 +3 -5
  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/action_menu.rb +1 -1
  19. data/app/components/primer/alpha/auto_complete.css +1 -1
  20. data/app/components/primer/alpha/auto_complete.css.map +1 -1
  21. data/app/components/primer/alpha/auto_complete.pcss +3 -3
  22. data/app/components/primer/alpha/banner.css +1 -1
  23. data/app/components/primer/alpha/banner.css.map +1 -1
  24. data/app/components/primer/alpha/banner.pcss +11 -11
  25. data/app/components/primer/alpha/button_marketing.css.map +1 -1
  26. data/app/components/primer/alpha/button_marketing.pcss +5 -12
  27. data/app/components/primer/alpha/button_marketing.rb +3 -0
  28. data/app/components/primer/alpha/dialog.css +1 -1
  29. data/app/components/primer/alpha/dialog.css.map +1 -1
  30. data/app/components/primer/alpha/dialog.pcss +36 -36
  31. data/app/components/primer/alpha/dropdown.css +1 -1
  32. data/app/components/primer/alpha/dropdown.css.map +1 -1
  33. data/app/components/primer/alpha/dropdown.pcss +12 -12
  34. data/app/components/primer/alpha/form_control.html.erb +1 -1
  35. data/app/components/primer/alpha/hellip_button.rb +3 -1
  36. data/app/components/primer/alpha/layout.css +1 -1
  37. data/app/components/primer/alpha/layout.css.map +1 -1
  38. data/app/components/primer/alpha/layout.pcss +4 -4
  39. data/app/components/primer/alpha/menu.css +1 -1
  40. data/app/components/primer/alpha/menu.css.map +1 -1
  41. data/app/components/primer/alpha/menu.pcss +21 -21
  42. data/app/components/primer/alpha/modal_dialog.js +17 -4
  43. data/app/components/primer/alpha/modal_dialog.ts +17 -4
  44. data/app/components/primer/alpha/nav_list/item.rb +2 -0
  45. data/app/components/primer/alpha/nav_list.js +6 -0
  46. data/app/components/primer/alpha/nav_list.rb +55 -36
  47. data/app/components/primer/alpha/nav_list.ts +8 -0
  48. data/app/components/primer/alpha/octicon_symbols.html.erb +1 -1
  49. data/app/components/primer/alpha/overlay/header.html.erb +5 -3
  50. data/app/components/primer/alpha/overlay/header.rb +4 -1
  51. data/app/components/primer/alpha/overlay.css +1 -1
  52. data/app/components/primer/alpha/overlay.css.json +1 -2
  53. data/app/components/primer/alpha/overlay.css.map +1 -1
  54. data/app/components/primer/alpha/overlay.pcss +14 -4
  55. data/app/components/primer/alpha/overlay.rb +1 -0
  56. data/app/components/primer/alpha/segmented_control.css +1 -1
  57. data/app/components/primer/alpha/segmented_control.css.map +1 -1
  58. data/app/components/primer/alpha/segmented_control.pcss +24 -33
  59. data/app/components/primer/alpha/tab_nav.css +1 -1
  60. data/app/components/primer/alpha/tab_nav.css.map +1 -1
  61. data/app/components/primer/alpha/tab_nav.pcss +12 -12
  62. data/app/components/primer/alpha/text_field.css +1 -3
  63. data/app/components/primer/alpha/text_field.css.json +1 -0
  64. data/app/components/primer/alpha/text_field.css.map +1 -1
  65. data/app/components/primer/alpha/text_field.pcss +87 -83
  66. data/app/components/primer/alpha/toggle_switch.css +1 -1
  67. data/app/components/primer/alpha/toggle_switch.css.json +11 -11
  68. data/app/components/primer/alpha/toggle_switch.css.map +1 -1
  69. data/app/components/primer/alpha/toggle_switch.d.ts +1 -1
  70. data/app/components/primer/alpha/toggle_switch.html.erb +2 -2
  71. data/app/components/primer/alpha/toggle_switch.js +44 -42
  72. data/app/components/primer/alpha/toggle_switch.pcss +16 -16
  73. data/app/components/primer/alpha/toggle_switch.rb +7 -0
  74. data/app/components/primer/alpha/toggle_switch.ts +50 -41
  75. data/app/components/primer/alpha/underline_nav.css +1 -1
  76. data/app/components/primer/alpha/underline_nav.css.map +1 -1
  77. data/app/components/primer/alpha/underline_nav.pcss +11 -11
  78. data/app/components/primer/beta/auto_complete.rb +1 -1
  79. data/app/components/primer/beta/avatar.css +1 -1
  80. data/app/components/primer/beta/avatar.css.map +1 -1
  81. data/app/components/primer/beta/avatar.pcss +18 -18
  82. data/app/components/primer/beta/avatar_stack.css +1 -1
  83. data/app/components/primer/beta/avatar_stack.css.map +1 -1
  84. data/app/components/primer/beta/avatar_stack.pcss +5 -5
  85. data/app/components/primer/beta/base_button.rb +11 -0
  86. data/app/components/primer/beta/blankslate.css +1 -1
  87. data/app/components/primer/beta/blankslate.css.map +1 -1
  88. data/app/components/primer/beta/blankslate.pcss +16 -16
  89. data/app/components/primer/beta/border_box.css +1 -1
  90. data/app/components/primer/beta/border_box.css.json +1 -1
  91. data/app/components/primer/beta/border_box.css.map +1 -1
  92. data/app/components/primer/beta/border_box.pcss +40 -42
  93. data/app/components/primer/beta/button.css +1 -1
  94. data/app/components/primer/beta/button.css.json +4 -0
  95. data/app/components/primer/beta/button.css.map +1 -1
  96. data/app/components/primer/beta/button.pcss +39 -24
  97. data/app/components/primer/beta/button.rb +3 -0
  98. data/app/components/primer/beta/button_group.css +1 -0
  99. data/app/components/primer/beta/button_group.css.json +14 -0
  100. data/app/components/primer/beta/button_group.css.map +1 -0
  101. data/app/components/primer/beta/button_group.pcss +27 -0
  102. data/app/components/primer/beta/button_group.rb +19 -19
  103. data/app/components/primer/beta/close_button.rb +3 -1
  104. data/app/components/primer/beta/counter.css +1 -1
  105. data/app/components/primer/beta/counter.css.map +1 -1
  106. data/app/components/primer/beta/counter.pcss +5 -5
  107. data/app/components/primer/beta/details.html.erb +6 -2
  108. data/app/components/primer/beta/details.rb +18 -10
  109. data/app/components/primer/beta/flash.css +1 -1
  110. data/app/components/primer/beta/flash.css.map +1 -1
  111. data/app/components/primer/beta/flash.pcss +12 -12
  112. data/app/components/primer/beta/icon_button.rb +7 -3
  113. data/app/components/primer/beta/label.css +1 -1
  114. data/app/components/primer/beta/label.css.map +1 -1
  115. data/app/components/primer/beta/label.pcss +3 -3
  116. data/app/components/primer/beta/popover.css +1 -1
  117. data/app/components/primer/beta/popover.css.map +1 -1
  118. data/app/components/primer/beta/popover.pcss +4 -4
  119. data/app/components/primer/beta/state.css +1 -1
  120. data/app/components/primer/beta/state.css.map +1 -1
  121. data/app/components/primer/beta/state.pcss +7 -7
  122. data/app/components/primer/beta/subhead.css +1 -1
  123. data/app/components/primer/beta/subhead.css.map +1 -1
  124. data/app/components/primer/beta/subhead.pcss +9 -9
  125. data/app/components/primer/beta/timeline_item.css +1 -1
  126. data/app/components/primer/beta/timeline_item.css.map +1 -1
  127. data/app/components/primer/beta/timeline_item.pcss +18 -18
  128. data/app/components/primer/beta/truncate.css +1 -1
  129. data/app/components/primer/beta/truncate.css.map +1 -1
  130. data/app/components/primer/beta/truncate.pcss +1 -1
  131. data/app/components/primer/focus_group.js +8 -13
  132. data/app/components/primer/focus_group.ts +8 -12
  133. data/app/components/primer/primer.d.ts +1 -0
  134. data/app/components/primer/primer.js +1 -0
  135. data/app/components/primer/primer.pcss +1 -0
  136. data/app/components/primer/primer.ts +1 -0
  137. data/lib/postcss_mixins/activeIndicatorLine.pcss +4 -4
  138. data/lib/primer/accessibility.rb +74 -0
  139. data/lib/primer/forms/dsl/input.rb +4 -8
  140. data/lib/primer/forms/dsl/text_field_input.rb +0 -4
  141. data/lib/primer/forms/dsl/toggle_switch_input.rb +4 -0
  142. data/lib/primer/forms/form_control.html.erb +3 -5
  143. data/lib/primer/forms/primer_base_component_wrapper.html.erb +3 -0
  144. data/lib/primer/forms/primer_base_component_wrapper.rb +24 -0
  145. data/lib/primer/forms/toggle_switch.html.erb +3 -3
  146. data/lib/primer/forms/toggle_switch.rb +6 -2
  147. data/lib/primer/forms/toggle_switch_input.js +7 -2
  148. data/lib/primer/forms/toggle_switch_input.ts +9 -2
  149. data/lib/primer/static/generate_info_arch.rb +3 -0
  150. data/lib/primer/static/generate_previews.rb +15 -8
  151. data/lib/primer/view_components/linters/deprecated_components_counter.rb +37 -13
  152. data/lib/primer/view_components/version.rb +2 -2
  153. data/lib/primer/yard/component_manifest.rb +1 -1
  154. data/lib/primer/yard/lookbook_pages_backend.rb +8 -2
  155. data/lib/primer/yard/registry.rb +4 -0
  156. data/previews/pages/forms/03_caption_templates.md.erb +1 -1
  157. data/previews/pages/forms/04_after_content.md.erb +1 -1
  158. data/previews/pages/forms/06_miscellaneous_inputs.md.erb +1 -1
  159. data/previews/pages/forms/07_toggle_switch_forms.md.erb +1 -1
  160. data/previews/primer/alpha/action_menu_preview/two_menus.html.erb +13 -0
  161. data/previews/primer/alpha/action_menu_preview/with_actions.html.erb +21 -0
  162. data/previews/primer/alpha/action_menu_preview.rb +5 -13
  163. data/previews/primer/alpha/button_marketing_preview.rb +3 -2
  164. data/previews/primer/alpha/dialog_preview.rb +4 -3
  165. data/previews/primer/alpha/hellip_button_preview.rb +3 -2
  166. data/previews/primer/alpha/nav_list_preview.rb +1 -1
  167. data/previews/primer/alpha/overlay_preview/middle_of_page_with_relative_container.html.erb +19 -0
  168. data/previews/primer/alpha/overlay_preview.rb +31 -0
  169. data/previews/primer/beta/base_button_preview.rb +9 -2
  170. data/previews/primer/beta/button_group_preview/action_menus.html.erb +8 -0
  171. data/previews/primer/beta/button_group_preview.rb +49 -11
  172. data/previews/primer/beta/button_preview/trailing_counter.html.erb +1 -1
  173. data/previews/primer/beta/button_preview.rb +5 -2
  174. data/previews/primer/beta/close_button_preview.rb +3 -2
  175. data/previews/primer/beta/details_preview.rb +11 -8
  176. data/previews/primer/forms_preview.rb +44 -0
  177. data/static/arguments.json +11 -5
  178. data/static/classes.json +378 -372
  179. data/static/constants.json +0 -1
  180. data/static/info_arch.json +5457 -1364
  181. data/static/previews.json +5197 -1428
  182. metadata +40 -36
  183. data/lib/tasks/docs.rake +0 -185
  184. data/lib/tasks/helpers/ast_processor.rb +0 -44
  185. data/lib/tasks/helpers/ast_traverser.rb +0 -77
  186. data/lib/tasks/primer_view_components.rake +0 -47
  187. data/lib/tasks/static.rake +0 -29
  188. data/lib/tasks/test.rake +0 -83
  189. data/lib/tasks/utilities.rake +0 -109
  190. data/previews/primer/forms/forms_preview.rb +0 -48
  191. /data/previews/primer/{forms/forms_preview → forms_preview}/after_content_form.html.erb +0 -0
  192. /data/previews/primer/{forms/forms_preview → forms_preview}/array_check_box_group_form.html.erb +0 -0
  193. /data/previews/primer/{forms/forms_preview → forms_preview}/caption_template_form.html.erb +0 -0
  194. /data/previews/primer/{forms/forms_preview → forms_preview}/check_box_group_form.html.erb +0 -0
  195. /data/previews/primer/{forms/forms_preview → forms_preview}/check_box_with_nested_form.html.erb +0 -0
  196. /data/previews/primer/{forms/forms_preview → forms_preview}/composed_form.html.erb +0 -0
  197. /data/previews/primer/{forms/forms_preview → forms_preview}/example_toggle_switch_form.html.erb +0 -0
  198. /data/previews/primer/{forms/forms_preview → forms_preview}/horizontal_form.html.erb +0 -0
  199. /data/previews/primer/{forms/forms_preview → forms_preview}/immediate_validation_form.html.erb +0 -0
  200. /data/previews/primer/{forms/forms_preview → forms_preview}/invalid_form.html.erb +0 -0
  201. /data/previews/primer/{forms/forms_preview → forms_preview}/multi_input_form.html.erb +0 -0
  202. /data/previews/primer/{forms/forms_preview → forms_preview}/multi_text_field_form.html.erb +0 -0
  203. /data/previews/primer/{forms/forms_preview → forms_preview}/name_with_question_mark_form.html.erb +0 -0
  204. /data/previews/primer/{forms/forms_preview → forms_preview}/radio_button_group_form.html.erb +0 -0
  205. /data/previews/primer/{forms/forms_preview → forms_preview}/radio_button_with_nested_form.html.erb +0 -0
  206. /data/previews/primer/{forms/forms_preview → forms_preview}/select_form.html.erb +0 -0
  207. /data/previews/primer/{forms/forms_preview → forms_preview}/single_text_field_form.html.erb +0 -0
  208. /data/previews/primer/{forms/forms_preview → forms_preview}/submit_button_form.html.erb +0 -0
  209. /data/previews/primer/{forms/forms_preview → forms_preview}/text_field_and_checkbox_form.html.erb +0 -0
@@ -9,11 +9,9 @@
9
9
  <% end %>
10
10
  <% end %>
11
11
  <%= content %>
12
- <% if @input.need_validation_element? %>
13
- <%= content_tag(:div, **@input.validation_arguments) do %>
14
- <%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %>
15
- <%= content_tag(:span, @input.validation_messages.first, **@input.validation_message_arguments) %>
16
- <% end %>
12
+ <%= content_tag(:div, **@input.validation_arguments) do %>
13
+ <span class="FormControl-inlineValidation--visual"><%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %></span>
14
+ <%= content_tag(:span, @input.invalid? ? @input.validation_messages.first : "", **@input.validation_message_arguments) %>
17
15
  <% end %>
18
16
  <%= render(Caption.new(input: @input)) %>
19
17
  <% end %>
@@ -0,0 +1,3 @@
1
+ <%= render(Primer::BaseComponent.new(classes: @classes, **@system_arguments)) do %>
2
+ <%= content %>
3
+ <% end %>
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "primer/class_name_helper"
4
+
5
+ module Primer
6
+ module Forms
7
+ # Wraps Primer::BaseComponent.
8
+ class PrimerBaseComponentWrapper < BaseComponent
9
+ include Primer::ClassNameHelper
10
+
11
+ def initialize(**system_arguments)
12
+ @system_arguments = system_arguments
13
+
14
+ # Extract class and classes so they can be passed to Primer::BaseComponent
15
+ # as classes:. The class: argument is expected by Rails, but Primer expects
16
+ # classes:, reminiscent of HashWithIndifferentAccess shenanigans.
17
+ @classes = class_names(
18
+ system_arguments.delete(:classes),
19
+ system_arguments.delete(:class)
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,6 +1,6 @@
1
- <%= content_tag("toggle-switch-input", **@input.input_arguments) do %>
1
+ <%= content_tag("toggle-switch-input", class: "FormControl-toggleSwitchInput", hidden: @input.hidden?) do %>
2
2
  <span style="flex-grow: 1">
3
- <%= builder.label(@input.name, **@input.label_arguments) do %>
3
+ <%= render(Primer::Forms::PrimerBaseComponentWrapper.new(tag: :span, **@input.label_arguments)) do %>
4
4
  <%= @input.label %>
5
5
  <% end %>
6
6
 
@@ -18,5 +18,5 @@
18
18
  }
19
19
  )
20
20
  %>
21
- <%= render(Primer::Alpha::ToggleSwitch.new(src: @input.src, csrf: csrf)) %>
21
+ <%= render(Primer::Alpha::ToggleSwitch.new(src: @input.src, csrf: csrf, **@input.input_arguments)) %>
22
22
  <% end %>
@@ -9,8 +9,12 @@ module Primer
9
9
  def initialize(input:)
10
10
  @input = input
11
11
  @input.add_label_classes("FormControl-label")
12
- @input.add_input_classes("FormControl-toggleSwitchInput")
13
- @input.input_arguments[:hidden] = "hidden" if @input.hidden?
12
+ @input.label_arguments[:id] = label_id
13
+ @input.add_input_aria(:labelledby, label_id)
14
+ end
15
+
16
+ def label_id
17
+ @label_id ||= "label-#{@input.base_id}"
14
18
  end
15
19
  end
16
20
  end
@@ -1,3 +1,4 @@
1
+ /* eslint-disable custom-elements/expose-class-on-global */
1
2
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
3
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
4
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -8,11 +9,15 @@ import { controller, target } from '@github/catalyst';
8
9
  let ToggleSwitchInputElement = class ToggleSwitchInputElement extends HTMLElement {
9
10
  connectedCallback() {
10
11
  this.addEventListener('toggleSwitchError', (event) => {
11
- this.validationMessageElement.innerText = event.detail;
12
+ this.validationMessageElement.textContent = event.detail;
12
13
  this.validationElement.removeAttribute('hidden');
13
14
  });
14
15
  this.addEventListener('toggleSwitchSuccess', () => {
15
- this.validationMessageElement.innerText = '';
16
+ this.validationMessageElement.textContent = '';
17
+ this.validationElement.setAttribute('hidden', 'hidden');
18
+ });
19
+ this.addEventListener('toggleSwitchLoading', () => {
20
+ this.validationMessageElement.textContent = '';
16
21
  this.validationElement.setAttribute('hidden', 'hidden');
17
22
  });
18
23
  }
@@ -1,3 +1,5 @@
1
+ /* eslint-disable custom-elements/expose-class-on-global */
2
+
1
3
  import {controller, target} from '@github/catalyst'
2
4
 
3
5
  @controller
@@ -7,12 +9,17 @@ export class ToggleSwitchInputElement extends HTMLElement {
7
9
 
8
10
  connectedCallback() {
9
11
  this.addEventListener('toggleSwitchError', (event: Event) => {
10
- this.validationMessageElement.innerText = (event as CustomEvent).detail
12
+ this.validationMessageElement.textContent = (event as CustomEvent).detail
11
13
  this.validationElement.removeAttribute('hidden')
12
14
  })
13
15
 
14
16
  this.addEventListener('toggleSwitchSuccess', () => {
15
- this.validationMessageElement.innerText = ''
17
+ this.validationMessageElement.textContent = ''
18
+ this.validationElement.setAttribute('hidden', 'hidden')
19
+ })
20
+
21
+ this.addEventListener('toggleSwitchLoading', () => {
22
+ this.validationMessageElement.textContent = ''
16
23
  this.validationElement.setAttribute('hidden', 'hidden')
17
24
  })
18
25
  }
@@ -72,6 +72,9 @@ module Primer
72
72
  memo[component] = {
73
73
  "fully_qualified_name" => component.name,
74
74
  "description" => description,
75
+ "is_form_component" => docs.manifest_entry.form_component?,
76
+ "is_published" => docs.manifest_entry.published?,
77
+ "requires_js" => docs.manifest_entry.requires_js?,
75
78
  **arg_data,
76
79
  "slots" => slot_docs,
77
80
  "methods" => method_docs,
@@ -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 = 8
8
+ MINOR = 2
9
+ PATCH = 0
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
12
12
  end
@@ -129,7 +129,7 @@ module Primer
129
129
  end
130
130
 
131
131
  def ref_for(klass)
132
- ref_cache[klass] ||= ComponentRef.new(klass, COMPONENTS[klass])
132
+ ref_cache[klass] ||= ComponentRef.new(klass, COMPONENTS.fetch(klass, {}))
133
133
  end
134
134
 
135
135
  private
@@ -10,7 +10,7 @@ module Primer
10
10
  PREVIEW_MAP = {
11
11
  Primer::Alpha::TextField => [:single_text_field_form, :multi_text_field_form],
12
12
  Primer::Alpha::TextArea => [],
13
- Primer::Alpha::Select => [:select_list_form],
13
+ Primer::Alpha::Select => [:select_form],
14
14
  Primer::Alpha::MultiInput => [:multi_input_form],
15
15
  Primer::Alpha::RadioButton => [:radio_button_with_nested_form],
16
16
  Primer::Alpha::RadioButtonGroup => [:radio_button_group_form],
@@ -49,7 +49,13 @@ module Primer
49
49
 
50
50
  preview_methods = PREVIEW_MAP[component]
51
51
  preview_erbs = preview_methods.map do |preview_method|
52
- "<%= embed Primer::Forms::FormsPreview, #{preview_method.inspect} %>"
52
+ # rubocop:disable Style/IfUnlessModifier
53
+ if Primer::FormsPreview.instance_methods.exclude?(preview_method)
54
+ raise "Preview '#{preview_method}' does not exist in Primer::FormsPreview"
55
+ end
56
+ # rubocop:enable Style/IfUnlessModifier
57
+
58
+ "<%= embed Primer::FormsPreview, #{preview_method.inspect} %>"
53
59
  end
54
60
  # rubocop:enable Lint/UselessAssignment
55
61
 
@@ -89,6 +89,10 @@ module Primer
89
89
  def a11y_reviewed?
90
90
  metadata[:a11y_reviewed]
91
91
  end
92
+
93
+ def manifest_entry
94
+ @manifest_entry ||= ComponentManifest.ref_for(component)
95
+ end
92
96
  end
93
97
 
94
98
  # Wrapper around an instance of YARD::Registry that provides easy access to component
@@ -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|
@@ -0,0 +1,19 @@
1
+ <div style="width:100%; height: 400px; display: flex; justify-content: center; align-items: center;">
2
+ <div style="position:relative;">
3
+ <%= render(Primer::Alpha::Overlay.new(
4
+ title: title,
5
+ subtitle: subtitle,
6
+ role: role,
7
+ size: size,
8
+ placement: placement,
9
+ anchor_align: anchor_align,
10
+ anchor_side: anchor_side,
11
+ allow_out_of_bounds: allow_out_of_bounds,
12
+ visually_hide_title: visually_hide_title,
13
+ )) do |d| %>
14
+ <% d.with_header(title: title, size: header_size) %>
15
+ <% d.with_show_button { button_text } %>
16
+ <% d.with_body { body_text } %>
17
+ <% end %>
18
+ </div>
19
+ </div>
@@ -132,6 +132,37 @@ module Primer
132
132
  body_text: body_text
133
133
  })
134
134
  end
135
+
136
+ # @label Middle Of Page with relative container
137
+ #
138
+ # @param title [String] text
139
+ # @param subtitle [String] text
140
+ # @param role [Symbol] select [dialog, menu]
141
+ # @param size [Symbol] select [auto, small, medium, medium_portrait, large, xlarge]
142
+ # @param anchor_align [Symbol] select [start, center, end]
143
+ # @param anchor_side [Symbol] select [inside_top, inside_bottom, inside_left, inside_right, inside_center, outside_top, outside_bottom, outside_left, outside_right]
144
+ # @param allow_out_of_bounds [Boolean] toggle
145
+ # @param visually_hide_title [Boolean] toggle
146
+ #
147
+ # @param header_size [Symbol] select [medium, large]
148
+ # @param button_text [String] text
149
+ # @param body_text [String] text
150
+ def middle_of_page_with_relative_container(title: "Test Overlay", subtitle: nil, role: :dialog, size: :auto, placement: :anchored, anchor_align: :center, anchor_side: :outside_bottom, allow_out_of_bounds: false, visually_hide_title: false, header_size: :medium, button_text: "Show Overlay", body_text: "")
151
+ render_with_template(locals: {
152
+ title: title,
153
+ subtitle: subtitle,
154
+ role: role,
155
+ size: size,
156
+ placement: placement,
157
+ anchor_align: anchor_align,
158
+ anchor_side: anchor_side,
159
+ allow_out_of_bounds: allow_out_of_bounds,
160
+ visually_hide_title: visually_hide_title,
161
+ header_size: header_size,
162
+ button_text: button_text,
163
+ body_text: body_text
164
+ })
165
+ end
135
166
  end
136
167
  end
137
168
  end
@@ -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,