primer_view_components 0.0.86 → 0.0.89
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -0
- data/app/components/primer/alpha/text_field.rb +1 -1
- data/app/components/primer/alpha/tooltip.rb +1 -0
- data/app/components/primer/{button_group.html.erb → beta/button_group.html.erb} +0 -0
- data/app/components/primer/beta/button_group.rb +57 -0
- data/app/components/primer/blankslate_component.html.erb +25 -0
- data/app/components/primer/blankslate_component.rb +150 -2
- data/app/components/primer/box.rb +25 -0
- data/app/components/primer/box_component.rb +2 -20
- data/app/components/primer/button_group.rb +2 -50
- data/app/components/primer/flex_component.rb +20 -20
- data/app/components/primer/flex_item_component.rb +4 -4
- data/app/components/primer/icon_button.html.erb +8 -2
- data/app/components/primer/icon_button.rb +6 -0
- data/app/components/primer/label_component.rb +32 -10
- data/app/components/primer/link_component.rb +14 -0
- data/app/components/primer/popover_component.rb +1 -1
- data/app/helpers/primer/form_helper.rb +10 -0
- data/lib/primer/form_components.rb +2 -2
- data/lib/primer/forms/base.html.erb +1 -1
- data/lib/primer/forms/base.rb +5 -0
- data/lib/primer/forms/base_component.rb +4 -0
- data/lib/primer/forms/buffer_rewriter.rb +3 -2
- data/lib/primer/forms/builder.rb +48 -0
- data/lib/primer/forms/check_box_group.html.erb +1 -1
- data/lib/primer/forms/dsl/input.rb +1 -23
- data/lib/primer/forms/dsl/input_group.rb +0 -7
- data/lib/primer/forms/group.html.erb +1 -1
- data/lib/primer/forms/multi.html.erb +1 -1
- data/lib/primer/view_components/engine.rb +11 -0
- data/lib/primer/view_components/linters/argument_mappers/label.rb +11 -4
- data/lib/primer/view_components/linters/flash_migration_counter.rb +1 -1
- data/lib/primer/view_components/linters/helpers/deprecated_components_helpers.rb +2 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/cop/primer/component_name_migration.rb +2 -0
- data/lib/rubocop/cop/primer/deprecated_label_variants.rb +71 -0
- data/lib/tasks/docs.rake +2 -2
- data/lib/yard/docs_helper.rb +1 -1
- data/static/arguments.yml +56 -48
- data/static/audited_at.json +2 -0
- data/static/classes.yml +2 -0
- data/static/constants.json +20 -7
- data/static/statuses.json +4 -2
- metadata +11 -6
- data/app/components/primer/link_component.html.erb +0 -12
@@ -79,5 +79,19 @@ module Primer
|
|
79
79
|
def before_render
|
80
80
|
raise ArgumentError, "href is required when using <a> tag" if @system_arguments[:tag] == :a && @system_arguments[:href].nil? && !Rails.env.production?
|
81
81
|
end
|
82
|
+
|
83
|
+
def call
|
84
|
+
if tooltip.present?
|
85
|
+
render Primer::BaseComponent.new(tag: :span, position: :relative) do
|
86
|
+
render(Primer::BaseComponent.new(**@system_arguments)) do
|
87
|
+
content
|
88
|
+
end.to_s + tooltip.to_s
|
89
|
+
end
|
90
|
+
else
|
91
|
+
render(Primer::BaseComponent.new(**@system_arguments)) do
|
92
|
+
content
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
82
96
|
end
|
83
97
|
end
|
@@ -17,7 +17,7 @@ module Primer
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def call
|
20
|
-
builder =
|
20
|
+
builder = Primer::Forms::Builder.new(
|
21
21
|
nil, nil, __vc_original_view_context, {}
|
22
22
|
)
|
23
23
|
|
@@ -28,7 +28,7 @@ module Primer
|
|
28
28
|
&@block
|
29
29
|
)
|
30
30
|
|
31
|
-
input.render_in(__vc_original_view_context) { content }
|
31
|
+
input.to_component.render_in(__vc_original_view_context) { content }
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
data/lib/primer/forms/base.rb
CHANGED
@@ -17,6 +17,11 @@ module Primer
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def new(builder, **options)
|
20
|
+
if builder && !builder.is_a?(Primer::Forms::Builder)
|
21
|
+
raise ArgumentError, "please pass an instance of Primer::Forms::Builder when "\
|
22
|
+
"constructing a form object (consider using the `primer_form_with` helper)"
|
23
|
+
end
|
24
|
+
|
20
25
|
allocate.tap do |form|
|
21
26
|
form.instance_variable_set(:@builder, builder)
|
22
27
|
form.send(:initialize, **options)
|
@@ -16,8 +16,9 @@ module Primer
|
|
16
16
|
code.dup.tap do |result|
|
17
17
|
parser.var_refs.reverse_each do |lineno, stop|
|
18
18
|
line_offset = line_offsets[lineno]
|
19
|
-
start = (stop - "@output_buffer".length) + line_offset
|
20
19
|
stop += line_offset
|
20
|
+
stop -= 1 if stop < code.length
|
21
|
+
start = stop - "@output_buffer".length
|
21
22
|
result[start...stop] = "output_buffer"
|
22
23
|
end
|
23
24
|
end
|
@@ -39,7 +40,7 @@ module Primer
|
|
39
40
|
def on_var_ref(var)
|
40
41
|
return unless var == "@output_buffer"
|
41
42
|
|
42
|
-
var_refs << [lineno, column
|
43
|
+
var_refs << [lineno, column]
|
43
44
|
end
|
44
45
|
|
45
46
|
def var_refs
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "primer/classify"
|
4
|
+
|
5
|
+
module Primer
|
6
|
+
module Forms
|
7
|
+
# :nodoc:
|
8
|
+
class Builder < ActionView::Helpers::FormBuilder
|
9
|
+
include Primer::ClassNameHelper
|
10
|
+
|
11
|
+
UTILITY_KEYS = Primer::Classify::Utilities::UTILITIES.keys.freeze
|
12
|
+
|
13
|
+
def label(*args, **options, &block)
|
14
|
+
super(*args, classify(options), &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_box(*args, **options, &block)
|
18
|
+
super(*args, classify(options), &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def radio_button(*args, **options, &block)
|
22
|
+
super(*args, classify(options), &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def select(*args, **options, &block)
|
26
|
+
super(*args, classify(options), &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def text_field(*args, **options, &block)
|
30
|
+
super(*args, classify(options), &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def text_area(*args, **options, &block)
|
34
|
+
super(*args, classify(options), &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def classify(options)
|
40
|
+
options[:classes] = class_names(options.delete(:class), options[:classes])
|
41
|
+
options.merge!(Primer::Classify.call(options))
|
42
|
+
options.except!(*UTILITY_KEYS)
|
43
|
+
options[:class] = class_names(options[:class], options.delete(:classes))
|
44
|
+
options
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "primer/classify"
|
4
|
-
|
5
3
|
module Primer
|
6
4
|
module Forms
|
7
5
|
module Dsl
|
@@ -16,8 +14,6 @@ module Primer
|
|
16
14
|
}.freeze
|
17
15
|
SIZE_OPTIONS = SIZE_MAPPINGS.keys
|
18
16
|
|
19
|
-
UTILITY_KEYS = Primer::Classify::Utilities::UTILITIES.keys.freeze
|
20
|
-
|
21
17
|
include Primer::ClassNameHelper
|
22
18
|
|
23
19
|
attr_reader :builder, :form, :input_arguments, :label_arguments, :caption, :validation_message, :ids
|
@@ -27,14 +23,11 @@ module Primer
|
|
27
23
|
@form = form
|
28
24
|
|
29
25
|
@input_arguments = system_arguments
|
30
|
-
process_classes!(@input_arguments)
|
31
|
-
|
32
26
|
@label_arguments = @input_arguments.delete(:label_arguments) || {}
|
33
|
-
process_classes!(@label_arguments)
|
34
27
|
|
35
28
|
@label_arguments[:class] = class_names(
|
36
29
|
@label_arguments[:class],
|
37
|
-
@input_arguments.fetch(:visually_hide_label,
|
30
|
+
@input_arguments.fetch(:visually_hide_label, false) ? "sr-only" : nil
|
38
31
|
)
|
39
32
|
|
40
33
|
@input_arguments.delete(:visually_hide_label)
|
@@ -207,23 +200,8 @@ module Primer
|
|
207
200
|
true
|
208
201
|
end
|
209
202
|
|
210
|
-
# Avoid using Rails delegation here for performance reasons
|
211
|
-
# rubocop:disable Rails/Delegate
|
212
|
-
def render_in(view_context)
|
213
|
-
to_component.render_in(view_context)
|
214
|
-
end
|
215
|
-
# rubocop:enable Rails/Delegate
|
216
|
-
|
217
203
|
private
|
218
204
|
|
219
|
-
def process_classes!(args)
|
220
|
-
args[:classes] = class_names(args.delete(:class), args[:classes])
|
221
|
-
args.merge!(Primer::Classify.call(args))
|
222
|
-
args[:class] = class_names(args[:class], args.delete(:classes))
|
223
|
-
args.except!(*UTILITY_KEYS)
|
224
|
-
args
|
225
|
-
end
|
226
|
-
|
227
205
|
def input_data
|
228
206
|
@input_arguments[:data] ||= {}
|
229
207
|
end
|
@@ -28,13 +28,6 @@ module Primer
|
|
28
28
|
def input?
|
29
29
|
true
|
30
30
|
end
|
31
|
-
|
32
|
-
# Avoid using Rails delegation here for performance reasons
|
33
|
-
# rubocop:disable Rails/Delegate
|
34
|
-
def render_in(view_context)
|
35
|
-
to_component.render_in(view_context)
|
36
|
-
end
|
37
|
-
# rubocop:enable Rails/Delegate
|
38
31
|
end
|
39
32
|
end
|
40
33
|
end
|
@@ -15,6 +15,7 @@ module Primer
|
|
15
15
|
|
16
16
|
config.eager_load_paths = %W[
|
17
17
|
#{root}/app/components
|
18
|
+
#{root}/app/helpers
|
18
19
|
#{root}/app/lib
|
19
20
|
]
|
20
21
|
|
@@ -39,6 +40,16 @@ module Primer
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
43
|
+
initializer "primer.forms.helpers" do
|
44
|
+
ActiveSupport.on_load :action_controller do
|
45
|
+
require "primer/form_helper"
|
46
|
+
helper Primer::FormHelper
|
47
|
+
|
48
|
+
# make primer_form_with available to view components also
|
49
|
+
ViewComponent::Base.prepend(Primer::FormHelper)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
42
53
|
initializer "primer_view_components.zeitwerk_ignore" do
|
43
54
|
Rails.autoloaders.each do |autoloader|
|
44
55
|
autoloader.ignore(Engine.root.join("lib", "primer", "view_components", "linters.rb"))
|
@@ -13,9 +13,9 @@ module ERBLint
|
|
13
13
|
symbolize: true
|
14
14
|
).freeze
|
15
15
|
|
16
|
-
|
16
|
+
SIZE_MAPPINGS = Primer::ViewComponents::Constants.get(
|
17
17
|
component: "Primer::LabelComponent",
|
18
|
-
constant: "
|
18
|
+
constant: "SIZE_MAPPINGS",
|
19
19
|
symbolize: true
|
20
20
|
).freeze
|
21
21
|
|
@@ -24,6 +24,11 @@ module ERBLint
|
|
24
24
|
constant: "DEFAULT_TAG"
|
25
25
|
).freeze
|
26
26
|
|
27
|
+
INLINE_CLASS = Primer::ViewComponents::Constants.get(
|
28
|
+
component: "Primer::LabelComponent",
|
29
|
+
constant: "INLINE_CLASS"
|
30
|
+
).freeze
|
31
|
+
|
27
32
|
ATTRIBUTES = %w[title].freeze
|
28
33
|
|
29
34
|
def attribute_to_args(attribute)
|
@@ -36,8 +41,10 @@ module ERBLint
|
|
36
41
|
|
37
42
|
if SCHEME_MAPPINGS[class_name] && acc[:scheme].nil?
|
38
43
|
acc[:scheme] = SCHEME_MAPPINGS[class_name]
|
39
|
-
elsif
|
40
|
-
acc[:
|
44
|
+
elsif SIZE_MAPPINGS[class_name] && acc[:size].nil?
|
45
|
+
acc[:size] = SIZE_MAPPINGS[class_name]
|
46
|
+
elsif class_name == INLINE_CLASS && acc[:inline].nil?
|
47
|
+
acc[:inline] = true
|
41
48
|
else
|
42
49
|
acc[:classes] << class_name
|
43
50
|
end
|
@@ -12,7 +12,7 @@ module ERBLint
|
|
12
12
|
|
13
13
|
TAGS = %w[div].freeze
|
14
14
|
CLASSES = %w[flash].freeze
|
15
|
-
MESSAGE = "We are migrating flashes to use [Primer::Beta::Flash](https://primer.style/view-components/components/flash), please try to use that instead of raw HTML."
|
15
|
+
MESSAGE = "We are migrating flashes to use [Primer::Beta::Flash](https://primer.style/view-components/components/beta/flash), please try to use that instead of raw HTML."
|
16
16
|
ARGUMENT_MAPPER = ArgumentMappers::Flash
|
17
17
|
COMPONENT = "Primer::Beta::Flash"
|
18
18
|
|
@@ -7,10 +7,12 @@ module ERBLint
|
|
7
7
|
module DeprecatedComponentsHelpers
|
8
8
|
# If there is no alternative to suggest, set the value to nil
|
9
9
|
COMPONENT_TO_USE_INSTEAD = {
|
10
|
+
"Primer::ButtonGroup" => "Primer::Beta::ButtonGroup",
|
10
11
|
"Primer::Alpha::AutoComplete::Item" => "Primer::Beta::AutoComplete::Item",
|
11
12
|
"Primer::Alpha::AutoComplete" => "Primer::Beta::AutoComplete",
|
12
13
|
"Primer::BlankslateComponent" => "Primer::Beta::Blankslate",
|
13
14
|
"Primer::BorderBoxComponent" => "Primer::Beta::BorderBox",
|
15
|
+
"Primer::BoxComponent" => "Primer::Box",
|
14
16
|
"Primer::DropdownMenuComponent" => nil,
|
15
17
|
"Primer::Tooltip" => "Primer::Alpha::Tooltip",
|
16
18
|
"Primer::FlexComponent" => nil,
|
@@ -15,6 +15,8 @@ module RuboCop
|
|
15
15
|
# Primer::Beta::ComponentName.new()
|
16
16
|
class ComponentNameMigration < BaseCop
|
17
17
|
DEPRECATIONS = {
|
18
|
+
"Primer::BoxComponent" => "Primer::Box",
|
19
|
+
"Primer::ButtonGroup" => "Primer::Beta::ButtonGroup",
|
18
20
|
"Primer::BlankslateComponent" => "Primer::Beta::Blankslate",
|
19
21
|
"Primer::BorderBoxComponent" => "Primer::Beta::BorderBox",
|
20
22
|
"Primer::BaseButton" => "Primer::Beta::BaseButton",
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
|
5
|
+
# :nocov:
|
6
|
+
module RuboCop
|
7
|
+
module Cop
|
8
|
+
module Primer
|
9
|
+
# This cop ensures that `LabelComponent`s don't use the old `variant` argument.
|
10
|
+
#
|
11
|
+
# bad
|
12
|
+
# Primer::LabelComponent.new(variant: :large)
|
13
|
+
#
|
14
|
+
# good
|
15
|
+
# Primer::LabelComponent.new(size: :large)
|
16
|
+
#
|
17
|
+
# bad
|
18
|
+
# Primer::LabelComponent.new(variant: :inline)
|
19
|
+
#
|
20
|
+
# good
|
21
|
+
# Primer::LabelComponent.new(inline: true)
|
22
|
+
class DeprecatedLabelVariants < BaseCop
|
23
|
+
def on_send(node)
|
24
|
+
return unless label_node?(node)
|
25
|
+
return unless node.arguments?
|
26
|
+
|
27
|
+
# we are looking for hash arguments and they are always last
|
28
|
+
kwargs = node.arguments.last
|
29
|
+
|
30
|
+
return unless kwargs.type == :hash
|
31
|
+
|
32
|
+
kwargs.pairs.each do |pair|
|
33
|
+
# skip if we're not dealing with a symbol or string
|
34
|
+
next if pair.key.type != :sym
|
35
|
+
next unless pair.value.type == :sym || pair.value.type == :str
|
36
|
+
next if pair.key.value != :variant
|
37
|
+
|
38
|
+
case pair.value.value
|
39
|
+
when :large, "large"
|
40
|
+
add_offense(pair, message: "Avoid using `variant: :large` with `LabelComponent`. Use `size: :large` instead.")
|
41
|
+
when :inline, "inline"
|
42
|
+
add_offense(pair, message: "Avoid using `variant: :inline` with `LabelComponent`. Use `inline: true` instead.")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
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
|
+
|
57
|
+
corrector.replace(node, replacement)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def label_node?(node)
|
64
|
+
return if node.nil?
|
65
|
+
|
66
|
+
node.method_name == :new && !node.receiver.nil? && node.receiver.const_name == "Primer::LabelComponent"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/tasks/docs.rake
CHANGED
@@ -44,10 +44,10 @@ namespace :docs do
|
|
44
44
|
Primer::Beta::Blankslate,
|
45
45
|
Primer::Beta::BorderBox,
|
46
46
|
Primer::Beta::BorderBox::Header,
|
47
|
-
Primer::
|
47
|
+
Primer::Box,
|
48
48
|
Primer::Beta::Breadcrumbs,
|
49
49
|
Primer::ButtonComponent,
|
50
|
-
Primer::ButtonGroup,
|
50
|
+
Primer::Beta::ButtonGroup,
|
51
51
|
Primer::Alpha::ButtonMarketing,
|
52
52
|
Primer::ClipboardCopy,
|
53
53
|
Primer::CloseButton,
|
data/lib/yard/docs_helper.rb
CHANGED
@@ -28,7 +28,7 @@ module YARD
|
|
28
28
|
prefix = "One of"
|
29
29
|
prefix = prefix.downcase if lower
|
30
30
|
|
31
|
-
"#{prefix} #{values.to_sentence(last_word_connector: ', or ')}."
|
31
|
+
"#{prefix} #{values.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')}."
|
32
32
|
end
|
33
33
|
|
34
34
|
def link_to_accessibility
|