action_component 0.1.2 → 0.1.3

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
  SHA1:
3
- metadata.gz: c40a85133d9515f6130d1ef47ae902ca393dd071
4
- data.tar.gz: 7aab855f6a751caad576ab268505ef2acec1053a
3
+ metadata.gz: 2f33f7082a98706e560055f13359cde3c1047221
4
+ data.tar.gz: 71e05e1a88e06f812e0d8323713f71aaacea3f8f
5
5
  SHA512:
6
- metadata.gz: e8c35cfee98e7bb48b6f11d7b947ed51a6a04d4afed3cf38fa59d0c141258c7afd5bf09e27b0ce9ee02ecbbc36e6c6db4b0bc4af28cdea3b9499da9944778d97
7
- data.tar.gz: f2f6ae0fd3847fab3bccf2ac74a3456e9191f94aa6b9e9084a7cee1a98ca70239f307a55c1fba5aa0412a14c547ef9d4e21af1bc5033545ee26f0d37a57c2be9
6
+ metadata.gz: 73fb3c94cb8d6545196a41a63e75714e6bae851dbadf239ffa9b65c6a8bee22b2a73d0fed95d803be963d8028bf02fb42d2d00a8fc199074993feb9ded023879
7
+ data.tar.gz: 8152c4885c00c68a1dc7bb4fd99349b425350a7992a472925435e802ba8348543ea7fae7e5a76d7d7656a9a6eaee24893f9bc4b9348ca7b51b79aa1ebce68bce
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- action_component (0.1.2)
4
+ action_component (0.1.3)
5
5
  actionpack (>= 4, < 6)
6
6
  activesupport (>= 4, < 6)
7
7
  railties (>= 4, < 6)
data/README.md CHANGED
@@ -86,6 +86,10 @@ class PostComponent < ActionComponent::Base
86
86
  div(class: 'post') do
87
87
  h2 @post.title
88
88
 
89
+ # This renders a div with a class of 'published-at'
90
+ # Note the underscore has been replaced with a dash.
91
+ e.div.published_at "Published at #{l @post.published_at}"
92
+
89
93
  component AuthorComponent, author: @post.author
90
94
 
91
95
  insert simple_format(@post.content)
@@ -97,7 +101,7 @@ end
97
101
  ## More documentation to come
98
102
 
99
103
  ActionComponent is new. It works just fine, but at the moment if you need more information than is given above,
100
- please dive into the (very small) codebase to learn more.
104
+ please dive into the (small) codebase to learn more.
101
105
 
102
106
  ## Contributing
103
107
 
@@ -3,10 +3,19 @@ end
3
3
 
4
4
  require 'action_component/version'
5
5
 
6
+ # Rails integration
7
+
6
8
  require 'action_component/action_controller_rendering'
7
9
  require 'action_component/action_view_rendering'
10
+ require 'action_component/railtie'
11
+
12
+ # Base dependencies
13
+
14
+ require 'action_component/callbacks'
8
15
  require 'action_component/constraints'
9
16
  require 'action_component/elements'
17
+ require 'action_component/element_builder'
18
+
19
+ # Base
10
20
 
11
21
  require 'action_component/base'
12
- require 'action_component/railtie'
@@ -8,13 +8,14 @@ module ActionComponent
8
8
  class Base
9
9
  include ActionComponent::Constraints
10
10
  include ActionComponent::Elements
11
+ prepend ActionComponent::Callbacks
11
12
 
12
13
  delegate :concat, to: :@_view
13
14
 
14
15
  def self.render(view, opts = {})
15
16
  component = new(view, opts)
16
17
  component.load
17
- component.view
18
+ component.render_view
18
19
  nil
19
20
  end
20
21
 
@@ -35,6 +36,10 @@ module ActionComponent
35
36
  raise ActionComponent::ViewMissingError, "#{self.class.name} must define a view method to be a valid component"
36
37
  end
37
38
 
39
+ def render_view
40
+ view
41
+ end
42
+
38
43
  private
39
44
 
40
45
  def method_missing(method, *args, &block)
@@ -0,0 +1,29 @@
1
+ module ActionComponent
2
+ module Callbacks
3
+ def self.prepended(base)
4
+ base.class_attribute :before_render_callback_methods, :after_render_callback_methods
5
+
6
+ base.before_render_callback_methods = []
7
+ base.after_render_callback_methods = []
8
+
9
+ base.extend ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ def before_render(*methods)
14
+ self.before_render_callback_methods += methods
15
+ end
16
+
17
+ def after_render(*methods)
18
+ self.after_render_callback_methods += methods
19
+ end
20
+ end
21
+
22
+ def render_view
23
+ before_render_callback_methods.each { |method| send(method) }
24
+ result = super
25
+ after_render_callback_methods.each { |method| send(method) }
26
+ result
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,64 @@
1
+ module ActionComponent
2
+ class ElementBuilder
3
+ def initialize(base, element_name = nil, classes = nil, id = nil)
4
+ @base = base
5
+ @element_name = element_name
6
+ @classes = classes
7
+ @id = id
8
+ end
9
+
10
+ def method_missing(method, *args, &block)
11
+ element_name = @element_name
12
+ classes = @classes
13
+ id = @id
14
+
15
+ command = method.to_s
16
+
17
+ command = command[-1] == '?' ? command[0..-2] : command.gsub('_', '-')
18
+
19
+ if element_name
20
+ if command[-1] == '!'
21
+ id = command[0..-2]
22
+ else
23
+ classes = classes ? "#{classes} #{command}" : command
24
+ end
25
+ else
26
+ element_name = command
27
+ end
28
+
29
+ if !args.empty? || block
30
+ first, second = args
31
+
32
+ if second.is_a?(Hash)
33
+ build_options(classes, id, second)
34
+ elsif first.is_a?(Hash)
35
+ build_options(classes, id, first)
36
+ elsif first
37
+ second = build_options(classes, id)
38
+ else
39
+ first = build_options(classes, id)
40
+ end
41
+
42
+ @base.send(:element, element_name, first, second, &block)
43
+ else
44
+ self.class.new(@base, element_name, classes, id)
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def build_options(classes, id, options = {})
51
+ if classes
52
+ if options[:class]
53
+ options[:class] = "#{options[:class]} #{classes}"
54
+ else
55
+ options[:class] = classes
56
+ end
57
+ end
58
+
59
+ options[:id] = id if id
60
+
61
+ options
62
+ end
63
+ end
64
+ end
@@ -66,5 +66,9 @@ module ActionComponent
66
66
 
67
67
  nil
68
68
  end
69
+
70
+ def e
71
+ ElementBuilder.new(self)
72
+ end
69
73
  end
70
74
  end
@@ -1,3 +1,3 @@
1
1
  module ActionComponent
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -10,7 +10,7 @@ RSpec.describe ActionComponent::Base do
10
10
  it "makes a new component, then calls load and view, returning nil" do
11
11
  component = instance_double(ActionComponent::Base)
12
12
  expect(component).to receive(:load).ordered
13
- expect(component).to receive(:view).ordered
13
+ expect(component).to receive(:render_view).ordered
14
14
 
15
15
  expect(ActionComponent::Base).to receive(:new)
16
16
  .with(view, {option: 'value'})
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ActionComponent::Callbacks do
4
+ class FakeComponent
5
+ prepend ActionComponent::Callbacks
6
+
7
+ before_render :test1
8
+ before_render :test2
9
+ after_render :test3
10
+
11
+ def test1
12
+ end
13
+
14
+ def test2
15
+ end
16
+
17
+ def test3
18
+ end
19
+
20
+ def view
21
+ end
22
+
23
+ def render_view
24
+ view
25
+ end
26
+ end
27
+
28
+ subject { FakeComponent.new }
29
+
30
+ it "calls the before and after callbacks" do
31
+ expect(subject).to receive(:test1).ordered
32
+ expect(subject).to receive(:test2).ordered
33
+ expect(subject).to receive(:view).ordered.and_return('result')
34
+ expect(subject).to receive(:test3).ordered
35
+
36
+ expect(subject.render_view).to eq 'result'
37
+ end
38
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ActionComponent::ElementBuilder do
4
+ class FakeBase
5
+ def element(*args, &block)
6
+ [*args, block]
7
+ end
8
+ end
9
+
10
+ let(:base) { FakeBase.new }
11
+
12
+ subject { ActionComponent::ElementBuilder.new(base) }
13
+
14
+ it "builds a simple element" do
15
+ expect(subject.simple("test")).to eq ['simple', 'test', {}, nil]
16
+ end
17
+
18
+ it "builds an element with a class" do
19
+ expect(subject.simple.blue("test")).to eq ['simple', 'test', {class: 'blue'}, nil]
20
+ end
21
+
22
+ it "builds an element with two classes" do
23
+ expect(subject.simple.blue.loud("test")).to eq ['simple', 'test', {class: 'blue loud'}, nil]
24
+ end
25
+
26
+ it "builds an element with an id" do
27
+ expect(subject.simple.blue!("test")).to eq ['simple', 'test', {id: 'blue'}, nil]
28
+ end
29
+
30
+ it "converts underscores to dashes" do
31
+ expect(subject.simple.strong_blue("test")).to eq ['simple', 'test', {class: 'strong-blue'}, nil]
32
+ end
33
+
34
+ it "does not convert underscores to dashes if the method ends in a ?" do
35
+ expect(subject.simple.strong_blue?("test")).to eq ['simple', 'test', {class: 'strong_blue'}, nil]
36
+ end
37
+
38
+ it "merges classes with ones specified in the hash" do
39
+ expect(subject.simple.blue("test", testy: "very", class: "strong")).to eq ['simple', 'test', {testy: "very", class: 'strong blue'}, nil]
40
+ end
41
+
42
+ it "passes just a block" do
43
+ block = -> {}
44
+
45
+ expect(subject.simple.blue(&block)).to eq ['simple', {class: 'blue'}, nil, block]
46
+ end
47
+
48
+ it "passes a block with a hash" do
49
+ block = -> {}
50
+
51
+ expect(subject.simple.blue(testy: "very", &block)).to eq ['simple', {testy: "very", class: 'blue'}, nil, block]
52
+ end
53
+ end
@@ -121,4 +121,10 @@ RSpec.describe ActionComponent::Elements do
121
121
  end
122
122
  end
123
123
  end
124
+
125
+ describe "#e" do
126
+ it "returns an ElementBuilder" do
127
+ expect(subject.send(:e)).to be_a ActionComponent::ElementBuilder
128
+ end
129
+ end
124
130
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_component
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roger Nesbitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-29 00:00:00.000000000 Z
11
+ date: 2016-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -102,12 +102,16 @@ files:
102
102
  - lib/action_component/action_controller_rendering.rb
103
103
  - lib/action_component/action_view_rendering.rb
104
104
  - lib/action_component/base.rb
105
+ - lib/action_component/callbacks.rb
105
106
  - lib/action_component/constraints.rb
107
+ - lib/action_component/element_builder.rb
106
108
  - lib/action_component/elements.rb
107
109
  - lib/action_component/railtie.rb
108
110
  - lib/action_component/version.rb
109
111
  - spec/action_component/base_spec.rb
112
+ - spec/action_component/callbacks_spec.rb
110
113
  - spec/action_component/constraints_spec.rb
114
+ - spec/action_component/element_builder_spec.rb
111
115
  - spec/action_component/elements_spec.rb
112
116
  - spec/fake_view.rb
113
117
  - spec/spec_helper.rb
@@ -137,7 +141,9 @@ specification_version: 4
137
141
  summary: React-style components for Rails
138
142
  test_files:
139
143
  - spec/action_component/base_spec.rb
144
+ - spec/action_component/callbacks_spec.rb
140
145
  - spec/action_component/constraints_spec.rb
146
+ - spec/action_component/element_builder_spec.rb
141
147
  - spec/action_component/elements_spec.rb
142
148
  - spec/fake_view.rb
143
149
  - spec/spec_helper.rb