class React::Element
Wraps the React
Native element class
adds the on
method to add event handlers to the element
adds the render
method to place elements in the DOM and delete
(alias/deprecated as_node
) method to remove elements from the DOM
handles the haml style class notation so that
div.bar.blat becomes div(class: "bar blat")
by using method missing
Attributes
Public Class Methods
# File lib/react/element.rb, line 93 def self.haml_class_name(class_name) class_name.gsub(/__|_/, '__' => '_', '_' => '-') end
# File lib/react/element.rb, line 28 def initialize(native_element, type, properties, block) @type = type @properties = (`typeof #{properties} === 'undefined'` ? nil : properties) || {} @block = block @native = native_element end
Public Instance Methods
Deprecated version of delete method
# File lib/react/element.rb, line 68 def as_node React::RenderingContext.as_node(self) end
Delete (remove) element from rendering context, the element may later be added back in using the render method.
# File lib/react/element.rb, line 62 def delete React::RenderingContext.delete(self) end
Any other method applied to an element will be treated as class name (haml style) thus div.foo.bar(id: :fred) is the same as saying div(class: “foo bar”, id: :fred)
single underscores become dashes, and double underscores become a single underscore
params may be provide to each class (but typically only to the last for easy reading.)
# File lib/react/element.rb, line 79 def method_missing(class_name, args = {}, &new_block) return dup.render.method_missing(class_name, args, &new_block) unless rendered? React::RenderingContext.replace( self, RenderingContext.build do RenderingContext.render(type, build_new_properties(class_name, args), &new_block) end ) end
Attach event handlers.
# File lib/react/element.rb, line 37 def on(*event_names, &block) event_names.each { |event_name| merge_event_prop!(event_name, &block) } @native = `React.cloneElement(#{to_n}, #{properties.shallow_to_n})` self end
Render element into DOM in the current rendering context. Used for elements that are not yet in DOM, i.e. they are provided as children or they have been explicitly removed from the rendering context using the delete method.
# File lib/react/element.rb, line 47 def render(props = {}, &new_block) if props.empty? React::RenderingContext.render(self) else props = API.convert_props(props) React::RenderingContext.render( Element.new(`React.cloneElement(#{to_n}, #{props.shallow_to_n})`, type, properties.merge(props), block), ) end end
# File lib/react/element.rb, line 89 def rendered? React::RenderingContext.rendered? self end
Private Instance Methods
# File lib/react/element.rb, line 99 def build_new_properties(class_name, args) class_name = self.class.haml_class_name(class_name) new_props = properties.dup new_props[:className] = "\ #{class_name} #{new_props[:className]} #{args.delete(:class)} #{args.delete(:className)}\ ".split(' ').uniq.join(' ') new_props.merge! args end
# File lib/react/element.rb, line 135 def merge_built_in_event_prop!(prop_name) @properties.merge!( prop_name => %x{ function(event){ return #{yield(React::Event.new(`event`))} } } ) end
# File lib/react/element.rb, line 145 def merge_component_event_prop!(prop_name) @properties.merge!( prop_name => %x{ function(){ return #{yield(*Array(`arguments`))} } } ) end
# File lib/react/element.rb, line 155 def merge_deprecated_component_event_prop!(event_name) prop_name = "_on#{event_name.event_camelize}" fn = %x{function(){#{ React::Component.deprecation_warning( "In future releases React::Element#on('#{event_name}') will no longer respond "\ "to the '#{prop_name}' emitter.\n"\ "Rename your emitter param to 'on_#{event_name}' or use .on('<#{prop_name}>')" )} return #{yield(*Array(`arguments`))} }} @properties.merge!(prop_name => fn) end
built in events will have their event param translated to the Event
wrapper and the name will camelcased and have on prefixed, so :click becomes onClick.
events emitting from native components are assumed to have the same camel case and on prefixed.
events emitting from reactrb components will just have on_ prefixed. So :play_button_pushed attaches to the :on_play_button_pushed param
in all cases the default name convention can be overriden by wrapping in <…> brackets. So on(“<MyEvent>”) will attach to the “MyEvent” param.
# File lib/react/element.rb, line 122 def merge_event_prop!(event_name, &block) if event_name =~ /^<(.+)>$/ merge_component_event_prop! event_name.gsub(/^<(.+)>$/, '\1'), &block elsif React::Event::BUILT_IN_EVENTS.include?(name = "on#{event_name.event_camelize}") merge_built_in_event_prop! name, &block elsif @type.instance_variable_get('@native_import') merge_component_event_prop! name, &block else merge_deprecated_component_event_prop! event_name, &block merge_component_event_prop! "on_#{event_name}", &block end end