primer_view_components 0.0.85 → 0.0.86
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- 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/auto_complete/item.rb +1 -1
- data/app/components/primer/alpha/auto_complete.rb +1 -1
- data/app/components/primer/alpha/button_marketing.rb +1 -1
- data/app/components/primer/alpha/text_field.rb +105 -0
- data/app/components/primer/alpha/tool-tip-element.d.ts +3 -1
- data/app/components/primer/alpha/tool-tip-element.js +20 -13
- data/app/components/primer/alpha/tool-tip-element.ts +23 -14
- data/app/components/primer/alpha/tooltip.rb +1 -1
- data/app/components/primer/beta/base_button.rb +47 -0
- data/app/components/primer/{alpha → beta}/border_box/header.html.erb +0 -0
- data/app/components/primer/{alpha → beta}/border_box/header.rb +6 -6
- data/app/components/primer/{border_box_component.html.erb → beta/border_box.html.erb} +0 -0
- data/app/components/primer/beta/border_box.rb +147 -0
- data/app/components/primer/blankslate_component.rb +2 -150
- data/app/components/primer/border_box_component.rb +2 -140
- data/app/components/primer/button_component.html.erb +12 -4
- data/app/components/primer/button_component.rb +2 -2
- data/app/components/primer/clipboard_copy.rb +6 -2
- data/app/components/primer/close_button.rb +1 -1
- data/app/components/primer/hellip_button.rb +1 -1
- data/app/components/primer/icon_button.html.erb +6 -0
- data/app/components/primer/icon_button.rb +46 -10
- data/app/components/primer/link_component.html.erb +12 -0
- data/app/components/primer/link_component.rb +2 -9
- data/app/lib/primer/join_style_arguments_helper.rb +1 -1
- data/lib/primer/classify/utilities.rb +3 -6
- data/lib/primer/form_components.rb +36 -0
- data/lib/primer/forms/acts_as_component.rb +118 -0
- data/lib/primer/forms/base.html.erb +8 -0
- data/lib/primer/forms/base.rb +137 -0
- data/lib/primer/forms/base_component.rb +58 -0
- data/lib/primer/forms/buffer_rewriter.rb +50 -0
- data/lib/primer/forms/caption.html.erb +10 -0
- data/lib/primer/forms/caption.rb +29 -0
- data/lib/primer/forms/check_box.html.erb +9 -0
- data/lib/primer/forms/check_box.rb +16 -0
- data/lib/primer/forms/check_box_group.html.erb +12 -0
- data/lib/primer/forms/check_box_group.rb +14 -0
- data/lib/primer/forms/dsl/check_box_group_input.rb +41 -0
- data/lib/primer/forms/dsl/check_box_input.rb +27 -0
- data/lib/primer/forms/dsl/form_object.rb +25 -0
- data/lib/primer/forms/dsl/form_reference_input.rb +36 -0
- data/lib/primer/forms/dsl/hidden_input.rb +29 -0
- data/lib/primer/forms/dsl/input.rb +259 -0
- data/lib/primer/forms/dsl/input_group.rb +41 -0
- data/lib/primer/forms/dsl/input_methods.rb +86 -0
- data/lib/primer/forms/dsl/multi_input.rb +58 -0
- data/lib/primer/forms/dsl/radio_button_group_input.rb +38 -0
- data/lib/primer/forms/dsl/radio_button_input.rb +37 -0
- data/lib/primer/forms/dsl/select_list_input.rb +53 -0
- data/lib/primer/forms/dsl/submit_button_input.rb +28 -0
- data/lib/primer/forms/dsl/text_area_input.rb +33 -0
- data/lib/primer/forms/dsl/text_field_input.rb +65 -0
- data/lib/primer/forms/form_control.html.erb +18 -0
- data/lib/primer/forms/form_control.rb +23 -0
- data/lib/primer/forms/form_list.html.erb +5 -0
- data/lib/primer/forms/form_list.rb +21 -0
- data/lib/primer/forms/form_reference.html.erb +3 -0
- data/lib/primer/forms/form_reference.rb +14 -0
- data/lib/primer/forms/group.html.erb +5 -0
- data/lib/primer/forms/group.rb +27 -0
- data/lib/primer/forms/hidden_field.html.erb +1 -0
- data/lib/primer/forms/hidden_field.rb +15 -0
- data/lib/primer/forms/multi.html.erb +3 -0
- data/lib/primer/forms/multi.rb +14 -0
- data/lib/primer/forms/radio_button.html.erb +14 -0
- data/lib/primer/forms/radio_button.rb +29 -0
- data/lib/primer/forms/radio_button_group.html.erb +12 -0
- data/lib/primer/forms/radio_button_group.rb +14 -0
- data/lib/primer/forms/select_list.html.erb +5 -0
- data/lib/primer/forms/select_list.rb +26 -0
- data/lib/primer/forms/separator.html.erb +1 -0
- data/lib/primer/forms/separator.rb +8 -0
- data/lib/primer/forms/spacing_wrapper.html.erb +3 -0
- data/lib/primer/forms/spacing_wrapper.rb +8 -0
- data/lib/primer/forms/submit_button.html.erb +4 -0
- data/lib/primer/forms/submit_button.rb +50 -0
- data/lib/primer/forms/text_area.html.erb +5 -0
- data/lib/primer/forms/text_area.rb +16 -0
- data/lib/primer/forms/text_field.html.erb +19 -0
- data/lib/primer/forms/text_field.rb +14 -0
- data/lib/primer/view_components/engine.rb +23 -0
- data/lib/primer/view_components/linters/argument_mappers/button.rb +2 -2
- data/lib/primer/view_components/linters/button_component_migration_counter.rb +1 -1
- data/lib/primer/view_components/linters/helpers/deprecated_components_helpers.rb +2 -8
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/cop/primer/component_name_migration.rb +3 -0
- data/lib/tasks/deprecated.rake +22 -0
- data/lib/tasks/docs.rake +5 -3
- data/static/arguments.yml +148 -39
- data/static/audited_at.json +4 -2
- data/static/classes.yml +2 -1
- data/static/constants.json +44 -39
- data/static/statuses.json +7 -5
- metadata +66 -7
- data/app/components/primer/base_button.rb +0 -43
- data/app/components/primer/blankslate_component.html.erb +0 -30
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pathname"
|
|
4
|
+
|
|
5
|
+
module Primer
|
|
6
|
+
module Forms
|
|
7
|
+
# :nodoc:
|
|
8
|
+
module ActsAsComponent
|
|
9
|
+
# :nodoc:
|
|
10
|
+
module InstanceMethods
|
|
11
|
+
delegate :render, :content_tag, :output_buffer, :capture, to: :@view_context
|
|
12
|
+
|
|
13
|
+
def render_in(view_context, &block)
|
|
14
|
+
@view_context = view_context
|
|
15
|
+
before_render
|
|
16
|
+
perform_render(&block)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# :nocov:
|
|
20
|
+
def perform_render(&_block)
|
|
21
|
+
raise NotImplementedError, "subclasses must implement ##{__method__}."
|
|
22
|
+
end
|
|
23
|
+
# :nocov:
|
|
24
|
+
|
|
25
|
+
def before_render; end
|
|
26
|
+
|
|
27
|
+
# :nocov:
|
|
28
|
+
# rubocop:disable Naming/AccessorMethodName
|
|
29
|
+
def set_original_view_context(view_context)
|
|
30
|
+
@view_context = view_context
|
|
31
|
+
end
|
|
32
|
+
# rubocop:enable Naming/AccessorMethodName
|
|
33
|
+
# :nocov:
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.extended(base)
|
|
37
|
+
base.include(InstanceMethods)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
TemplateGlob = Struct.new(:glob_pattern, :method_name, :on_compile_callback)
|
|
41
|
+
TemplateParams = Struct.new(:source, :identifier, :type, :format)
|
|
42
|
+
|
|
43
|
+
attr_accessor :template_root_path
|
|
44
|
+
|
|
45
|
+
def renders_templates(glob_pattern, method_name = nil, &block)
|
|
46
|
+
template_globs << TemplateGlob.new(glob_pattern, method_name, block)
|
|
47
|
+
end
|
|
48
|
+
alias renders_template renders_templates
|
|
49
|
+
|
|
50
|
+
def compile!
|
|
51
|
+
# always recompile in dev
|
|
52
|
+
return if defined?(@compiled) && @compiled && !Rails.env.development?
|
|
53
|
+
|
|
54
|
+
template_globs.each do |template_glob|
|
|
55
|
+
compile_templates_in(template_glob)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
@compiled = true
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def template_globs
|
|
64
|
+
@template_globs ||= []
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def compile_templates_in(template_glob)
|
|
68
|
+
pattern = if Pathname(template_glob.glob_pattern).absolute?
|
|
69
|
+
template_glob.glob_pattern
|
|
70
|
+
else
|
|
71
|
+
# skip compilation for anonymous form classes, as in tests
|
|
72
|
+
return unless template_root_path
|
|
73
|
+
|
|
74
|
+
File.join(template_root_path, template_glob.glob_pattern)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
template_paths = Dir.glob(pattern)
|
|
78
|
+
|
|
79
|
+
raise "Cannot compile multiple templates with the same method name." if template_paths.size > 1 && template_glob.method_name
|
|
80
|
+
|
|
81
|
+
template_paths.each do |template_path|
|
|
82
|
+
method_name = template_glob.method_name
|
|
83
|
+
method_name ||= "render_#{File.basename(template_path).chomp('.html.erb')}"
|
|
84
|
+
define_template_method(template_path, method_name)
|
|
85
|
+
template_glob&.on_compile_callback&.call(template_path)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def define_template_method(template_path, method_name)
|
|
90
|
+
# rubocop:disable Style/DocumentDynamicEvalDefinition
|
|
91
|
+
# rubocop:disable Style/EvalWithLocation
|
|
92
|
+
class_eval <<-RUBY, template_path, 0
|
|
93
|
+
private def #{method_name}
|
|
94
|
+
capture { #{compile_template(template_path)} }
|
|
95
|
+
end
|
|
96
|
+
RUBY
|
|
97
|
+
# rubocop:enable Style/EvalWithLocation
|
|
98
|
+
# rubocop:enable Style/DocumentDynamicEvalDefinition
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def compile_template(path)
|
|
102
|
+
handler = ActionView::Template.handler_for_extension("erb")
|
|
103
|
+
template = File.read(path)
|
|
104
|
+
template_params = TemplateParams.new({
|
|
105
|
+
source: template,
|
|
106
|
+
identifier: __FILE__,
|
|
107
|
+
type: "text/html",
|
|
108
|
+
format: "text/html"
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
# change @output_buffer ivar to output_buffer method call
|
|
112
|
+
BufferRewriter.rewrite(
|
|
113
|
+
handler.call(template_params, template)
|
|
114
|
+
)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module Forms
|
|
5
|
+
# :nodoc:
|
|
6
|
+
class Base
|
|
7
|
+
extend ActsAsComponent
|
|
8
|
+
|
|
9
|
+
renders_template File.join(__dir__, "base.html.erb"), :render_base_form
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
attr_reader :has_after_content, :__vcf_form_block, :__vcf_builder
|
|
13
|
+
alias after_content? has_after_content
|
|
14
|
+
|
|
15
|
+
def form(&block)
|
|
16
|
+
@__vcf_form_block = block
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def new(builder, **options)
|
|
20
|
+
allocate.tap do |form|
|
|
21
|
+
form.instance_variable_set(:@builder, builder)
|
|
22
|
+
form.send(:initialize, **options)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def inherited(base)
|
|
27
|
+
form_path = const_source_location(base.name)
|
|
28
|
+
return unless form_path
|
|
29
|
+
|
|
30
|
+
base.template_root_path = File.join(File.dirname(form_path), base.name.demodulize.underscore)
|
|
31
|
+
|
|
32
|
+
base.renders_template "after_content.html.erb" do
|
|
33
|
+
base.instance_variable_set(:@has_after_content, true)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
base.renders_templates "*_caption.html.erb" do |path|
|
|
37
|
+
base.fields_with_caption_templates << File.basename(path).chomp("_caption.html.erb").to_sym
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def caption_template?(field_name)
|
|
42
|
+
fields_with_caption_templates.include?(field_name)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def fields_with_caption_templates
|
|
46
|
+
@fields_with_caption_templates ||= []
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# Unfortunately this bug (https://github.com/ruby/ruby/pull/5646) prevents us from using
|
|
52
|
+
# Ruby's native Module.const_source_location. Instead we have to fudge it by searching
|
|
53
|
+
# for the file in the configured autoload paths. Doing so relies on Rails' autoloading
|
|
54
|
+
# conventions, so it should work ok. Zeitwerk also has this information but lacks a
|
|
55
|
+
# public API to map constants to source files.
|
|
56
|
+
def const_source_location(class_name)
|
|
57
|
+
# NOTE: underscore respects namespacing, i.e. will convert Foo::Bar to foo/bar.
|
|
58
|
+
class_path = "#{class_name.underscore}.rb"
|
|
59
|
+
|
|
60
|
+
ActiveSupport::Dependencies.autoload_paths.each do |autoload_path|
|
|
61
|
+
absolute_path = File.join(autoload_path, class_path)
|
|
62
|
+
return absolute_path if File.exist?(absolute_path)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
nil
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def inputs
|
|
70
|
+
@inputs ||= form_object.inputs.map do |input|
|
|
71
|
+
next input unless input.input?
|
|
72
|
+
|
|
73
|
+
# wrap inputs in a group (unless they are already groups)
|
|
74
|
+
if input.type == :group
|
|
75
|
+
input
|
|
76
|
+
else
|
|
77
|
+
Primer::Forms::Dsl::InputGroup.new(builder: @builder, form: self) do |group|
|
|
78
|
+
group.send(:add_input, input)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def each_input_in(root_input, &block)
|
|
85
|
+
return enum_for(__method__, root_input) unless block
|
|
86
|
+
|
|
87
|
+
root_input.inputs.each do |input|
|
|
88
|
+
if input.respond_to?(:inputs)
|
|
89
|
+
each_input_in(input, &block)
|
|
90
|
+
else
|
|
91
|
+
yield input
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def before_render
|
|
97
|
+
each_input_in(self) do |input|
|
|
98
|
+
if input.input? && input.invalid? && input.focusable?
|
|
99
|
+
input.autofocus!
|
|
100
|
+
break
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def caption_template?(*args)
|
|
106
|
+
self.class.caption_template?(*args)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def after_content?(*args)
|
|
110
|
+
self.class.after_content?(*args)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def render_caption_template(name)
|
|
114
|
+
send(:"render_#{name}_caption")
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def perform_render(&_block)
|
|
118
|
+
Base.compile!
|
|
119
|
+
self.class.compile!
|
|
120
|
+
|
|
121
|
+
render_base_form
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def form_object
|
|
127
|
+
# rubocop:disable Naming/MemoizedInstanceVariableName
|
|
128
|
+
@__pf_form_object ||= Primer::Forms::Dsl::FormObject.new(builder: @builder, form: self).tap do |obj|
|
|
129
|
+
# compile before adding inputs so caption templates are identified
|
|
130
|
+
self.class.compile!
|
|
131
|
+
instance_exec(obj, &self.class.__vcf_form_block)
|
|
132
|
+
end
|
|
133
|
+
# rubocop:enable Naming/MemoizedInstanceVariableName
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "primer/class_name_helper"
|
|
4
|
+
|
|
5
|
+
module Primer
|
|
6
|
+
module Forms
|
|
7
|
+
# :nodoc:
|
|
8
|
+
class BaseComponent
|
|
9
|
+
include Primer::ClassNameHelper
|
|
10
|
+
extend ActsAsComponent
|
|
11
|
+
|
|
12
|
+
def self.inherited(base)
|
|
13
|
+
base.renders_template File.join(__dir__, "#{base.name.demodulize.underscore}.html.erb"), :render_template
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
delegate :required?, :disabled?, :hidden?, to: :@input
|
|
17
|
+
|
|
18
|
+
def perform_render(&block)
|
|
19
|
+
@__prf_content_block = block
|
|
20
|
+
compile_and_render_template
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def content
|
|
24
|
+
return @__prf_content if defined?(@__prf_content_evaluated) && @__prf_content_evaluated
|
|
25
|
+
|
|
26
|
+
@__prf_content_evaluated = true
|
|
27
|
+
@__prf_content = capture do
|
|
28
|
+
@__prf_content_block.call
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# :nocov:
|
|
33
|
+
def type
|
|
34
|
+
:component
|
|
35
|
+
end
|
|
36
|
+
# :nocov:
|
|
37
|
+
|
|
38
|
+
def input?
|
|
39
|
+
false
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def compile_and_render_template
|
|
45
|
+
self.class.compile! unless self.class.instance_methods(false).include?(:render_template)
|
|
46
|
+
render_template
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def content_tag_if(condition, tag, **kwargs, &block)
|
|
50
|
+
if condition
|
|
51
|
+
content_tag(tag, **kwargs, &block)
|
|
52
|
+
else
|
|
53
|
+
capture(&block)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ripper"
|
|
4
|
+
|
|
5
|
+
module Primer
|
|
6
|
+
module Forms
|
|
7
|
+
# :nodoc:
|
|
8
|
+
class BufferRewriter < Ripper
|
|
9
|
+
class << self
|
|
10
|
+
def rewrite(code)
|
|
11
|
+
parser = new(code, "(code)", 0)
|
|
12
|
+
parser.parse
|
|
13
|
+
|
|
14
|
+
line_offsets = calc_line_offsets(code)
|
|
15
|
+
|
|
16
|
+
code.dup.tap do |result|
|
|
17
|
+
parser.var_refs.reverse_each do |lineno, stop|
|
|
18
|
+
line_offset = line_offsets[lineno]
|
|
19
|
+
start = (stop - "@output_buffer".length) + line_offset
|
|
20
|
+
stop += line_offset
|
|
21
|
+
result[start...stop] = "output_buffer"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def calc_line_offsets(code)
|
|
29
|
+
idx = -1
|
|
30
|
+
|
|
31
|
+
[0].tap do |offsets|
|
|
32
|
+
while (idx = code.index(/\r?\n/, idx + 1))
|
|
33
|
+
offsets << Regexp.last_match.end(0)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def on_var_ref(var)
|
|
40
|
+
return unless var == "@output_buffer"
|
|
41
|
+
|
|
42
|
+
var_refs << [lineno, column - 1]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def var_refs
|
|
46
|
+
@var_refs ||= []
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<% if @input.caption? && !@input.caption.blank? %>
|
|
2
|
+
<span class="FormControl-caption" id="<%= @input.caption_id %>"><%= @input.caption %></span>
|
|
3
|
+
<% elsif caption_template? %>
|
|
4
|
+
<% caption_template = render_caption_template %>
|
|
5
|
+
<% unless caption_template.blank? %>
|
|
6
|
+
<span class="FormControl-caption" id="<%= @input.caption_id %>">
|
|
7
|
+
<%= caption_template %>
|
|
8
|
+
</span>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module Forms
|
|
5
|
+
# :nodoc:
|
|
6
|
+
class Caption < BaseComponent
|
|
7
|
+
def initialize(input:)
|
|
8
|
+
@input = input
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def caption_template?
|
|
12
|
+
@input.caption_template?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def render_caption_template
|
|
16
|
+
@input.render_caption_template
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def before_render
|
|
20
|
+
return unless @input.caption? && caption_template?
|
|
21
|
+
|
|
22
|
+
raise <<~MESSAGE
|
|
23
|
+
Please provide either a caption: argument or caption template for the
|
|
24
|
+
'#{@input.name}' input; both were found.
|
|
25
|
+
MESSAGE
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div class="FormControl-checkbox-wrap">
|
|
2
|
+
<%= builder.check_box(@input.name, **@input.input_arguments) %>
|
|
3
|
+
<span class="FormControl-checkbox-labelWrap">
|
|
4
|
+
<%= builder.label(@input.name, **@input.label_arguments) do %>
|
|
5
|
+
<%= @input.label %>
|
|
6
|
+
<% end %>
|
|
7
|
+
<%= render(Caption.new(input: @input)) %>
|
|
8
|
+
</span>
|
|
9
|
+
</div>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module Forms
|
|
5
|
+
# :nodoc:
|
|
6
|
+
class CheckBox < BaseComponent
|
|
7
|
+
delegate :builder, :form, to: :@input
|
|
8
|
+
|
|
9
|
+
def initialize(input:)
|
|
10
|
+
@input = input
|
|
11
|
+
@input.add_label_classes("FormControl-label")
|
|
12
|
+
@input.add_input_classes("FormControl-checkbox")
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<fieldset>
|
|
2
|
+
<% if @input.label %>
|
|
3
|
+
<%= content_tag(:legend, **@input.label_arguments) do %>
|
|
4
|
+
<%= @input.label %>
|
|
5
|
+
<% end %>
|
|
6
|
+
<% end %>
|
|
7
|
+
<%= render(SpacingWrapper.new) do %>
|
|
8
|
+
<% @input.check_boxes.each do |check_box| %>
|
|
9
|
+
<%= render(check_box) %>
|
|
10
|
+
<% end %>
|
|
11
|
+
<% end %>
|
|
12
|
+
</fieldset>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module Forms
|
|
5
|
+
module Dsl
|
|
6
|
+
# :nodoc:
|
|
7
|
+
class CheckBoxGroupInput < Input
|
|
8
|
+
attr_reader :label, :check_boxes
|
|
9
|
+
|
|
10
|
+
def initialize(label: nil, **system_arguments)
|
|
11
|
+
@label = label
|
|
12
|
+
@check_boxes = []
|
|
13
|
+
|
|
14
|
+
super(**system_arguments)
|
|
15
|
+
|
|
16
|
+
add_label_classes("FormControl-label", "mb-2")
|
|
17
|
+
|
|
18
|
+
yield(self) if block_given?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_component
|
|
22
|
+
CheckBoxGroup.new(input: self)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def name
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def type
|
|
30
|
+
:check_box_group
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def check_box(**system_arguments)
|
|
34
|
+
@check_boxes << CheckBoxInput.new(
|
|
35
|
+
builder: @builder, form: @form, **system_arguments
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module Forms
|
|
5
|
+
module Dsl
|
|
6
|
+
# :nodoc:
|
|
7
|
+
class CheckBoxInput < Input
|
|
8
|
+
attr_reader :name, :label
|
|
9
|
+
|
|
10
|
+
def initialize(name:, label:, **system_arguments)
|
|
11
|
+
@name = name
|
|
12
|
+
@label = label
|
|
13
|
+
|
|
14
|
+
super(**system_arguments)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_component
|
|
18
|
+
CheckBox.new(input: self)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def type
|
|
22
|
+
:check_box
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module Forms
|
|
5
|
+
module Dsl
|
|
6
|
+
# :nodoc:
|
|
7
|
+
class FormObject
|
|
8
|
+
include InputMethods
|
|
9
|
+
|
|
10
|
+
attr_reader :builder, :form
|
|
11
|
+
|
|
12
|
+
def initialize(builder:, form:)
|
|
13
|
+
@builder = builder
|
|
14
|
+
@form = form
|
|
15
|
+
|
|
16
|
+
yield(self) if block_given?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def group(**options, &block)
|
|
20
|
+
add_input InputGroup.new(builder: @builder, form: @form, **options, &block)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module Forms
|
|
5
|
+
module Dsl
|
|
6
|
+
# :nodoc:
|
|
7
|
+
class FormReferenceInput < Input
|
|
8
|
+
attr_reader :ref_block, :fields_for_args, :fields_for_kwargs
|
|
9
|
+
|
|
10
|
+
def initialize(*fields_for_args, builder:, form:, **fields_for_kwargs, &block)
|
|
11
|
+
@fields_for_args = fields_for_args
|
|
12
|
+
@fields_for_kwargs = fields_for_kwargs
|
|
13
|
+
@ref_block = block
|
|
14
|
+
|
|
15
|
+
super(builder: builder, form: form, **fields_for_kwargs)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_component
|
|
19
|
+
FormReference.new(input: self)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def name
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def label
|
|
27
|
+
nil
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def type
|
|
31
|
+
:form
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module Forms
|
|
5
|
+
module Dsl
|
|
6
|
+
# :nodoc:
|
|
7
|
+
class HiddenInput < Input
|
|
8
|
+
attr_reader :name
|
|
9
|
+
|
|
10
|
+
def initialize(name:, **system_arguments)
|
|
11
|
+
@name = name
|
|
12
|
+
super(**system_arguments)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_component
|
|
16
|
+
HiddenField.new(input: self)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def label
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def type
|
|
24
|
+
:hidden
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|