lite-component 1.0.1 → 1.0.2

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.
@@ -2,7 +2,22 @@
2
2
 
3
3
  module Lite
4
4
  module Component
5
- class Base < Lite::Component::Element
5
+ class Base
6
+
7
+ include ActionView::Context
8
+ include ActionView::Helpers
9
+
10
+ attr_reader :context, :options
11
+ attr_writer :iteration
12
+
13
+ def initialize(context, options = {})
14
+ @context = context
15
+ @options = default_options.deep_merge(options)
16
+ end
17
+
18
+ alias helpers context
19
+ alias c context
20
+ alias h helpers
6
21
 
7
22
  class << self
8
23
 
@@ -11,21 +26,59 @@ module Lite
11
26
  end
12
27
 
13
28
  def component_path
14
- name.chomp('Component').underscore
29
+ name.underscore.sub('_component', '')
15
30
  end
16
31
 
17
- def model_name
18
- ActiveModel::Name.new(Lite::Component::Base)
32
+ def render(context, options = {})
33
+ klass = new(context, options)
34
+ klass.render
19
35
  end
20
36
 
21
37
  end
22
38
 
39
+ def iteration
40
+ @iteration ||= Lite::Component::Iteration.new(1, 0)
41
+ end
42
+
43
+ alias i iteration
44
+
45
+ def locals
46
+ @locals ||= Lite::Component::Locals.new(options[:locals])
47
+ end
48
+
49
+ alias l locals
50
+
23
51
  def render
24
- context.render(partial: to_partial_path, object: self)
52
+ collection = options.delete(:collection)
53
+ return render_content if collection.nil? || !collection.respond_to?(:to_a)
54
+
55
+ Lite::Component::Collection.render(
56
+ collection,
57
+ component: self,
58
+ spacer_template: options.delete(:spacer_template)
59
+ )
60
+ end
61
+
62
+ def render_content
63
+ context.render(options)
25
64
  end
26
65
 
27
66
  def to_partial_path
28
- "components/#{self.class.component_path}"
67
+ "components/#{self.class.component_name}"
68
+ end
69
+
70
+ private
71
+
72
+ def default_options
73
+ {
74
+ partial: to_partial_path,
75
+ object: self,
76
+ as: :component,
77
+ locals: {
78
+ object: nil,
79
+ iteration: iteration
80
+ }
81
+ }
29
82
  end
30
83
 
31
84
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lite
4
+ module Component
5
+ class Collection
6
+
7
+ attr_reader :collection, :component, :spacer_template
8
+
9
+ def initialize(collection, component:, spacer_template: nil)
10
+ @collection = collection
11
+ @component = component
12
+ @spacer_template = spacer_template
13
+ end
14
+
15
+ class << self
16
+
17
+ def render(collection, component)
18
+ klass = new(collection, component)
19
+ klass.render
20
+ end
21
+
22
+ end
23
+
24
+ def render
25
+ component.context.safe_join(iterated_collection)
26
+ end
27
+
28
+ private
29
+
30
+ def collection_size
31
+ @collection_size ||= collection.size
32
+ end
33
+
34
+ # rubocop:disable Metrics/AbcSize
35
+ def iterated_collection
36
+ collection.each_with_object([]).with_index do |(object, array), index|
37
+ component.iteration = Lite::Component::Iteration.new(collection_size, index)
38
+ component.options.deep_merge!(locals: { object: object, iteration: component.iteration })
39
+
40
+ array << component.render_content
41
+ next unless spacer_template && !component.iteration.last?
42
+
43
+ array << component.context.render(spacer_template)
44
+ end
45
+ end
46
+ # rubocop:enable Metrics/AbcSize
47
+
48
+ end
49
+ end
50
+ end
@@ -8,17 +8,6 @@ module Lite
8
8
 
9
9
  initializer('lite-component.setup', group: :all) do |app|
10
10
  app.paths['config'] << File.join(config.root, 'app')
11
- app.paths['config'] << File.join(config.root, 'vendor')
12
- end
13
-
14
- initializer('lite-component.asset_path') do |app|
15
- app.config.assets.paths << Lite::Component.path if app.config.respond_to?(:assets)
16
- end
17
-
18
- initializer('lite-component.view_paths') do
19
- ActiveSupport.on_load(:action_controller) do
20
- append_view_path Lite::Component.path
21
- end
22
11
  end
23
12
 
24
13
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lite
4
+ module Component
5
+ class Iteration
6
+
7
+ attr_reader :index, :size
8
+
9
+ def initialize(size, index)
10
+ @size = size
11
+ @index = index
12
+ end
13
+
14
+ def first?
15
+ index.zero?
16
+ end
17
+
18
+ def last?
19
+ index == (size - 1)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lite
4
+ module Component
5
+ class Locals
6
+
7
+ attr_reader :locals
8
+
9
+ def initialize(locals)
10
+ @locals = (locals || {}).symbolize_keys
11
+ end
12
+
13
+ private
14
+
15
+ def method_missing(method_name, *arguments, &block)
16
+ if locals.key?(method_name)
17
+ locals[method_name]
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ def respond_to_missing?(method_name, include_private = false)
24
+ locals.key?(method_name) || super
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -3,7 +3,7 @@
3
3
  module Lite
4
4
  module Component
5
5
 
6
- VERSION ||= '1.0.1'
6
+ VERSION ||= '1.0.2'
7
7
 
8
8
  end
9
9
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- %w[version errors application engine element base].each do |filename|
3
+ %w[version engine iteration collection locals base].each do |filename|
4
4
  require "lite/component/#{filename}"
5
5
  end
6
6
 
7
- require 'generators/component_generator'
7
+ require 'generators/rails/component_generator'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lite-component
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Gomez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-13 00:00:00.000000000 Z
11
+ date: 2019-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -159,20 +159,19 @@ files:
159
159
  - app/helpers/lite/component/component_helper.rb
160
160
  - bin/console
161
161
  - bin/setup
162
- - lib/generators/component_generator.rb
163
- - lib/generators/templates/install.js
164
- - lib/generators/templates/install.rb.erb
165
- - lib/generators/templates/install.scss
162
+ - lib/generators/rails/USAGE
163
+ - lib/generators/rails/component_generator.rb
164
+ - lib/generators/rails/templates/install.js
165
+ - lib/generators/rails/templates/install.rb.erb
166
+ - lib/generators/rails/templates/install.scss
166
167
  - lib/lite/component.rb
167
- - lib/lite/component/application.rb
168
168
  - lib/lite/component/base.rb
169
- - lib/lite/component/element.rb
169
+ - lib/lite/component/collection.rb
170
170
  - lib/lite/component/engine.rb
171
- - lib/lite/component/errors.rb
171
+ - lib/lite/component/iteration.rb
172
+ - lib/lite/component/locals.rb
172
173
  - lib/lite/component/version.rb
173
174
  - lite-component.gemspec
174
- - vendor/assets/javascripts/lite-component.js.erb
175
- - vendor/assets/stylesheets/lite-component.css.erb
176
175
  homepage: http://drexed.github.io/lite-component
177
176
  licenses:
178
177
  - MIT
@@ -192,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
191
  - !ruby/object:Gem::Version
193
192
  version: '0'
194
193
  requirements: []
195
- rubygems_version: 3.0.6
194
+ rubygems_version: 3.1.1
196
195
  signing_key:
197
196
  specification_version: 4
198
197
  summary: Generate component from collections of data points
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails/generators'
4
-
5
- class ComponentGenerator < Rails::Generators::NamedBase
6
-
7
- class_option :skip_erb, type: :boolean, default: false
8
- class_option :skip_css, type: :boolean, default: false
9
- class_option :skip_js, type: :boolean, default: false
10
-
11
- source_root File.expand_path('../templates', __FILE__)
12
-
13
- def create_component_file
14
- template('install.rb.erb', "app/components/#{name}_component.rb")
15
- end
16
-
17
- def create_erb_file
18
- return if options['skip_erb']
19
-
20
- name_parts = name.split('/')
21
- file_parts = name_parts[0..-2]
22
- file_parts << "_#{name_parts.last}.html.erb"
23
-
24
- create_file("app/views/components/#{file_parts.join('/')}")
25
- end
26
-
27
- def copy_javascript_file
28
- return if options['skip_js']
29
-
30
- copy_file('install.js', "app/assets/javascripts/components/#{name}.js")
31
- end
32
-
33
- def copy_stylesheet_file
34
- return if options['skip_css']
35
-
36
- copy_file('install.scss', "app/assets/stylesheets/components/#{name}.scss")
37
- end
38
-
39
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Lite
4
- module Component
5
-
6
- def self.names
7
- components_ext = '_component.rb'
8
- components_dir = "#{path}/"
9
- components_glob = path.join("**/*#{components_ext}")
10
-
11
- Dir.glob(components_glob).map { |name| name.sub(components_dir, '').chomp(components_ext) }
12
- end
13
-
14
- def self.path
15
- Rails.root.join('app/components')
16
- end
17
-
18
- end
19
- end
@@ -1,124 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'action_view'
4
-
5
- module Lite
6
- module Component
7
- class Element
8
-
9
- include ActiveModel::Validations
10
- include ActionView::Context
11
- include ActionView::Helpers
12
-
13
- attr_reader :context
14
-
15
- def initialize(context, attributes = nil, &block)
16
- initialize_attributes(attributes || {})
17
- initialize_elements
18
-
19
- @context = context
20
- @yield = block_given? ? @context.capture(self, &block) : nil
21
-
22
- validate!
23
- rescue ActiveModel::ValidationError => e
24
- raise Lite::Component::ValidationError, e.message
25
- end
26
-
27
- class << self
28
-
29
- def attribute(name, default: nil)
30
- attributes[name] = { default: default }
31
- define_method_or_raise(name) { get_instance_variable(name) }
32
- end
33
-
34
- def attributes
35
- @attributes ||= {}
36
- end
37
-
38
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
39
- # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
40
- def element(name, multiple: false, &config)
41
- plural_name = name.to_s.pluralize.to_sym if multiple
42
-
43
- elements[name] = {
44
- multiple: plural_name || false,
45
- class: Class.new(Element, &config)
46
- }
47
-
48
- define_method_or_raise(name) do |attributes = nil, &block|
49
- return get_instance_variable(multiple ? plural_name : name) unless attributes || block
50
-
51
- element = self.class.elements[name][:class].new(context, attributes, &block)
52
-
53
- if multiple
54
- get_instance_variable(plural_name) << element
55
- else
56
- set_instance_variable(name, element)
57
- end
58
- end
59
-
60
- return if !multiple || name == plural_name
61
-
62
- define_method_or_raise(plural_name) { get_instance_variable(plural_name) }
63
- end
64
- # rubocop:enable Metrics/MethodLength, Metrics/PerceivedComplexity
65
- # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
66
-
67
- def elements
68
- @elements ||= {}
69
- end
70
-
71
- def model_name
72
- ActiveModel::Name.new(Lite::Component::Element)
73
- end
74
-
75
- private
76
-
77
- def define_method_or_raise(method_name, &block)
78
- return define_method(method_name, &block) unless method_defined?(method_name.to_sym)
79
-
80
- raise Lite::Component::BuildError, "Method #{method_name.inspect} already exists"
81
- end
82
-
83
- end
84
-
85
- def to_s
86
- @yield
87
- end
88
-
89
- alias render to_s
90
-
91
- protected
92
-
93
- def initialize_attributes(attributes)
94
- self.class.attributes.each do |name, options|
95
- set_instance_variable(
96
- name,
97
- attributes[name] || (options[:default] && options[:default].dup)
98
- )
99
- end
100
- end
101
-
102
- def initialize_elements
103
- self.class.elements.each do |name, options|
104
- if (plural_name = options[:multiple])
105
- set_instance_variable(plural_name, [])
106
- else
107
- set_instance_variable(name, nil)
108
- end
109
- end
110
- end
111
-
112
- private
113
-
114
- def get_instance_variable(name)
115
- instance_variable_get(:"@#{name}")
116
- end
117
-
118
- def set_instance_variable(name, value)
119
- instance_variable_set(:"@#{name}", value)
120
- end
121
-
122
- end
123
- end
124
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Lite
4
- module Component
5
-
6
- class BuildError < StandardError; end
7
- class ValidationError < StandardError; end
8
-
9
- end
10
- end
@@ -1,7 +0,0 @@
1
- <% Lite::Component.names.each do |name| %>
2
- <% begin %>
3
- <% require_asset("components/#{name}") %>
4
- <% rescue Sprockets::FileNotFound %>
5
- <%# Do nothing %>
6
- <% end %>
7
- <% end %>
@@ -1,7 +0,0 @@
1
- <% Lite::Component.names.each do |name| %>
2
- <% begin %>
3
- <% require_asset("components/#{name}") %>
4
- <% rescue Sprockets::FileNotFound %>
5
- <%# Do nothing %>
6
- <% end %>
7
- <% end %>