Class: React::API

Inherits:
Object
  • Object
show all
Defined in:
lib/react/api.rb

Constant Summary collapse

@@component_classes =
{}

Class Method Summary collapse

Class Method Details

.clear_component_class_cacheObject



91
92
93
# File 'lib/react/api.rb', line 91

def self.clear_component_class_cache
  @@component_classes = {}
end

.create_element(type, properties = {}, &block) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/react/api.rb', line 5

def self.create_element(type, properties = {}, &block)
  params = []

  # Component Spec or Nomral DOM
  if type.kind_of?(Class)
    raise "Provided class should define `render` method"  if !(type.method_defined? :render)
    @@component_classes[type.to_s] ||= %x{
      React.createClass({
        propTypes: #{type.respond_to?(:prop_types) ? type.prop_types.to_n : `{}`},
        getDefaultProps: function(){
          return #{type.respond_to?(:default_props) ? type.default_props.to_n : `{}`};
        },
        getInitialState: function(){
          return #{type.respond_to?(:initial_state) ? type.initial_state.to_n : `{}`};
        },
        componentWillMount: function() {
          var instance = this._getOpalInstance.apply(this);
          return #{`instance`.component_will_mount if type.method_defined? :component_will_mount};
        },
        componentDidMount: function() {
          var instance = this._getOpalInstance.apply(this);
          return #{`instance`.component_did_mount if type.method_defined? :component_did_mount};
        },
        componentWillReceiveProps: function(next_props) {
          var instance = this._getOpalInstance.apply(this);
          return #{`instance`.component_will_receive_props(`next_props`) if type.method_defined? :component_will_receive_props};
        },
        shouldComponentUpdate: function(next_props, next_state) {
          var instance = this._getOpalInstance.apply(this);
          return #{`instance`.should_component_update?(`next_props`, `next_state`) if type.method_defined? :should_component_update?};
        },
        componentWillUpdate: function(next_props, next_state) {
          var instance = this._getOpalInstance.apply(this);
          return #{`instance`.component_will_update(`next_props`, `next_state`) if type.method_defined? :component_will_update};
        },
        componentDidUpdate: function(prev_props, prev_state) {
          var instance = this._getOpalInstance.apply(this);
          return #{`instance`.component_did_update(`prev_props`, `prev_state`) if type.method_defined? :component_did_update};
        },
        componentWillUnmount: function() {
          var instance = this._getOpalInstance.apply(this);
          return #{`instance`.component_will_unmount if type.method_defined? :component_will_unmount};
        },
        _getOpalInstance: function() {
          if (this.__opalInstance == undefined) {
            var instance = #{type.new(`this`)};
          } else {
            var instance = this.__opalInstance;
          }
          this.__opalInstance = instance;
          return instance;
        },
        render: function() {
          var instance = this._getOpalInstance.apply(this);
          return #{`instance`.render.to_n};
        }
      })
    }

    params << @@component_classes[type.to_s]
  else
    raise "#{type} not implemented" unless HTML_TAGS.include?(type)
    params << type
  end

  # Passed in properties
  props = {}
  properties.map do |key, value|
     if key == "class_name" && value.is_a?(Hash)
       props[lower_camelize(key)] = `React.addons.classSet(#{value.to_n})`
     else
       props[React::ATTRIBUTES.include?(lower_camelize(key)) ? lower_camelize(key) : key] = value
     end
  end
  params << props.shallow_to_n

  # Children Nodes
  if block_given?
    children = [yield].flatten.each do |ele|
      params << ele.to_n
    end
  end

  return React::Element.new(`React.createElement.apply(null, #{params})`)
end