react-components-rails 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7e8b48934b25fc73c93eadc46d1fb4386a9289f40d1441be9a4a3f3cdb1cfb5d
4
+ data.tar.gz: 284e9e9ec4e81e4659f2a34385b3e7ab0df67ef258b60359da0b1a01e88eea1c
5
+ SHA512:
6
+ metadata.gz: 422e20effaf3f3b830a7f68fb771e8b61a7f42450cc80a4d491533be07995be85c4f11e4c37fea7643aaea7da857136e6909d725a5bf53d4dfe308a5a8bc42a4
7
+ data.tar.gz: 2487723877f13ea41e3652fb38355935f237ea9b59f4285a7c8583485e1eb933e622c19b0a54863472a7bb39d704e2c015558539e4719f2a4c607071f9233269
@@ -0,0 +1,9 @@
1
+ Fixes # .
2
+
3
+ Changes:
4
+
5
+ Please ensure that:
6
+ - [ ] Changelog is updated if not a minor patch
7
+ - [ ] Ruby linting is ok: `rubocop` is all green
8
+ - [ ] Javascript linting is ok: `cd javascript/webpacker_react-npm-module/ && yarn lint` is all green
9
+ - [ ] [Tests](https://github.com/renchap/webpacker-react#testing) are all green
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ node_modules/
2
+ tmp/
3
+ pkg/
4
+ dist/
data/.rubocop.yml ADDED
@@ -0,0 +1,119 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3
3
+ # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
4
+ # to ignore them, so only the ones explicitly set in this file are enabled.
5
+ DisabledByDefault: true
6
+ Exclude:
7
+ - '**/node_modules/**/*'
8
+ - '**/vendor/**/*'
9
+
10
+ # Prefer &&/|| over and/or.
11
+ Style/AndOr:
12
+ Enabled: true
13
+
14
+ # Do not use braces for hash literals when they are the last argument of a
15
+ # method call.
16
+ Style/BracesAroundHashParameters:
17
+ Enabled: true
18
+
19
+ # Align `when` with `case`.
20
+ Layout/CaseIndentation:
21
+ Enabled: true
22
+
23
+ # Align comments with method definitions.
24
+ Layout/CommentIndentation:
25
+ Enabled: true
26
+
27
+ # No extra empty lines.
28
+ Layout/EmptyLines:
29
+ Enabled: true
30
+
31
+ # In a regular class definition, no empty lines around the body.
32
+ Layout/EmptyLinesAroundClassBody:
33
+ Enabled: true
34
+
35
+ # In a regular module definition, no empty lines around the body.
36
+ Layout/EmptyLinesAroundModuleBody:
37
+ Enabled: true
38
+
39
+ # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
40
+ Style/HashSyntax:
41
+ Enabled: true
42
+
43
+ # Method definitions after `private` or `protected` isolated calls need one
44
+ # extra level of indentation.
45
+ Layout/IndentationConsistency:
46
+ Enabled: true
47
+ EnforcedStyle: indented_internal_methods
48
+
49
+ # Two spaces, no tabs (for indentation).
50
+ Layout/IndentationWidth:
51
+ Enabled: true
52
+
53
+ Layout/SpaceAfterColon:
54
+ Enabled: true
55
+
56
+ Layout/SpaceAfterComma:
57
+ Enabled: true
58
+
59
+ Layout/SpaceAroundEqualsInParameterDefault:
60
+ Enabled: true
61
+
62
+ Layout/SpaceAroundKeyword:
63
+ Enabled: true
64
+
65
+ Layout/SpaceAroundOperators:
66
+ Enabled: true
67
+
68
+ Layout/SpaceBeforeFirstArg:
69
+ Enabled: true
70
+
71
+ # Defining a method with parameters needs parentheses.
72
+ Style/MethodDefParentheses:
73
+ Enabled: true
74
+
75
+ # Use `foo {}` not `foo{}`.
76
+ Layout/SpaceBeforeBlockBraces:
77
+ Enabled: true
78
+
79
+ # Use `foo { bar }` not `foo {bar}`.
80
+ Layout/SpaceInsideBlockBraces:
81
+ Enabled: true
82
+
83
+ # Use `{ a: 1 }` not `{a:1}`.
84
+ Layout/SpaceInsideHashLiteralBraces:
85
+ Enabled: true
86
+
87
+ Layout/SpaceInsideParens:
88
+ Enabled: true
89
+
90
+ # Check quotes usage according to lint rule below.
91
+ Style/StringLiterals:
92
+ Enabled: true
93
+ EnforcedStyle: double_quotes
94
+
95
+ # Detect hard tabs, no hard tabs.
96
+ Layout/Tab:
97
+ Enabled: true
98
+
99
+ # Blank lines should not have any spaces.
100
+ Layout/TrailingBlankLines:
101
+ Enabled: true
102
+
103
+ # No trailing whitespace.
104
+ Layout/TrailingWhitespace:
105
+ Enabled: true
106
+
107
+ # Use quotes for string literals when they are enough.
108
+ Style/UnneededPercentQ:
109
+ Enabled: true
110
+
111
+ # Align `end` with the matching keyword or starting expression except for
112
+ # assignments, where it should be aligned with the LHS.
113
+ Lint/EndAlignment:
114
+ Enabled: true
115
+ EnforcedStyleAlignWith: variable
116
+
117
+ # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
118
+ Lint/RequireParentheses:
119
+ Enabled: true
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project maintainer at renchap@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rubocop", require: false
6
+
7
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ react-components-rails (1.0.0.beta1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.2)
10
+ parallel (1.21.0)
11
+ parser (3.1.1.0)
12
+ ast (~> 2.4.1)
13
+ rainbow (3.1.1)
14
+ rake (13.0.6)
15
+ regexp_parser (2.2.1)
16
+ rexml (3.2.5)
17
+ rubocop (1.25.1)
18
+ parallel (~> 1.10)
19
+ parser (>= 3.1.0.0)
20
+ rainbow (>= 2.2.2, < 4.0)
21
+ regexp_parser (>= 1.8, < 3.0)
22
+ rexml
23
+ rubocop-ast (>= 1.15.1, < 2.0)
24
+ ruby-progressbar (~> 1.7)
25
+ unicode-display_width (>= 1.4.0, < 3.0)
26
+ rubocop-ast (1.16.0)
27
+ parser (>= 3.1.1.0)
28
+ ruby-progressbar (1.11.0)
29
+ unicode-display_width (2.1.0)
30
+
31
+ PLATFORMS
32
+ x86_64-darwin-21
33
+
34
+ DEPENDENCIES
35
+ bundler (~> 2.3)
36
+ rake (~> 13.0)
37
+ react-components-rails!
38
+ rubocop
39
+
40
+ BUNDLED WITH
41
+ 2.3.7
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Renaud Chaput
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # React-Components-Rails
2
+
3
+ _**Note:** This project was formerly known as `webpacker-rails`. Following Webpacker's deprecation, it has been renamed and rewritten to no longer rely on Webpacker. Documentation for the latest `webpacker-rails` release (1.0.0-beta.1) is [available here](https://github.com/renchap/webpacker-react/tree/v1.0.0-beta.1)._
4
+
5
+ React-Components-Rails makes it easy to use [React](https://reactjs.org/) with your Rails applications. It provides Controller and View helpers to render React Components on your application, and does not case about the way you ship your Javascript
6
+
7
+ ## Installation
8
+
9
+ First, you need to add this gem to your Rails app Gemfile:
10
+
11
+ ```ruby
12
+ gem 'react-components-rails', "~> 1.0.0.beta.1"
13
+ ```
14
+
15
+ Once done, run `bundle` to install the gem.
16
+
17
+ Then you need to update your `package.json` file to include the `react-components-rails` Javascript module:
18
+
19
+ `yarn add react-components-rails`
20
+
21
+ You are now all set!
22
+
23
+ ### Note about versions
24
+
25
+ React-Components-Rails contains two parts: a Javascript module and a Ruby gem. Both of those components respect [semantic versioning](http://semver.org). **When upgrading the gem, you need to upgrade the NPM module to the same minor version**. New patch versions can be released for each of the two independently, so it is ok to have the NPM module at version `A.X.Y` and the gem at version `A.X.Z`, but you should never have a different `A` or `X`.
26
+
27
+ ## Usage
28
+
29
+ The first step is to register your root components (those you want to load from your HTML).
30
+ In your app entry file, import your components as well as `react-components-rails` and register them. Considering you have a component in `app/javascript/components/hello.js`:
31
+
32
+ ```javascript
33
+ import Hello from "components/hello"
34
+ import ReactComponentsRails from "react-components-rails"
35
+
36
+ ReactComponentsRails.setup({ Hello }) // ES6 shorthand for {Hello: Hello}
37
+ ```
38
+
39
+ ### Rendering from a view
40
+
41
+ Use the `react_component` helper. The first argument is your component's name, the second one is the `props`:
42
+
43
+ ```erb
44
+ <%= react_component('Hello', name: 'React') %>
45
+ ```
46
+
47
+ You can pass a `tag` argument to render the React component in another tag than the default `div`. All other arguments will be passed to `content_tag`:
48
+
49
+ ```erb
50
+ <%= react_component('Hello', { name: 'React' }, tag: :span, class: 'my-custom-component') %>
51
+ # This will render <span class="my-custom-component" data-react-class="Hello" data-react-props="..."></span>
52
+ ```
53
+
54
+ ### Rendering from a controller
55
+
56
+ ```rb
57
+ class PageController < ApplicationController
58
+ def main
59
+ render react_component: 'Hello', props: { name: 'React' }
60
+ end
61
+ end
62
+ ```
63
+
64
+ You can use the `tag_options` argument to change the generated HTML, similar to the `react_component` method above:
65
+
66
+ ```rb
67
+ render react_component: 'Hello', props: { name: 'React' }, tag_options: { tag: :span, class: 'my-custom-component' }
68
+ ```
69
+
70
+ You can also pass any of the usual arguments to `render` in this call: `layout`, `status`, `content_type`, etc.
71
+
72
+ ### Hot Module Replacement
73
+
74
+ It should be supported out of the box, if supported by your Javascript stack. Please refer to your Javascript compiler/bundler documentation to do so.
75
+
76
+ <!--
77
+ ## Development
78
+
79
+ To work on this gem locally, you first need to clone and setup [the example application](https://github.com/renchap/webpacker-react-example).
80
+
81
+ Then you need to change the example app Gemfile to point to your local repository and run bundle afterwise:
82
+
83
+ ```ruby
84
+ gem 'webpacker-react', path: '~/code/webpacker-react/'
85
+ ```
86
+
87
+ Finally, you need to tell Yarn to use your local copy of the NPM module in this application, using [`yarn link`](https://yarnpkg.com/en/docs/cli/link):
88
+
89
+ ```
90
+ $ cd ~/code/webpacker-react/javascript/webpacker_react-npm-module/
91
+ $ yarn
92
+ $ cd dist/
93
+ $ yarn # compiles the code from src/ to dist/
94
+ $ yarn link
95
+ success Registered "webpacker-react".
96
+ info You can now run `yarn link "webpacker-react"` in the projects where you want to use this module and it will be used instead.
97
+ $ cd ~/code/webpacker-react-example/
98
+ $ yarn link webpacker-react
99
+ success Registered "webpacker-react".
100
+ ```
101
+
102
+ After launching `./bin/webpack-watcher` and `./bin/rails server` in your example app directory, you can now change the Ruby or Javascript code in your local `webpacker-react` repository, and test it immediately using the example app.
103
+
104
+ ## Testing
105
+
106
+ If you changed the local javascript package, first ensure it is build (see above).
107
+
108
+ To run the test suite:
109
+
110
+ ```sh
111
+ $ rake test
112
+ ```
113
+
114
+ If you change the javascript code, please ensure there are no style errors before committing:
115
+
116
+ ```sh
117
+ $ cd javascript/webpacker_react-npm-module/
118
+ $ yarn lint
119
+ ``` -->
120
+
121
+ ## Contributing
122
+
123
+ Bug reports and pull requests are welcome on GitHub at https://github.com/renchap/webpacker-react.
124
+ Please feel free to open issues about your needs and features you would like to be added.
125
+
126
+ ### Thanks
127
+
128
+ This gem has been inspired by the awesome work on [react-rails](https://github.com/reactjs/react-rails) and [react_on_rails](https://github.com/shakacode/react_on_rails/). Many thanks to their authors!
data/lib/component.rb ADDED
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ReactComponentsRails
4
+ class Component
5
+ include ActionView::Helpers::TagHelper
6
+ include ActionView::Helpers::TextHelper
7
+
8
+ attr_accessor :name
9
+
10
+ def initialize(name)
11
+ @name = name
12
+ end
13
+
14
+ def render(props = {}, options = {})
15
+ tag = options.delete(:tag) || :div
16
+ data = { data: { "react-class" => @name, "react-props" => props.to_json } }
17
+
18
+ content_tag(tag, nil, options.deep_merge(data))
19
+ end
20
+ end
21
+ end
data/lib/helpers.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ReactComponentsRails
4
+ module Helpers
5
+ def react_component(component_name, props = {}, options = {})
6
+ ReactComponentsRails::Component.new(component_name).render(props, options)
7
+ end
8
+ end
9
+ end
data/lib/railtie.rb ADDED
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/railtie"
4
+
5
+ module ReactComponentsRails
6
+ class Engine < ::Rails::Engine
7
+ initializer :react_components do
8
+ ActiveSupport.on_load(:action_controller) do
9
+ ActionController::Base.helper ::ReactComponentsRails::Helpers
10
+ end
11
+
12
+ ActiveSupport.on_load :action_view do
13
+ include ::ReactComponentsRails::Helpers
14
+ end
15
+ end
16
+
17
+ initializer :react_components_rails_renderer, group: :all do |_app|
18
+ ActionController::Renderers.add :react_component do |component_name, options|
19
+ props = options.fetch(:props, {})
20
+ tag_options = options.fetch(:tag_options, {})
21
+ html = ReactComponentsRails::Component.new(component_name).render(props, tag_options)
22
+ render_options = options.merge(inline: html)
23
+ render(render_options)
24
+ end
25
+ end
26
+ end
27
+ end
data/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "react-components-rails",
3
+ "version": "1.0.0-beta.1",
4
+ "homepage": "https://github.com/renchap/react-components-rails",
5
+ "repository": "renchap/react-components-rails",
6
+ "author": {
7
+ "name": "Renaud Chaput",
8
+ "email": "renchap@gmail.com"
9
+ },
10
+ "license": "MIT",
11
+ "type": "module",
12
+ "source": "src/index.ts",
13
+ "exports": {
14
+ "require": "./dist/react-components-rails.cjs",
15
+ "default": "./dist/react-components-rails.modern.js"
16
+ },
17
+ "main": "./dist/react-components-rails.cjs",
18
+ "module": "./dist/react-components-rails.module.js",
19
+ "unpkg": "./dist/react-components-rails.umd.js",
20
+ "scripts": {
21
+ "build": "microbundle",
22
+ "dev": "microbundle watch"
23
+ },
24
+ "dependencies": {
25
+ "@types/lodash": "^4.14.179",
26
+ "lodash": "^4.17.21"
27
+ },
28
+ "peerDependencies": {
29
+ "react": ">= 0.14",
30
+ "react-dom": ">= 0.14"
31
+ },
32
+ "devDependencies": {
33
+ "@types/react": "^17.0.39",
34
+ "@types/react-dom": "^17.0.11",
35
+ "microbundle": "^0.14.2",
36
+ "prettier": "^2.5.1",
37
+ "react": "^17.0.2",
38
+ "react-dom": "^17.0.2",
39
+ "typescript": "^4.5.5"
40
+ },
41
+ "packageManager": "yarn@3.2.0",
42
+ "prettier": {
43
+ "semi": false
44
+ }
45
+ }
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "react-components-rails"
8
+ spec.licenses = ["MIT"]
9
+ spec.version = "1.0.0.beta1"
10
+ spec.authors = ["Renaud Chaput"]
11
+ spec.email = ["renchap@gmail.com"]
12
+
13
+ spec.summary = "Provides Rails helpers to render React Components"
14
+ # spec.description = %q{TODO: Write a longer description or delete this line.}
15
+ spec.homepage = "https://github.com/renchap/webpacker-react"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.required_ruby_version = ">= 2.7.0"
25
+
26
+ spec.add_development_dependency "bundler", "~> 2.3"
27
+ spec.add_development_dependency "rake", "~> 13.0"
28
+ # spec.add_development_dependency "minitest", "~> 5.0"
29
+ # spec.add_development_dependency "capybara"
30
+ # spec.add_development_dependency "selenium-webdriver"
31
+ end
data/src/index.ts ADDED
@@ -0,0 +1,90 @@
1
+ import React from "react"
2
+ import ReactDOM from "react-dom"
3
+ import intersection from "lodash/intersection"
4
+ import keys from "lodash/keys"
5
+ import assign from "lodash/assign"
6
+ import omit from "lodash/omit"
7
+ // import ujs from './ujs'
8
+
9
+ const CLASS_ATTRIBUTE_NAME = "data-react-class"
10
+ const PROPS_ATTRIBUTE_NAME = "data-react-props"
11
+
12
+ declare global {
13
+ interface Window {
14
+ ReactComponentsRails: typeof ReactComponentsRails
15
+ }
16
+ }
17
+
18
+ const ReactComponentsRails = {
19
+ registeredComponents: {} as { [name: string]: React.ComponentType },
20
+
21
+ render(node: Element, component: React.ComponentType) {
22
+ const propsJson = node.getAttribute(PROPS_ATTRIBUTE_NAME)
23
+ const props = propsJson && JSON.parse(propsJson)
24
+
25
+ const reactElement = React.createElement(component, props)
26
+
27
+ ReactDOM.render(reactElement, node)
28
+ },
29
+
30
+ registerComponents(components: { [name: string]: React.Component }) {
31
+ const collisions = intersection(
32
+ keys(this.registeredComponents),
33
+ keys(components)
34
+ )
35
+ if (collisions.length > 0) {
36
+ console.error(
37
+ `react-components-rails: can not register components. Following components are already registered: ${collisions}`
38
+ )
39
+ }
40
+
41
+ assign(this.registeredComponents, omit(components, collisions))
42
+ return true
43
+ },
44
+
45
+ unmountComponents() {
46
+ const mounted = document.querySelectorAll(`[${CLASS_ATTRIBUTE_NAME}]`)
47
+ for (let i = 0; i < mounted.length; i += 1) {
48
+ ReactDOM.unmountComponentAtNode(mounted[i])
49
+ }
50
+ },
51
+
52
+ mountComponents() {
53
+ const { registeredComponents } = this
54
+ const toMount = document.querySelectorAll(`[${CLASS_ATTRIBUTE_NAME}]`)
55
+
56
+ for (let i = 0; i < toMount.length; i += 1) {
57
+ const node = toMount[i]
58
+ const className = node.getAttribute(CLASS_ATTRIBUTE_NAME)
59
+
60
+ if (!className) {
61
+ console.error(
62
+ `react-components-rails: no ${CLASS_ATTRIBUTE_NAME} attribute on element: ${node}`
63
+ )
64
+ continue
65
+ }
66
+
67
+ const component = registeredComponents[className]
68
+
69
+ if (component) {
70
+ if (node.innerHTML.length === 0) this.render(node, component)
71
+ } else {
72
+ console.error(
73
+ `react-components-rails: can not render a component that has not been registered: ${className}`
74
+ )
75
+ }
76
+ }
77
+ },
78
+
79
+ setup(components = {}) {
80
+ if (typeof window.ReactComponentsRails === "undefined") {
81
+ window.ReactComponentsRails = this
82
+ // ujs.setup(this.mountComponents.bind(this), this.unmountComponents.bind(this))
83
+ }
84
+
85
+ window.ReactComponentsRails.registerComponents(components)
86
+ window.ReactComponentsRails.mountComponents()
87
+ },
88
+ }
89
+
90
+ export default ReactComponentsRails