anchor_view_components 0.45.0 → 0.45.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/app/components/anchor/autocomplete_component.html.erb +5 -5
- data/app/components/anchor/error_message_component.rb +7 -5
- data/app/components/anchor/input_component.rb +5 -1
- data/app/components/anchor/label_component.rb +7 -3
- data/app/components/anchor/radio_button_collection_component.rb +34 -1
- data/app/components/anchor/radio_button_component.html.erb +1 -1
- data/app/components/anchor/radio_button_component.rb +7 -3
- data/app/components/anchor/select_component.rb +5 -1
- data/app/helpers/anchor/form_builder.rb +23 -9
- data/app/helpers/anchor/model_validators.rb +5 -10
- data/lib/anchor/view_components/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e70ad5e5ff2eb34b41352d913159bfa0baae9417393ce24007ef061a7eae1c8a
|
4
|
+
data.tar.gz: 4245d65fc162e270dc8d4711b17159d1ef271eb8b283c6d75ed4d59b77faf1cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 383e4c7e44d61c1346d192fbe0fb6362b112b97854f87a98f7ea506ea2a5cd9449c68c4d80cd77020d2ad950d69e652e81b9b46980fb5cdc8c8a2c9c484bb485
|
7
|
+
data.tar.gz: cff07e92d9e67bb1d8228eea11d950cbef4420505c6f349203d3bcd3dd98c9d80ac7a0cd51f80980da60aadf1403fd797d5bc9420e2555ae12592c094ba080ce
|
data/CHANGELOG.md
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
-
<%= tag.div(
|
1
|
+
<%= tag.div(
|
2
2
|
data: { controller: "autocomplete", autocomplete_url_value: src },
|
3
3
|
role: "combobox",
|
4
4
|
class: "group relative"
|
5
|
-
)
|
5
|
+
) do %>
|
6
6
|
<% if form_builder.class.module_parent_name == "Anchor" %>
|
7
7
|
<%= form_builder.text_field(
|
8
8
|
name,
|
9
9
|
**merge_options(input_options, default_input_options)
|
10
10
|
) %>
|
11
11
|
<%= form_builder.text_field(
|
12
|
-
|
12
|
+
"#{name}_id".to_sym,
|
13
13
|
{ class: "hidden", data: { autocomplete_target: "hidden" }}
|
14
14
|
) %>
|
15
15
|
<% else %>
|
16
16
|
<%= form_builder.input(
|
17
|
-
|
17
|
+
"#{name}_search".to_sym,
|
18
18
|
input_html: merge_options(input_options, default_input_options)
|
19
19
|
) %>
|
20
20
|
<div class="hidden">
|
21
21
|
<%= form_builder.input(
|
22
|
-
|
22
|
+
"#{name}_id".to_sym,
|
23
23
|
input_html: { data: { autocomplete_target: "hidden" } }
|
24
24
|
) %>
|
25
25
|
</div>
|
@@ -13,8 +13,8 @@ module Anchor
|
|
13
13
|
text-sm
|
14
14
|
).freeze
|
15
15
|
|
16
|
-
def initialize(
|
17
|
-
@
|
16
|
+
def initialize(form_builder:, attribute:, **kwargs)
|
17
|
+
@form_builder = form_builder
|
18
18
|
@attribute = attribute
|
19
19
|
|
20
20
|
super(**kwargs)
|
@@ -22,14 +22,16 @@ module Anchor
|
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
|
-
attr_reader :attribute
|
25
|
+
attr_reader :attribute, :form_builder
|
26
|
+
|
27
|
+
delegate :object, to: :form_builder
|
26
28
|
|
27
29
|
def error_message
|
28
|
-
|
30
|
+
object.errors.full_messages_for(attribute).to_sentence
|
29
31
|
end
|
30
32
|
|
31
33
|
def render?
|
32
|
-
|
34
|
+
object.errors.has_key?(attribute)
|
33
35
|
end
|
34
36
|
end
|
35
37
|
end
|
@@ -20,19 +20,23 @@ module Anchor
|
|
20
20
|
).freeze
|
21
21
|
|
22
22
|
def initialize(
|
23
|
+
form_builder:,
|
23
24
|
attribute:,
|
25
|
+
type:,
|
24
26
|
starting_icon: nil,
|
25
27
|
ending_icon: nil,
|
26
28
|
**kwargs
|
27
29
|
)
|
30
|
+
@form_builder = form_builder
|
28
31
|
@attribute = attribute
|
32
|
+
@type = type
|
29
33
|
@starting_icon = starting_icon
|
30
34
|
@ending_icon = ending_icon
|
31
35
|
|
32
36
|
super(**kwargs)
|
33
37
|
end
|
34
38
|
|
35
|
-
attr_reader :attribute, :starting_icon, :ending_icon
|
39
|
+
attr_reader :attribute, :type, :starting_icon, :ending_icon
|
36
40
|
|
37
41
|
def options
|
38
42
|
{
|
@@ -8,10 +8,14 @@ module Anchor
|
|
8
8
|
|
9
9
|
attr_accessor :options
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
@
|
11
|
+
def initialize(form_builder:, attribute:, **options)
|
12
|
+
@form_builder = form_builder
|
13
|
+
@attribute = attribute
|
14
|
+
@options = options.merge(
|
15
|
+
class: Array(options.delete(:class)) + LABEL_CLASSES
|
16
|
+
)
|
13
17
|
@required = ModelValidators
|
14
|
-
.new(object,
|
18
|
+
.new(@form_builder.object, options)
|
15
19
|
.attribute_required?(attribute)
|
16
20
|
|
17
21
|
super()
|
@@ -1,7 +1,40 @@
|
|
1
1
|
module Anchor
|
2
2
|
class RadioButtonCollectionComponent < Component
|
3
|
+
attr_reader :attribute, :descriptions, :form_builder
|
4
|
+
|
5
|
+
def initialize(
|
6
|
+
form_builder:,
|
7
|
+
attribute:,
|
8
|
+
collection:,
|
9
|
+
value_method:,
|
10
|
+
text_method:,
|
11
|
+
descriptions: nil,
|
12
|
+
**options
|
13
|
+
)
|
14
|
+
@form_builder = form_builder
|
15
|
+
@attribute = attribute
|
16
|
+
@collection = collection
|
17
|
+
@value_method = value_method
|
18
|
+
@text_method = text_method
|
19
|
+
@descriptions = descriptions
|
20
|
+
@options = options
|
21
|
+
|
22
|
+
super()
|
23
|
+
end
|
24
|
+
|
3
25
|
def options
|
4
|
-
|
26
|
+
@options.merge(
|
27
|
+
class: Array(@options.delete(:class)) +
|
28
|
+
RadioButtonComponent::INPUT_CLASSES
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def radio(radio:)
|
33
|
+
RadioButtonComponent.new(
|
34
|
+
radio:,
|
35
|
+
attribute:,
|
36
|
+
form_builder:
|
37
|
+
)
|
5
38
|
end
|
6
39
|
end
|
7
40
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<% if description.present? %>
|
6
6
|
<div class="flex flex-col gap-1">
|
7
7
|
<%= radio.label %>
|
8
|
-
<%=
|
8
|
+
<%= description_span %>
|
9
9
|
</div>
|
10
10
|
<% else %>
|
11
11
|
<%= tag.div radio.label, class: "self-center" %>
|
@@ -36,20 +36,24 @@ module Anchor
|
|
36
36
|
text-sm
|
37
37
|
).freeze
|
38
38
|
|
39
|
-
def initialize(
|
40
|
-
@form_builder = form_builder
|
39
|
+
def initialize(radio:, attribute:, form_builder:, **kwargs)
|
41
40
|
@radio = radio
|
42
41
|
@attribute = attribute
|
42
|
+
@form_builder = form_builder
|
43
43
|
|
44
44
|
super(**kwargs)
|
45
45
|
end
|
46
46
|
|
47
47
|
private
|
48
48
|
|
49
|
-
attr_reader :
|
49
|
+
attr_reader :radio, :attribute, :form_builder
|
50
50
|
|
51
51
|
delegate :value, :object, to: :radio
|
52
52
|
|
53
|
+
def description_span
|
54
|
+
tag.span description, id: description_id, class: DESCRIPTION_CLASSES
|
55
|
+
end
|
56
|
+
|
53
57
|
def radio_options
|
54
58
|
{
|
55
59
|
aria: description.present? && aria_description,
|
@@ -1,11 +1,15 @@
|
|
1
1
|
module Anchor
|
2
2
|
class SelectComponent < Component
|
3
|
+
attr_reader :attribute
|
4
|
+
|
3
5
|
def initialize(
|
6
|
+
form_builder:,
|
4
7
|
attribute:,
|
5
8
|
choices:,
|
6
9
|
show_marker: true,
|
7
10
|
**kwargs
|
8
11
|
)
|
12
|
+
@form_builder = form_builder
|
9
13
|
@attribute = attribute
|
10
14
|
@choices = choices
|
11
15
|
@show_marker = show_marker
|
@@ -20,7 +24,7 @@ module Anchor
|
|
20
24
|
def html_options
|
21
25
|
{
|
22
26
|
class: InputComponent::INPUT_CLASSES,
|
23
|
-
data: { testid: "select-#{
|
27
|
+
data: { testid: "select-#{attribute.to_s.dasherize}" },
|
24
28
|
}
|
25
29
|
end
|
26
30
|
|
@@ -32,7 +32,15 @@ module Anchor
|
|
32
32
|
options = {},
|
33
33
|
html_options = {}
|
34
34
|
)
|
35
|
-
render RadioButtonCollectionComponent.new
|
35
|
+
render RadioButtonCollectionComponent.new(
|
36
|
+
form_builder: self,
|
37
|
+
attribute:,
|
38
|
+
collection:,
|
39
|
+
value_method:,
|
40
|
+
text_method:,
|
41
|
+
**options,
|
42
|
+
**html_options
|
43
|
+
) do |component|
|
36
44
|
super(
|
37
45
|
attribute,
|
38
46
|
collection,
|
@@ -41,11 +49,7 @@ module Anchor
|
|
41
49
|
options,
|
42
50
|
component.options.merge(html_options),
|
43
51
|
) do |radio|
|
44
|
-
render
|
45
|
-
radio:,
|
46
|
-
attribute:,
|
47
|
-
form_builder: self
|
48
|
-
)
|
52
|
+
render component.radio(radio:)
|
49
53
|
end
|
50
54
|
end
|
51
55
|
end
|
@@ -82,7 +86,9 @@ module Anchor
|
|
82
86
|
|
83
87
|
def email_field(attribute, options = {})
|
84
88
|
render InputComponent.new(
|
89
|
+
form_builder: self,
|
85
90
|
attribute:,
|
91
|
+
type: :email,
|
86
92
|
starting_icon: options.delete(:starting_icon),
|
87
93
|
ending_icon: options.delete(:ending_icon)
|
88
94
|
) do |component|
|
@@ -92,7 +98,7 @@ module Anchor
|
|
92
98
|
|
93
99
|
def error_message_for(attribute, options = {})
|
94
100
|
render ErrorMessageComponent.new(
|
95
|
-
|
101
|
+
form_builder: self,
|
96
102
|
attribute:,
|
97
103
|
**options
|
98
104
|
)
|
@@ -100,9 +106,10 @@ module Anchor
|
|
100
106
|
|
101
107
|
def label(attribute, text = nil, options = {}, &block)
|
102
108
|
render LabelComponent.new(
|
103
|
-
|
109
|
+
form_builder: self,
|
104
110
|
attribute:,
|
105
|
-
|
111
|
+
text:,
|
112
|
+
**options
|
106
113
|
) do |component|
|
107
114
|
if block.present?
|
108
115
|
super
|
@@ -119,7 +126,9 @@ module Anchor
|
|
119
126
|
|
120
127
|
def number_field(attribute, options = {})
|
121
128
|
render InputComponent.new(
|
129
|
+
form_builder: self,
|
122
130
|
attribute:,
|
131
|
+
type: :number,
|
123
132
|
starting_icon: options.delete(:starting_icon),
|
124
133
|
ending_icon: options.delete(:ending_icon)
|
125
134
|
) do |component|
|
@@ -129,7 +138,9 @@ module Anchor
|
|
129
138
|
|
130
139
|
def search_field(attribute, options = {})
|
131
140
|
render InputComponent.new(
|
141
|
+
form_builder: self,
|
132
142
|
attribute:,
|
143
|
+
type: :search,
|
133
144
|
starting_icon: options.delete(:starting_icon),
|
134
145
|
ending_icon: options.delete(:ending_icon)
|
135
146
|
) do |component|
|
@@ -139,6 +150,7 @@ module Anchor
|
|
139
150
|
|
140
151
|
def select(attribute, choices = nil, options = {}, html_options = {}, &)
|
141
152
|
render SelectComponent.new(
|
153
|
+
form_builder: self,
|
142
154
|
attribute:,
|
143
155
|
choices:,
|
144
156
|
show_marker: options.fetch(:show_marker, true),
|
@@ -156,7 +168,9 @@ module Anchor
|
|
156
168
|
|
157
169
|
def text_field(attribute, options = {})
|
158
170
|
render InputComponent.new(
|
171
|
+
form_builder: self,
|
159
172
|
attribute:,
|
173
|
+
type: :text,
|
160
174
|
starting_icon: options.delete(:starting_icon),
|
161
175
|
ending_icon: options.delete(:ending_icon)
|
162
176
|
) do |component|
|
@@ -1,18 +1,13 @@
|
|
1
1
|
module Anchor
|
2
2
|
class ModelValidators
|
3
|
-
|
4
|
-
# indicate an unspecified value. Passing any other value will result in
|
5
|
-
# `required`'s truthiness being used to determine whether the attribute is
|
6
|
-
# required, while passing :if_has_validators will check the model's
|
7
|
-
# validators.
|
8
|
-
def initialize(model, required: :if_has_validators)
|
3
|
+
def initialize(model, options)
|
9
4
|
@model = model
|
10
|
-
@
|
5
|
+
@options = options
|
11
6
|
end
|
12
7
|
|
13
8
|
def attribute_required?(attribute)
|
14
|
-
if required
|
15
|
-
required
|
9
|
+
if options.has_key?(:required)
|
10
|
+
options[:required]
|
16
11
|
elsif has_validators?
|
17
12
|
attribute_required_by_validators?(attribute)
|
18
13
|
else
|
@@ -22,7 +17,7 @@ module Anchor
|
|
22
17
|
|
23
18
|
private
|
24
19
|
|
25
|
-
attr_reader :model, :
|
20
|
+
attr_reader :model, :options
|
26
21
|
|
27
22
|
def has_validators?
|
28
23
|
model.class.respond_to?(:validators_on)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anchor_view_components
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.45.
|
4
|
+
version: 0.45.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Buoy Software
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|