lifeform 0.1.0 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db20cd6cdb2581c3943d46e325a07a30ac89581cb6d29c1fd8297aab9663f202
4
- data.tar.gz: ccd569f076822e5df6eecee26021b4a2f7044d5d91721f6b3523c6944bb64bfa
3
+ metadata.gz: 6f1e91a0e3977e9c1ee9bf2fadc00d427efa8f7fcf720ba0670905832e89e41c
4
+ data.tar.gz: 458c2edd232353260115c6eb794ebfcc7298696723e3ec5f49518ed8ccb68e19
5
5
  SHA512:
6
- metadata.gz: 6d71ebf92fb482bdb9d34bb8ace8f1fae6625a191d6595fc73c0b144b11ab94f8d3352b2c03d43b9f4de64c9c67bace0ba6f40898d8165592132786dd25757b5
7
- data.tar.gz: 800dbc481b4860d53c71b420cdb28da5b32d9781aecbe901ed75e1b8bfc36d1c6b626d504bfa377b68ceaff58158b47cead59406be31a1beb3a88fafd1cfbe17
6
+ metadata.gz: f8c0c7b398b5375cc50f0fb9d59ad5f759dcd05cd355fba4ed8c24c6c1e3e11c2447d888592f0c2ccb799a596bdfc23902fd822bd397cbf731c2ef77f453effc
7
+ data.tar.gz: e96679b59c1abae814f740ba190659eb29a4bae5c1fcc8809bff3336b138b13aded6f87d5bf0a2522ec86de80f8c98c1586eb8fcb81986edd242093294c0d1b0
data/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.2.0] - 2022-05-31
6
+
7
+ - Fields now support content blocks, conditional rendering
8
+ - Form subclass will now inherit parent form library
9
+
5
10
  ## [0.1.0] - 2022-05-29
6
11
 
7
12
  - Initial release
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lifeform (0.1.0)
4
+ lifeform (0.4.0)
5
5
  activesupport (>= 6.0)
6
6
  papercraft (~> 0.24)
7
7
  zeitwerk (~> 2.5)
@@ -31,6 +31,8 @@ GEM
31
31
  minitest (5.15.0)
32
32
  nokogiri (1.13.6-arm64-darwin)
33
33
  racc (~> 1.4)
34
+ nokogiri (1.13.6-x86_64-linux)
35
+ racc (~> 1.4)
34
36
  papercraft (0.24)
35
37
  escape_utils (~> 1.2.1)
36
38
  kramdown (~> 2.3.1)
@@ -93,6 +95,7 @@ GEM
93
95
 
94
96
  PLATFORMS
95
97
  arm64-darwin-21
98
+ x86_64-linux
96
99
 
97
100
  DEPENDENCIES
98
101
  lifeform!
data/README.md CHANGED
@@ -12,7 +12,60 @@ $ bundle add lifeform
12
12
 
13
13
  ## Usage
14
14
 
15
- TODO: Write usage instructions here
15
+ Full documentation coming as the library begins to mature. TL;DR:
16
+
17
+ Given a form object of:
18
+
19
+ ```rb
20
+ class TestForm < Lifeform::Form
21
+ field :occupation, label: "Your Job", id: "your-occupation", required: true
22
+ field :age, library: :shoelace, label: "Your Age"
23
+
24
+ field :submit, type: :submit_button, label: "Save", class: "font-bold"
25
+ end
26
+ ```
27
+
28
+ And a template rendering of:
29
+
30
+ ```erb
31
+ <%= render TestForm.new(url: "/path") do %>
32
+ <%= render f.field(:occupation) %>
33
+ <%= render f.field(:age, value: 47) %>
34
+ <%= render f.field(:submit) %>
35
+ <% end %>
36
+ ```
37
+
38
+ You get the following HTML output:
39
+
40
+ ```html
41
+ <form method="post" accept-charset="UTF-8" action="/path">
42
+ <input type="hidden" name="authenticity_token" value="[token]" />
43
+ <form-field name="occupation">
44
+ <label for="your-occupation">Your Job</label>
45
+ <input type="text" id="your-occupation" required name="occupation" />
46
+ </form-field>
47
+ <form-field name="age">
48
+ <sl-input type="text" label="Your Age" name="age" value="47" id="age"></sl-input>
49
+ </form-field>
50
+ <form-button name="commit">
51
+ <button class="font-bold" name="commit" type="submit">Save</button>
52
+ </form-button>
53
+ </form>
54
+ ```
55
+
56
+ Nested names based on models (aka `profile[name]`) and inferred action paths are supported as well.
57
+
58
+ Multiple component libraries and input types—and easy customizability via [Papercraft](https://github.com/digital-fabric/papercraft) templates—are a fundamental aspect of the architecture of Lifeform.
59
+
60
+ ### Automatic Field Rendering
61
+
62
+ For simple forms, you can avoid the need to render fields individually in your template. Given the form example above, you could write in your template:
63
+
64
+ ```erb
65
+ <%= render TestForm.new(url: "/path") %>
66
+ ```
67
+
68
+ And the fields defined in `TestForm` would render out automatically (since no block was provided to the `render` method).
16
69
 
17
70
  ## Development
18
71
 
data/lib/lifeform/form.rb CHANGED
@@ -10,6 +10,11 @@ module Lifeform
10
10
  MODEL_PATH_HELPER = :polymorphic_path
11
11
 
12
12
  class << self
13
+ def inherited(subclass)
14
+ super
15
+ subclass.library library
16
+ end
17
+
13
18
  # Helper to point to `I18n.t` method
14
19
  def t(...)
15
20
  I18n.t(...)
@@ -26,7 +31,8 @@ module Lifeform
26
31
  end
27
32
 
28
33
  def library(library_name = nil)
29
- @library ||= library_name || :default
34
+ @library = library_name if library_name
35
+ @library ||= :default
30
36
  end
31
37
 
32
38
  def escape_value(value)
@@ -112,17 +118,24 @@ module Lifeform
112
118
  end
113
119
 
114
120
  def field(name, **field_parameters)
121
+ # @type [FieldDefinition]
115
122
  field_definition = self.class.fields[name]
116
- field_definition.library.object_for_field_definition(
123
+ # @type [Class<Libraries::Default>]
124
+ field_library = field_definition.library
125
+ field_library.object_for_field_definition(
117
126
  self, field_definition, self.class.parameters_to_attributes(field_parameters)
118
127
  )
119
128
  end
120
129
 
121
- def render_in(view_context, &block) # rubocop:disable Metrics/AbcSize
130
+ def render_in(view_context, &block) # rubocop:disable Metrics
122
131
  form_tag = library::FORM_TAG
123
132
  parameters[:action] ||= url || (model ? view_context.send(self.class.const_get(:MODEL_PATH_HELPER), model) : nil)
124
133
 
125
- content = view_context.capture(self, &block)
134
+ content = if block
135
+ view_context.capture(self, &block)
136
+ else
137
+ self.class.fields.map { |k, _v| field(k).render_in(self) }.join
138
+ end
126
139
 
127
140
  return content unless emit_form_tag
128
141
 
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lifeform
4
+ module Libraries
5
+ class Default
6
+ class Button
7
+ attr_reader :form, :field_definition, :attributes
8
+
9
+ WRAPPER_TAG = :form_button
10
+ BUTTON_TAG = :button
11
+
12
+ def initialize(form, field_definition, **attributes)
13
+ @form = form
14
+ @field_definition = field_definition
15
+ @attributes = Lifeform::Form.parameters_to_attributes(field_definition.parameters).merge(attributes)
16
+ @if = @attributes.delete(:if)
17
+ @label = @attributes.delete(:label) || "Unlabeled Button"
18
+ @attributes[:type] ||= :button
19
+ end
20
+
21
+ def render_in(view_context, &block)
22
+ @view_context = view_context
23
+ @content = block
24
+ return "" if !@if.nil? && !@if
25
+
26
+ template
27
+ end
28
+
29
+ def template # rubocop:disable Metrics/AbcSize
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
+ )
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -22,6 +22,7 @@ module Lifeform
22
22
  @model = attributes.delete(:model)
23
23
  @model = form.model if form.model && @model.nil?
24
24
 
25
+ @if = attributes.delete(:if)
25
26
  attributes[:value] ||= value_for_model if form.model
26
27
  attributes[:name] = "#{model_name}[#{attributes[:name]}]" if @model
27
28
  attributes[:id] ||= attributes[:name].parameterize(separator: "_")
@@ -50,16 +51,20 @@ module Lifeform
50
51
  end
51
52
  end
52
53
 
53
- def render_in(view_context)
54
+ def render_in(view_context, &block)
54
55
  @view_context = view_context
56
+ @content = block
57
+ return "" if !@if.nil? && !@if
58
+
55
59
  template
56
60
  end
57
61
 
58
- def template
59
- Papercraft.html do |wrapper_tag:, input_tag:, attributes:, field_type:, field_label:|
62
+ def template # rubocop:disable Metrics/AbcSize
63
+ Papercraft.html do |wrapper_tag:, input_tag:, attributes:, field_data:|
60
64
  field_body = proc {
61
- emit(field_label) if field_label
62
- send input_tag, type: field_type, **attributes
65
+ emit(field_data[:label]) if field_data[:label]
66
+ send input_tag, type: field_data[:type], **attributes
67
+ emit(field_data[:content]) if field_data[:content]
63
68
  }
64
69
  next field_body.call unless wrapper_tag
65
70
 
@@ -68,8 +73,11 @@ module Lifeform
68
73
  wrapper_tag: self.class.const_get(:WRAPPER_TAG),
69
74
  input_tag: self.class.const_get(:INPUT_TAG),
70
75
  attributes: attributes,
71
- field_type: @field_type,
72
- field_label: @label
76
+ field_data: {
77
+ type: @field_type,
78
+ label: @label,
79
+ content: @content && @view_context.capture(&@content)
80
+ }
73
81
  )
74
82
  end
75
83
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lifeform
4
+ module Libraries
5
+ class Default
6
+ class SubmitButton < Button
7
+ def initialize(form, field_definition, **attributes)
8
+ attributes[:name] ||= "commit"
9
+ attributes[:type] = :submit
10
+
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -5,6 +5,9 @@ module Lifeform
5
5
  class Default
6
6
  FORM_TAG = :form
7
7
 
8
+ # @param form [LifeForm::Form]
9
+ # @param field_definition [LifeForm::FieldDefinition]
10
+ # @param attributes [Hash]
8
11
  # @return [Input]
9
12
  def self.object_for_field_definition(form, field_definition, attributes)
10
13
  type_classname = field_definition[:type].to_s.classify
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lifeform
4
- VERSION = "0.1.0"
4
+ VERSION = "0.4.0"
5
5
  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.1.0
4
+ version: 0.4.0
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-05-30 00:00:00.000000000 Z
11
+ date: 2022-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -74,7 +74,9 @@ files:
74
74
  - lib/lifeform.rb
75
75
  - lib/lifeform/form.rb
76
76
  - lib/lifeform/libraries/default.rb
77
+ - lib/lifeform/libraries/default/button.rb
77
78
  - lib/lifeform/libraries/default/input.rb
79
+ - lib/lifeform/libraries/default/submit_button.rb
78
80
  - lib/lifeform/libraries/shoelace.rb
79
81
  - lib/lifeform/libraries/shoelace/input.rb
80
82
  - lib/lifeform/version.rb