Skip to content
This repository was archived by the owner on Oct 19, 2018. It is now read-only.

Commit 212ea1c

Browse files
committed
closes #114 #272
1 parent 229ee99 commit 212ea1c

File tree

3 files changed

+68
-7
lines changed

3 files changed

+68
-7
lines changed

lib/react/api.rb

+33-7
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ class extends React.Component {
146146
end
147147
end
148148

149-
def self.create_element(type, properties = {}, &block)
149+
def self.create_element(type, *args, &block)
150150
params = []
151151

152152
# Component Spec, Normal DOM, String or Native Component
@@ -164,7 +164,7 @@ def self.create_element(type, properties = {}, &block)
164164
end
165165

166166
# Convert Passed in properties
167-
properties = convert_props(properties)
167+
properties = convert_props(args)
168168
params << properties.shallow_to_n
169169

170170
# Children Nodes
@@ -183,15 +183,41 @@ def self.clear_component_class_cache
183183
@@component_classes = {}
184184
end
185185

186-
def self.convert_props(properties)
187-
raise "Component parameters must be a hash. Instead you sent #{properties}" unless properties.is_a? Hash
186+
def self.convert_props(args)
187+
# merge args together into a single properties hash
188+
properties = {}
189+
args.each do |arg|
190+
if arg.is_a? String
191+
properties[arg] = true
192+
elsif arg.is_a? Hash
193+
arg.each do |key, value|
194+
if ['class', 'className', 'class_name'].include? key
195+
if value.is_a?(String)
196+
value = value.split(' ')
197+
elsif !value.is_a?(Array)
198+
raise "The class param must be a string or array of strings"
199+
end
200+
properties['className'] = (properties['className'] || []) + value
201+
elsif key == 'style'
202+
if !value.is_a?(Hash)
203+
raise "The style param must be a Hash"
204+
end
205+
properties['style'] = (properties['style'] || {}).merge(value)
206+
else
207+
properties[key] = value
208+
end
209+
end
210+
end
211+
end
212+
# process properties according to react rules
188213
props = {}
189214
properties.each do |key, value|
190-
if key == "class" || key == "class_name"
191-
props["className"] = value
192-
elsif ["style", "dangerously_set_inner_HTML"].include? key
215+
if ["style", "dangerously_set_inner_HTML"].include? key
193216
props[lower_camelize(key)] = value.to_n
194217

218+
elsif key == "className"
219+
props[key] = value.join(' ')
220+
195221
elsif key == "key"
196222
props["key"] = value.to_key
197223

lib/react/component/class_methods.rb

+3
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ def collect_other_params_as(name)
9595
validator.all_other_params(name) { props }
9696
end
9797

98+
alias other_params collect_other_params_as
99+
alias others collect_other_params_as
100+
98101
def define_state(*states, &block)
99102
deprecation_warning "'define_state' is deprecated. Use the 'state' macro to declare states."
100103
default_initial_value = (block && block.arity == 0) ? yield : nil

spec/react/param_declaration_spec.rb

+32
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,38 @@ def render
183183
.to match(/Warning: Failed prop( type|Type): In component `Foo`\nProvided prop `foo` could not be converted to BazWoggle/)
184184
end
185185

186+
it 'allows passing and merging complex arguments to params' do
187+
mount 'Tester' do
188+
class TakesParams < Hyperloop::Component
189+
param :flag
190+
param :a
191+
param :b
192+
param :c
193+
param :d
194+
others :opts
195+
render do
196+
DIV(params.opts, id: :tp, class: "another-class", style: {marginLeft: 12}) do
197+
"flag: #{params.flag}, a: #{params.a}, b: #{params.b}, c: #{params.c}, d: #{params.d}"
198+
end
199+
end
200+
end
201+
class Tester < Hyperloop::Component
202+
render do
203+
TakesParams(
204+
:flag,
205+
{a: 1, b: 2, class: [:x, :y], className: 'foo', class_name: 'bar baz', style: {marginRight: 12}},
206+
c: 3, d: 4
207+
)
208+
end
209+
end
210+
end
211+
tp = find('#tp')
212+
expect(tp[:class].split).to contain_exactly("x", "y", "foo", "bar", "baz", "another-class")
213+
expect(tp[:style]).to match('margin-right: 12px')
214+
expect(tp[:style]).to match('margin-left: 12px')
215+
expect(tp).to have_content('flag: true, a: 1, b: 2, c: 3, d: 4')
216+
end
217+
186218
describe "converts params only once" do
187219
it "not on every access" do
188220
mount 'Foo', foo: {bazwoggle: 1} do

0 commit comments

Comments
 (0)