primer_view_components 0.43.2 → 0.43.3

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/app/assets/javascripts/components/primer/beta/details_toggle_element.d.ts +4 -3
  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 -1
  7. data/app/assets/styles/primer_view_components.css.map +1 -1
  8. data/app/components/primer/alpha/action_list.js +0 -2
  9. data/app/components/primer/alpha/action_list.ts +0 -2
  10. data/app/components/primer/alpha/toggle_switch.js +1 -0
  11. data/app/components/primer/alpha/toggle_switch.ts +1 -0
  12. data/app/components/primer/beta/breadcrumbs.css +1 -1
  13. data/app/components/primer/beta/breadcrumbs.css.map +1 -1
  14. data/app/components/primer/beta/breadcrumbs.pcss +1 -0
  15. data/app/components/primer/beta/details.rb +22 -12
  16. data/app/components/primer/beta/details_toggle_element.d.ts +4 -3
  17. data/app/components/primer/beta/details_toggle_element.js +12 -7
  18. data/app/components/primer/beta/details_toggle_element.ts +12 -7
  19. data/app/components/primer/beta/nav_list.js +0 -1
  20. data/app/components/primer/beta/nav_list.ts +0 -1
  21. data/app/components/primer/beta/nav_list_group_element.js +1 -0
  22. data/app/components/primer/beta/nav_list_group_element.ts +1 -0
  23. data/app/lib/primer/forms/acts_as_component.rb +0 -2
  24. data/config/routes.rb +27 -0
  25. data/lib/primer/accessibility.rb +3 -0
  26. data/lib/primer/view_components/linters/autocorrectable.rb +1 -1
  27. data/lib/primer/view_components/linters/migrations/iconbutton_component.rb +4 -7
  28. data/lib/primer/view_components/linters/migrations/truncate_component.rb +4 -7
  29. data/lib/primer/view_components/version.rb +1 -1
  30. data/lib/rubocop/cop/primer/base_cop.rb +1 -1
  31. data/lib/rubocop/cop/primer/component_name_migration.rb +7 -8
  32. data/lib/rubocop/cop/primer/deprecated_arguments.rb +7 -8
  33. data/lib/rubocop/cop/primer/deprecated_button_arguments.rb +5 -6
  34. data/lib/rubocop/cop/primer/deprecated_label_schemes.rb +6 -7
  35. data/lib/rubocop/cop/primer/deprecated_label_variants.rb +7 -14
  36. data/lib/rubocop/cop/primer/no_tag_memoize.rb +1 -1
  37. data/lib/rubocop/cop/primer/primer_octicon.rb +5 -6
  38. data/previews/primer/beta/breadcrumbs_preview/with_long_items.html.erb +13 -0
  39. data/previews/primer/beta/breadcrumbs_preview.rb +6 -0
  40. data/previews/primer/beta/details_preview.rb +16 -0
  41. data/static/arguments.json +67 -37
  42. data/static/audited_at.json +1 -0
  43. data/static/constants.json +13 -2
  44. data/static/info_arch.json +638 -1407
  45. data/static/previews.json +112 -0
  46. data/static/statuses.json +1 -0
  47. metadata +4 -2
@@ -17,7 +17,6 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
17
17
  };
18
18
  var _ActionListElement_truncationObserver;
19
19
  import { controller } from '@github/catalyst';
20
- // eslint-disable-next-line custom-elements/no-exports-with-element
21
20
  export class ActionListTruncationObserver {
22
21
  constructor(el) {
23
22
  this.resizeObserver = new ResizeObserver(entries => {
@@ -67,6 +66,5 @@ let ActionListElement = class ActionListElement extends HTMLElement {
67
66
  _ActionListElement_truncationObserver = new WeakMap();
68
67
  ActionListElement = __decorate([
69
68
  controller
70
- // eslint-disable-next-line custom-elements/expose-class-on-global
71
69
  ], ActionListElement);
72
70
  export { ActionListElement };
@@ -1,6 +1,5 @@
1
1
  import {controller} from '@github/catalyst'
2
2
 
3
- // eslint-disable-next-line custom-elements/no-exports-with-element
4
3
  export class ActionListTruncationObserver {
5
4
  resizeObserver = new ResizeObserver(entries => {
6
5
  for (const entry of entries) {
@@ -41,7 +40,6 @@ export class ActionListTruncationObserver {
41
40
  }
42
41
 
43
42
  @controller
44
- // eslint-disable-next-line custom-elements/expose-class-on-global
45
43
  export class ActionListElement extends HTMLElement {
46
44
  #truncationObserver: ActionListTruncationObserver
47
45
 
@@ -144,6 +144,7 @@ let ToggleSwitchElement = class ToggleSwitchElement extends HTMLElement {
144
144
  headers: requestHeaders,
145
145
  body,
146
146
  });
147
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
147
148
  }
148
149
  catch (error) {
149
150
  throw new Error('A network error occurred, please try again.');
@@ -175,6 +175,7 @@ class ToggleSwitchElement extends HTMLElement {
175
175
  headers: requestHeaders,
176
176
  body,
177
177
  })
178
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
178
179
  } catch (error) {
179
180
  throw new Error('A network error occurred, please try again.')
180
181
  }
@@ -1 +1 @@
1
- .breadcrumb-item{display:inline-block;list-style:none;margin-left:-.35em}.breadcrumb-item:after{border-right:.1em solid var(--borderColor-neutral-emphasis);content:"";display:inline-block;height:.8em;margin:0 .5em;transform:rotate(15deg) translateY(.0625em)}.breadcrumb-item:first-child{margin-left:0}:is(.breadcrumb-item-selected,.breadcrumb-item[aria-current]:not([aria-current=false])):after{content:none}.breadcrumb-item-selected a{color:var(--fgColor-default);cursor:default!important;-webkit-text-decoration:none!important;text-decoration:none!important}
1
+ .breadcrumb-item{display:inline-block;list-style:none;margin-left:-.35em;max-width:100%}.breadcrumb-item:after{border-right:.1em solid var(--borderColor-neutral-emphasis);content:"";display:inline-block;height:.8em;margin:0 .5em;transform:rotate(15deg) translateY(.0625em)}.breadcrumb-item:first-child{margin-left:0}:is(.breadcrumb-item-selected,.breadcrumb-item[aria-current]:not([aria-current=false])):after{content:none}.breadcrumb-item-selected a{color:var(--fgColor-default);cursor:default!important;-webkit-text-decoration:none!important;text-decoration:none!important}
@@ -1 +1 @@
1
- {"version":3,"sources":["breadcrumbs.pcss"],"names":[],"mappings":"AAAA,iBACE,oBAAqB,CAGrB,eAAgB,CADhB,kBAiBF,CAdE,uBAOE,2DAA6D,CAF7D,UAAW,CAJX,oBAAqB,CACrB,WAAa,CAEb,aAAe,CAIf,2CACF,CAEA,6BACE,aACF,CAKA,8FACE,YACF,CAIF,4BACE,4BAA6B,CAE7B,wBAA0B,CAD1B,sCAAgC,CAAhC,8BAEF","file":"breadcrumbs.css","sourcesContent":[".breadcrumb-item {\n display: inline-block;\n /* stylelint-disable-next-line primer/spacing */\n margin-left: -0.35em;\n list-style: none;\n\n &::after {\n display: inline-block;\n height: 0.8em;\n /* stylelint-disable-next-line primer/spacing */\n margin: 0 0.5em;\n content: '';\n /* stylelint-disable-next-line primer/borders */\n border-right: 0.1em solid var(--borderColor-neutral-emphasis);\n transform: rotate(15deg) translateY(0.0625em);\n }\n\n &:first-child {\n margin-left: 0;\n }\n}\n\n.breadcrumb-item-selected,\n.breadcrumb-item[aria-current]:not([aria-current='false']) {\n &::after {\n content: none;\n }\n}\n\n/* stylelint-disable-next-line selector-max-type */\n.breadcrumb-item-selected a {\n color: var(--fgColor-default);\n text-decoration: none !important;\n cursor: default !important;\n}\n"]}
1
+ {"version":3,"sources":["breadcrumbs.pcss"],"names":[],"mappings":"AAAA,iBACE,oBAAqB,CAGrB,eAAgB,CADhB,kBAAoB,CAEpB,cAgBF,CAdE,uBAOE,2DAA6D,CAF7D,UAAW,CAJX,oBAAqB,CACrB,WAAa,CAEb,aAAe,CAIf,2CACF,CAEA,6BACE,aACF,CAKA,8FACE,YACF,CAIF,4BACE,4BAA6B,CAE7B,wBAA0B,CAD1B,sCAAgC,CAAhC,8BAEF","file":"breadcrumbs.css","sourcesContent":[".breadcrumb-item {\n display: inline-block;\n /* stylelint-disable-next-line primer/spacing */\n margin-left: -0.35em;\n list-style: none;\n max-width: 100%;\n\n &::after {\n display: inline-block;\n height: 0.8em;\n /* stylelint-disable-next-line primer/spacing */\n margin: 0 0.5em;\n content: '';\n /* stylelint-disable-next-line primer/borders */\n border-right: 0.1em solid var(--borderColor-neutral-emphasis);\n transform: rotate(15deg) translateY(0.0625em);\n }\n\n &:first-child {\n margin-left: 0;\n }\n}\n\n.breadcrumb-item-selected,\n.breadcrumb-item[aria-current]:not([aria-current='false']) {\n &::after {\n content: none;\n }\n}\n\n/* stylelint-disable-next-line selector-max-type */\n.breadcrumb-item-selected a {\n color: var(--fgColor-default);\n text-decoration: none !important;\n cursor: default !important;\n}\n"]}
@@ -3,6 +3,7 @@
3
3
  /* stylelint-disable-next-line primer/spacing */
4
4
  margin-left: -0.35em;
5
5
  list-style: none;
6
+ max-width: 100%;
6
7
 
7
8
  &::after {
8
9
  display: inline-block;
@@ -32,26 +32,36 @@ module Primer
32
32
  system_arguments[:tag] = :summary
33
33
  system_arguments[:role] = "button"
34
34
 
35
- aria_label_closed = system_arguments[:aria_label_closed] || ARIA_LABEL_CLOSED_DEFAULT
36
- aria_label_open = system_arguments[:aria_label_open] || ARIA_LABEL_OPEN_DEFAULT
35
+ aria_label_closed = system_arguments[:aria_label_closed]
36
+ aria_label_open = system_arguments[:aria_label_open]
37
+
38
+ data_attributes = {
39
+ target: "details-toggle.summaryTarget",
40
+ action: "click:details-toggle#toggle",
41
+ }
42
+
43
+ # Only add aria-label data attributes if explicitly provided
44
+ if aria_label_closed || aria_label_open
45
+ data_attributes[:aria_label_closed] = aria_label_closed || ARIA_LABEL_CLOSED_DEFAULT
46
+ data_attributes[:aria_label_open] = aria_label_open || ARIA_LABEL_OPEN_DEFAULT
47
+ end
37
48
 
38
49
  system_arguments[:data] = merge_data(
39
50
  system_arguments, {
40
- data: {
41
- target: "details-toggle.summaryTarget",
42
- action: "click:details-toggle#toggle",
43
- aria_label_closed: aria_label_closed,
44
- aria_label_open: aria_label_open,
45
- }
51
+ data: data_attributes
46
52
  }
47
53
  )
48
54
 
55
+ aria_attributes = { expanded: open? }
56
+ # Only add aria-label if explicitly provided
57
+ if aria_label_closed || aria_label_open
58
+ current_label = open? ? (aria_label_open || ARIA_LABEL_OPEN_DEFAULT) : (aria_label_closed || ARIA_LABEL_CLOSED_DEFAULT)
59
+ aria_attributes[:label] = current_label
60
+ end
61
+
49
62
  system_arguments[:aria] = merge_aria(
50
63
  system_arguments, {
51
- aria: {
52
- label: open? ? aria_label_open : aria_label_closed,
53
- expanded: open?,
54
- }
64
+ aria: aria_attributes
55
65
  }
56
66
  )
57
67
 
@@ -3,9 +3,10 @@
3
3
  * ensures the <details> and <summary> elements markup is properly accessible by
4
4
  * updating the aria-label and aria-expanded attributes on click.
5
5
  *
6
- * aria-label values default to "Expand" and "Collapse". To override those
7
- * values, use the `data-aria-label-open` and `data-aria-label-closed`
8
- * attributes on the summary target.
6
+ * aria-label values are only set if provided via the `data-aria-label-open` and
7
+ * `data-aria-label-closed` attributes on the summary target. If these attributes
8
+ * are not present, no aria-label will be set, allowing screen readers to use
9
+ * the visible text content.
9
10
  *
10
11
  * @example
11
12
  * ```html
@@ -10,9 +10,10 @@ import { controller, target } from '@github/catalyst';
10
10
  * ensures the <details> and <summary> elements markup is properly accessible by
11
11
  * updating the aria-label and aria-expanded attributes on click.
12
12
  *
13
- * aria-label values default to "Expand" and "Collapse". To override those
14
- * values, use the `data-aria-label-open` and `data-aria-label-closed`
15
- * attributes on the summary target.
13
+ * aria-label values are only set if provided via the `data-aria-label-open` and
14
+ * `data-aria-label-closed` attributes on the summary target. If these attributes
15
+ * are not present, no aria-label will be set, allowing screen readers to use
16
+ * the visible text content.
16
17
  *
17
18
  * @example
18
19
  * ```html
@@ -37,13 +38,17 @@ let DetailsToggleElement = class DetailsToggleElement extends HTMLElement {
37
38
  toggle() {
38
39
  const detailsIsOpen = this.detailsTarget.hasAttribute('open');
39
40
  if (detailsIsOpen) {
40
- const ariaLabelClosed = this.summaryTarget.getAttribute('data-aria-label-closed') || 'Expand';
41
- this.summaryTarget.setAttribute('aria-label', ariaLabelClosed);
41
+ const ariaLabelClosed = this.summaryTarget.getAttribute('data-aria-label-closed');
42
+ if (ariaLabelClosed) {
43
+ this.summaryTarget.setAttribute('aria-label', ariaLabelClosed);
44
+ }
42
45
  this.summaryTarget.setAttribute('aria-expanded', 'false');
43
46
  }
44
47
  else {
45
- const ariaLabelOpen = this.summaryTarget.getAttribute('data-aria-label-open') || 'Collapse';
46
- this.summaryTarget.setAttribute('aria-label', ariaLabelOpen);
48
+ const ariaLabelOpen = this.summaryTarget.getAttribute('data-aria-label-open');
49
+ if (ariaLabelOpen) {
50
+ this.summaryTarget.setAttribute('aria-label', ariaLabelOpen);
51
+ }
47
52
  this.summaryTarget.setAttribute('aria-expanded', 'true');
48
53
  }
49
54
  }
@@ -5,9 +5,10 @@ import {controller, target} from '@github/catalyst'
5
5
  * ensures the <details> and <summary> elements markup is properly accessible by
6
6
  * updating the aria-label and aria-expanded attributes on click.
7
7
  *
8
- * aria-label values default to "Expand" and "Collapse". To override those
9
- * values, use the `data-aria-label-open` and `data-aria-label-closed`
10
- * attributes on the summary target.
8
+ * aria-label values are only set if provided via the `data-aria-label-open` and
9
+ * `data-aria-label-closed` attributes on the summary target. If these attributes
10
+ * are not present, no aria-label will be set, allowing screen readers to use
11
+ * the visible text content.
11
12
  *
12
13
  * @example
13
14
  * ```html
@@ -37,12 +38,16 @@ class DetailsToggleElement extends HTMLElement {
37
38
  toggle() {
38
39
  const detailsIsOpen = this.detailsTarget.hasAttribute('open')
39
40
  if (detailsIsOpen) {
40
- const ariaLabelClosed = this.summaryTarget.getAttribute('data-aria-label-closed') || 'Expand'
41
- this.summaryTarget.setAttribute('aria-label', ariaLabelClosed)
41
+ const ariaLabelClosed = this.summaryTarget.getAttribute('data-aria-label-closed')
42
+ if (ariaLabelClosed) {
43
+ this.summaryTarget.setAttribute('aria-label', ariaLabelClosed)
44
+ }
42
45
  this.summaryTarget.setAttribute('aria-expanded', 'false')
43
46
  } else {
44
- const ariaLabelOpen = this.summaryTarget.getAttribute('data-aria-label-open') || 'Collapse'
45
- this.summaryTarget.setAttribute('aria-label', ariaLabelOpen)
47
+ const ariaLabelOpen = this.summaryTarget.getAttribute('data-aria-label-open')
48
+ if (ariaLabelOpen) {
49
+ this.summaryTarget.setAttribute('aria-label', ariaLabelOpen)
50
+ }
46
51
  this.summaryTarget.setAttribute('aria-expanded', 'true')
47
52
  }
48
53
  }
@@ -16,7 +16,6 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
16
16
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
17
17
  };
18
18
  var _NavListElement_instances, _NavListElement_truncationObserver, _NavListElement_findSelectedNavItemById, _NavListElement_findSelectedNavItemByHref, _NavListElement_findSelectedNavItemByCurrentLocation, _NavListElement_select, _NavListElement_deselect, _NavListElement_findParentMenu;
19
- /* eslint-disable custom-elements/expose-class-on-global */
20
19
  import { controller, target, targets } from '@github/catalyst';
21
20
  import { ActionListTruncationObserver } from '../alpha/action_list';
22
21
  let NavListElement = class NavListElement extends HTMLElement {
@@ -1,4 +1,3 @@
1
- /* eslint-disable custom-elements/expose-class-on-global */
2
1
  import {controller, target, targets} from '@github/catalyst'
3
2
  import {ActionListTruncationObserver} from '../alpha/action_list'
4
3
 
@@ -62,6 +62,7 @@ let NavListGroupElement = class NavListGroupElement extends HTMLElement {
62
62
  if (this.currentPage === this.totalPages) {
63
63
  this.showMoreItem.hidden = true;
64
64
  }
65
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
65
66
  }
66
67
  catch (err) {
67
68
  // Ignore network errors
@@ -54,6 +54,7 @@ export class NavListGroupElement extends HTMLElement {
54
54
  if (this.currentPage === this.totalPages) {
55
55
  this.showMoreItem.hidden = true
56
56
  }
57
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
57
58
  } catch (err) {
58
59
  // Ignore network errors
59
60
  this.showMoreDisabled = false
@@ -71,8 +71,6 @@ module Primer
71
71
 
72
72
  if base_path
73
73
  @base_template_path = File.dirname(base_path)
74
- else
75
- warn "Could not identify the template for #{self}"
76
74
  end
77
75
  end
78
76
 
data/config/routes.rb ADDED
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ Primer::ViewComponents::Engine.routes.draw do
4
+ get "/auto_complete", to: "auto_complete_test#index", as: :autocomplete_index
5
+ get "/auto_complete_no_results", to: "auto_complete_test#no_results", as: :autocomplete_no_results
6
+
7
+ resources :toggle_switch, only: [:create]
8
+ resources :nav_list_items, only: [:index]
9
+ resources :multi, only: [:create]
10
+ resources :select_panel_items, only: [:index]
11
+ resources :tree_view_items, only: [:index]
12
+
13
+ # generic form submission path
14
+ post "/form_handler", to: "form_handler#form_action", as: :generic_form_submission
15
+
16
+ post "/example_check/accepted", to: "auto_check#accepted", as: :example_check_accepted
17
+ post "/example_check/ok", to: "auto_check#ok", as: :example_check_ok
18
+ post "/example_check/error", to: "auto_check#error", as: :example_check_error
19
+ post "/example_check/random", to: "auto_check#random", as: :example_check_random
20
+
21
+ get "/action_menu/landing_page", to: "action_menu#landing", as: :action_menu_landing
22
+ post "/action_menu/form_action", to: "action_menu#form_action", as: :action_menu_form_action
23
+ get "/action_menu/deferred", to: "action_menu#deferred", as: :action_menu_deferred
24
+ get "/action_menu/deferred_preload", to: "action_menu#deferred_preload", as: :action_menu_deferred_preload
25
+
26
+ get "/include_fragment/deferred", to: "include_fragment#deferred", as: :include_fragment_deferred
27
+ end
@@ -37,7 +37,10 @@ module Primer
37
37
  }
38
38
  }.freeze
39
39
 
40
+ # rubocop:disable Style/ClassMethodsDefinitions
40
41
  class << self
42
+ # rubocop:enable Style/ClassMethodsDefinitions
43
+
41
44
  def ignore_preview?(preview_class)
42
45
  IGNORED_PREVIEWS.include?(preview_class)
43
46
  end
@@ -25,7 +25,7 @@ module ERBLint
25
25
  def message(args, processed_source)
26
26
  return self.class::MESSAGE if args.nil?
27
27
 
28
- "#{self.class::MESSAGE}\nTry using:\n\n#{correction(args)}\n\nYou can also run erblint in autocorrect mode:\n\nbundle exec erblint -a #{processed_source.filename}\n"
28
+ "#{self.class::MESSAGE}\nTry using:\n\n#{correction(args)}\n\nYou can also run erb_lint in autocorrect mode:\n\nbundle exec erb_lint -a #{processed_source.filename}\n"
29
29
  end
30
30
  end
31
31
  end
@@ -4,7 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Migrations
6
6
  # Lint and autocorrect deprecated IconButton
7
- class IconButtonComponent < RuboCop::Cop::Cop
7
+ class IconButtonComponent < RuboCop::Cop::Base
8
+ extend AutoCorrector
8
9
  INVALID_MESSAGE = <<~STR
9
10
  `Primer::IconButton` is deprecated. Please use `Primer::Beta::IconButton` instead.
10
11
  STR
@@ -20,13 +21,9 @@ module RuboCop
20
21
  def on_send(node)
21
22
  return unless icon_button(node)
22
23
 
23
- add_offense(node, message: INVALID_MESSAGE)
24
- end
25
-
26
- def autocorrect(node)
27
- return if hash_with_box_value?(node.arguments.first)
24
+ add_offense(node, message: INVALID_MESSAGE) do |corrector|
25
+ next if hash_with_box_value?(node.arguments.first)
28
26
 
29
- lambda do |corrector|
30
27
  corrector.replace(icon_button(node), "Primer::Beta::IconButton")
31
28
  end
32
29
  end
@@ -4,7 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Migrations
6
6
  # Lint & autocorrect Truncate components
7
- class TruncateComponent < RuboCop::Cop::Cop
7
+ class TruncateComponent < RuboCop::Cop::Base
8
+ extend AutoCorrector
8
9
  INVALID_MESSAGE = <<~STR
9
10
  `Primer::Truncate` is deprecated. Please use `Primer::Beta::Truncate` instead!
10
11
  STR
@@ -24,13 +25,9 @@ module RuboCop
24
25
  def on_send(node)
25
26
  return unless truncate_component(node)
26
27
 
27
- add_offense(node, message: INVALID_MESSAGE)
28
- end
29
-
30
- def autocorrect(node)
31
- return if hash_with_inline_value?(node.arguments.first)
28
+ add_offense(node, message: INVALID_MESSAGE) do |corrector|
29
+ next if hash_with_inline_value?(node.arguments.first)
32
30
 
33
- lambda do |corrector|
34
31
  if node.arguments.first.nil? == false
35
32
  corrector.replace(node.children.first, "Primer::Beta::Truncate")
36
33
  corrector.insert_after(node.arguments.first, ", tag: :div") unless truncate_with_tag?(node.arguments.first)
@@ -6,7 +6,7 @@ module Primer
6
6
  module VERSION
7
7
  MAJOR = 0
8
8
  MINOR = 43
9
- PATCH = 2
9
+ PATCH = 3
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
12
12
  end
@@ -8,7 +8,7 @@ module RuboCop
8
8
  module Cop
9
9
  module Primer
10
10
  # :nodoc:
11
- class BaseCop < RuboCop::Cop::Cop
11
+ class BaseCop < RuboCop::Cop::Base
12
12
  # We only verify SystemArguments if it's a `.new` call on a component or
13
13
  # a ViewHeleper call.
14
14
  def valid_node?(node)
@@ -15,20 +15,19 @@ module RuboCop
15
15
  # good
16
16
  # Primer::Beta::ComponentName.new()
17
17
  class ComponentNameMigration < BaseCop
18
+ extend AutoCorrector
19
+
18
20
  def on_send(node)
19
21
  return unless node.method_name == :new && !node.receiver.nil? && ::Primer::Deprecations.deprecated?(node.receiver.const_name)
20
22
 
21
23
  message = ::Primer::Deprecations.deprecation_message(node.receiver.const_name)
22
- add_offense(node.receiver, message: message)
23
- end
24
-
25
- def autocorrect(node)
26
- lambda do |corrector|
27
- component_name = node.const_name
28
- return unless ::Primer::Deprecations.correctable?(component_name)
24
+
25
+ add_offense(node.receiver, message: message) do |corrector|
26
+ component_name = node.receiver.const_name
27
+ next unless ::Primer::Deprecations.correctable?(component_name)
29
28
 
30
29
  replacement = ::Primer::Deprecations.replacement(component_name)
31
- corrector.replace(node, replacement) if replacement.present?
30
+ corrector.replace(node.receiver, replacement) if replacement.present?
32
31
  end
33
32
  end
34
33
  end
@@ -14,6 +14,7 @@ module RuboCop
14
14
  # good
15
15
  # Component.new(foo: :bar)
16
16
  class DeprecatedArguments < BaseCop
17
+ extend AutoCorrector
17
18
  INVALID_MESSAGE = <<~STR
18
19
  Avoid using deprecated arguments: https://primer.style/view-components/deprecated.
19
20
  STR
@@ -283,17 +284,15 @@ module RuboCop
283
284
  key, value = extract_kv_from(pair)
284
285
  next unless DEPRECATED.key?(key) && DEPRECATED[key].key?(value)
285
286
 
286
- add_offense(pair, message: INVALID_MESSAGE)
287
+ add_offense(pair, message: INVALID_MESSAGE) do |corrector|
288
+ key, value = extract_kv_from(pair)
289
+ replacement = DEPRECATED[key][value]
290
+ corrector.replace(pair, replacement) if replacement.present?
291
+ end
287
292
  end
288
293
  end
289
294
 
290
- def autocorrect(node)
291
- lambda do |corrector|
292
- key, value = extract_kv_from(node)
293
- replacement = DEPRECATED[key][value]
294
- corrector.replace(node, replacement) if replacement.present?
295
- end
296
- end
295
+
297
296
 
298
297
  def extract_kv_from(pair)
299
298
  key = pair.key.value
@@ -14,6 +14,7 @@ module RuboCop
14
14
  # good
15
15
  # ButtonComponent.new(size: :small)
16
16
  class DeprecatedButtonArguments < BaseCop
17
+ extend AutoCorrector
17
18
  INVALID_MESSAGE = <<~STR
18
19
  `variant` is deprecated. Use `size` instead.
19
20
  STR
@@ -37,14 +38,12 @@ module RuboCop
37
38
 
38
39
  return if pair.nil?
39
40
 
40
- add_offense(pair.key, message: INVALID_MESSAGE)
41
- end
42
-
43
- def autocorrect(node)
44
- lambda do |corrector|
45
- corrector.replace(node, DEPRECATIONS[node.value])
41
+ add_offense(pair.key, message: INVALID_MESSAGE) do |corrector|
42
+ corrector.replace(pair.key, DEPRECATIONS[pair.key.value])
46
43
  end
47
44
  end
45
+
46
+
48
47
  end
49
48
  end
50
49
  end
@@ -14,6 +14,7 @@ module RuboCop
14
14
  # good
15
15
  # Primer::Beta::Label.new(scheme: :accent)
16
16
  class DeprecatedLabelSchemes < BaseCop
17
+ extend AutoCorrector
17
18
  INVALID_MESSAGE = <<~STR
18
19
  Avoid using deprecated schemes: https://primer.style/view-components/deprecated#labelcomponent.
19
20
  STR
@@ -44,16 +45,14 @@ module RuboCop
44
45
 
45
46
  next unless DEPRECATIONS.key?(value)
46
47
 
47
- add_offense(pair.value, message: INVALID_MESSAGE)
48
+ add_offense(pair.value, message: INVALID_MESSAGE) do |corrector|
49
+ replacement = DEPRECATIONS[pair.value.value.to_sym]
50
+ corrector.replace(pair.value, replacement)
51
+ end
48
52
  end
49
53
  end
50
54
 
51
- def autocorrect(node)
52
- lambda do |corrector|
53
- replacement = DEPRECATIONS[node.value.to_sym]
54
- corrector.replace(node, replacement)
55
- end
56
- end
55
+
57
56
 
58
57
  private
59
58
 
@@ -20,6 +20,7 @@ module RuboCop
20
20
  # good
21
21
  # Primer::Beta::Label.new(inline: true)
22
22
  class DeprecatedLabelVariants < BaseCop
23
+ extend AutoCorrector
23
24
  def on_send(node)
24
25
  return unless label_node?(node)
25
26
  return unless node.arguments?
@@ -37,26 +38,18 @@ module RuboCop
37
38
 
38
39
  case pair.value.value
39
40
  when :large, "large"
40
- add_offense(pair, message: "Avoid using `variant: :large` with `LabelComponent`. Use `size: :large` instead.")
41
+ add_offense(pair, message: "Avoid using `variant: :large` with `LabelComponent`. Use `size: :large` instead.") do |corrector|
42
+ corrector.replace(pair, "size: :large")
43
+ end
41
44
  when :inline, "inline"
42
- add_offense(pair, message: "Avoid using `variant: :inline` with `LabelComponent`. Use `inline: true` instead.")
45
+ add_offense(pair, message: "Avoid using `variant: :inline` with `LabelComponent`. Use `inline: true` instead.") do |corrector|
46
+ corrector.replace(pair, "inline: true")
47
+ end
43
48
  end
44
49
  end
45
50
  end
46
51
 
47
- def autocorrect(node)
48
- lambda do |corrector|
49
- replacement =
50
- case node.value.value
51
- when :large, "large"
52
- "size: :large"
53
- when :inline, "inline"
54
- "inline: true"
55
- end
56
52
 
57
- corrector.replace(node, replacement)
58
- end
59
- end
60
53
 
61
54
  private
62
55
 
@@ -16,7 +16,7 @@ module RuboCop
16
16
  #
17
17
  # good
18
18
  # @system_arguments[:tag] = :h2
19
- class NoTagMemoize < RuboCop::Cop::Cop
19
+ class NoTagMemoize < RuboCop::Cop::Base
20
20
  INVALID_MESSAGE = <<~STR
21
21
  Avoid `[:tag] ||=`. Instead, try one of the following:
22
22
  - Don't allow consumers to update the tag by having a fixed tag (e.g. `system_arguments[:tag] = :div`)
@@ -22,7 +22,8 @@ module RuboCop
22
22
  # primer_octicon(:"icon-with-daashes")
23
23
  # primer_octicon(@ivar)
24
24
  # primer_octicon(condition > "icon" : "other-icon")
25
- class PrimerOcticon < RuboCop::Cop::Cop
25
+ class PrimerOcticon < RuboCop::Cop::Base
26
+ extend AutoCorrector
26
27
  INVALID_MESSAGE = <<~STR
27
28
  Replace the octicon helper with primer_octicon. See https://primer.style/view-components/components/octicon for details.
28
29
  STR
@@ -65,11 +66,7 @@ module RuboCop
65
66
  return if invalid_classes.present?
66
67
  end
67
68
 
68
- add_offense(node, message: INVALID_MESSAGE)
69
- end
70
-
71
- def autocorrect(node)
72
- lambda do |corrector|
69
+ add_offense(node, message: INVALID_MESSAGE) do |corrector|
73
70
  kwargs = kwargs(node)
74
71
 
75
72
  # Converting arguments for the component
@@ -86,6 +83,8 @@ module RuboCop
86
83
  end
87
84
  end
88
85
 
86
+
87
+
89
88
  private
90
89
 
91
90
  def transform_sizes(kwargs)
@@ -0,0 +1,13 @@
1
+ <% texts = [
2
+ "Home",
3
+ "This is a very long breadcrumb item that would normally cause overflow issues by being much longer than expected breadcrumb text should be",
4
+ "And another extremely long breadcrumb item name that demonstrates the max-width fix working correctly to prevent page overflow"
5
+ ] %>
6
+
7
+ <%= render(Primer::Beta::Breadcrumbs.new) do |breadcrumbs| %>
8
+ <% texts.each_with_index do |text, i| %>
9
+ <% breadcrumbs.with_item(href: "##{i}") do %>
10
+ <%= text %>
11
+ <% end %>
12
+ <% end %>
13
+ <% end %>
@@ -47,6 +47,12 @@ module Primer
47
47
  end
48
48
  end
49
49
  end
50
+
51
+ # @label With long items (no truncation)
52
+ # @snapshot
53
+ def with_long_items
54
+ render_with_template
55
+ end
50
56
  end
51
57
  end
52
58
  end
@@ -70,6 +70,22 @@ module Primer
70
70
  component.with_body { "Body" }
71
71
  end
72
72
  end
73
+
74
+ # @label With aria labels
75
+ #
76
+ # @param overlay [Symbol] select [none, default, dark]
77
+ # @param reset [Boolean] toggle
78
+ # @param disabled [Boolean] toggle
79
+ def with_aria_labels(reset: false, overlay: :default, disabled: false)
80
+ render Primer::Beta::Details.new(reset: reset, overlay: overlay, disabled: disabled) do |component|
81
+ component.with_summary(aria_label_closed: "Expand details", aria_label_open: "Collapse details") do
82
+ "Summary with aria labels"
83
+ end
84
+ component.with_body do
85
+ "Body"
86
+ end
87
+ end
88
+ end
73
89
  end
74
90
  end
75
91
  end