class React::API

Public Class Methods

create_element(type, properties = {}) { |].each do |ele| params << to_n| ... } click to toggle source
# File lib/react/api.rb, line 69
def self.create_element(type, properties = {}, &block)
  params = []

  # Component Spec, Normal DOM, String or Native Component
  if @@component_classes[type]
    params << @@component_classes[type]
  elsif type.kind_of?(Class)
    params << create_native_react_class(type)
  elsif HTML_TAGS.include?(type)
    params << type
  elsif type.is_a? String
    return React::Element.new(type)
  else
    raise "#{type} not implemented"
  end

  # Passed in properties
  params << convert_props(properties)

  # Children Nodes
  if block_given?
    children = [yield].flatten.each do |ele|
      params << ele.to_n
    end
  end
create_native_react_class(type) click to toggle source
# File lib/react/api.rb, line 11
def self.create_native_react_class(type)
  raise "Provided class should define `render` method"  if !(type.method_defined? :render)
  render_fn = (type.method_defined? :_render_wrapper) ? :_render_wrapper : :render
  # this was hashing type.to_s, not sure why but .to_s does not work as it Foo::Bar::View.to_s just returns "View"
  @@component_classes[type] ||= %x{
    React.createClass({
      displayName: #{type.name},
      propTypes: #{type.respond_to?(:prop_types) ? type.prop_types.to_n : `{}`},
      getDefaultProps: function(){
        return #{type.respond_to?(:default_props) ? type.default_props.to_n : `{}`};
      },
      mixins: #{type.respond_to?(:native_mixins) ? type.native_mixins : `[]`},
      statics: #{type.respond_to?(:static_call_backs) ? type.static_call_backs.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`.send(render_fn).to_n};
      }
    })
  }
end
import_native_component(opal_class, native_class) click to toggle source
# File lib/react/api.rb, line 7
def self.import_native_component(opal_class, native_class)
  @@component_classes[opal_class.to_s] = native_class
end