Module: React::Component::ClassMethods

Defined in:
lib/react/component/class_methods.rb

Overview

class level methods (macros) for components

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &children) ⇒ Object

method missing will assume the method is a class name, and will treat this a render of of the component, i.e. Foo::Bar.baz === Foo::Bar().baz



38
39
40
41
42
43
# File 'lib/react/component/class_methods.rb', line 38

def method_missing(name, *args, &children)
  Object.method_missing(name, *args, &children) unless args.empty?
  React::RenderingContext.render(
    self, class: React::Element.haml_class_name(name), &children
  )
end

Instance Method Details

#add_item_to_tree(current_tree, new_item) ⇒ Object



159
160
161
162
163
164
165
166
167
168
# File 'lib/react/component/class_methods.rb', line 159

def add_item_to_tree(current_tree, new_item)
  if Native(current_tree).class != Native::Object || new_item.length == 1
    new_item.inject { |a, e| { e => a } }
  else
    Native(current_tree)[new_item.last] = add_item_to_tree(
      Native(current_tree)[new_item.last], new_item[0..-2]
    )
    current_tree
  end
end

#append_backtrace(message_array, backtrace) ⇒ Object



19
20
21
22
# File 'lib/react/component/class_methods.rb', line 19

def append_backtrace(message_array, backtrace)
  message_array << "    #{backtrace[0]}"
  backtrace[1..-1].each { |line| message_array << line }
end

#backtrace(*args) ⇒ Object



14
15
16
17
# File 'lib/react/component/class_methods.rb', line 14

def backtrace(*args)
  @dont_catch_exceptions = (args[0] == :none)
  @backtrace_off = @dont_catch_exceptions || (args[0] == :off)
end

#collect_other_params_as(name) ⇒ Object Also known as: other_params, others



94
95
96
# File 'lib/react/component/class_methods.rb', line 94

def collect_other_params_as(name)
  validator.all_other_params(name) { props }
end

#default_propsObject



64
65
66
# File 'lib/react/component/class_methods.rb', line 64

def default_props
  validator.default_props
end

#define_state(*states, &block) ⇒ Object



101
102
103
104
105
106
107
# File 'lib/react/component/class_methods.rb', line 101

def define_state(*states, &block)
  deprecation_warning "'define_state' is deprecated. Use the 'state' macro to declare states."
  default_initial_value = (block && block.arity == 0) ? yield : nil
  states_hash = (states.last.is_a?(Hash)) ? states.pop : {}
  states.each { |name| state(name => default_initial_value) } # was states_hash[name] = default_initial_value
  states_hash.each { |name, value| state(name => value) }
end

#deprecation_warning(message) ⇒ Object



6
7
8
# File 'lib/react/component/class_methods.rb', line 6

def deprecation_warning(message)
  React::Component.deprecation_warning(self, message)
end

#export_component(opts = {}) ⇒ Object



138
139
140
141
142
143
144
145
# File 'lib/react/component/class_methods.rb', line 138

def export_component(opts = {})
  export_name = (opts[:as] || name).split('::')
  first_name = export_name.first
  Native(`Opal.global`)[first_name] = add_item_to_tree(
    Native(`Opal.global`)[first_name],
    [React::API.create_native_react_class(self)] + export_name[1..-1].reverse
  ).to_n
end

#export_state(*states, &block) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/react/component/class_methods.rb', line 109

def export_state(*states, &block)
  deprecation_warning "'export_state' is deprecated. Use the 'state' macro to declare states."
  default_initial_value = (block && block.arity == 0) ? yield : nil
  states_hash = (states.last.is_a?(Hash)) ? states.pop : {}
  states.each { |name| states_hash[name] = default_initial_value }
  states_hash.each do |name, value|
    state(name => value, scope: :class, reader: true)
    singleton_class.define_method("#{name}!") do |*args|
      mutate.__send__(name, *args)
    end
  end
end

#imports(component_name) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
# File 'lib/react/component/class_methods.rb', line 147

def imports(component_name)
  React::API.import_native_component(
    self, React::API.eval_native_react_component(component_name)
  )
  define_method(:render) {} # define a dummy render method - will never be called...
rescue Exception => e # rubocop:disable Lint/RescueException : we need to catch everything!
  raise "#{self} cannot import '#{component_name}': #{e.message}."
  # rubocop:enable Lint/RescueException
ensure
  self
end

#native_mixin(item) ⇒ Object



122
123
124
# File 'lib/react/component/class_methods.rb', line 122

def native_mixin(item)
  native_mixins << item
end

#native_mixinsObject



126
127
128
# File 'lib/react/component/class_methods.rb', line 126

def native_mixins
  @native_mixins ||= []
end

#param(*args) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/react/component/class_methods.rb', line 76

def param(*args)
  if args[0].is_a? Hash
    options = args[0]
    name = options.first[0]
    default = options.first[1]
    options.delete(name)
    options.merge!({default: default})
  else
    name = args[0]
    options = args[1] || {}
  end
  if options[:default]
    validator.optional(name, options)
  else
    validator.requires(name, options)
  end
end

#params(&block) ⇒ Object



68
69
70
# File 'lib/react/component/class_methods.rb', line 68

def params(&block)
  validator.build(&block)
end

#prop_typesObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/react/component/class_methods.rb', line 49

def prop_types
  if self.validator
    {
      _componentValidator: %x{
        function(props, propName, componentName) {
          var errors = #{validator.validate(Hash.new(`props`))};
          return #{`errors`.count > 0 ? `new Error(#{"In component `#{name}`\n" + `errors`.join("\n")})` : `undefined`};
        }
      }
    }
  else
    {}
  end
end

#props_wrapperObject



72
73
74
# File 'lib/react/component/class_methods.rb', line 72

def props_wrapper
  @props_wrapper ||= Class.new(PropsWrapper)
end

#reactrb_component?Boolean

Returns:



10
11
12
# File 'lib/react/component/class_methods.rb', line 10

def reactrb_component?
  true
end

#render(container = nil, params = {}, &block) ⇒ Object



24
25
26
27
28
29
30
31
32
33
# File 'lib/react/component/class_methods.rb', line 24

def render(container = nil, params = {}, &block)
  if container
    container = container.type if container.is_a? React::Element
    define_method :render do
      React::RenderingContext.render(container, params) { instance_eval(&block) if block }
    end
  else
    define_method(:render) { instance_eval(&block) }
  end
end

#static_call_back(name, &block) ⇒ Object



130
131
132
# File 'lib/react/component/class_methods.rb', line 130

def static_call_back(name, &block)
  static_call_backs[name] = block
end

#static_call_backsObject



134
135
136
# File 'lib/react/component/class_methods.rb', line 134

def static_call_backs
  @static_call_backs ||= {}
end

#to_nObject



170
171
172
# File 'lib/react/component/class_methods.rb', line 170

def to_n
  React::API.class_eval('@@component_classes')[self]
end

#validatorObject



45
46
47
# File 'lib/react/component/class_methods.rb', line 45

def validator
  @validator ||= Validator.new(props_wrapper)
end