isomorfeus-react 16.13.10 → 16.13.11
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 +2 -10
- data/lib/isomorfeus-react-native.rb +5 -0
- data/lib/isomorfeus-react-paper.rb +4 -0
- data/lib/isomorfeus-react.rb +6 -4
- data/lib/isomorfeus/props/validator.rb +2 -2
- data/lib/isomorfeus/{react_config.rb → react/config.rb} +0 -0
- data/lib/isomorfeus/react/memcached_component_cache.rb +19 -0
- data/lib/isomorfeus/react/redis_component_cache.rb +19 -0
- data/lib/isomorfeus/{thread_local_component_cache.rb → react/thread_local_component_cache.rb} +0 -0
- data/lib/isomorfeus_react/lucid_app/mixin.rb +1 -0
- data/lib/isomorfeus_react/lucid_app/native_component_constructor.rb +0 -1
- data/lib/isomorfeus_react/lucid_component/api.rb +0 -27
- data/lib/isomorfeus_react/lucid_component/mixin.rb +1 -0
- data/lib/isomorfeus_react/lucid_component/styles_api.rb +34 -0
- data/lib/isomorfeus_react/lucid_func/mixin.rb +1 -0
- data/lib/isomorfeus_react/react/function_component/api.rb +7 -6
- data/lib/isomorfeus_react_material/lucid_material/app/mixin.rb +1 -0
- data/lib/isomorfeus_react_material/lucid_material/app/native_component_constructor.rb +0 -1
- data/lib/isomorfeus_react_material/lucid_material/component/mixin.rb +1 -0
- data/lib/isomorfeus_react_material/lucid_material/func/mixin.rb +1 -0
- data/lib/isomorfeus_react_paper/lucid_paper/app/base.rb +9 -0
- data/lib/isomorfeus_react_paper/lucid_paper/app/mixin.rb +19 -0
- data/lib/isomorfeus_react_paper/lucid_paper/app/native_component_constructor.rb +32 -0
- data/lib/isomorfeus_react_paper/lucid_paper/component/base.rb +9 -0
- data/lib/isomorfeus_react_paper/lucid_paper/component/mixin.rb +18 -0
- data/lib/isomorfeus_react_paper/lucid_paper/component/native_component_constructor.rb +25 -0
- data/lib/isomorfeus_react_paper/lucid_paper/func/base.rb +9 -0
- data/lib/isomorfeus_react_paper/lucid_paper/func/mixin.rb +14 -0
- data/lib/isomorfeus_react_paper/lucid_paper/func/native_component_constructor.rb +71 -0
- data/lib/react.rb +6 -5
- data/lib/react/component/api.rb +5 -4
- data/lib/react/version.rb +1 -1
- data/lib/react_native/component/elements.rb +203 -0
- data/lib/react_native/lucid_app/react_native_component_constructor.rb +51 -0
- data/lib/react_native/lucid_component/react_native_component_constructor.rb +37 -0
- data/lib/react_native/lucid_func/react_native_component_constructor.rb +82 -0
- data/lib/react_native/react.rb +120 -0
- metadata +69 -22
@@ -0,0 +1,14 @@
|
|
1
|
+
module LucidPaper
|
2
|
+
module Func
|
3
|
+
module Mixin
|
4
|
+
def self.included(base)
|
5
|
+
base.include(::React::Component::Elements)
|
6
|
+
base.include(::React::Component::Features)
|
7
|
+
base.include(::LucidFunc::Initializer)
|
8
|
+
base.include(::React::FunctionComponent::Api)
|
9
|
+
base.extend(::LucidPaper::Func::NativeComponentConstructor)
|
10
|
+
base.include(::LucidComponent::Api)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module LucidPaper
|
2
|
+
module Func
|
3
|
+
module NativeComponentConstructor
|
4
|
+
def self.extended(base)
|
5
|
+
component_name = "#{base.to_s}Wrapper"
|
6
|
+
%x{
|
7
|
+
base.store_updates = true;
|
8
|
+
base.equality_checker = null;
|
9
|
+
base.instance_init = function(initial) {
|
10
|
+
let ruby_state = { instance: #{base.new(`{}`)} };
|
11
|
+
ruby_state.instance.__ruby_instance = ruby_state.instance;
|
12
|
+
ruby_state.instance.data_access = function() { return this.props.store; }
|
13
|
+
ruby_state.instance.data_access.bind(ruby_state.instance);
|
14
|
+
return ruby_state;
|
15
|
+
}
|
16
|
+
base.instance_reducer = function(state, action) { return state; }
|
17
|
+
base.react_component = Opal.global.React.memo(function(props) {
|
18
|
+
const og = Opal.global;
|
19
|
+
const oper = Opal.React;
|
20
|
+
oper.render_buffer.push([]);
|
21
|
+
// console.log("function pushed", oper.render_buffer, oper.render_buffer.toString());
|
22
|
+
// Lucid functionality
|
23
|
+
let store;
|
24
|
+
if (base.store_updates) { store = og.React.useContext(og.LucidApplicationContext); }
|
25
|
+
// prepare Ruby instance
|
26
|
+
const [__ruby_state, __ruby_dispatch] = og.React.useReducer(base.instance_reducer, null, base.instance_init);
|
27
|
+
const __ruby_instance = __ruby_state.instance;
|
28
|
+
__ruby_instance.props = Object.assign({}, props);
|
29
|
+
__ruby_instance.props.store = store;
|
30
|
+
__ruby_instance.props.theme = Opal.global.Paper.useTheme();
|
31
|
+
oper.active_components.push(__ruby_instance);
|
32
|
+
oper.active_redux_components.push(__ruby_instance);
|
33
|
+
let block_result = #{`__ruby_instance`.instance_exec(&`base.render_block`)};
|
34
|
+
if (block_result && block_result !== nil) { oper.render_block_result(block_result); }
|
35
|
+
oper.active_redux_components.pop();
|
36
|
+
oper.active_components.pop();
|
37
|
+
// console.log("function popping", oper.render_buffer, oper.render_buffer.toString());
|
38
|
+
let result = oper.render_buffer.pop();
|
39
|
+
return (result.length === 1) ? result[0] : result;
|
40
|
+
}, base.equality_checker);
|
41
|
+
base.react_component.displayName = #{component_name};
|
42
|
+
}
|
43
|
+
|
44
|
+
base_module = base.to_s.deconstantize
|
45
|
+
if base_module != ''
|
46
|
+
base_module.constantize.define_singleton_method(base.to_s.demodulize) do |*args, &block|
|
47
|
+
`Opal.React.internal_prepare_args_and_render(#{base}.react_component, args, block)`
|
48
|
+
end
|
49
|
+
else
|
50
|
+
Object.define_method(base.to_s) do |*args, &block|
|
51
|
+
`Opal.React.internal_prepare_args_and_render(#{base}.react_component, args, block)`
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def props_are_equal?(&block)
|
56
|
+
%x{
|
57
|
+
base.equality_checker = function (prev_props, next_props) {
|
58
|
+
var prev_ruby_props = Opal.React.Component.Props.$new({props: prev_props});
|
59
|
+
var next_ruby_props = Opal.React.Component.Props.$new({props: next_props});
|
60
|
+
return #{block.call(`prev_ruby_props`, `next_ruby_props`)};
|
61
|
+
}
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def render(&block)
|
66
|
+
`base.render_block = #{block}`
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/react.rb
CHANGED
@@ -135,11 +135,12 @@ module React
|
|
135
135
|
let ruby_event = self.native_to_ruby_event(event);
|
136
136
|
#{`active_c.__ruby_instance`.instance_exec(`ruby_event`, `info`, &`value`)};
|
137
137
|
}
|
138
|
-
} else if (type === "object" && typeof value.$call === "function" ) {
|
138
|
+
} else if (type === "object" && typeof value.m === "object" && typeof value.m.$call === "function" ) {
|
139
139
|
if (!value.react_event_handler_function) {
|
140
140
|
value.react_event_handler_function = function(event, info) {
|
141
141
|
let ruby_event = self.native_to_ruby_event(event);
|
142
|
-
value.$call(ruby_event, info)
|
142
|
+
if (value.a.length > 0) { value.m.$call.apply(value.m, [ruby_event, info].concat(value.a)); }
|
143
|
+
else { value.m.$call(ruby_event, info); }
|
143
144
|
};
|
144
145
|
}
|
145
146
|
result[self.lower_camelize(key)] = value.react_event_handler_function;
|
@@ -161,7 +162,7 @@ module React
|
|
161
162
|
if (!method_ref.react_event_handler_function) {
|
162
163
|
method_ref.react_event_handler_function = function(event, info) {
|
163
164
|
let ruby_event = self.native_to_ruby_event(event);
|
164
|
-
method_ref.$call(ruby_event, info)
|
165
|
+
method_ref.m.$call(ruby_event, info)
|
165
166
|
};
|
166
167
|
}
|
167
168
|
result[self.lower_camelize(key)] = method_ref.react_event_handler_function;
|
@@ -181,9 +182,9 @@ module React
|
|
181
182
|
}
|
182
183
|
} else if (key[0] === 'a' && key.startsWith("aria_")) {
|
183
184
|
result[key.replace("_", "-")] = value;
|
184
|
-
} else if (key === "style") {
|
185
|
+
} else if (key === "style" || key === "theme") {
|
185
186
|
if (typeof value.$to_n === "function") { value = value.$to_n() }
|
186
|
-
result[
|
187
|
+
result[key] = value;
|
187
188
|
} else {
|
188
189
|
result[self.lower_camelize(key)] = value;
|
189
190
|
}
|
data/lib/react/component/api.rb
CHANGED
@@ -98,12 +98,13 @@ module React
|
|
98
98
|
end
|
99
99
|
alias gre get_react_element
|
100
100
|
|
101
|
-
def method_ref(method_symbol)
|
101
|
+
def method_ref(method_symbol, *args)
|
102
|
+
method_key = "#{method_symbol}#{args}"
|
102
103
|
%x{
|
103
|
-
if (#@native.method_refs && #@native.method_refs[#{
|
104
|
+
if (#@native.method_refs && #@native.method_refs[#{method_key}]) { return #@native.method_refs[#{method_key}]; }
|
104
105
|
if (!#@native.method_refs) { #@native.method_refs = {}; }
|
105
|
-
#@native.method_refs[#{
|
106
|
-
return #@native.method_refs[#{
|
106
|
+
#@native.method_refs[#{method_key}] = { m: #{method(method_symbol)}, a: args };
|
107
|
+
return #@native.method_refs[#{method_key}];
|
107
108
|
}
|
108
109
|
end
|
109
110
|
alias m_ref method_ref
|
data/lib/react/version.rb
CHANGED
@@ -0,0 +1,203 @@
|
|
1
|
+
module ReactNative
|
2
|
+
module Component
|
3
|
+
module Elements
|
4
|
+
# https://www.w3.org/TR/html52/fullindex.html#index-elements
|
5
|
+
# https://www.w3.org/TR/SVG11/eltindex.html
|
6
|
+
UNSUPPORTED_HTML_AND_SVG_ELEMENTS = %w[
|
7
|
+
a abbr address area article aside audio
|
8
|
+
base bdi bdo blockquote body br
|
9
|
+
canvas caption cite col colgroup
|
10
|
+
data datalist dd del details dfn dialog dl dt
|
11
|
+
em embed
|
12
|
+
fieldset figcaption figure footer form
|
13
|
+
head header hr html
|
14
|
+
iframe ins
|
15
|
+
kbd
|
16
|
+
label legend li link
|
17
|
+
main map mark meta meter
|
18
|
+
nav noscript
|
19
|
+
object ol optgroup option output
|
20
|
+
param picture progress
|
21
|
+
q
|
22
|
+
rp rt rtc ruby
|
23
|
+
s samp script section select small source span strong style sub summary sup
|
24
|
+
table tbody td template textarea tfoot th thead time title tr track
|
25
|
+
ul
|
26
|
+
var video
|
27
|
+
wbr
|
28
|
+
|
29
|
+
altGlyph altGlyphDef altGlyphItem animate animateColor animateMotion animateTransform
|
30
|
+
color-profile cursor
|
31
|
+
desc
|
32
|
+
feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting
|
33
|
+
feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur
|
34
|
+
feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting
|
35
|
+
feSpotLight feTile feTurbulence
|
36
|
+
filter font font-face font-face-format font-face-name font-face-src font-face-uri
|
37
|
+
glyph glyphRef
|
38
|
+
hkern
|
39
|
+
metadata missing-glyph mpath
|
40
|
+
script set style switch
|
41
|
+
tref
|
42
|
+
view vkern
|
43
|
+
]
|
44
|
+
|
45
|
+
UNSUPPORTED_HTML_AND_SVG_ELEMENTS.each do |element|
|
46
|
+
define_method(element) do |*args, &block|
|
47
|
+
`console.warn("Element " + element + " is not yet supported, using a Text component as substitute!")`
|
48
|
+
`Opal.React.internal_prepare_args_and_render(Opal.global.Text, args, block)`
|
49
|
+
end
|
50
|
+
define_method(`element.toUpperCase()`) do |*args, &block|
|
51
|
+
`console.warn("Element " + element + " is not yet supported, using a Text component as substitute!")`
|
52
|
+
`Opal.React.internal_prepare_args_and_render(Opal.global.Text, args, block)`
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# button
|
57
|
+
%x{
|
58
|
+
self['supported_button'] = function(props) {
|
59
|
+
let theme = Opal.global.React.useContext(Opal.global.ThemeContext);
|
60
|
+
let style = {};
|
61
|
+
if (theme && typeof theme['button'] !== 'undefined') { style = theme['button']; }
|
62
|
+
if (typeof props.style !== 'undefined') {
|
63
|
+
style = Opal.React.merge_deep(style, props.style);
|
64
|
+
}
|
65
|
+
let new_props = Object.assign({}, props, { style: style });
|
66
|
+
if (typeof props.title === 'undefined') {
|
67
|
+
try {
|
68
|
+
new_props.title = props.children.props.children;
|
69
|
+
} catch (e) {
|
70
|
+
console.error("BUTTON accepts only one string child!")
|
71
|
+
}
|
72
|
+
}
|
73
|
+
return Opal.global.React.createElement(Opal.global.Button, new_props);
|
74
|
+
}
|
75
|
+
self['supported_button'].displayName = 'BUTTON';
|
76
|
+
}
|
77
|
+
define_method('button') do |*args, &block|
|
78
|
+
`Opal.React.internal_prepare_args_and_render(Opal.ReactNative.Component.Elements.supported_button, args, block)`
|
79
|
+
end
|
80
|
+
define_method('BUTTON') do |*args, &block|
|
81
|
+
`Opal.React.internal_prepare_args_and_render(Opal.ReactNative.Component.Elements.supported_button, args, block)`
|
82
|
+
end
|
83
|
+
|
84
|
+
# img
|
85
|
+
define_method('img') do |*args, &block|
|
86
|
+
`Opal.React.internal_prepare_args_and_render(Opal.global.Image, args, block)`
|
87
|
+
end
|
88
|
+
define_method('IMG') do |*args, &block|
|
89
|
+
`Opal.React.internal_prepare_args_and_render(Opal.global.Image, args, block)`
|
90
|
+
end
|
91
|
+
|
92
|
+
# input
|
93
|
+
%x{
|
94
|
+
self.supported_input = function(props) {
|
95
|
+
Opal.React.render_buffer.push([]);
|
96
|
+
if (typeof props.type !== 'undefined') {
|
97
|
+
if (props.type === 'text') { return Opal.React.internal_prepare_args_and_render(Opal.global.TextInput, props); }
|
98
|
+
else if (props.type === 'checkbox') { return Opal.React.internal_prepare_args_and_render(Opal.global.InputSwitch, props); }
|
99
|
+
else {
|
100
|
+
console.warn("Input type " + props.type + " not supported. Using TextInput as substitute!");
|
101
|
+
return Opal.React.internal_prepare_args_and_render(Opal.global.TextInput, props);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
Opal.React.internal_prepare_args_and_render(Opal.global.TextInput, props);
|
105
|
+
return Opal.React.render_buffer.pop();
|
106
|
+
}
|
107
|
+
}
|
108
|
+
define_method('input') do |*args, &block|
|
109
|
+
`Opal.React.internal_prepare_args_and_render(Opal.ReactNative.Component.Elements.supported_input, args, block)`
|
110
|
+
end
|
111
|
+
define_method('INPUT') do |*args, &block|
|
112
|
+
`Opal.React.internal_prepare_args_and_render(Opal.ReactNative.Component.Elements.supported_input, args, block)`
|
113
|
+
end
|
114
|
+
|
115
|
+
# elements that map to Text with style
|
116
|
+
SUPPORTED_TEXT_HTML_ELEMENTS = %w[
|
117
|
+
b
|
118
|
+
code
|
119
|
+
h1 h2 h3 h4 h5 h6
|
120
|
+
i
|
121
|
+
pre
|
122
|
+
span
|
123
|
+
u
|
124
|
+
]
|
125
|
+
|
126
|
+
SUPPORTED_TEXT_HTML_ELEMENTS.each do |element|
|
127
|
+
fun_name = 'supported_' + element
|
128
|
+
%x{
|
129
|
+
self[fun_name] = function(props) {
|
130
|
+
let theme = Opal.global.React.useContext(Opal.global.ThemeContext);
|
131
|
+
let style = {};
|
132
|
+
if (theme && typeof theme[element] !== 'undefined') { style = theme[element]; }
|
133
|
+
if (typeof props.style !== 'undefined') {
|
134
|
+
style = Opal.React.merge_deep(style, props.style);
|
135
|
+
}
|
136
|
+
let new_props = Object.assign({}, props, { style: style });
|
137
|
+
return Opal.global.React.createElement(Opal.global.Text, new_props);
|
138
|
+
}
|
139
|
+
self[fun_name].displayName = element.toUpperCase();
|
140
|
+
}
|
141
|
+
define_method(`element.toLowerCase()`) do |*args, &block|
|
142
|
+
`Opal.React.internal_prepare_args_and_render(Opal.ReactNative.Component.Elements[fun_name], args, block)`
|
143
|
+
end
|
144
|
+
define_method(`element.toUpperCase()`) do |*args, &block|
|
145
|
+
`Opal.React.internal_prepare_args_and_render(Opal.ReactNative.Component.Elements[fun_name], args, block)`
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
SUPPORTED_VIEW_HTML_ELEMENTS = %w[
|
150
|
+
div
|
151
|
+
p
|
152
|
+
]
|
153
|
+
|
154
|
+
SUPPORTED_VIEW_HTML_ELEMENTS.each do |element|
|
155
|
+
fun_name = 'supported_' + element
|
156
|
+
%x{
|
157
|
+
self[fun_name] = function(props) {
|
158
|
+
let theme = Opal.global.React.useContext(Opal.global.ThemeContext);
|
159
|
+
let style = {};
|
160
|
+
if (theme && typeof theme[element] !== 'undefined') { style = theme[element]; }
|
161
|
+
if (typeof props.style !== 'undefined') {
|
162
|
+
style = Opal.React.merge_deep(style, props.style);
|
163
|
+
}
|
164
|
+
let new_props = Object.assign({}, props, { style: style });
|
165
|
+
return Opal.global.React.createElement(Opal.global.View, new_props);
|
166
|
+
}
|
167
|
+
self[fun_name].displayName = element.toUpperCase();
|
168
|
+
}
|
169
|
+
define_method(`element.toLowerCase()`) do |*args, &block|
|
170
|
+
`Opal.React.internal_prepare_args_and_render(Opal.ReactNative.Component.Elements[fun_name], args, block)`
|
171
|
+
end
|
172
|
+
define_method(`element.toUpperCase()`) do |*args, &block|
|
173
|
+
`Opal.React.internal_prepare_args_and_render(Opal.ReactNative.Component.Elements[fun_name], args, block)`
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
SUPPORTED_SVG_ELEMENTS = %w[
|
178
|
+
Circle ClipPath
|
179
|
+
Defs
|
180
|
+
Ellipse
|
181
|
+
ForeignObject
|
182
|
+
G
|
183
|
+
Image
|
184
|
+
Line LinearGradient
|
185
|
+
Marker Mask
|
186
|
+
Path Pattern Polygon Polyline
|
187
|
+
RadialGradient Rect
|
188
|
+
Stop Svg Symbol
|
189
|
+
Text TextPath TSpan
|
190
|
+
Use
|
191
|
+
]
|
192
|
+
|
193
|
+
SUPPORTED_SVG_ELEMENTS.each do |element|
|
194
|
+
define_method(`element.toLowerCase()`) do |*args, &block|
|
195
|
+
`Opal.React.internal_prepare_args_and_render(Opal.global.ReactNativeSvg[element], args, block)`
|
196
|
+
end
|
197
|
+
define_method(`element.toUpperCase()`) do |*args, &block|
|
198
|
+
`Opal.React.internal_prepare_args_and_render(Opal.global.ReactNativeSvg[element], args, block)`
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module LucidApp
|
2
|
+
module ReactNativeComponentConstructor
|
3
|
+
# for should_component_update we apply ruby semantics for comparing props
|
4
|
+
# to do so, we convert the props to ruby hashes and then compare
|
5
|
+
# this makes sure, that for example rubys Nil object gets handled properly
|
6
|
+
def self.extended(base)
|
7
|
+
component_name = base.to_s + 'Wrapper'
|
8
|
+
theme_component_name = base.to_s + 'ThemeWrapper'
|
9
|
+
# language=JS
|
10
|
+
%x{
|
11
|
+
base.jss_theme = {};
|
12
|
+
base.themed_react_component = function(props) {
|
13
|
+
const opag = Opal.global;
|
14
|
+
const theme = opag.React.useContext(opag.ThemeContext);
|
15
|
+
let classes;
|
16
|
+
if (base.jss_styles) {
|
17
|
+
if (!base.use_styles || (Opal.Isomorfeus.development === true)) {
|
18
|
+
let styles;
|
19
|
+
if (typeof base.jss_styles === 'function') { styles = base.jss_styles(theme); }
|
20
|
+
else { styles = base.jss_styles; }
|
21
|
+
base.use_styles = Opal.React.merge_deep(theme, opag.StyleSheet.create(styles));
|
22
|
+
}
|
23
|
+
classes = base.use_styles;
|
24
|
+
} else {
|
25
|
+
classes = theme;
|
26
|
+
}
|
27
|
+
let themed_classes_props = Object.assign({}, props, { classes: classes, theme: theme });
|
28
|
+
return opag.React.createElement(base.lucid_react_component, themed_classes_props);
|
29
|
+
};
|
30
|
+
base.themed_react_component.displayName = #{theme_component_name};
|
31
|
+
base.react_component = class extends Opal.global.React.Component {
|
32
|
+
constructor(props) {
|
33
|
+
super(props);
|
34
|
+
if (Opal.Isomorfeus.$top_component() == nil) { Opal.Isomorfeus['$top_component='](this); }
|
35
|
+
}
|
36
|
+
static get displayName() {
|
37
|
+
return "IsomorfeusTopLevelComponent";
|
38
|
+
}
|
39
|
+
static set displayName(new_name) {
|
40
|
+
// dont do anything here except returning the set value
|
41
|
+
return new_name;
|
42
|
+
}
|
43
|
+
render() {
|
44
|
+
let themed_component = Opal.global.React.createElement(base.themed_react_component, this.props);
|
45
|
+
return Opal.global.React.createElement(Opal.global.ThemeContext.Provider, { value: Opal.global.DefaultTheme }, themed_component);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module LucidComponent
|
2
|
+
module ReactNativeComponentConstructor
|
3
|
+
# for should_component_update we apply ruby semantics for comparing props
|
4
|
+
# to do so, we convert the props to ruby hashes and then compare
|
5
|
+
# this makes sure, that for example rubys Nil object gets handled properly
|
6
|
+
def self.extended(base)
|
7
|
+
component_name = base.to_s + 'Wrapper'
|
8
|
+
# language=JS
|
9
|
+
%x{
|
10
|
+
base.react_component = Opal.global.React.memo(function(props) {
|
11
|
+
let opag = Opal.global;
|
12
|
+
let store;
|
13
|
+
if (base.store_updates) { store = opag.React.useContext(opag.LucidApplicationContext); }
|
14
|
+
const theme = opag.React.useContext(opag.ThemeContext);
|
15
|
+
let classes;
|
16
|
+
if (base.jss_styles) {
|
17
|
+
if (!base.use_styles || (Opal.Isomorfeus.development === true)) {
|
18
|
+
let styles;
|
19
|
+
if (typeof base.jss_styles === 'function') { styles = base.jss_styles(theme); }
|
20
|
+
else { styles = base.jss_styles; }
|
21
|
+
base.use_styles = Opal.React.merge_deep(theme, opag.StyleSheet.create(styles));
|
22
|
+
}
|
23
|
+
classes = base.use_styles;
|
24
|
+
} else {
|
25
|
+
classes = theme;
|
26
|
+
}
|
27
|
+
let new_props = Object.assign({}, props);
|
28
|
+
new_props.theme = theme;
|
29
|
+
new_props.classes = classes;
|
30
|
+
new_props.store = store;
|
31
|
+
return opag.React.createElement(base.lucid_react_component, new_props);
|
32
|
+
}, Opal.React.props_are_equal);
|
33
|
+
base.react_component.displayName = #{component_name};
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|