isomorfeus-react 16.5.1
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 +7 -0
- data/Gemfile +1 -0
- data/README.md +620 -0
- data/isomorfeus-react.gemspec +23 -0
- data/lib/isomorfeus-react.rb +131 -0
- data/lib/isomorfeus/config.rb +84 -0
- data/lib/isomorfeus/top_level.rb +48 -0
- data/lib/isomorfeus/view_helpers.rb +38 -0
- data/lib/lucid_app/api.rb +22 -0
- data/lib/lucid_app/base.rb +7 -0
- data/lib/lucid_app/context.rb +7 -0
- data/lib/lucid_app/mixin.rb +17 -0
- data/lib/lucid_app/native_component_constructor.rb +70 -0
- data/lib/lucid_component/api.rb +97 -0
- data/lib/lucid_component/base.rb +7 -0
- data/lib/lucid_component/event_handler.rb +17 -0
- data/lib/lucid_component/initializer.rb +12 -0
- data/lib/lucid_component/mixin.rb +17 -0
- data/lib/lucid_component/native_component_constructor.rb +131 -0
- data/lib/react.rb +147 -0
- data/lib/react/active_support_support.rb +13 -0
- data/lib/react/component/api.rb +226 -0
- data/lib/react/component/base.rb +9 -0
- data/lib/react/component/elements.rb +78 -0
- data/lib/react/component/event_handler.rb +19 -0
- data/lib/react/component/features.rb +47 -0
- data/lib/react/component/history.rb +36 -0
- data/lib/react/component/initializer.rb +11 -0
- data/lib/react/component/location.rb +15 -0
- data/lib/react/component/match.rb +31 -0
- data/lib/react/component/mixin.rb +19 -0
- data/lib/react/component/native_component_constructor.rb +76 -0
- data/lib/react/component/native_component_validate_prop.rb +37 -0
- data/lib/react/component/props.rb +49 -0
- data/lib/react/component/resolution.rb +71 -0
- data/lib/react/component/should_component_update.rb +14 -0
- data/lib/react/component/state.rb +52 -0
- data/lib/react/component/unsafe_api.rb +33 -0
- data/lib/react/context_wrapper.rb +47 -0
- data/lib/react/function_component/creator.rb +47 -0
- data/lib/react/function_component/resolution.rb +61 -0
- data/lib/react/function_component/runner.rb +19 -0
- data/lib/react/native_constant_wrapper.rb +34 -0
- data/lib/react/pure_component/base.rb +9 -0
- data/lib/react/pure_component/mixin.rb +17 -0
- data/lib/react/redux_component/api.rb +132 -0
- data/lib/react/redux_component/app_store_defaults.rb +38 -0
- data/lib/react/redux_component/app_store_proxy.rb +46 -0
- data/lib/react/redux_component/base.rb +9 -0
- data/lib/react/redux_component/class_store_proxy.rb +50 -0
- data/lib/react/redux_component/component_class_store_defaults.rb +40 -0
- data/lib/react/redux_component/component_instance_store_defaults.rb +41 -0
- data/lib/react/redux_component/initializer.rb +14 -0
- data/lib/react/redux_component/instance_store_proxy.rb +50 -0
- data/lib/react/redux_component/mixin.rb +18 -0
- data/lib/react/redux_component/native_component_constructor.rb +119 -0
- data/lib/react/redux_component/reducers.rb +53 -0
- data/lib/react/ref.rb +19 -0
- data/lib/react/synthetic_event.rb +53 -0
- data/lib/react/version.rb +3 -0
- data/lib/react_dom.rb +31 -0
- data/lib/react_dom_server.rb +17 -0
- metadata +167 -0
@@ -0,0 +1,226 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module API
|
4
|
+
def self.included(base)
|
5
|
+
base.instance_exec do
|
6
|
+
base_module = base.to_s.deconstantize
|
7
|
+
if base_module != ''
|
8
|
+
base_module.constantize.define_singleton_method(base.to_s.demodulize) do |*args, &block|
|
9
|
+
%x{
|
10
|
+
var props = null;
|
11
|
+
|
12
|
+
if (args.length > 0) {
|
13
|
+
props = Opal.React.to_native_react_props(args[0]);
|
14
|
+
}
|
15
|
+
Opal.React.internal_render(#{base}.react_component, props, block);
|
16
|
+
}
|
17
|
+
end
|
18
|
+
else
|
19
|
+
Object.define_method(base.to_s) do |*args, &block|
|
20
|
+
%x{
|
21
|
+
var props = null;
|
22
|
+
|
23
|
+
if (args.length > 0) {
|
24
|
+
props = Opal.React.to_native_react_props(args[0]);
|
25
|
+
}
|
26
|
+
Opal.React.internal_render(#{base}.react_component, props, block);
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
attr_accessor :props
|
33
|
+
attr_accessor :state
|
34
|
+
|
35
|
+
def ref(ref_name, &block)
|
36
|
+
defined_refs.JS[ref_name] = if block_given?
|
37
|
+
block
|
38
|
+
else
|
39
|
+
`null`
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def defined_refs
|
44
|
+
@defined_ref ||= `{}`
|
45
|
+
end
|
46
|
+
|
47
|
+
def default_state_defined
|
48
|
+
@default_state_defined
|
49
|
+
end
|
50
|
+
|
51
|
+
def state
|
52
|
+
return @default_state if @default_state
|
53
|
+
@default_state_defined = true
|
54
|
+
%x{
|
55
|
+
var native_state = {state: {}};
|
56
|
+
native_state.setState = function(new_state, callback) {
|
57
|
+
for (var key in new_state) {
|
58
|
+
this.state[key] = new_state[key];
|
59
|
+
}
|
60
|
+
if (callback) { callback.call(); }
|
61
|
+
}
|
62
|
+
}
|
63
|
+
@default_state = React::Component::State.new(`native_state`)
|
64
|
+
end
|
65
|
+
|
66
|
+
def prop(name, options = `null`)
|
67
|
+
name = `Opal.React.lower_camelize(name)`
|
68
|
+
if options
|
69
|
+
if options.has_key?(:default)
|
70
|
+
%x{
|
71
|
+
if (typeof self.react_component.defaultProps == "undefined") {
|
72
|
+
self.react_component.defaultProps = {};
|
73
|
+
}
|
74
|
+
self.react_component.defaultProps[name] = options.$fetch("default");
|
75
|
+
}
|
76
|
+
end
|
77
|
+
if options.has_key?(:class)
|
78
|
+
%x{
|
79
|
+
if (typeof self.react_component.propTypes == "undefined") {
|
80
|
+
self.react_component.propTypes = {};
|
81
|
+
self.react_component.propValidations = {};
|
82
|
+
self.react_component.propValidations[name] = {};
|
83
|
+
}
|
84
|
+
self.react_component.propTypes[name] = self.react_component.prototype.validateProp;
|
85
|
+
self.react_component.propValidations[name].ruby_class = options.$fetch("class");
|
86
|
+
}
|
87
|
+
elsif options.has_key?(:is_a)
|
88
|
+
%x{
|
89
|
+
if (typeof self.react_component.propTypes == "undefined") {
|
90
|
+
self.react_component.propTypes = {};
|
91
|
+
self.react_component.propValidations = {};
|
92
|
+
self.react_component.propValidations[name] = {};
|
93
|
+
}
|
94
|
+
self.react_component.propTypes[name] = self.react_component.prototype.validateProp;
|
95
|
+
self.react_component.propValidations[name].is_a = options.$fetch("is_a");
|
96
|
+
}
|
97
|
+
end
|
98
|
+
if options.has_key?(:required)
|
99
|
+
%x{
|
100
|
+
if (typeof self.react_component.propTypes == "undefined") {
|
101
|
+
self.react_component.propTypes = {};
|
102
|
+
self.react_component.propValidations = {};
|
103
|
+
self.react_component.propValidations[name] = {};
|
104
|
+
}
|
105
|
+
self.react_component.propTypes[name] = self.react_component.prototype.validateProp;
|
106
|
+
self.react_component.propValidations[name].required = options.$fetch("required");
|
107
|
+
}
|
108
|
+
elsif !options.has_key?(:default)
|
109
|
+
%x{
|
110
|
+
if (typeof self.react_component.propTypes == "undefined") {
|
111
|
+
self.react_component.propTypes = {};
|
112
|
+
self.react_component.propValidations = {};
|
113
|
+
}
|
114
|
+
self.react_component.propTypes[name] = self.react_component.prototype.validateProp;
|
115
|
+
self.react_component.propValidations[name].required = true;
|
116
|
+
}
|
117
|
+
end
|
118
|
+
else
|
119
|
+
%x{
|
120
|
+
if (typeof self.react_component.propTypes == "undefined") {
|
121
|
+
self.react_component.propTypes = {};
|
122
|
+
self.react_component.propValidations = {};
|
123
|
+
self.react_component.propValidations[name] = {};
|
124
|
+
}
|
125
|
+
self.react_component.propTypes[name] = self.react_component.prototype.validateProp;
|
126
|
+
self.react_component.propValidations[name].required = options.$fetch("required");
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def default_props
|
132
|
+
return @default_props if @default_props
|
133
|
+
%x{
|
134
|
+
if (typeof self.react_component.defaultProps == "undefined") {
|
135
|
+
self.lucid_react_component.defaultProps = {};
|
136
|
+
}
|
137
|
+
}
|
138
|
+
@default_props = React::Component::Props.new(`self.react_component.defaultProps`)
|
139
|
+
end
|
140
|
+
|
141
|
+
def component_did_catch(&block)
|
142
|
+
# TODO convert error and info
|
143
|
+
%x{
|
144
|
+
self.react_component.prototype.componentDidCatch = function(error, info) {
|
145
|
+
return #{`this.__ruby_instance`.instance_exec(error, info, &block)};
|
146
|
+
}
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
def component_did_mount(&block)
|
151
|
+
%x{
|
152
|
+
self.react_component.prototype.componentDidMount = function() {
|
153
|
+
return #{`this.__ruby_instance`.instance_exec(&block)};
|
154
|
+
}
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
def component_did_update(&block)
|
159
|
+
%x{
|
160
|
+
self.react_component.prototype.componentDidUpdate = function() {
|
161
|
+
return #{`this.__ruby_instance`.instance_exec(&block)};
|
162
|
+
}
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
def component_will_unmount(&block)
|
167
|
+
%x{
|
168
|
+
self.react_component.prototype.componentWillUnmount = function() {
|
169
|
+
return #{`this.__ruby_instance`.instance_exec(&block)};
|
170
|
+
}
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
def get_derived_state_from_error(&block)
|
175
|
+
%x{
|
176
|
+
self.react_component.prototype.getDerivedStateFromError = function(error) {
|
177
|
+
return #{`this.__ruby_instance`.instance_exec(error, &block)};
|
178
|
+
}
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
def get_derived_state_from_props(&block)
|
183
|
+
%x{
|
184
|
+
self.react_component.prototype.getDerivedStateFromProps = function(props, state) {
|
185
|
+
return #{`this.__ruby_instance`.instance_exec(React::Component::Props.new(`props`), `Opal.Hash.$new(state)`, &block)};
|
186
|
+
}
|
187
|
+
}
|
188
|
+
end
|
189
|
+
|
190
|
+
def get_snapshot_before_update(&block)
|
191
|
+
%x{
|
192
|
+
self.react_component.prototype.getSnapshotBeforeUpdate = function(prev_props, prev_state) {
|
193
|
+
return #{`this.__ruby_instance`.instance_exec(React::Component::Props.new(`prev_props`), `Opal.Hash.$new(prev_state)`, &block)};
|
194
|
+
}
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
198
|
+
def render(&block)
|
199
|
+
%x{
|
200
|
+
self.react_component.prototype.render = function() {
|
201
|
+
Opal.React.render_buffer.push([]);
|
202
|
+
Opal.React.active_components.push(this);
|
203
|
+
#{`this.__ruby_instance`.instance_exec(&block)};
|
204
|
+
Opal.React.active_components.pop();
|
205
|
+
return Opal.React.render_buffer.pop();
|
206
|
+
}
|
207
|
+
}
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def force_update(&block)
|
213
|
+
if block_given?
|
214
|
+
# this maybe needs instance_exec too
|
215
|
+
@native.JS.forceUpdate(`function() { block.$call(); }`)
|
216
|
+
else
|
217
|
+
@native.JS.forceUpdate
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def set_state(updater, &callback)
|
222
|
+
@state.set_state(updater, &callback)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module Elements
|
4
|
+
# https://www.w3.org/TR/html52/fullindex.html#index-elements
|
5
|
+
SUPPORTED_HTML_AND_SVG_ELEMENTS = %w[
|
6
|
+
a abbr address area article aside audio
|
7
|
+
b base bdi bdo blockquote body br button
|
8
|
+
canvas caption cite code col colgroup
|
9
|
+
data datalist dd del details dfn dialog div dl dt
|
10
|
+
em embed
|
11
|
+
fieldset figcaption figure footer form
|
12
|
+
h1 h2 h3 h4 h5 h6 head header hr html
|
13
|
+
i iframe img input ins
|
14
|
+
kbd
|
15
|
+
label legend li link
|
16
|
+
main map mark meta meter
|
17
|
+
nav noscript
|
18
|
+
object ol optgroup option output
|
19
|
+
p param picture pre progress
|
20
|
+
q
|
21
|
+
rp rt rtc ruby
|
22
|
+
s samp script section select small source span strong style sub summary sup
|
23
|
+
table tbody td template textarea tfoot th thead time title tr track
|
24
|
+
u ul
|
25
|
+
var video
|
26
|
+
wbr
|
27
|
+
] +
|
28
|
+
# https://www.w3.org/TR/SVG11/eltindex.html
|
29
|
+
# elements listed above not mentioned a second time
|
30
|
+
%w[
|
31
|
+
altGlyph altGlyphDef altGlyphItem animate animateColor animateMotion animateTransform
|
32
|
+
circle clipPath color-profile cursor
|
33
|
+
defs desc
|
34
|
+
ellipse
|
35
|
+
feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting
|
36
|
+
feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur
|
37
|
+
feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting
|
38
|
+
feSpotLight feTile feTurbulence
|
39
|
+
filter font font-face font-face-format font-face-name font-face-src font-face-uri foreignObject
|
40
|
+
g glyph glyphRef
|
41
|
+
hkern
|
42
|
+
image
|
43
|
+
line linearGradient
|
44
|
+
marker mask metadata missing-glyph mpath
|
45
|
+
path pattern polygon polyline
|
46
|
+
radialGradient rect
|
47
|
+
script set stop style svg switch symbol
|
48
|
+
text textPath tref tspan
|
49
|
+
use
|
50
|
+
view vkern
|
51
|
+
]
|
52
|
+
|
53
|
+
|
54
|
+
SUPPORTED_HTML_AND_SVG_ELEMENTS.each do |element|
|
55
|
+
define_method(element) do |*args, &block|
|
56
|
+
%x{
|
57
|
+
var props = null;
|
58
|
+
|
59
|
+
if (args.length > 0) {
|
60
|
+
props = Opal.React.to_native_react_props(args[0]);
|
61
|
+
}
|
62
|
+
Opal.React.internal_render(element, props, block);
|
63
|
+
}
|
64
|
+
end
|
65
|
+
define_method(`element.toUpperCase()`) do |*args, &block|
|
66
|
+
%x{
|
67
|
+
var props = null;
|
68
|
+
|
69
|
+
if (args.length > 0) {
|
70
|
+
props = Opal.React.to_native_react_props(args[0]);
|
71
|
+
}
|
72
|
+
Opal.React.internal_render(element, props, block);
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module EventHandler
|
4
|
+
def event_handlers
|
5
|
+
@event_handlers ||= []
|
6
|
+
end
|
7
|
+
|
8
|
+
def event_handler(name, &block)
|
9
|
+
event_handlers << name
|
10
|
+
%x{
|
11
|
+
self.react_component.prototype[name] = function(event, info) {
|
12
|
+
#{ruby_event = ::React::SyntheticEvent.new(`event`)};
|
13
|
+
#{`this.__ruby_instance`.instance_exec(ruby_event, `info`, &block)};
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module Features
|
4
|
+
def Fragment(props = `null`, &block)
|
5
|
+
%x{
|
6
|
+
var native_props = null;
|
7
|
+
|
8
|
+
if (props) {
|
9
|
+
native_props = Opal.React.to_native_react_props(args[0]);
|
10
|
+
}
|
11
|
+
Opal.React.internal_render(React.Fragment, native_props, block);
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def Portal(dom_node, &block)
|
16
|
+
%x{
|
17
|
+
var children = null;
|
18
|
+
var block_result = null;
|
19
|
+
|
20
|
+
Opal.React.render_buffer.push([]);
|
21
|
+
if (block !== nil) {
|
22
|
+
block_result = block.$call()
|
23
|
+
if (block_result && (block_result !== nil && (typeof block_result === "string" || typeof block_result.$$typeof === "symbol" ||
|
24
|
+
(typeof block_result.constructor !== "undefined" && block_result.constructor === Array && block_result[0] && typeof block_result[0].$$typeof === "symbol")
|
25
|
+
))) {
|
26
|
+
Opal.React.render_buffer[Opal.React.render_buffer.length - 1].push(block_result);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
var react_element = React.createPortal(Opal.React.render_buffer.pop(), dom_node);
|
30
|
+
Opal.React.render_buffer[Opal.React.render_buffer.length - 1].push(react_element);
|
31
|
+
return null;
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def StrictMode(props = `null`, &block)
|
36
|
+
%x{
|
37
|
+
var native_props = null;
|
38
|
+
|
39
|
+
if (props) {
|
40
|
+
native_props = Opal.React.to_native_react_props(args[0]);
|
41
|
+
}
|
42
|
+
Opal.React.internal_render(React.StrictMode, native_props, block);
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
class History
|
4
|
+
include ::Native::Wrapper
|
5
|
+
|
6
|
+
alias_native :block, :block
|
7
|
+
alias_native :create_href, :createHref
|
8
|
+
alias_native :go, :go
|
9
|
+
alias_native :go_back, :goBack
|
10
|
+
alias_native :go_forward, :goForward
|
11
|
+
alias_native :listen, :listen
|
12
|
+
alias_native :push, :push
|
13
|
+
alias_native :replace, :replace
|
14
|
+
|
15
|
+
alias _react_component_hitory_original_method_missing method_missing
|
16
|
+
|
17
|
+
def method_missing(prop, *args, &block)
|
18
|
+
@native.JS[:params].JS[prop]
|
19
|
+
end
|
20
|
+
|
21
|
+
def location
|
22
|
+
return @location if @location
|
23
|
+
return nil unless @native.JS[:props].JS[:location]
|
24
|
+
if @native.JS[:props].JS[:location].JS[:pathname]
|
25
|
+
@location = React::Component::Location.new(@native.JS[:props].JS[:location])
|
26
|
+
else
|
27
|
+
@native.JS[:props].JS[:location]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_n
|
32
|
+
@native
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|