primer_view_components 0.0.72 → 0.0.75
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -47
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/components/primer/alpha/tool-tip-element.js +21 -19
- data/app/components/primer/alpha/tool-tip-element.ts +22 -19
- data/app/components/primer/beta/auto_complete/auto_complete.html.erb +19 -17
- data/app/components/primer/beta/auto_complete/item.rb +8 -4
- data/app/components/primer/beta/auto_complete.rb +109 -33
- data/app/components/primer/clipboard_copy_component.ts +1 -1
- data/lib/primer/view_components/linters/super_in_component_templates.rb +65 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/cop/primer/deprecated_arguments.rb +10 -0
- data/lib/tasks/docs.rake +1 -2
- data/static/arguments.yml +24 -13
- data/static/classes.yml +22 -7
- data/static/constants.json +12 -1
- metadata +3 -2
@@ -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
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
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
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
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
|
-
<
|
3
|
-
<% if @
|
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
|
-
|
15
|
+
<%= input %>
|
7
16
|
<% end %>
|
8
|
-
</
|
9
|
-
<
|
10
|
-
|
11
|
-
<div class="
|
12
|
-
<%=
|
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
|
-
|
21
|
-
|
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
|
-
"
|
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))
|
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
|
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
|
-
"
|
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 `
|
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
|
-
"
|
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
|
94
|
+
# @example Leading visual
|
69
95
|
# @description
|
70
|
-
#
|
96
|
+
# Display any Octicon as a leading visual within the field
|
71
97
|
# @code
|
72
|
-
# <%= render(Primer::Beta::AutoComplete.new(label_text: "
|
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
|
110
|
+
# @example Trailing action
|
75
111
|
# @description
|
76
|
-
#
|
112
|
+
# Show a clear button
|
77
113
|
# @code
|
78
|
-
# <%= render(Primer::Beta::AutoComplete.new(label_text: "
|
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
|
125
|
+
# @example Visually hidden label
|
81
126
|
# @description
|
82
|
-
# A non-visible label may be rendered with `
|
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: "
|
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
|
141
|
+
# @example Full width field
|
87
142
|
# @description
|
88
|
-
# To
|
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: "
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
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
|
121
|
-
# @param
|
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
|
-
|
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
|
-
@
|
131
|
-
@
|
132
|
-
@
|
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
|
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
|
@@ -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["
|
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
|