isomorfeus-react 16.6.8 → 16.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +39 -413
- data/lib/isomorfeus-react-base.rb +55 -0
- data/lib/isomorfeus-react-component.rb +20 -0
- data/lib/isomorfeus-react-lucid.rb +39 -0
- data/lib/isomorfeus-react-material-ui.rb +41 -0
- data/lib/isomorfeus-react-redux-component.rb +25 -0
- data/lib/isomorfeus-react.rb +4 -101
- data/lib/isomorfeus/config.rb +3 -8
- data/lib/isomorfeus/top_level_browser.rb +1 -1
- data/lib/lucid_app/api.rb +1 -12
- data/lib/lucid_app/mixin.rb +1 -0
- data/lib/lucid_app/native_component_constructor.rb +10 -0
- data/lib/lucid_component/api.rb +1 -1
- data/lib/lucid_component/initializer.rb +5 -5
- data/lib/lucid_component/mixin.rb +1 -0
- data/lib/lucid_component/native_component_constructor.rb +13 -3
- data/lib/lucid_material/app/base.rb +9 -0
- data/lib/lucid_material/app/mixin.rb +20 -0
- data/lib/lucid_material/app/native_component_constructor.rb +116 -0
- data/lib/lucid_material/component/api.rb +19 -0
- data/lib/lucid_material/component/base.rb +9 -0
- data/lib/lucid_material/component/mixin.rb +21 -0
- data/lib/lucid_material/component/native_component_constructor.rb +158 -0
- data/lib/react.rb +13 -5
- data/lib/react/children.rb +35 -0
- data/lib/react/component/api.rb +5 -91
- data/lib/react/component/callbacks.rb +103 -0
- data/lib/react/component/elements.rb +3 -23
- data/lib/react/component/features.rb +12 -29
- data/lib/react/component/initializer.rb +2 -2
- data/lib/react/component/mixin.rb +1 -0
- data/lib/react/component/native_component_constructor.rb +7 -0
- data/lib/react/component/props.rb +13 -1
- data/lib/react/component/resolution.rb +14 -15
- data/lib/react/component/styles.rb +23 -0
- data/lib/react/context_wrapper.rb +4 -0
- data/lib/react/function_component/api.rb +83 -0
- data/lib/react/function_component/base.rb +9 -0
- data/lib/react/function_component/creator.rb +19 -65
- data/lib/react/function_component/event_handler.rb +13 -0
- data/lib/react/function_component/mixin.rb +14 -0
- data/lib/react/function_component/resolution.rb +17 -15
- data/lib/react/memo_component/base.rb +9 -0
- data/lib/react/memo_component/creator.rb +32 -0
- data/lib/react/memo_component/mixin.rb +14 -0
- data/lib/react/native_constant_wrapper.rb +1 -11
- data/lib/react/pure_component/mixin.rb +2 -0
- data/lib/react/redux_component/api.rb +1 -93
- data/lib/react/redux_component/initializer.rb +5 -5
- data/lib/react/redux_component/mixin.rb +1 -0
- data/lib/react/redux_component/native_component_constructor.rb +13 -3
- data/lib/react/redux_component/reducers.rb +29 -35
- data/lib/react/ref.rb +4 -0
- data/lib/react/version.rb +1 -1
- data/lib/react_dom.rb +9 -3
- metadata +70 -8
- data/lib/lucid_router.rb +0 -18
- data/lib/react/function_component/runner.rb +0 -19
@@ -0,0 +1,20 @@
|
|
1
|
+
module LucidMaterial
|
2
|
+
module App
|
3
|
+
module Mixin
|
4
|
+
def self.included(base)
|
5
|
+
base.include(::Native::Wrapper)
|
6
|
+
base.extend(::LucidMaterial::App::NativeComponentConstructor)
|
7
|
+
base.extend(::React::Component::ShouldComponentUpdate)
|
8
|
+
base.extend(::React::Component::EventHandler)
|
9
|
+
base.include(::React::Component::Elements)
|
10
|
+
base.include(::React::Component::API)
|
11
|
+
base.include(::React::Component::Callbacks)
|
12
|
+
base.include(::React::ReduxComponent::API)
|
13
|
+
base.include(::LucidMaterial::Component::API)
|
14
|
+
base.include(::LucidApp::API)
|
15
|
+
base.include(::React::Component::Features)
|
16
|
+
base.include(::React::Component::Resolution)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module LucidMaterial
|
2
|
+
module App
|
3
|
+
module NativeComponentConstructor
|
4
|
+
# for should_component_update we apply ruby semantics for comparing props
|
5
|
+
# to do so, we convert the props to ruby hashes and then compare
|
6
|
+
# this makes sure, that for example rubys Nil object gets handled properly
|
7
|
+
def self.extended(base)
|
8
|
+
component_name = base.to_s
|
9
|
+
# language=JS
|
10
|
+
%x{
|
11
|
+
base.jss_styles = {};
|
12
|
+
base.lucid_react_component = class extends Opal.global.React.Component {
|
13
|
+
constructor(props) {
|
14
|
+
super(props);
|
15
|
+
if (base.$default_state_defined()) {
|
16
|
+
this.state = base.$state().$to_n();
|
17
|
+
} else {
|
18
|
+
this.state = {};
|
19
|
+
};
|
20
|
+
this.state.isomorfeus_store_state = Opal.Isomorfeus.store.native.getState();
|
21
|
+
var current_store_state = this.state.isomorfeus_store_state;
|
22
|
+
if (typeof current_store_state.component_class_state[#{component_name}] !== "undefined") {
|
23
|
+
this.state.component_class_state = {};
|
24
|
+
this.state.component_class_state[#{component_name}] = current_store_state.component_class_state[#{component_name}];
|
25
|
+
} else {
|
26
|
+
this.state.component_class_state = {};
|
27
|
+
this.state.component_class_state[#{component_name}] = {};
|
28
|
+
};
|
29
|
+
this.__ruby_instance = base.$new(this);
|
30
|
+
this.__object_id = this.__ruby_instance.$object_id().$to_s();
|
31
|
+
if (!this.state.component_state) {
|
32
|
+
this.state.component_state = {};
|
33
|
+
this.state.component_state[this.__object_id] = {};
|
34
|
+
};
|
35
|
+
var event_handlers = #{base.event_handlers};
|
36
|
+
for (var i = 0; i < event_handlers.length; i++) {
|
37
|
+
this[event_handlers[i]] = this[event_handlers[i]].bind(this);
|
38
|
+
}
|
39
|
+
var defined_refs = #{base.defined_refs};
|
40
|
+
for (var ref in defined_refs) {
|
41
|
+
if (defined_refs[ref] != null) {
|
42
|
+
this[ref] = function(element) {
|
43
|
+
#{`this.__ruby_instance`.instance_exec(React::Ref.new(`element`), `defined_refs[ref]`)}
|
44
|
+
}
|
45
|
+
this[ref] = this[ref].bind(this);
|
46
|
+
} else {
|
47
|
+
this[ref] = Opal.global.React.createRef();
|
48
|
+
}
|
49
|
+
}
|
50
|
+
this.listener = this.listener.bind(this);
|
51
|
+
this.unsubscriber = Opal.Isomorfeus.store.native.subscribe(this.listener);
|
52
|
+
}
|
53
|
+
static get displayName() {
|
54
|
+
return #{component_name};
|
55
|
+
}
|
56
|
+
render() {
|
57
|
+
Opal.React.render_buffer.push([]);
|
58
|
+
Opal.React.active_components.push(this);
|
59
|
+
Opal.React.active_redux_components.push(this.__ruby_instance);
|
60
|
+
#{`this.__ruby_instance`.instance_exec(&`base.render_block`)};
|
61
|
+
Opal.React.active_redux_components.pop();
|
62
|
+
Opal.React.active_components.pop();
|
63
|
+
var children = Opal.React.render_buffer.pop();
|
64
|
+
return Opal.global.React.createElement(Opal.global.LucidApplicationContext.Provider, { value: this.state.isomorfeus_store_state }, children);
|
65
|
+
}
|
66
|
+
listener() {
|
67
|
+
var next_state = Opal.Isomorfeus.store.native.getState();
|
68
|
+
var current_ruby_state = Opal.Hash.$new(this.state.isomorfeus_store_state);
|
69
|
+
var next_ruby_state = Opal.Hash.$new(next_state);
|
70
|
+
if (#{`next_ruby_state` != `current_ruby_state`}) {
|
71
|
+
var self = this;
|
72
|
+
/* setTimeout(function() { */ self.setState({ isomorfeus_store_state: next_state }); /*}, 0 ); */
|
73
|
+
}
|
74
|
+
}
|
75
|
+
componentWillUnmount() {
|
76
|
+
if (typeof this.unsubscriber === "function") { this.unsubscriber(); };
|
77
|
+
}
|
78
|
+
validateProp(props, propName, componentName) {
|
79
|
+
if (propName === "isomorfeus_store") { return null };
|
80
|
+
var prop_data = base.lucid_react_component.propValidations[propName];
|
81
|
+
if (!prop_data) { return true; };
|
82
|
+
var value = props[propName];
|
83
|
+
var result;
|
84
|
+
if (typeof prop_data.ruby_class != "undefined") {
|
85
|
+
result = (value.$class() == prop_data.ruby_class);
|
86
|
+
if (!result) {
|
87
|
+
return new Error('Invalid prop ' + propName + '! Expected ' + prop_data.ruby_class.$to_s() + ' but was ' + value.$class().$to_s() + '!');
|
88
|
+
}
|
89
|
+
} else if (typeof prop_data.is_a != "undefined") {
|
90
|
+
result = value["$is_a?"](prop_data.is_a);
|
91
|
+
if (!result) {
|
92
|
+
return new Error('Invalid prop ' + propName + '! Expected a child of ' + prop_data.is_a.$to_s() + '!');
|
93
|
+
}
|
94
|
+
}
|
95
|
+
if (typeof prop_data.required != "undefined") {
|
96
|
+
if (prop_data.required && (typeof props[propName] == "undefined")) {
|
97
|
+
return new Error('Prop ' + propName + ' is required but not given!');
|
98
|
+
}
|
99
|
+
}
|
100
|
+
return null;
|
101
|
+
}
|
102
|
+
}
|
103
|
+
base.lucid_material_component = null;
|
104
|
+
base.react_component = function(outer_props) {
|
105
|
+
if (!base.lucid_material_component) {
|
106
|
+
base.lucid_material_component = Opal.global.MuiStyles.withStyles(base.jss_styles)(function(props){
|
107
|
+
return Opal.global.React.createElement(base.lucid_react_component, props);
|
108
|
+
});
|
109
|
+
}
|
110
|
+
return Opal.global.React.createElement(base.lucid_material_component, outer_props);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module LucidMaterial
|
2
|
+
module Component
|
3
|
+
module API
|
4
|
+
def self.included(base)
|
5
|
+
base.instance_exec do
|
6
|
+
def styles(styles_hash = nil, &block)
|
7
|
+
styles_hash = block.call if block_given?
|
8
|
+
`base.jss_styles = #{styles_hash.to_n}` if styles_hash
|
9
|
+
`Opal.Hash.$new(base.jss_styles)`
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def classes
|
14
|
+
props.classes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module LucidMaterial
|
2
|
+
module Component
|
3
|
+
module Mixin
|
4
|
+
def self.included(base)
|
5
|
+
base.include(::Native::Wrapper)
|
6
|
+
base.extend(::LucidMaterial::Component::NativeComponentConstructor)
|
7
|
+
base.extend(::React::Component::NativeComponentValidateProp)
|
8
|
+
base.extend(::LucidComponent::EventHandler)
|
9
|
+
base.include(::React::Component::Elements)
|
10
|
+
base.include(::React::Component::API)
|
11
|
+
base.include(::React::Component::Callbacks)
|
12
|
+
base.include(::React::ReduxComponent::API)
|
13
|
+
base.include(::LucidComponent::API)
|
14
|
+
base.include(::LucidMaterial::Component::API)
|
15
|
+
base.include(::LucidComponent::Initializer)
|
16
|
+
base.include(::React::Component::Features)
|
17
|
+
base.include(::React::Component::Resolution)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module LucidMaterial
|
2
|
+
module Component
|
3
|
+
module NativeComponentConstructor
|
4
|
+
# for should_component_update we apply ruby semantics for comparing props
|
5
|
+
# to do so, we convert the props to ruby hashes and then compare
|
6
|
+
# this makes sure, that for example rubys Nil object gets handled properly
|
7
|
+
def self.extended(base)
|
8
|
+
component_name = base.to_s
|
9
|
+
# language=JS
|
10
|
+
%x{
|
11
|
+
base.jss_styles = {};
|
12
|
+
base.lucid_react_component = class extends Opal.global.React.Component {
|
13
|
+
constructor(props) {
|
14
|
+
super(props);
|
15
|
+
if (base.$default_state_defined()) {
|
16
|
+
this.state = base.$state().$to_n();
|
17
|
+
} else {
|
18
|
+
this.state = {};
|
19
|
+
};
|
20
|
+
this.__ruby_instance = base.$new(this);
|
21
|
+
this.__object_id = this.__ruby_instance.$object_id().$to_s();
|
22
|
+
if (!this.state.component_state) {
|
23
|
+
this.state.component_state = {};
|
24
|
+
this.state.component_state[this.__object_id] = {};
|
25
|
+
};
|
26
|
+
var event_handlers = #{base.event_handlers};
|
27
|
+
for (var i = 0; i < event_handlers.length; i++) {
|
28
|
+
this[event_handlers[i]] = this[event_handlers[i]].bind(this);
|
29
|
+
}
|
30
|
+
var defined_refs = #{base.defined_refs};
|
31
|
+
for (var ref in defined_refs) {
|
32
|
+
if (defined_refs[ref] != null) {
|
33
|
+
this[ref] = function(element) {
|
34
|
+
#{`this.__ruby_instance`.instance_exec(React::Ref.new(`element`), `defined_refs[ref]`)}
|
35
|
+
}
|
36
|
+
this[ref] = this[ref].bind(this);
|
37
|
+
} else {
|
38
|
+
this[ref] = Opal.global.React.createRef();
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
static get displayName() {
|
43
|
+
return #{component_name};
|
44
|
+
}
|
45
|
+
render() {
|
46
|
+
Opal.React.render_buffer.push([]);
|
47
|
+
Opal.React.active_components.push(this);
|
48
|
+
Opal.React.active_redux_components.push(this);
|
49
|
+
this.used_store_paths = [];
|
50
|
+
#{`this.__ruby_instance`.instance_exec(&`base.render_block`)};
|
51
|
+
Opal.React.active_redux_components.pop();
|
52
|
+
Opal.React.active_components.pop();
|
53
|
+
return Opal.React.render_buffer.pop();
|
54
|
+
}
|
55
|
+
data_access() {
|
56
|
+
return this.props.isomorfeus_store
|
57
|
+
}
|
58
|
+
register_used_store_path(path) {
|
59
|
+
this.used_store_paths.push(path);
|
60
|
+
}
|
61
|
+
shouldComponentUpdate(next_props, next_state) {
|
62
|
+
var next_props_keys = Object.keys(next_props);
|
63
|
+
var this_props_keys = Object.keys(this.props);
|
64
|
+
if (next_props_keys.length !== this_props_keys.length) { return true; }
|
65
|
+
|
66
|
+
var next_state_keys = Object.keys(next_state);
|
67
|
+
var this_state_keys = Object.keys(this.state);
|
68
|
+
if (next_state_keys.length !== this_state_keys.length) { return true; }
|
69
|
+
|
70
|
+
var used_store_result;
|
71
|
+
for (var property in next_props) {
|
72
|
+
if (property === "isomorfeus_store") {
|
73
|
+
used_store_result = this.scu_for_used_store_paths(this, this.state.isomorfeus_store, next_state.isomorfeus_store);
|
74
|
+
if (used_store_result) {
|
75
|
+
return true;
|
76
|
+
}
|
77
|
+
} else if (next_props.hasOwnProperty(property)) {
|
78
|
+
if (!this.props.hasOwnProperty(property)) { return true; };
|
79
|
+
if (property == "children") { if (next_props.children !== this.props.children) { return true; }}
|
80
|
+
else if (typeof next_props[property] !== "undefined" && typeof next_props[property]['$!='] !== "undefined" && typeof this.props[property] !== "undefined" && typeof this.props[property]['$!='] !== "undefined") {
|
81
|
+
if (#{ !! (`next_props[property]` != `this.props[property]`) }) { return true; };
|
82
|
+
} else if (next_props[property] !== this.props[property]) { return true; };
|
83
|
+
}
|
84
|
+
}
|
85
|
+
for (var property in next_state) {
|
86
|
+
if (next_state.hasOwnProperty(property)) {
|
87
|
+
if (!this.state.hasOwnProperty(property)) { return true; };
|
88
|
+
if (typeof next_state[property]['$!='] !== "undefined" && typeof this.state[property]['$!='] !== "undefined") {
|
89
|
+
if (#{ !! (`next_state[property]` != `this.state[property]`) }) { return true };
|
90
|
+
} else if (next_state[property] !== this.state[property]) { return true };
|
91
|
+
}
|
92
|
+
}
|
93
|
+
return false;
|
94
|
+
}
|
95
|
+
scu_for_used_store_paths(self, current_state, next_state) {
|
96
|
+
var unique_used_store_paths = self.used_store_paths.filter(function(elem, pos, paths) {
|
97
|
+
return (paths.indexOf(elem) === pos);
|
98
|
+
});
|
99
|
+
var used_length = unique_used_store_paths.length;
|
100
|
+
var store_path;
|
101
|
+
var current_value;
|
102
|
+
var next_value;
|
103
|
+
var store_path_last;
|
104
|
+
for (var i = 0; i < used_length; i++) {
|
105
|
+
store_path = unique_used_store_paths[i];
|
106
|
+
store_path_last = store_path.length - 1;
|
107
|
+
if (store_path[store_path_last].constructor === Array) {
|
108
|
+
store_path[store_path_last] = JSON.stringify(store_path[store_path_last]);
|
109
|
+
}
|
110
|
+
current_value = store_path.reduce(function(prev, curr) { return prev && prev[curr]; }, current_state);
|
111
|
+
next_value = store_path.reduce(function(prev, curr) { return prev && prev[curr]; }, next_state);
|
112
|
+
if (current_value !== next_value) { return true; };
|
113
|
+
}
|
114
|
+
return false;
|
115
|
+
}
|
116
|
+
validateProp(props, propName, componentName) {
|
117
|
+
if (propName === "isomorfeus_store") { return null };
|
118
|
+
var prop_data = base.lucid_react_component.propValidations[propName];
|
119
|
+
if (!prop_data) { return true; };
|
120
|
+
var value = props[propName];
|
121
|
+
var result;
|
122
|
+
if (typeof prop_data.ruby_class != "undefined") {
|
123
|
+
result = (value.$class() == prop_data.ruby_class);
|
124
|
+
if (!result) {
|
125
|
+
return new Error('Invalid prop ' + propName + '! Expected ' + prop_data.ruby_class.$to_s() + ' but was ' + value.$class().$to_s() + '!');
|
126
|
+
}
|
127
|
+
} else if (typeof prop_data.is_a != "undefined") {
|
128
|
+
result = value["$is_a?"](prop_data.is_a);
|
129
|
+
if (!result) {
|
130
|
+
return new Error('Invalid prop ' + propName + '! Expected a child of ' + prop_data.is_a.$to_s() + '!');
|
131
|
+
}
|
132
|
+
}
|
133
|
+
if (typeof prop_data.required != "undefined") {
|
134
|
+
if (prop_data.required && (typeof props[propName] == "undefined")) {
|
135
|
+
return new Error('Prop ' + propName + ' is required but not given!');
|
136
|
+
}
|
137
|
+
}
|
138
|
+
return null;
|
139
|
+
}
|
140
|
+
};
|
141
|
+
base.lucid_react_component.contextType = Opal.global.LucidApplicationContext;
|
142
|
+
base.lucid_material_component = null;
|
143
|
+
base.react_component = function(outer_props) {
|
144
|
+
return Opal.global.React.createElement(Opal.global.LucidApplicationContext.Consumer, null, function(store) {
|
145
|
+
var store_props = Object.assign({}, outer_props, { isomorfeus_store: store });
|
146
|
+
if (!base.lucid_material_component) {
|
147
|
+
base.lucid_material_component = Opal.global.MuiStyles.withStyles(base.jss_styles)(function(props){
|
148
|
+
return Opal.global.React.createElement(base.lucid_react_component, props);
|
149
|
+
});
|
150
|
+
}
|
151
|
+
return Opal.global.React.createElement(base.lucid_material_component, store_props);
|
152
|
+
});
|
153
|
+
}
|
154
|
+
}
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
data/lib/react.rb
CHANGED
@@ -37,6 +37,16 @@ module React
|
|
37
37
|
return result;
|
38
38
|
};
|
39
39
|
|
40
|
+
self.internal_prepare_args_and_render = function(component, args, block) {
|
41
|
+
if (args.length > 0) {
|
42
|
+
var last_arg = args[args.length - 1];
|
43
|
+
if (typeof last_arg === 'string' || last_arg instanceof String) {
|
44
|
+
if (args.length === 1) { Opal.React.internal_render(component, null, last_arg, null); }
|
45
|
+
else { Opal.React.internal_render(component, args[0], last_arg, null); }
|
46
|
+
} else { Opal.React.internal_render(component, args[0], null, block); }
|
47
|
+
} else { Opal.React.internal_render(component, null, null, block); }
|
48
|
+
};
|
49
|
+
|
40
50
|
self.internal_render = function(component, props, string_child, block) {
|
41
51
|
var children;
|
42
52
|
var block_result;
|
@@ -103,11 +113,9 @@ module React
|
|
103
113
|
var component = null;
|
104
114
|
var block_result = null;
|
105
115
|
var native_props = null;
|
106
|
-
|
107
|
-
if (typeof type.react_component == "function") {
|
116
|
+
if (typeof type.react_component !== 'undefined') {
|
108
117
|
component = type.react_component;
|
109
|
-
}
|
110
|
-
else {
|
118
|
+
} else {
|
111
119
|
component = type;
|
112
120
|
}
|
113
121
|
|
@@ -145,7 +153,7 @@ module React
|
|
145
153
|
`Opal.global.React.forwardRef( function(props, ref) { return block.$call().$to_n(); })`
|
146
154
|
end
|
147
155
|
|
148
|
-
def self.
|
156
|
+
def self.is_valid_element(react_element)
|
149
157
|
`Opal.global.React.isValidElement(react_element)`
|
150
158
|
end
|
151
159
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module React
|
2
|
+
module Children
|
3
|
+
class << self
|
4
|
+
def count(children)
|
5
|
+
`Opal.global.React.Children.count(children)`
|
6
|
+
end
|
7
|
+
|
8
|
+
def for_each(children, &block)
|
9
|
+
%x{
|
10
|
+
var fun = function(child) {
|
11
|
+
#{block.call(child)};
|
12
|
+
}
|
13
|
+
Opal.global.React.Children.forEach(children, fun);
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def map(children, &block)
|
18
|
+
%x{
|
19
|
+
var fun = function(child) {
|
20
|
+
return #{block.call(child)};
|
21
|
+
}
|
22
|
+
return Opal.global.React.Children.map(children, fun);
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def only(children)
|
27
|
+
`Opal.global.React.Children.only(children)`
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_array(children)
|
31
|
+
`Opal.global.React.Children.toArray(children)`
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/react/component/api.rb
CHANGED
@@ -6,40 +6,19 @@ module React
|
|
6
6
|
base_module = base.to_s.deconstantize
|
7
7
|
if base_module != ''
|
8
8
|
base_module.constantize.define_singleton_method(base.to_s.demodulize) do |*args, &block|
|
9
|
-
|
10
|
-
if (args.length > 0) {
|
11
|
-
var last_arg = args[args.length - 1];
|
12
|
-
if (typeof last_arg === 'string' || last_arg instanceof String) {
|
13
|
-
if (args.length === 1) { Opal.React.internal_render(#{base}.react_component, null, last_arg, null); }
|
14
|
-
else { Opal.React.internal_render(#{base}.react_component, args[0], last_arg, null); }
|
15
|
-
} else { Opal.React.internal_render(#{base}.react_component, args[0], null, block); }
|
16
|
-
} else { Opal.React.internal_render(#{base}.react_component, null, null, block); }
|
17
|
-
}
|
9
|
+
`Opal.React.internal_prepare_args_and_render(#{base}.react_component, args, block)`
|
18
10
|
end
|
19
11
|
else
|
20
12
|
Object.define_method(base.to_s) do |*args, &block|
|
21
|
-
|
22
|
-
if (args.length > 0) {
|
23
|
-
var last_arg = args[args.length - 1];
|
24
|
-
if (typeof last_arg === 'string' || last_arg instanceof String) {
|
25
|
-
if (args.length === 1) { Opal.React.internal_render(#{base}.react_component, null, last_arg, null); }
|
26
|
-
else { Opal.React.internal_render(#{base}.react_component, args[0], last_arg, null); }
|
27
|
-
} else { Opal.React.internal_render(#{base}.react_component, args[0], null, block); }
|
28
|
-
} else { Opal.React.internal_render(#{base}.react_component, null, null, block); }
|
29
|
-
}
|
13
|
+
`Opal.React.internal_prepare_args_and_render(#{base}.react_component, args, block)`
|
30
14
|
end
|
31
15
|
end
|
32
16
|
|
33
|
-
|
34
17
|
attr_accessor :props
|
35
18
|
attr_accessor :state
|
36
19
|
|
37
20
|
def ref(ref_name, &block)
|
38
|
-
defined_refs.JS[ref_name] =
|
39
|
-
block
|
40
|
-
else
|
41
|
-
`null`
|
42
|
-
end
|
21
|
+
defined_refs.JS[ref_name] = block_given? ? block : `null`
|
43
22
|
end
|
44
23
|
|
45
24
|
def defined_refs
|
@@ -137,76 +116,11 @@ module React
|
|
137
116
|
self.lucid_react_component.defaultProps = {};
|
138
117
|
}
|
139
118
|
}
|
140
|
-
@default_props = React
|
141
|
-
end
|
142
|
-
|
143
|
-
def component_did_catch(&block)
|
144
|
-
# TODO convert error and info
|
145
|
-
%x{
|
146
|
-
self.react_component.prototype.componentDidCatch = function(error, info) {
|
147
|
-
return #{`this.__ruby_instance`.instance_exec(error, info, &block)};
|
148
|
-
}
|
149
|
-
}
|
150
|
-
end
|
151
|
-
|
152
|
-
def component_did_mount(&block)
|
153
|
-
%x{
|
154
|
-
self.react_component.prototype.componentDidMount = function() {
|
155
|
-
return #{`this.__ruby_instance`.instance_exec(&block)};
|
156
|
-
}
|
157
|
-
}
|
158
|
-
end
|
159
|
-
|
160
|
-
def component_did_update(&block)
|
161
|
-
%x{
|
162
|
-
self.react_component.prototype.componentDidUpdate = function() {
|
163
|
-
return #{`this.__ruby_instance`.instance_exec(&block)};
|
164
|
-
}
|
165
|
-
}
|
166
|
-
end
|
167
|
-
|
168
|
-
def component_will_unmount(&block)
|
169
|
-
%x{
|
170
|
-
self.react_component.prototype.componentWillUnmount = function() {
|
171
|
-
return #{`this.__ruby_instance`.instance_exec(&block)};
|
172
|
-
}
|
173
|
-
}
|
174
|
-
end
|
175
|
-
|
176
|
-
def get_derived_state_from_error(&block)
|
177
|
-
%x{
|
178
|
-
self.react_component.prototype.getDerivedStateFromError = function(error) {
|
179
|
-
return #{`this.__ruby_instance`.instance_exec(error, &block)};
|
180
|
-
}
|
181
|
-
}
|
182
|
-
end
|
183
|
-
|
184
|
-
def get_derived_state_from_props(&block)
|
185
|
-
%x{
|
186
|
-
self.react_component.prototype.getDerivedStateFromProps = function(props, state) {
|
187
|
-
return #{`this.__ruby_instance`.instance_exec(React::Component::Props.new(`props`), `Opal.Hash.$new(state)`, &block)};
|
188
|
-
}
|
189
|
-
}
|
190
|
-
end
|
191
|
-
|
192
|
-
def get_snapshot_before_update(&block)
|
193
|
-
%x{
|
194
|
-
self.react_component.prototype.getSnapshotBeforeUpdate = function(prev_props, prev_state) {
|
195
|
-
return #{`this.__ruby_instance`.instance_exec(React::Component::Props.new(`prev_props`), `Opal.Hash.$new(prev_state)`, &block)};
|
196
|
-
}
|
197
|
-
}
|
119
|
+
@default_props = `Opal.React.Component.Props.$new(self.react_component.defaultProps)`
|
198
120
|
end
|
199
121
|
|
200
122
|
def render(&block)
|
201
|
-
|
202
|
-
self.react_component.prototype.render = function() {
|
203
|
-
Opal.React.render_buffer.push([]);
|
204
|
-
Opal.React.active_components.push(this);
|
205
|
-
#{`this.__ruby_instance`.instance_exec(&block)};
|
206
|
-
Opal.React.active_components.pop();
|
207
|
-
return Opal.React.render_buffer.pop();
|
208
|
-
}
|
209
|
-
}
|
123
|
+
`base.render_block = block`
|
210
124
|
end
|
211
125
|
end
|
212
126
|
end
|