lifeform 0.4.1 → 0.7
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/.rubocop.yml +11 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +36 -27
- data/README.md +1 -1
- data/lib/lifeform/capturing_renderable.rb +17 -0
- data/lib/lifeform/form.rb +81 -49
- data/lib/lifeform/libraries/default/button.rb +19 -27
- data/lib/lifeform/libraries/default/input.rb +28 -39
- data/lib/lifeform/libraries/default/submit_button.rb +1 -1
- data/lib/lifeform/libraries/shoelace/input.rb +2 -0
- data/lib/lifeform/version.rb +1 -1
- data/lib/lifeform.rb +2 -1
- data/lifeform.gemspec +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0bd913233e25c58ae11c6e356383384f4fd995a35a530f62525524abbb3902f2
|
|
4
|
+
data.tar.gz: a9cbb5ec298a1e291486fe993f14c69a6aff0ef35baf1ec061d9e9bc93e87b78
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 144a5f5b14116f6471acd45c66fb369119d2256a6da724a83df428819d694d3ff017f539c0a2fd7b0ff9f94237d57216116efdd60aac8524e11b3fdb93f801b2
|
|
7
|
+
data.tar.gz: 892413ee58661eb72851f2fbd0ffc1b4a831cbab406eac8f61d17a03ced7c06e59c5b5716659d5e0df5b90c15ab65569e2819fbf3ccd3be30dcf0a2607a09751
|
data/.rubocop.yml
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
|
+
require:
|
|
2
|
+
- rubocop-minitest
|
|
3
|
+
- rubocop-rake
|
|
4
|
+
|
|
1
5
|
AllCops:
|
|
2
6
|
TargetRubyVersion: 2.7
|
|
3
7
|
NewCops: enable
|
|
4
8
|
|
|
9
|
+
Lint/MissingSuper:
|
|
10
|
+
Enabled: false
|
|
11
|
+
|
|
5
12
|
Metrics/AbcSize:
|
|
6
13
|
Exclude:
|
|
7
14
|
- test/**/*.rb
|
|
8
15
|
|
|
16
|
+
Metrics/ClassLength:
|
|
17
|
+
Exclude:
|
|
18
|
+
- test/**/*.rb
|
|
19
|
+
|
|
9
20
|
Metrics/MethodLength:
|
|
10
21
|
Max: 20
|
|
11
22
|
Exclude:
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.7.0] - 2022-09-30
|
|
6
|
+
|
|
7
|
+
- Rearchitect library to be built on top of the Phlex view library
|
|
8
|
+
|
|
9
|
+
## [0.5.0] - 2022-06-10
|
|
10
|
+
|
|
11
|
+
## [0.4.0] - 2022-06-08
|
|
12
|
+
|
|
13
|
+
- Add support for submit buttons
|
|
14
|
+
|
|
15
|
+
## [0.3.0] - 2022-06-08
|
|
16
|
+
|
|
17
|
+
- Add automatic field rendering
|
|
18
|
+
|
|
5
19
|
## [0.2.0] - 2022-05-31
|
|
6
20
|
|
|
7
21
|
- Fields now support content blocks, conditional rendering
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,69 +1,75 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
lifeform (0.
|
|
4
|
+
lifeform (0.7)
|
|
5
5
|
activesupport (>= 6.0)
|
|
6
|
-
|
|
6
|
+
phlex (~> 0.3)
|
|
7
7
|
zeitwerk (~> 2.5)
|
|
8
8
|
|
|
9
9
|
GEM
|
|
10
10
|
remote: https://rubygems.org/
|
|
11
11
|
specs:
|
|
12
|
-
activesupport (7.0.
|
|
12
|
+
activesupport (7.0.4)
|
|
13
13
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
14
14
|
i18n (>= 1.6, < 2)
|
|
15
15
|
minitest (>= 5.1)
|
|
16
16
|
tzinfo (~> 2.0)
|
|
17
|
+
ansi (1.5.0)
|
|
17
18
|
ast (2.4.2)
|
|
18
19
|
backport (1.2.0)
|
|
19
20
|
benchmark (0.2.0)
|
|
21
|
+
builder (3.2.4)
|
|
20
22
|
concurrent-ruby (1.1.10)
|
|
21
23
|
diff-lcs (1.5.0)
|
|
22
24
|
e2mmap (0.1.0)
|
|
23
|
-
|
|
24
|
-
i18n (1.10.0)
|
|
25
|
+
i18n (1.12.0)
|
|
25
26
|
concurrent-ruby (~> 1.0)
|
|
26
27
|
jaro_winkler (1.5.4)
|
|
27
|
-
|
|
28
|
+
json (2.6.2)
|
|
29
|
+
kramdown (2.4.0)
|
|
28
30
|
rexml
|
|
29
31
|
kramdown-parser-gfm (1.1.0)
|
|
30
32
|
kramdown (~> 2.0)
|
|
31
|
-
minitest (5.
|
|
32
|
-
|
|
33
|
+
minitest (5.16.3)
|
|
34
|
+
minitest-reporters (1.5.0)
|
|
35
|
+
ansi
|
|
36
|
+
builder
|
|
37
|
+
minitest (>= 5.0)
|
|
38
|
+
ruby-progressbar
|
|
39
|
+
nokogiri (1.13.8-arm64-darwin)
|
|
33
40
|
racc (~> 1.4)
|
|
34
|
-
nokogiri (1.13.
|
|
41
|
+
nokogiri (1.13.8-x86_64-linux)
|
|
35
42
|
racc (~> 1.4)
|
|
36
|
-
papercraft (0.24)
|
|
37
|
-
escape_utils (~> 1.2.1)
|
|
38
|
-
kramdown (~> 2.3.1)
|
|
39
|
-
kramdown-parser-gfm (~> 1.1.0)
|
|
40
|
-
rouge (~> 3.27.0)
|
|
41
43
|
parallel (1.22.1)
|
|
42
|
-
parser (3.1.2.
|
|
44
|
+
parser (3.1.2.1)
|
|
43
45
|
ast (~> 2.4.1)
|
|
46
|
+
phlex (0.3.1)
|
|
47
|
+
syntax_tree (~> 3.6)
|
|
48
|
+
zeitwerk (~> 2.6)
|
|
49
|
+
prettier_print (0.1.0)
|
|
44
50
|
racc (1.6.0)
|
|
45
51
|
rails-dom-testing (2.0.3)
|
|
46
52
|
activesupport (>= 4.2.0)
|
|
47
53
|
nokogiri (>= 1.6)
|
|
48
54
|
rainbow (3.1.1)
|
|
49
55
|
rake (13.0.6)
|
|
50
|
-
regexp_parser (2.
|
|
56
|
+
regexp_parser (2.6.0)
|
|
51
57
|
reverse_markdown (2.1.1)
|
|
52
58
|
nokogiri
|
|
53
59
|
rexml (3.2.5)
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
rubocop (1.36.0)
|
|
61
|
+
json (~> 2.3)
|
|
56
62
|
parallel (~> 1.10)
|
|
57
|
-
parser (>= 3.1.
|
|
63
|
+
parser (>= 3.1.2.1)
|
|
58
64
|
rainbow (>= 2.2.2, < 4.0)
|
|
59
65
|
regexp_parser (>= 1.8, < 3.0)
|
|
60
66
|
rexml (>= 3.2.5, < 4.0)
|
|
61
|
-
rubocop-ast (>= 1.
|
|
67
|
+
rubocop-ast (>= 1.20.1, < 2.0)
|
|
62
68
|
ruby-progressbar (~> 1.7)
|
|
63
69
|
unicode-display_width (>= 1.4.0, < 3.0)
|
|
64
|
-
rubocop-ast (1.
|
|
70
|
+
rubocop-ast (1.21.0)
|
|
65
71
|
parser (>= 3.1.1.0)
|
|
66
|
-
rubocop-minitest (0.20.
|
|
72
|
+
rubocop-minitest (0.20.1)
|
|
67
73
|
rubocop (>= 0.90, < 2.0)
|
|
68
74
|
rubocop-rake (0.6.0)
|
|
69
75
|
rubocop (~> 1.0)
|
|
@@ -83,15 +89,17 @@ GEM
|
|
|
83
89
|
thor (~> 1.0)
|
|
84
90
|
tilt (~> 2.0)
|
|
85
91
|
yard (~> 0.9, >= 0.9.24)
|
|
92
|
+
syntax_tree (3.6.1)
|
|
93
|
+
prettier_print
|
|
86
94
|
thor (1.2.1)
|
|
87
|
-
tilt (2.0.
|
|
88
|
-
tzinfo (2.0.
|
|
95
|
+
tilt (2.0.11)
|
|
96
|
+
tzinfo (2.0.5)
|
|
89
97
|
concurrent-ruby (~> 1.0)
|
|
90
|
-
unicode-display_width (2.
|
|
98
|
+
unicode-display_width (2.3.0)
|
|
91
99
|
webrick (1.7.0)
|
|
92
|
-
yard (0.9.
|
|
100
|
+
yard (0.9.28)
|
|
93
101
|
webrick (~> 1.7.0)
|
|
94
|
-
zeitwerk (2.
|
|
102
|
+
zeitwerk (2.6.0)
|
|
95
103
|
|
|
96
104
|
PLATFORMS
|
|
97
105
|
arm64-darwin-21
|
|
@@ -100,6 +108,7 @@ PLATFORMS
|
|
|
100
108
|
DEPENDENCIES
|
|
101
109
|
lifeform!
|
|
102
110
|
minitest (~> 5.0)
|
|
111
|
+
minitest-reporters (~> 1.5)
|
|
103
112
|
rails-dom-testing (~> 2.0)
|
|
104
113
|
rake (~> 13.0)
|
|
105
114
|
rubocop (~> 1.21)
|
data/README.md
CHANGED
|
@@ -55,7 +55,7 @@ You get the following HTML output:
|
|
|
55
55
|
|
|
56
56
|
Nested names based on models (aka `profile[name]`) and inferred action paths are supported as well.
|
|
57
57
|
|
|
58
|
-
Multiple component libraries and input types—and easy customizability via [
|
|
58
|
+
Multiple component libraries and input types—and easy customizability via [Phlex](https://github.com/joeldrapper/phlex) templates—are a fundamental aspect of the architecture of Lifeform.
|
|
59
59
|
|
|
60
60
|
### Automatic Field Rendering
|
|
61
61
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lifeform
|
|
4
|
+
module CapturingRenderable
|
|
5
|
+
# NOTE: the previous `with_output_buffer` stuff is for some reason incompatible with Serbea.
|
|
6
|
+
# So we'll use a simpler capture.
|
|
7
|
+
def render_in(view_context, &block)
|
|
8
|
+
if block
|
|
9
|
+
call(view_context: view_context) do |*args, **kwargs|
|
|
10
|
+
raw(view_context.capture(*args, **kwargs, &block))
|
|
11
|
+
end.html_safe
|
|
12
|
+
else
|
|
13
|
+
call(view_context: view_context).html_safe
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/lifeform/form.rb
CHANGED
|
@@ -6,7 +6,8 @@ module Lifeform
|
|
|
6
6
|
FieldDefinition = Struct.new(:type, :library, :parameters)
|
|
7
7
|
|
|
8
8
|
# A form object which stores field definitions and can be rendered as a component
|
|
9
|
-
class Form # rubocop:todo Metrics/ClassLength
|
|
9
|
+
class Form < Phlex::View # rubocop:todo Metrics/ClassLength
|
|
10
|
+
include CapturingRenderable
|
|
10
11
|
MODEL_PATH_HELPER = :polymorphic_path
|
|
11
12
|
|
|
12
13
|
class << self
|
|
@@ -25,46 +26,66 @@ module Lifeform
|
|
|
25
26
|
@fields ||= {}
|
|
26
27
|
end
|
|
27
28
|
|
|
29
|
+
def subforms
|
|
30
|
+
@subforms ||= {}
|
|
31
|
+
end
|
|
32
|
+
|
|
28
33
|
def field(name, type: :text, library: self.library, **parameters)
|
|
29
|
-
parameters[:name] = name
|
|
34
|
+
parameters[:name] = name.to_sym
|
|
30
35
|
fields[name] = FieldDefinition.new(type, Libraries.const_get(library.to_s.classify), parameters)
|
|
31
36
|
end
|
|
32
37
|
|
|
38
|
+
def subform(name, klass, parent_name: nil)
|
|
39
|
+
subforms[name.to_sym] = { class: klass, parent_name: parent_name }
|
|
40
|
+
end
|
|
41
|
+
|
|
33
42
|
def library(library_name = nil)
|
|
34
|
-
@library = library_name if library_name
|
|
43
|
+
@library = library_name.to_sym if library_name
|
|
35
44
|
@library ||= :default
|
|
36
45
|
end
|
|
37
46
|
|
|
38
|
-
def
|
|
47
|
+
def process_value(key, value)
|
|
48
|
+
return value if key == :if
|
|
49
|
+
|
|
39
50
|
case value
|
|
40
|
-
when TrueClass
|
|
41
|
-
|
|
51
|
+
when TrueClass
|
|
52
|
+
key.to_s
|
|
53
|
+
when FalseClass
|
|
54
|
+
nil
|
|
55
|
+
when Symbol, Integer
|
|
56
|
+
value.to_s
|
|
42
57
|
else
|
|
43
|
-
|
|
58
|
+
value
|
|
44
59
|
end
|
|
45
60
|
end
|
|
46
61
|
|
|
47
62
|
# @param kwargs [Hash]
|
|
48
63
|
def parameters_to_attributes(kwargs)
|
|
49
|
-
previous_value = EscapeUtils.html_secure
|
|
50
|
-
EscapeUtils.html_secure = false
|
|
51
|
-
|
|
52
64
|
attributes = {}
|
|
53
65
|
kwargs.each do |key, value|
|
|
54
66
|
case value
|
|
55
67
|
when Hash
|
|
56
68
|
value.each do |inner_key, inner_value|
|
|
57
|
-
attributes[:"#{key}_#{inner_key}"] =
|
|
69
|
+
attributes[:"#{key}_#{inner_key}"] = process_value(inner_key, inner_value)
|
|
58
70
|
end
|
|
59
71
|
else
|
|
60
|
-
attributes[key] =
|
|
72
|
+
attributes[key] = process_value(key, value) unless value.nil?
|
|
61
73
|
end
|
|
62
74
|
end
|
|
63
75
|
|
|
64
|
-
EscapeUtils.html_secure = previous_value
|
|
65
|
-
|
|
66
76
|
attributes
|
|
67
77
|
end
|
|
78
|
+
|
|
79
|
+
def name_of_model(model)
|
|
80
|
+
return "" if model.nil?
|
|
81
|
+
|
|
82
|
+
if model.respond_to?(:to_model)
|
|
83
|
+
model.to_model.model_name.param_key
|
|
84
|
+
else
|
|
85
|
+
# Or just use basic underscore
|
|
86
|
+
model.class.name.underscore.tr("/", "_")
|
|
87
|
+
end
|
|
88
|
+
end
|
|
68
89
|
end
|
|
69
90
|
|
|
70
91
|
# @return [Object]
|
|
@@ -82,9 +103,16 @@ module Lifeform
|
|
|
82
103
|
# @return [Boolean]
|
|
83
104
|
attr_reader :emit_form_tag
|
|
84
105
|
|
|
85
|
-
|
|
86
|
-
|
|
106
|
+
# @return [Boolean]
|
|
107
|
+
attr_reader :parent_name
|
|
108
|
+
|
|
109
|
+
def initialize( # rubocop:disable Metrics/ParameterLists
|
|
110
|
+
model = nil, url: nil, library: self.class.library, emit_form_tag: true, parent_name: nil, **parameters
|
|
111
|
+
)
|
|
112
|
+
@model, @url, @library_name, @parameters, @emit_form_tag, @parent_name =
|
|
113
|
+
model, url, library, parameters, emit_form_tag, parent_name
|
|
87
114
|
@library = Libraries.const_get(@library_name.to_s.classify)
|
|
115
|
+
@subform_instances = {}
|
|
88
116
|
|
|
89
117
|
parameters[:method] ||= model.respond_to?(:persisted?) && model.persisted? ? :patch : :post
|
|
90
118
|
parameters[:accept_charset] ||= "UTF-8"
|
|
@@ -94,20 +122,27 @@ module Lifeform
|
|
|
94
122
|
def verify_method
|
|
95
123
|
return if %w[get post].include?(parameters[:method].to_s.downcase)
|
|
96
124
|
|
|
97
|
-
@method_tag =
|
|
98
|
-
|
|
99
|
-
|
|
125
|
+
@method_tag = Class.new(Phlex::View) do # TODO: break this out into a real component
|
|
126
|
+
def initialize(method:)
|
|
127
|
+
@method = method
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def template
|
|
131
|
+
input type: "hidden", name: "_method", value: @method, autocomplete: "off"
|
|
132
|
+
end
|
|
133
|
+
end.new(method: @parameters[:method].to_s.downcase)
|
|
134
|
+
|
|
100
135
|
parameters[:method] = :post
|
|
101
136
|
end
|
|
102
137
|
|
|
103
|
-
def add_authenticity_token
|
|
104
|
-
if
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
elsif
|
|
110
|
-
|
|
138
|
+
def add_authenticity_token # rubocop:disable Metrics/AbcSize
|
|
139
|
+
if helpers.respond_to?(:token_tag, true) # Rails
|
|
140
|
+
helpers.send(:token_tag, nil, form_options: {
|
|
141
|
+
action: parameters[:action].to_s,
|
|
142
|
+
method: parameters[:method].to_s.downcase
|
|
143
|
+
})
|
|
144
|
+
elsif helpers.respond_to?(:csrf_tag, true) # Roda
|
|
145
|
+
helpers.send(:csrf_tag, action: parameters[:action].to_s, method: parameters[:method].to_s)
|
|
111
146
|
else
|
|
112
147
|
raise Lifeform::Error, "Missing token tag helper. Override `add_authenticity_token' in your Form object"
|
|
113
148
|
end
|
|
@@ -119,7 +154,7 @@ module Lifeform
|
|
|
119
154
|
|
|
120
155
|
def field(name, **field_parameters)
|
|
121
156
|
# @type [FieldDefinition]
|
|
122
|
-
field_definition = self.class.fields[name]
|
|
157
|
+
field_definition = self.class.fields[name.to_sym]
|
|
123
158
|
# @type [Class<Libraries::Default>]
|
|
124
159
|
field_library = field_definition.library
|
|
125
160
|
field_library.object_for_field_definition(
|
|
@@ -127,30 +162,27 @@ module Lifeform
|
|
|
127
162
|
)
|
|
128
163
|
end
|
|
129
164
|
|
|
130
|
-
def
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
self.class.fields.map { |k, _v| field(k).render_in(self) }.join.then do |renderings|
|
|
138
|
-
renderings.respond_to?(:html_safe) ? renderings.html_safe : renderings
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
return content unless emit_form_tag
|
|
165
|
+
def subform(name, model = nil)
|
|
166
|
+
@subform_instances[name.to_sym] ||= self.class.subforms[name.to_sym][:class].new(
|
|
167
|
+
model,
|
|
168
|
+
emit_form_tag: false,
|
|
169
|
+
parent_name: self.class.subforms[name.to_sym][:parent_name] || self.class.name_of_model(self.model)
|
|
170
|
+
)
|
|
171
|
+
end
|
|
143
172
|
|
|
144
|
-
|
|
145
|
-
|
|
173
|
+
def template(&block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
174
|
+
form_tag = library::FORM_TAG
|
|
175
|
+
parameters[:action] ||= url || (model ? helpers.send(self.class.const_get(:MODEL_PATH_HELPER), model) : nil)
|
|
146
176
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
177
|
+
send(form_tag, **attributes) do
|
|
178
|
+
raw(add_authenticity_token) unless parameters[:method].to_s.downcase == "get"
|
|
179
|
+
raw @method_tag&.() || ""
|
|
180
|
+
block ? yield_content(&block) : auto_render_fields
|
|
181
|
+
end
|
|
182
|
+
end
|
|
150
183
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
end.render(attributes)
|
|
184
|
+
def auto_render_fields
|
|
185
|
+
self.class.fields.map { |k, _v| render(field(k)) }
|
|
154
186
|
end
|
|
155
187
|
end
|
|
156
188
|
end
|
|
@@ -3,48 +3,40 @@
|
|
|
3
3
|
module Lifeform
|
|
4
4
|
module Libraries
|
|
5
5
|
class Default
|
|
6
|
-
class Button
|
|
6
|
+
class Button < Phlex::View
|
|
7
|
+
include CapturingRenderable
|
|
8
|
+
|
|
7
9
|
attr_reader :form, :field_definition, :attributes
|
|
8
10
|
|
|
9
11
|
WRAPPER_TAG = :form_button
|
|
10
12
|
BUTTON_TAG = :button
|
|
11
13
|
|
|
14
|
+
register_element WRAPPER_TAG
|
|
15
|
+
|
|
12
16
|
def initialize(form, field_definition, **attributes)
|
|
13
17
|
@form = form
|
|
14
18
|
@field_definition = field_definition
|
|
15
19
|
@attributes = Lifeform::Form.parameters_to_attributes(field_definition.parameters).merge(attributes)
|
|
16
20
|
@if = @attributes.delete(:if)
|
|
17
21
|
@label = @attributes.delete(:label) || "Unlabeled Button"
|
|
18
|
-
@attributes[:type] ||=
|
|
22
|
+
@attributes[:type] ||= "button"
|
|
19
23
|
end
|
|
20
24
|
|
|
21
|
-
def
|
|
22
|
-
|
|
23
|
-
@content = block
|
|
24
|
-
return "" if !@if.nil? && !@if
|
|
25
|
+
def template(&block)
|
|
26
|
+
return if !@if.nil? && !@if
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
wrapper_tag = self.class.const_get(:WRAPPER_TAG)
|
|
29
|
+
button_tag = self.class.const_get(:BUTTON_TAG)
|
|
30
|
+
|
|
31
|
+
field_body = proc {
|
|
32
|
+
send(button_tag, **@attributes) do
|
|
33
|
+
raw(@label.to_s) unless block
|
|
34
|
+
yield_content(&block)
|
|
35
|
+
end
|
|
36
|
+
}
|
|
37
|
+
return field_body.() unless wrapper_tag
|
|
28
38
|
|
|
29
|
-
|
|
30
|
-
Papercraft.html do |wrapper_tag:, button_tag:, attributes:, field_data:|
|
|
31
|
-
field_body = proc {
|
|
32
|
-
send(button_tag, **attributes) do
|
|
33
|
-
emit field_data[:content] || field_data[:label]
|
|
34
|
-
end
|
|
35
|
-
}
|
|
36
|
-
next field_body.call unless wrapper_tag
|
|
37
|
-
|
|
38
|
-
send wrapper_tag, name: attributes[:name], &field_body
|
|
39
|
-
end.render(
|
|
40
|
-
wrapper_tag: self.class.const_get(:WRAPPER_TAG),
|
|
41
|
-
button_tag: self.class.const_get(:BUTTON_TAG),
|
|
42
|
-
attributes: attributes,
|
|
43
|
-
field_data: {
|
|
44
|
-
label: @label,
|
|
45
|
-
content: @content && @view_context.capture(&@content)
|
|
46
|
-
}
|
|
47
|
-
)
|
|
39
|
+
send wrapper_tag, name: @attributes[:name], &field_body
|
|
48
40
|
end
|
|
49
41
|
end
|
|
50
42
|
end
|
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
module Lifeform
|
|
4
4
|
module Libraries
|
|
5
5
|
class Default
|
|
6
|
-
class Input
|
|
6
|
+
class Input < Phlex::View
|
|
7
|
+
include CapturingRenderable
|
|
8
|
+
|
|
7
9
|
attr_reader :form, :field_definition, :attributes
|
|
8
10
|
|
|
9
|
-
INPUT_TAG = :input
|
|
10
11
|
WRAPPER_TAG = :form_field
|
|
12
|
+
INPUT_TAG = :input
|
|
13
|
+
|
|
14
|
+
register_element WRAPPER_TAG
|
|
11
15
|
|
|
12
16
|
def initialize(form, field_definition, **attributes)
|
|
13
17
|
@form = form
|
|
@@ -30,10 +34,9 @@ module Lifeform
|
|
|
30
34
|
end
|
|
31
35
|
|
|
32
36
|
def model_name
|
|
33
|
-
|
|
37
|
+
name_of_model = @form.class.name_of_model(@model)
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
@model.class.name.underscore.tr("/", "_")
|
|
39
|
+
form.parent_name ? "#{form.parent_name}[#{name_of_model}]" : name_of_model
|
|
37
40
|
end
|
|
38
41
|
|
|
39
42
|
def value_for_model
|
|
@@ -41,44 +44,30 @@ module Lifeform
|
|
|
41
44
|
end
|
|
42
45
|
|
|
43
46
|
def handle_labels
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
end.render(
|
|
47
|
-
attributes[:label].to_s,
|
|
48
|
-
(attributes[:id] || attributes[:name]).to_s
|
|
49
|
-
).tap do
|
|
50
|
-
@attributes = attributes.filter_map { |k, v| [k, v] unless k == :label }.to_h
|
|
51
|
-
end
|
|
52
|
-
end
|
|
47
|
+
label_text = attributes[:label].to_s
|
|
48
|
+
label_name = (attributes[:id] || attributes[:name]).to_s
|
|
53
49
|
|
|
54
|
-
|
|
55
|
-
@view_context = view_context
|
|
56
|
-
@content = block
|
|
57
|
-
return "" if !@if.nil? && !@if
|
|
50
|
+
@attributes = attributes.filter_map { |k, v| [k, v] unless k == :label }.to_h
|
|
58
51
|
|
|
59
|
-
|
|
52
|
+
proc {
|
|
53
|
+
label(for: label_name) { raw label_text }
|
|
54
|
+
}
|
|
60
55
|
end
|
|
61
56
|
|
|
62
|
-
def template
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
field_data: {
|
|
77
|
-
type: @field_type,
|
|
78
|
-
label: @label,
|
|
79
|
-
content: @content && @view_context.capture(&@content)
|
|
80
|
-
}
|
|
81
|
-
)
|
|
57
|
+
def template(&block)
|
|
58
|
+
return if !@if.nil? && !@if
|
|
59
|
+
|
|
60
|
+
wrapper_tag = self.class.const_get(:WRAPPER_TAG)
|
|
61
|
+
input_tag = self.class.const_get(:INPUT_TAG)
|
|
62
|
+
|
|
63
|
+
field_body = proc {
|
|
64
|
+
@label&.()
|
|
65
|
+
send input_tag, type: @field_type.to_s, **@attributes
|
|
66
|
+
yield_content(&block)
|
|
67
|
+
}
|
|
68
|
+
return field_body.() unless wrapper_tag
|
|
69
|
+
|
|
70
|
+
send wrapper_tag, name: @attributes[:name], &field_body
|
|
82
71
|
end
|
|
83
72
|
end
|
|
84
73
|
end
|
data/lib/lifeform/version.rb
CHANGED
data/lib/lifeform.rb
CHANGED
data/lifeform.gemspec
CHANGED
|
@@ -25,6 +25,6 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
|
|
26
26
|
# Uncomment to register a new dependency of your gem
|
|
27
27
|
spec.add_dependency "activesupport", ">= 6.0"
|
|
28
|
-
spec.add_dependency "
|
|
28
|
+
spec.add_dependency "phlex", "~> 0.3"
|
|
29
29
|
spec.add_dependency "zeitwerk", "~> 2.5"
|
|
30
30
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lifeform
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: '0.7'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bridgetown Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-09-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -25,19 +25,19 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '6.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: phlex
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0.
|
|
33
|
+
version: '0.3'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0.
|
|
40
|
+
version: '0.3'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: zeitwerk
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -72,6 +72,7 @@ files:
|
|
|
72
72
|
- bin/rubocop
|
|
73
73
|
- bin/setup
|
|
74
74
|
- lib/lifeform.rb
|
|
75
|
+
- lib/lifeform/capturing_renderable.rb
|
|
75
76
|
- lib/lifeform/form.rb
|
|
76
77
|
- lib/lifeform/libraries/default.rb
|
|
77
78
|
- lib/lifeform/libraries/default/button.rb
|