react-rails 1.9.0 → 3.2.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 +5 -5
- data/CHANGELOG.md +345 -9
- data/README.md +137 -389
- data/lib/assets/javascripts/JSXTransformer.js +6 -6
- data/lib/assets/javascripts/react_ujs.js +1 -7
- data/lib/assets/react-source/development/react-server.js +423 -21528
- data/lib/assets/react-source/development/react.js +191 -21409
- data/lib/assets/react-source/production/react-server.js +2 -19
- data/lib/assets/react-source/production/react.js +2 -19
- data/lib/generators/react/component_generator.rb +203 -73
- data/lib/generators/react/install_generator.rb +98 -25
- data/lib/generators/templates/component.es6.jsx +9 -12
- data/lib/generators/templates/component.es6.tsx +24 -0
- data/lib/generators/templates/component.js.jsx +15 -18
- data/lib/generators/templates/component.js.jsx.coffee +5 -8
- data/lib/generators/templates/component.js.jsx.tsx +36 -0
- data/lib/generators/templates/react_server_rendering.rb +4 -0
- data/lib/generators/templates/server_rendering.js +6 -0
- data/lib/generators/templates/server_rendering_pack.js +5 -0
- data/lib/react/jsx/babel_transformer.rb +12 -6
- data/lib/react/jsx/jsx_transformer.rb +7 -6
- data/lib/react/jsx/processor.rb +3 -1
- data/lib/react/jsx/sprockets_strategy.rb +12 -6
- data/lib/react/jsx/template.rb +7 -6
- data/lib/react/jsx.rb +11 -7
- data/lib/react/rails/asset_variant.rb +7 -8
- data/lib/react/rails/component_mount.rb +48 -14
- data/lib/react/rails/controller_lifecycle.rb +36 -7
- data/lib/react/rails/controller_renderer.rb +13 -4
- data/lib/react/rails/railtie.rb +34 -29
- data/lib/react/rails/test_helper.rb +25 -0
- data/lib/react/rails/version.rb +4 -2
- data/lib/react/rails/view_helper.rb +3 -1
- data/lib/react/rails.rb +9 -7
- data/lib/react/server_rendering/{sprockets_renderer → bundle_renderer}/console_replay.js +1 -1
- data/lib/react/server_rendering/bundle_renderer/console_reset.js +3 -0
- data/lib/react/server_rendering/bundle_renderer/timeout_polyfill.js +26 -0
- data/lib/react/server_rendering/bundle_renderer.rb +117 -0
- data/lib/react/server_rendering/environment_container.rb +2 -0
- data/lib/react/server_rendering/exec_js_renderer.rb +43 -16
- data/lib/react/server_rendering/manifest_container.rb +5 -1
- data/lib/react/server_rendering/separate_server_bundle_container.rb +19 -0
- data/lib/react/server_rendering/yaml_manifest_container.rb +12 -4
- data/lib/react/server_rendering.rb +26 -12
- data/lib/react-rails.rb +12 -4
- data/lib/react.rb +8 -4
- metadata +106 -41
- data/lib/assets/javascripts/react_ujs_event_setup.js +0 -29
- data/lib/assets/javascripts/react_ujs_mount.js +0 -104
- data/lib/assets/javascripts/react_ujs_native.js +0 -18
- data/lib/assets/javascripts/react_ujs_pjax.js +0 -10
- data/lib/assets/javascripts/react_ujs_turbolinks.js +0 -9
- data/lib/assets/javascripts/react_ujs_turbolinks_classic.js +0 -10
- data/lib/assets/javascripts/react_ujs_turbolinks_classic_deprecated.js +0 -13
- data/lib/assets/react-source/development-with-addons/react-server.js +0 -24053
- data/lib/assets/react-source/development-with-addons/react.js +0 -23890
- data/lib/assets/react-source/production-with-addons/react-server.js +0 -19
- data/lib/assets/react-source/production-with-addons/react.js +0 -19
- data/lib/generators/react/ujs_generator.rb +0 -44
- data/lib/react/server_rendering/sprockets_renderer.rb +0 -79
- /data/lib/react/server_rendering/{sprockets_renderer → bundle_renderer}/console_polyfill.js +0 -0
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module React
|
2
4
|
module Generators
|
3
5
|
class ComponentGenerator < ::Rails::Generators::NamedBase
|
4
|
-
source_root File.expand_path
|
6
|
+
source_root File.expand_path "../templates", __dir__
|
5
7
|
desc <<-DESC.strip_heredoc
|
6
8
|
Description:
|
7
|
-
Scaffold a
|
9
|
+
Scaffold a React component into `components/` of your Shakapacker source or asset pipeline.
|
8
10
|
The generated component will include a basic render function and a PropTypes
|
9
11
|
hash to help with development.
|
10
12
|
|
@@ -46,100 +48,228 @@ module React
|
|
46
48
|
DESC
|
47
49
|
|
48
50
|
argument :attributes,
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
51
|
+
type: :array,
|
52
|
+
default: [],
|
53
|
+
banner: "field[:type] field[:type] ..."
|
52
54
|
|
53
55
|
class_option :es6,
|
54
56
|
type: :boolean,
|
55
57
|
default: false,
|
56
|
-
desc:
|
58
|
+
desc: "Output es6 class based component"
|
59
|
+
|
60
|
+
class_option :ts,
|
61
|
+
type: :boolean,
|
62
|
+
default: false,
|
63
|
+
desc: "Output tsx class based component"
|
57
64
|
|
58
65
|
class_option :coffee,
|
59
66
|
type: :boolean,
|
60
67
|
default: false,
|
61
|
-
desc:
|
68
|
+
desc: "Output coffeescript based component"
|
62
69
|
|
63
70
|
REACT_PROP_TYPES = {
|
64
|
-
"node" =>
|
65
|
-
"bool" =>
|
66
|
-
"boolean" =>
|
67
|
-
"string" =>
|
68
|
-
"number" =>
|
69
|
-
"object" =>
|
70
|
-
"array" =>
|
71
|
-
"shape" =>
|
72
|
-
"element" =>
|
73
|
-
"func" =>
|
74
|
-
"function" =>
|
75
|
-
"any" =>
|
76
|
-
|
77
|
-
"instanceOf" =>
|
78
|
-
|
71
|
+
"node" => "PropTypes.node",
|
72
|
+
"bool" => "PropTypes.bool",
|
73
|
+
"boolean" => "PropTypes.bool",
|
74
|
+
"string" => "PropTypes.string",
|
75
|
+
"number" => "PropTypes.number",
|
76
|
+
"object" => "PropTypes.object",
|
77
|
+
"array" => "PropTypes.array",
|
78
|
+
"shape" => "PropTypes.shape({})",
|
79
|
+
"element" => "PropTypes.element",
|
80
|
+
"func" => "PropTypes.func",
|
81
|
+
"function" => "PropTypes.func",
|
82
|
+
"any" => "PropTypes.any",
|
83
|
+
|
84
|
+
"instanceOf" => lambda { |type|
|
85
|
+
"PropTypes.instanceOf(#{type.to_s.camelize})"
|
86
|
+
},
|
87
|
+
|
88
|
+
"oneOf" => lambda { |*options|
|
89
|
+
enums = options.map { |k| "'#{k}'" }.join(",")
|
90
|
+
"PropTypes.oneOf([#{enums}])"
|
79
91
|
},
|
80
92
|
|
81
|
-
"
|
82
|
-
|
83
|
-
|
93
|
+
"oneOfType" => lambda { |*options|
|
94
|
+
types = options.map { |k| lookup(k.to_s, k.to_s).to_s }.join(",")
|
95
|
+
"PropTypes.oneOfType([#{types}])"
|
96
|
+
}
|
97
|
+
}.freeze
|
98
|
+
|
99
|
+
TYPESCRIPT_TYPES = {
|
100
|
+
"node" => "React.ReactNode",
|
101
|
+
"bool" => "boolean",
|
102
|
+
"boolean" => "boolean",
|
103
|
+
"string" => "string",
|
104
|
+
"number" => "number",
|
105
|
+
"object" => "object",
|
106
|
+
"array" => "Array<any>",
|
107
|
+
"shape" => "object",
|
108
|
+
"element" => "object",
|
109
|
+
"func" => "object",
|
110
|
+
"function" => "object",
|
111
|
+
"any" => "any",
|
112
|
+
|
113
|
+
"instanceOf" => lambda { |type|
|
114
|
+
type.to_s.camelize
|
84
115
|
},
|
85
116
|
|
86
|
-
"
|
87
|
-
|
88
|
-
'React.PropTypes.oneOfType([%s])' % types
|
117
|
+
"oneOf" => lambda { |*opts|
|
118
|
+
opts.map { |k| "'#{k}'" }.join(" | ")
|
89
119
|
},
|
90
|
-
|
120
|
+
|
121
|
+
"oneOfType" => lambda { |*opts|
|
122
|
+
opts.map { |k| ts_lookup(k.to_s, k.to_s).to_s }.join(" | ")
|
123
|
+
}
|
124
|
+
}.freeze
|
91
125
|
|
92
126
|
def create_component_file
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
127
|
+
template_extension = detect_template_extension
|
128
|
+
# Prefer Shakapacker to Sprockets:
|
129
|
+
if shakapacker?
|
130
|
+
new_file_name = file_name.camelize
|
131
|
+
extension = if options[:coffee]
|
132
|
+
"coffee"
|
133
|
+
elsif options[:ts]
|
134
|
+
"tsx"
|
98
135
|
else
|
99
|
-
|
100
|
-
|
136
|
+
"js"
|
137
|
+
end
|
138
|
+
target_dir = webpack_configuration.source_path
|
139
|
+
.join("components")
|
140
|
+
.relative_path_from(::Rails.root)
|
141
|
+
.to_s
|
142
|
+
else
|
143
|
+
new_file_name = file_name
|
144
|
+
extension = template_extension
|
145
|
+
target_dir = "app/assets/javascripts/components"
|
146
|
+
end
|
101
147
|
|
102
|
-
file_path = File.join(
|
103
|
-
template("component.#{
|
148
|
+
file_path = File.join(target_dir, class_path, "#{new_file_name}.#{extension}")
|
149
|
+
template("component.#{template_extension}", file_path)
|
104
150
|
end
|
105
151
|
|
106
152
|
private
|
107
153
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
154
|
+
def webpack_configuration
|
155
|
+
Shakapacker.respond_to?(:config) ? Shakapacker.config : Shakapacker::Configuration
|
156
|
+
end
|
157
|
+
|
158
|
+
def component_name
|
159
|
+
file_name.camelize
|
160
|
+
end
|
161
|
+
|
162
|
+
def file_header
|
163
|
+
if shakapacker?
|
164
|
+
return %(import * as React from "react"\n) if options[:ts]
|
165
|
+
|
166
|
+
<<~JS
|
167
|
+
import React from "react"
|
168
|
+
import PropTypes from "prop-types"
|
169
|
+
JS
|
170
|
+
else
|
171
|
+
""
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def file_footer
|
176
|
+
if shakapacker?
|
177
|
+
%(export default #{component_name})
|
178
|
+
else
|
179
|
+
""
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def shakapacker?
|
184
|
+
defined?(Shakapacker)
|
185
|
+
end
|
186
|
+
|
187
|
+
def parse_attributes!
|
188
|
+
self.attributes = (attributes || []).map do |attr|
|
189
|
+
args = ""
|
190
|
+
args_regex = /(?<args>{.*})/
|
191
|
+
|
192
|
+
name, type = attr.split(":")
|
193
|
+
|
194
|
+
if (matchdata = args_regex.match(type))
|
195
|
+
args = matchdata[:args]
|
196
|
+
type = type.gsub(args_regex, "")
|
197
|
+
end
|
198
|
+
|
199
|
+
if options[:ts]
|
200
|
+
{ name: name, type: ts_lookup(name, type, args), union: union?(args) }
|
201
|
+
else
|
202
|
+
{ name: name, type: lookup(type, args) }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def union?(args = "")
|
208
|
+
args.to_s.gsub(/[{}]/, "").split(",").count > 1
|
209
|
+
end
|
210
|
+
|
211
|
+
def self.ts_lookup(_name, type = "node", args = "")
|
212
|
+
ts_type = TYPESCRIPT_TYPES[type]
|
213
|
+
if ts_type.blank?
|
214
|
+
ts_type = if /^[[:upper:]]/.match?(type)
|
215
|
+
TYPESCRIPT_TYPES["instanceOf"]
|
216
|
+
else
|
217
|
+
TYPESCRIPT_TYPES["node"]
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
args = args.to_s.gsub(/[{}]/, "").split(",")
|
222
|
+
|
223
|
+
if ts_type.respond_to? :call
|
224
|
+
return ts_type.call(type) if args.blank?
|
225
|
+
|
226
|
+
ts_type = ts_type.call(*args)
|
227
|
+
end
|
228
|
+
|
229
|
+
ts_type
|
230
|
+
end
|
231
|
+
|
232
|
+
def ts_lookup(name, type = "node", args = "")
|
233
|
+
self.class.ts_lookup(name, type, args)
|
234
|
+
end
|
235
|
+
|
236
|
+
def self.lookup(type = "node", options = "")
|
237
|
+
react_prop_type = REACT_PROP_TYPES[type]
|
238
|
+
if react_prop_type.blank?
|
239
|
+
react_prop_type = if /^[[:upper:]]/.match?(type)
|
240
|
+
REACT_PROP_TYPES["instanceOf"]
|
241
|
+
else
|
242
|
+
REACT_PROP_TYPES["node"]
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
options = options.to_s.gsub(/[{}]/, "").split(",")
|
247
|
+
|
248
|
+
react_prop_type = react_prop_type.call(*options) if react_prop_type.respond_to? :call
|
249
|
+
react_prop_type
|
250
|
+
end
|
251
|
+
|
252
|
+
def lookup(type = "node", options = "")
|
253
|
+
self.class.lookup(type, options)
|
254
|
+
end
|
255
|
+
|
256
|
+
def detect_template_extension
|
257
|
+
if options[:coffee]
|
258
|
+
"js.jsx.coffee"
|
259
|
+
elsif options[:ts] && es6_enabled?
|
260
|
+
"es6.tsx"
|
261
|
+
elsif options[:ts]
|
262
|
+
"js.jsx.tsx"
|
263
|
+
elsif es6_enabled?
|
264
|
+
"es6.jsx"
|
265
|
+
else
|
266
|
+
"js.jsx"
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def es6_enabled?
|
271
|
+
options[:es6] || shakapacker?
|
272
|
+
end
|
143
273
|
end
|
144
274
|
end
|
145
275
|
end
|
@@ -1,30 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module React
|
2
4
|
module Generators
|
3
5
|
class InstallGenerator < ::Rails::Generators::Base
|
4
|
-
source_root File.expand_path
|
6
|
+
source_root File.expand_path "../templates", __dir__
|
5
7
|
|
6
|
-
desc
|
8
|
+
desc "Create default react.js folder layout and prep application.js"
|
7
9
|
|
8
10
|
class_option :skip_git,
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
type: :boolean,
|
12
|
+
aliases: "-g",
|
13
|
+
default: false,
|
14
|
+
desc: "Skip Git keeps"
|
15
|
+
|
16
|
+
class_option :skip_server_rendering,
|
17
|
+
type: :boolean,
|
18
|
+
default: false,
|
19
|
+
desc: "Don't generate server_rendering.js or config/initializers/react_server_rendering.rb"
|
13
20
|
|
21
|
+
# Make an empty `components/` directory in the right place:
|
14
22
|
def create_directory
|
15
|
-
|
16
|
-
|
23
|
+
components_dir = if shakapacker?
|
24
|
+
Pathname.new(javascript_dir).parent.to_s
|
25
|
+
else
|
26
|
+
javascript_dir
|
27
|
+
end
|
28
|
+
empty_directory File.join(components_dir, "components")
|
29
|
+
return if options[:skip_git]
|
30
|
+
|
31
|
+
create_file File.join(components_dir, "components/.keep")
|
32
|
+
end
|
33
|
+
|
34
|
+
# Add requires, setup UJS
|
35
|
+
def setup_react
|
36
|
+
if shakapacker?
|
37
|
+
setup_react_shakapacker
|
38
|
+
else
|
39
|
+
setup_react_sprockets
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_server_rendering
|
44
|
+
if options[:skip_server_rendering]
|
45
|
+
nil
|
46
|
+
elsif shakapacker?
|
47
|
+
ssr_manifest_path = File.join(javascript_dir, "server_rendering.js")
|
48
|
+
template("server_rendering_pack.js", ssr_manifest_path)
|
49
|
+
else
|
50
|
+
ssr_manifest_path = File.join(javascript_dir, "server_rendering.js")
|
51
|
+
template("server_rendering.js", ssr_manifest_path)
|
52
|
+
initializer_path = "config/initializers/react_server_rendering.rb"
|
53
|
+
template("react_server_rendering.rb", initializer_path)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def shakapacker?
|
60
|
+
!!defined?(Shakapacker)
|
61
|
+
end
|
62
|
+
|
63
|
+
def javascript_dir
|
64
|
+
if shakapacker?
|
65
|
+
shakapacker_source_path
|
66
|
+
.relative_path_from(::Rails.root)
|
67
|
+
.to_s
|
68
|
+
else
|
69
|
+
"app/assets/javascripts"
|
70
|
+
end
|
17
71
|
end
|
18
72
|
|
19
|
-
def
|
20
|
-
|
73
|
+
def manifest
|
74
|
+
Pathname.new(destination_root).join(javascript_dir, "application.js")
|
75
|
+
end
|
76
|
+
|
77
|
+
def setup_react_sprockets
|
78
|
+
require_react = "//= require react\n//= require react_ujs\n//= require components\n"
|
21
79
|
|
22
80
|
if manifest.exist?
|
23
81
|
manifest_contents = File.read(manifest)
|
24
82
|
|
25
|
-
if match = manifest_contents.match(
|
83
|
+
if (match = manifest_contents.match(%r{//=\s+require\s+turbolinks\s+\n}))
|
26
84
|
inject_into_file manifest, require_react, { after: match[0] }
|
27
|
-
elsif match = manifest_contents.match(
|
85
|
+
elsif (match = manifest_contents.match(%r{//=\s+require_tree[^\n]*}))
|
28
86
|
inject_into_file manifest, require_react, { before: match[0] }
|
29
87
|
else
|
30
88
|
append_file manifest, require_react
|
@@ -32,26 +90,41 @@ module React
|
|
32
90
|
else
|
33
91
|
create_file manifest, require_react
|
34
92
|
end
|
35
|
-
end
|
36
93
|
|
37
|
-
|
38
|
-
|
94
|
+
components_js = "//= require_tree ./components\n"
|
95
|
+
components_file = File.join(javascript_dir, "components.js")
|
96
|
+
create_file components_file, components_js
|
39
97
|
end
|
40
98
|
|
41
|
-
|
42
|
-
|
43
|
-
|
99
|
+
SHAKAPACKER_SETUP_UJS = <<~JS
|
100
|
+
// Support component names relative to this directory:
|
101
|
+
var componentRequireContext = require.context("components", true);
|
102
|
+
var ReactRailsUJS = require("react_ujs");
|
103
|
+
ReactRailsUJS.useContext(componentRequireContext);
|
104
|
+
JS
|
44
105
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
106
|
+
def require_package_json_gem
|
107
|
+
require "bundler/inline"
|
108
|
+
|
109
|
+
gemfile(true) { gem "package_json" }
|
110
|
+
|
111
|
+
puts "using package_json v#{PackageJson::VERSION}"
|
49
112
|
end
|
50
113
|
|
51
|
-
|
114
|
+
def setup_react_shakapacker
|
115
|
+
require_package_json_gem
|
52
116
|
|
53
|
-
|
54
|
-
|
117
|
+
PackageJson.read.manager.add(["react_ujs"])
|
118
|
+
|
119
|
+
if manifest.exist?
|
120
|
+
append_file(manifest, SHAKAPACKER_SETUP_UJS)
|
121
|
+
else
|
122
|
+
create_file(manifest, SHAKAPACKER_SETUP_UJS)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def shakapacker_source_path
|
127
|
+
Shakapacker.config.source_entry_path
|
55
128
|
end
|
56
129
|
end
|
57
130
|
end
|
@@ -1,17 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
<div>
|
1
|
+
<%= file_header %>
|
2
|
+
const <%= component_name %> = (props) => {
|
3
|
+
return (
|
4
|
+
<React.Fragment>
|
6
5
|
<% attributes.each do |attribute| -%>
|
7
|
-
|
8
|
-
<% end -%>
|
9
|
-
</div>
|
10
|
-
);
|
11
|
-
<% else -%>
|
12
|
-
return <div />;
|
6
|
+
<%= attribute[:name].titleize %>: {props.<%= attribute[:name].camelize(:lower) %>}
|
13
7
|
<% end -%>
|
14
|
-
|
8
|
+
</React.Fragment>
|
9
|
+
)
|
15
10
|
}
|
16
11
|
|
17
12
|
<% if attributes.size > 0 -%>
|
@@ -21,3 +16,5 @@ class <%= file_name.camelize %> extends React.Component {
|
|
21
16
|
<% end -%>
|
22
17
|
};
|
23
18
|
<% end -%>
|
19
|
+
|
20
|
+
<%= file_footer %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%= file_header %>
|
2
|
+
interface I<%= component_name %>Props {
|
3
|
+
<% if attributes.size > 0 -%>
|
4
|
+
<% attributes.each do |attribute| -%>
|
5
|
+
<% if attribute[:union] -%>
|
6
|
+
<%= attribute[:name].camelize(:lower) %>: <%= attribute[:name].titleize %>;
|
7
|
+
<% else -%>
|
8
|
+
<%= attribute[:name].camelize(:lower) %>: <%= attribute[:type] %>;
|
9
|
+
<% end -%>
|
10
|
+
<% end -%>
|
11
|
+
<% end -%>
|
12
|
+
}
|
13
|
+
|
14
|
+
const <%= component_name %> = (props: I<%= component_name %>Props) => {
|
15
|
+
return (
|
16
|
+
<React.Fragment>
|
17
|
+
<% attributes.each do |attribute| -%>
|
18
|
+
<%= attribute[:name].titleize %>: {props.<%= attribute[:name].camelize(:lower) %>}
|
19
|
+
<% end -%>
|
20
|
+
</React.Fragment>
|
21
|
+
)
|
22
|
+
}
|
23
|
+
|
24
|
+
<%= file_footer %>
|
@@ -1,23 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
},
|
1
|
+
<%= file_header %>
|
2
|
+
function <%= component_name %>(props) {
|
3
|
+
return (
|
4
|
+
<React.Fragment>
|
5
|
+
<% attributes.each do |attribute| -%>
|
6
|
+
<%= attribute[:name].titleize %>: {props.<%= attribute[:name].camelize(:lower) %>}
|
8
7
|
<% end -%>
|
8
|
+
</React.Fragment>
|
9
|
+
);
|
10
|
+
}
|
9
11
|
|
10
|
-
render: function() {
|
11
12
|
<% if attributes.size > 0 -%>
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
<div><%= attribute[:name].titleize %>: {this.props.<%= attribute[:name].camelize(:lower) %>}</div>
|
13
|
+
<%= file_name.camelize %>.propTypes = {
|
14
|
+
<% attributes.each_with_index do |attribute, idx| -%>
|
15
|
+
<%= attribute[:name].camelize(:lower) %>: <%= attribute[:type] %><% if (idx < attributes.length-1) %>,<% end %>
|
16
16
|
<% end -%>
|
17
|
-
|
18
|
-
);
|
19
|
-
<% else -%>
|
20
|
-
return <div />;
|
17
|
+
};
|
21
18
|
<% end -%>
|
22
|
-
|
23
|
-
|
19
|
+
|
20
|
+
<%= file_footer %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class
|
1
|
+
<%= file_header %>class <%= component_name %> extends React.Component
|
2
2
|
<% if attributes.size > 0 -%>
|
3
3
|
@propTypes =
|
4
4
|
<% attributes.each do |attribute| -%>
|
@@ -7,12 +7,9 @@ class @<%= file_name.camelize %> extends React.Component
|
|
7
7
|
|
8
8
|
<% end -%>
|
9
9
|
render: ->
|
10
|
-
|
11
|
-
`<div>
|
10
|
+
`<React.Fragment>
|
12
11
|
<% attributes.each do |attribute| -%>
|
13
|
-
|
12
|
+
<%= attribute[:name].titleize %>: {this.props.<%= attribute[:name].camelize(:lower) %>}
|
14
13
|
<% end -%>
|
15
|
-
</
|
16
|
-
|
17
|
-
`<div />`
|
18
|
-
<% end -%>
|
14
|
+
</React.Fragment>`
|
15
|
+
<%= file_footer %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<%= file_header %>
|
2
|
+
<% unions = attributes.select{ |a| a[:union] } -%>
|
3
|
+
<% if unions.size > 0 -%>
|
4
|
+
<% unions.each do |e| -%>
|
5
|
+
type <%= e[:name].titleize %> = <%= e[:type]%>
|
6
|
+
<% end -%>
|
7
|
+
<% end -%>
|
8
|
+
|
9
|
+
interface I<%= component_name %>Props {
|
10
|
+
<% if attributes.size > 0 -%>
|
11
|
+
<% attributes.each do | attribute | -%>
|
12
|
+
<% if attribute[:union] -%>
|
13
|
+
<%= attribute[:name].camelize(:lower) %>: <%= attribute[:name].titleize %>;
|
14
|
+
<% else -%>
|
15
|
+
<%= attribute[:name].camelize(:lower) %>: <%= attribute[:type] %>;
|
16
|
+
<% end -%>
|
17
|
+
<% end -%>
|
18
|
+
<% end -%>
|
19
|
+
}
|
20
|
+
|
21
|
+
interface I<%= component_name %>State {
|
22
|
+
}
|
23
|
+
|
24
|
+
class <%= component_name %> extends React.Component <I<%= component_name %>Props, I<%= component_name %>State> {
|
25
|
+
render() {
|
26
|
+
return (
|
27
|
+
<React.Fragment>
|
28
|
+
<% attributes.each do |attribute| -%>
|
29
|
+
<%= attribute[:name].titleize %>: {this.props.<%= attribute[:name].camelize(:lower) %>}
|
30
|
+
<% end -%>
|
31
|
+
</React.Fragment>
|
32
|
+
);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
<%= file_footer %>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
// By default, this pack is loaded for server-side rendering.
|
2
|
+
// It must expose react_ujs as `ReactRailsUJS` and prepare a require context.
|
3
|
+
var componentRequireContext = require.context("components", true);
|
4
|
+
var ReactRailsUJS = require("react_ujs");
|
5
|
+
ReactRailsUJS.useContext(componentRequireContext);
|