primer_view_components 0.0.72 → 0.0.75

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.
@@ -56,7 +56,7 @@ class ToolTipElement extends HTMLElement {
56
56
  white-space: normal;
57
57
  width: max-content;
58
58
  }
59
-
59
+
60
60
  :host:before{
61
61
  position: absolute;
62
62
  z-index: 1000001;
@@ -65,7 +65,7 @@ class ToolTipElement extends HTMLElement {
65
65
  border: 6px solid transparent;
66
66
  opacity: 0
67
67
  }
68
-
68
+
69
69
  @keyframes tooltip-appear {
70
70
  from {
71
71
  opacity: 0
@@ -74,7 +74,7 @@ class ToolTipElement extends HTMLElement {
74
74
  opacity: 1
75
75
  }
76
76
  }
77
-
77
+
78
78
  :host:after{
79
79
  position: absolute;
80
80
  display: block;
@@ -83,7 +83,7 @@ class ToolTipElement extends HTMLElement {
83
83
  height: 12px;
84
84
  content: ""
85
85
  }
86
-
86
+
87
87
  :host(.${TOOLTIP_OPEN_CLASS}),
88
88
  :host(.${TOOLTIP_OPEN_CLASS}):before {
89
89
  animation-name: tooltip-appear;
@@ -92,7 +92,7 @@ class ToolTipElement extends HTMLElement {
92
92
  animation-timing-function: ease-in;
93
93
  animation-delay: .4s
94
94
  }
95
-
95
+
96
96
  :host(.tooltip-s):before,
97
97
  :host(.tooltip-n):before {
98
98
  right: 50%;
@@ -105,38 +105,38 @@ class ToolTipElement extends HTMLElement {
105
105
  bottom: 100%;
106
106
  border-bottom-color: var(--color-neutral-emphasis-plus)
107
107
  }
108
-
108
+
109
109
  :host(.tooltip-s):after,
110
110
  :host(.tooltip-se):after,
111
111
  :host(.tooltip-sw):after {
112
112
  bottom: 100%
113
113
  }
114
-
114
+
115
115
  :host(.tooltip-n):before,
116
116
  :host(.tooltip-ne):before,
117
117
  :host(.tooltip-nw):before {
118
118
  top: 100%;
119
119
  border-top-color: var(--color-neutral-emphasis-plus)
120
120
  }
121
-
121
+
122
122
  :host(.tooltip-n):after,
123
123
  :host(.tooltip-ne):after,
124
124
  :host(.tooltip-nw):after {
125
125
  top: 100%
126
126
  }
127
-
127
+
128
128
  :host(.tooltip-se):before,
129
129
  :host(.tooltip-ne):before {
130
130
  left: 0;
131
131
  margin-left: ${TOOLTIP_ARROW_EDGE_OFFSET}px;
132
132
  }
133
-
133
+
134
134
  :host(.tooltip-sw):before,
135
135
  :host(.tooltip-nw):before {
136
136
  right: 0;
137
137
  margin-right: ${TOOLTIP_ARROW_EDGE_OFFSET}px;
138
138
  }
139
-
139
+
140
140
  :host(.tooltip-w):before {
141
141
  top: 50%;
142
142
  bottom: 50%;
@@ -144,7 +144,7 @@ class ToolTipElement extends HTMLElement {
144
144
  margin-top: -6px;
145
145
  border-left-color: var(--color-neutral-emphasis-plus)
146
146
  }
147
-
147
+
148
148
  :host(.tooltip-e):before {
149
149
  top: 50%;
150
150
  right: 100%;
@@ -178,13 +178,15 @@ class ToolTipElement extends HTMLElement {
178
178
  }
179
179
  connectedCallback() {
180
180
  var _a;
181
- const shadow = this.attachShadow({ mode: 'open' });
182
- shadow.innerHTML = `
183
- <style>
184
- ${this.styles()}
185
- </style>
186
- <slot></slot>
187
- `;
181
+ if (!this.shadowRoot) {
182
+ const shadow = this.attachShadow({ mode: 'open' });
183
+ shadow.innerHTML = `
184
+ <style>
185
+ ${this.styles()}
186
+ </style>
187
+ <slot></slot>
188
+ `;
189
+ }
188
190
  this.hidden = true;
189
191
  __classPrivateFieldSet(this, _ToolTipElement_allowUpdatePosition, true, "f");
190
192
  if (!this.id) {
@@ -1,3 +1,4 @@
1
+ // eslint-disable-next-line prettier/prettier
1
2
  import type {AnchorAlignment, AnchorSide} from '@primer/behaviors'
2
3
  import {getAnchoredPosition} from '@primer/behaviors'
3
4
 
@@ -42,7 +43,7 @@ class ToolTipElement extends HTMLElement {
42
43
  white-space: normal;
43
44
  width: max-content;
44
45
  }
45
-
46
+
46
47
  :host:before{
47
48
  position: absolute;
48
49
  z-index: 1000001;
@@ -51,7 +52,7 @@ class ToolTipElement extends HTMLElement {
51
52
  border: 6px solid transparent;
52
53
  opacity: 0
53
54
  }
54
-
55
+
55
56
  @keyframes tooltip-appear {
56
57
  from {
57
58
  opacity: 0
@@ -60,7 +61,7 @@ class ToolTipElement extends HTMLElement {
60
61
  opacity: 1
61
62
  }
62
63
  }
63
-
64
+
64
65
  :host:after{
65
66
  position: absolute;
66
67
  display: block;
@@ -69,7 +70,7 @@ class ToolTipElement extends HTMLElement {
69
70
  height: 12px;
70
71
  content: ""
71
72
  }
72
-
73
+
73
74
  :host(.${TOOLTIP_OPEN_CLASS}),
74
75
  :host(.${TOOLTIP_OPEN_CLASS}):before {
75
76
  animation-name: tooltip-appear;
@@ -78,7 +79,7 @@ class ToolTipElement extends HTMLElement {
78
79
  animation-timing-function: ease-in;
79
80
  animation-delay: .4s
80
81
  }
81
-
82
+
82
83
  :host(.tooltip-s):before,
83
84
  :host(.tooltip-n):before {
84
85
  right: 50%;
@@ -91,38 +92,38 @@ class ToolTipElement extends HTMLElement {
91
92
  bottom: 100%;
92
93
  border-bottom-color: var(--color-neutral-emphasis-plus)
93
94
  }
94
-
95
+
95
96
  :host(.tooltip-s):after,
96
97
  :host(.tooltip-se):after,
97
98
  :host(.tooltip-sw):after {
98
99
  bottom: 100%
99
100
  }
100
-
101
+
101
102
  :host(.tooltip-n):before,
102
103
  :host(.tooltip-ne):before,
103
104
  :host(.tooltip-nw):before {
104
105
  top: 100%;
105
106
  border-top-color: var(--color-neutral-emphasis-plus)
106
107
  }
107
-
108
+
108
109
  :host(.tooltip-n):after,
109
110
  :host(.tooltip-ne):after,
110
111
  :host(.tooltip-nw):after {
111
112
  top: 100%
112
113
  }
113
-
114
+
114
115
  :host(.tooltip-se):before,
115
116
  :host(.tooltip-ne):before {
116
117
  left: 0;
117
118
  margin-left: ${TOOLTIP_ARROW_EDGE_OFFSET}px;
118
119
  }
119
-
120
+
120
121
  :host(.tooltip-sw):before,
121
122
  :host(.tooltip-nw):before {
122
123
  right: 0;
123
124
  margin-right: ${TOOLTIP_ARROW_EDGE_OFFSET}px;
124
125
  }
125
-
126
+
126
127
  :host(.tooltip-w):before {
127
128
  top: 50%;
128
129
  bottom: 50%;
@@ -130,7 +131,7 @@ class ToolTipElement extends HTMLElement {
130
131
  margin-top: -6px;
131
132
  border-left-color: var(--color-neutral-emphasis-plus)
132
133
  }
133
-
134
+
134
135
  :host(.tooltip-e):before {
135
136
  top: 50%;
136
137
  right: 100%;
@@ -176,13 +177,15 @@ class ToolTipElement extends HTMLElement {
176
177
  }
177
178
 
178
179
  connectedCallback() {
179
- const shadow = this.attachShadow({mode: 'open'})
180
- shadow.innerHTML = `
181
- <style>
182
- ${this.styles()}
183
- </style>
184
- <slot></slot>
185
- `
180
+ if (!this.shadowRoot) {
181
+ const shadow = this.attachShadow({mode: 'open'})
182
+ shadow.innerHTML = `
183
+ <style>
184
+ ${this.styles()}
185
+ </style>
186
+ <slot></slot>
187
+ `
188
+ }
186
189
  this.hidden = true
187
190
  this.#allowUpdatePosition = true
188
191
 
@@ -1,24 +1,26 @@
1
1
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
- <label for="<%= @input_id %>" class="<%= @label_classes %>">
3
- <% if @is_label_visible %>
2
+ <div class="<%= @form_group_classes %>">
3
+ <label for="<%= @input_id %>" class="FormControl-label <% if @visually_hide_label %>sr-only<% end %>">
4
4
  <%= @label_text %>
5
+ </label>
6
+ <% if leading_visual || @show_clear_button %>
7
+ <div class="<%= @field_wrap_classes %> <% if leading_visual %>FormControl-fieldWrap--input-leadingVisual<% end %>">
8
+ <%= leading_visual %>
9
+ <%= input %>
10
+ <% if @show_clear_button %>
11
+ <button id="<%= @input_id %>-clear" class="FormControl--input-trailingAction" aria-label="Clear"><%= primer_octicon "x-circle-fill" %></button>
12
+ <% end %>
13
+ </div>
5
14
  <% else %>
6
- <span class="sr-only"><%= @label_text %></span>
15
+ <%= input %>
7
16
  <% end %>
8
- </label>
9
- <span class="autocomplete-body">
10
- <% if @with_icon %>
11
- <div class="form-control autocomplete-embedded-icon-wrap">
12
- <%= render Primer::OcticonComponent.new(:search) %>
13
- <% end %>
14
- <%= input %>
15
- <% if @is_clearable %>
16
- <button id="<%= @input_id %>-clear" class="btn-octicon" aria-label="Clear"><%= primer_octicon "x" %></button>
17
- <% end %>
18
- <% if @with_icon %>
17
+ </div>
18
+ <div class="Overlay-backdrop--anchor">
19
+ <div class="Overlay Overlay--height-auto Overlay--width-auto">
20
+ <div class="Overlay-body Overlay-body--paddingNone">
21
+ <%= results %>
19
22
  </div>
20
- <% end %>
21
- <%= results %>
22
- </span>
23
+ </div>
24
+ </div>
23
25
  <div id="<%= @list_id %>-feedback" class="sr-only"></div>
24
26
  <% end %>
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # TODO: use generic ActionList item for Autocomplete
3
4
  module Primer
4
5
  module Beta
5
6
  class AutoComplete
@@ -29,14 +30,17 @@ module Primer
29
30
  @system_arguments[:"aria-disabled"] = true if disabled
30
31
 
31
32
  @system_arguments[:classes] = class_names(
32
- "autocomplete-item",
33
- system_arguments[:classes],
34
- "disabled" => disabled
33
+ "ActionList-item",
34
+ system_arguments[:classes]
35
35
  )
36
36
  end
37
37
 
38
38
  def call
39
- render(Primer::BaseComponent.new(**@system_arguments)) { content }
39
+ render(Primer::BaseComponent.new(**@system_arguments)) do
40
+ render(Primer::BaseComponent.new(tag: :span, classes: "ActionList-content")) do
41
+ render(Primer::BaseComponent.new(tag: :span, classes: "ActionList-item-label")) { content }
42
+ end
43
+ end
40
44
  end
41
45
  end
42
46
  end
@@ -8,11 +8,20 @@ module Primer
8
8
  # Always set an accessible label to help the user interact with the component.
9
9
  #
10
10
  # * `label_text` is required and visible by default.
11
- # * If you must use a non-visible label, set `is_label_visible` to `false`.
11
+ # * If you must hide the label, set `visually_hide_label` to `true`.
12
12
  # However, please note that a visible label should almost always
13
13
  # be used unless there is compelling reason not to. A placeholder is not a label.
14
14
  class AutoComplete < Primer::Component
15
15
  status :beta
16
+
17
+ DEFAULT_SIZE = :medium
18
+ SIZE_MAPPINGS = {
19
+ :small => "FormControl--small",
20
+ DEFAULT_SIZE => "FormControl--medium",
21
+ :large => "FormControl--large"
22
+ }.freeze
23
+ SIZE_OPTIONS = SIZE_MAPPINGS.keys
24
+
16
25
  #
17
26
  # Customizable results list.
18
27
  #
@@ -22,13 +31,26 @@ module Primer
22
31
  system_arguments[:tag] = :ul
23
32
  system_arguments[:id] = @list_id
24
33
  system_arguments[:classes] = class_names(
25
- "autocomplete-results",
34
+ "ActionList",
26
35
  system_arguments[:classes]
27
36
  )
28
37
 
29
38
  Primer::BaseComponent.new(**system_arguments)
30
39
  }
31
40
 
41
+ #
42
+ # Leading visual.
43
+ #
44
+ # - `leading_visual_icon` for a <%= link_to_component(Primer::OcticonComponent) %>.
45
+ #
46
+ # @param system_arguments [Hash] Same arguments as <%= link_to_component(Primer::OcticonComponent) %>.
47
+ renders_one :leading_visual, types: {
48
+ icon: lambda { |**system_arguments|
49
+ system_arguments[:classes] = class_names("FormControl--input-leadingVisual")
50
+ Primer::OcticonComponent.new(**system_arguments)
51
+ }
52
+ }
53
+
32
54
  # Customizable input used to search for results.
33
55
  # It is preferred to use this slot sparingly - it will be created by default if not explicity added.
34
56
  #
@@ -38,7 +60,7 @@ module Primer
38
60
  sanitized_args = deny_single_argument(:autofocus, "autofocus is not allowed for accessibility reasons. See https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus#accessibility_considerations for more information.", **sanitized_args)
39
61
  deny_aria_key(
40
62
  :label,
41
- "instead of `aria-label`, include `label_text` and set `is_label_visible` to `false` on the component initializer.",
63
+ "instead of `aria-label`, include `label_text` and set `visually_hide_label` to `true` on the component initializer.",
42
64
  **sanitized_args
43
65
  )
44
66
  deny_single_argument(
@@ -55,45 +77,82 @@ module Primer
55
77
  sanitized_args[:name] = @input_name
56
78
  sanitized_args[:tag] = :input
57
79
  sanitized_args[:autocomplete] = "off"
58
-
80
+ sanitized_args[:disabled] = true if @disabled
81
+ sanitized_args[:invalid] = true if @invalid
59
82
  sanitized_args[:type] = :text
60
83
  sanitized_args[:classes] = class_names(
61
- "form-control",
84
+ "FormControl",
85
+ "FormControl--input",
86
+ SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, @size, DEFAULT_SIZE)],
62
87
  sanitized_args[:classes]
63
88
  )
89
+ sanitized_args[:placeholder] = @placeholder
64
90
 
65
91
  Primer::BaseComponent.new(**sanitized_args)
66
92
  }
67
93
 
68
- # @example Default
94
+ # @example Leading visual
69
95
  # @description
70
- # Labels are stacked by default.
96
+ # Display any Octicon as a leading visual within the field
71
97
  # @code
72
- # <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input--default", list_id: "fruits-popup--default")) %>
98
+ # <%= render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", src: "/auto_complete", input_id:"input-id-1", list_id: "list-id-1")) do |c| %>
99
+ # <% c.leading_visual_icon(icon: :search) %>
100
+ # <% c.results do %>
101
+ # <%= render(Primer::Beta::AutoComplete::Item.new(selected: true, value: "apple")) do |_c| %>
102
+ # Apple
103
+ # <% end %>
104
+ # <%= render(Primer::Beta::AutoComplete::Item.new(value: "orange")) do |_c| %>
105
+ # Orange
106
+ # <% end %>
107
+ # <% end %>
108
+ # <% end %>
73
109
  #
74
- # @example With inline label
110
+ # @example Trailing action
75
111
  # @description
76
- # Labels can be inline by setting `is_label_inline: true`. However, labels will always become stacked on smaller screen sizes.
112
+ # Show a clear button
77
113
  # @code
78
- # <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", is_label_inline: true, input_id: "fruits-input--inline-label", list_id: "fruits-popup--inline-label")) %>
114
+ # <%= render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "input-id-2", list_id: "list-id-2", src: "/auto_complete", show_clear_button: true )) do |c| %>
115
+ # <% c.results do %>
116
+ # <%= render(Primer::Beta::AutoComplete::Item.new(selected: true, value: "apple")) do |_c| %>
117
+ # Apple
118
+ # <% end %>
119
+ # <%= render(Primer::Beta::AutoComplete::Item.new(value: "orange")) do |_c| %>
120
+ # Orange
121
+ # <% end %>
122
+ # <% end %>
123
+ # <% end %>
79
124
  #
80
- # @example With non-visible label
125
+ # @example Visually hidden label
81
126
  # @description
82
- # A non-visible label may be rendered with `is_label_visible: false`, but it is highly discouraged. See <%= link_to_accessibility %>.
127
+ # A non-visible label may be rendered with `visually_hide_label: true`, but it is highly discouraged. See <%= link_to_accessibility %>.
83
128
  # @code
84
- # <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input--non-visible-label", list_id: "fruits-popup--non-visible-label", is_label_visible: false)) %>
129
+ # <%= render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "fruits-input--custom-results-1", list_id: "fruits-popup--custom-result-1", src: "/auto_complete", visually_hide_label: true)) do |c| %>
130
+ # <% c.leading_visual_icon(icon: :search) %>
131
+ # <% c.results do %>
132
+ # <%= render(Primer::Beta::AutoComplete::Item.new(selected: true, value: "apple")) do |_c| %>
133
+ # Apple
134
+ # <% end %>
135
+ # <%= render(Primer::Beta::AutoComplete::Item.new(value: "orange")) do |_c| %>
136
+ # Orange
137
+ # <% end %>
138
+ # <% end %>
139
+ # <% end %>
85
140
  #
86
- # @example With icon
141
+ # @example Full width field
87
142
  # @description
88
- # To display a search icon, set `with_icon` to `true`.
143
+ # To allow field to span width of its container, set `full_width` to `true`.
89
144
  # @code
90
- # <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", list_id: "fruits-popup--icon", input_id: "fruits-input--icon", with_icon: true)) %>
91
- #
92
- # @example With icon and non-visible label
93
- # <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", list_id: "fruits-popup--icon-no-label", input_id: "fruits-input--icon-no-label", with_icon: true, is_label_visible: false)) %>
94
- #
95
- # @example With clear button
96
- # <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input--clear", list_id: "fruits-popup--clear", is_clearable: true)) %>
145
+ # <%= render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "fruits-input--custom-results-2", list_id: "fruits-popup--custom-results-2", src: "/auto_complete", full_width: true)) do |c| %>
146
+ # <% c.leading_visual_icon(icon: :search) %>
147
+ # <% c.results do %>
148
+ # <%= render(Primer::Beta::AutoComplete::Item.new(selected: true, value: "apple")) do |_c| %>
149
+ # Apple
150
+ # <% end %>
151
+ # <%= render(Primer::Beta::AutoComplete::Item.new(value: "orange")) do |_c| %>
152
+ # Orange
153
+ # <% end %>
154
+ # <% end %>
155
+ # <% end %>
97
156
  #
98
157
  # @example With custom classes for the input
99
158
  # <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input--custom-input", list_id: "fruits-popup--custom-input")) do |c| %>
@@ -117,25 +176,42 @@ module Primer
117
176
  # @param input_id [String] Id of the input element.
118
177
  # @param input_name [String] Optional name of the input element, defaults to `input_id` when not set.
119
178
  # @param list_id [String] Id of the list element.
120
- # @param with_icon [Boolean] Controls if a search icon is visible, defaults to `false`.
121
- # @param is_label_visible [Boolean] Controls if the label is visible. If `false`, screen reader only text will be added.
122
- # @param is_clearable [Boolean] Adds optional clear button.
123
- # @param is_label_inline [Boolean] Controls if the label is inline. On smaller screens, label will always become stacked.
179
+ # @param visually_hide_label [Boolean] Controls if the label is visible. If `true`, screen reader only text will be added.
180
+ # @param show_clear_button [Boolean] Adds optional clear button.
124
181
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
125
- def initialize(label_text:, src:, list_id:, input_id:, input_name: nil, is_label_visible: true, is_label_inline: false, with_icon: false, is_clearable: false, **system_arguments)
182
+ # @param size [Hash] Input size can be small, medium (default), or large
183
+ # @param full_width [Boolean] Input can be full-width or fit to content
184
+ # @param disabled [Boolean] Disabled input
185
+ # @param invalid [Boolean] Invalid input
186
+ # @param placeholder [String] The placeholder text displayed within the input
187
+ def initialize(label_text:, src:, list_id:, input_id:, input_name: nil, placeholder: nil, show_clear_button: false, visually_hide_label: false, size: DEFAULT_SIZE, full_width: false, disabled: false, invalid: false, **system_arguments)
126
188
  @label_text = label_text
127
189
  @list_id = list_id
128
190
  @input_id = input_id
129
191
  @input_name = input_name || input_id
130
- @is_label_visible = is_label_visible
131
- @with_icon = with_icon
132
- @is_clearable = is_clearable
133
-
134
- @label_classes = is_label_inline ? "autocomplete-label-inline" : "autocomplete-label-stacked"
192
+ @placeholder = placeholder
193
+ @visually_hide_label = visually_hide_label
194
+ @show_clear_button = show_clear_button
135
195
  @system_arguments = deny_tag_argument(**system_arguments)
136
196
  @system_arguments[:tag] = "auto-complete"
137
197
  @system_arguments[:src] = src
138
198
  @system_arguments[:for] = list_id
199
+ @disabled = disabled
200
+ @invalid = invalid
201
+ @size = size
202
+ @full_width = full_width
203
+ @field_wrap_classes = class_names(
204
+ "FormControl-fieldWrap",
205
+ "FormControl-fieldWrap--input",
206
+ SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, @size, DEFAULT_SIZE)],
207
+ "FormControl-fieldWrap--disabled": disabled,
208
+ "FormControl-fieldWrap--invalid": invalid,
209
+ "FormControl-fieldWrap--input-trailingAction": show_clear_button
210
+ )
211
+ @form_group_classes = class_names(
212
+ "FormGroup",
213
+ "FormGroup--fullWidth": full_width
214
+ )
139
215
  end
140
216
 
141
217
  # add `input` and `results` without needing to explicitly call them in the view
@@ -32,7 +32,7 @@ function showCheck(button: HTMLElement) {
32
32
 
33
33
  const clipboardCopyElementTimers = new WeakMap<HTMLElement, number>()
34
34
 
35
- document.addEventListener('clipboard-copy', function ({target}) {
35
+ document.addEventListener('clipboard-copy', function({target}) {
36
36
  if (!(target instanceof HTMLElement)) return
37
37
  if (!target.hasAttribute('data-view-component')) return
38
38
 
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helpers/rubocop_helpers"
4
+
5
+ module ERBLint
6
+ module Linters
7
+ # Replaces calls to `super` with calls to `render_parent`.
8
+ class SuperInComponentTemplates < Linter
9
+ include ERBLint::LinterRegistry
10
+ include Helpers::RubocopHelpers
11
+
12
+ def run(processed_source)
13
+ processed_source.ast.descendants(:erb).each do |erb_node|
14
+ indicator_node, _, code_node = *erb_node
15
+ code = code_node.children.first
16
+ ast = erb_ast(code)
17
+ next unless ast
18
+
19
+ super_call_nodes = find_super_call_nodes(ast)
20
+ next if super_call_nodes.empty?
21
+
22
+ indicator, = *indicator_node
23
+ indicator ||= ""
24
+
25
+ # +2 to account for the leading "<%" characters
26
+ code_start_pos = erb_node.location.begin_pos + indicator.size + 2
27
+
28
+ super_call_nodes.each do |super_call_node|
29
+ orig_loc = code_node.location
30
+ super_call_loc = super_call_node.location.expression
31
+
32
+ new_loc = orig_loc.with(
33
+ begin_pos: super_call_loc.begin_pos + code_start_pos,
34
+ end_pos: super_call_loc.end_pos + code_start_pos
35
+ )
36
+
37
+ add_offense(
38
+ new_loc,
39
+ "Avoid calling `super` in component templates. Call `render_parent` instead",
40
+ "render_parent"
41
+ )
42
+ end
43
+ end
44
+ end
45
+
46
+ def autocorrect(_, offense)
47
+ return unless offense.context
48
+
49
+ lambda do |corrector|
50
+ corrector.replace(offense.source_range, offense.context)
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def find_super_call_nodes(ast)
57
+ return [ast] if ast.type == :zsuper
58
+
59
+ ast.each_child_node.flat_map do |child_ast|
60
+ find_super_call_nodes(child_ast)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -5,7 +5,7 @@ module Primer
5
5
  module VERSION
6
6
  MAJOR = 0
7
7
  MINOR = 0
8
- PATCH = 72
8
+ PATCH = 75
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH].join(".")
11
11
  end
@@ -33,6 +33,16 @@ module RuboCop
33
33
  # }
34
34
  #
35
35
  DEPRECATED = {
36
+ is_label_inline: nil,
37
+ with_icon: nil,
38
+ is_label_visible: {
39
+ false => "visually_hide_label: true",
40
+ true => "visually_hide_label: false"
41
+ },
42
+ is_clearable: {
43
+ false => "show_clear_button: false",
44
+ true => "show_clear_button: true"
45
+ },
36
46
  bg: {
37
47
  white: "bg: :primary",
38
48
  gray_light: "bg: :secondary",
data/lib/tasks/docs.rake CHANGED
@@ -343,11 +343,10 @@ namespace :docs do
343
343
  nav_yaml = YAML.load_file(nav_yaml_file)
344
344
  adr_entry = {
345
345
  "title" => "Architecture decisions",
346
- "url" => "/adr",
347
346
  "children" => nav_entries.compact
348
347
  }
349
348
 
350
- existing_index = nav_yaml.index { |entry| entry["url"] == "/adr" }
349
+ existing_index = nav_yaml.index { |entry| entry["title"] == "Architecture decisions" }
351
350
  if existing_index
352
351
  nav_yaml[existing_index] = adr_entry
353
352
  else