Skip to content

Commit

Permalink
Added support for @hotwired/turbo. (#1374)
Browse files Browse the repository at this point in the history
Co-authored-by: Judah Meek <judah.meek@gmail.com>
  • Loading branch information
pgruener and Judahmeek authored Jun 29, 2021
1 parent 2a134ed commit 4e9570b
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 6 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@ Changes since last non-beta release.

*Please add entries here for your pull requests that are not yet released.*

- Ability to use with Turbo (@hotwired/turbo), as Turbolinks gets obsolete.
React on Rails Pro Node rendering [PR ...](https://github.com/shakacode/react_on_rails/pull/...) by [pgruener](https://github.com/pgruener).

To configure turbo the following option can be set:
`ReactOnRails.setOptions({ turbo: true })`

### [12.2.0] - 2021-03-25
#### Added
- Ability to configure server react rendering to throw rather than just logging the error. Useful for
React on Rails Pro Node rendering [PR 1365](https://github.com/shakacode/react_on_rails/pull/1365) by [justin808](https://github.com/justin808).

### [12.1.0] - 2021-03-23
#### Added
- Added the ability to assign a module with a `call` method to `config.build_production_command`. See [the configuration docs](./docs/basics/configuration.md). [PR 1362: Accept custom module for config.build_production_command](https://github.com/shakacode/react_on_rails/pull/1362).
Expand Down Expand Up @@ -67,7 +73,7 @@ invoked to return the React component. In that case, you won't need to pass any
[PR 1268](https://github.com/shakacode/react_on_rails/pull/1268) by [justin808](https://github.com/justin808)

See [docs/basics/upgrading-react-on-rails](./docs/basics/upgrading-react-on-rails.md#upgrading-to-v12)
for details.
for details.

#### Other Updates
* `react_on_rails` fully supports `rails/webpacker`. The example test app in `spec/dummy` was recently converted over to use rails/webpacker v4+. It's a good example of how to leverage rails/webpacker's webpack configuration for server-side rendering.
Expand Down
10 changes: 9 additions & 1 deletion node_package/src/ReactOnRails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,23 @@ ctx.ReactOnRails = {
* Set options for ReactOnRails, typically before you call ReactOnRails.register
* Available Options:
* `traceTurbolinks: true|false Gives you debugging messages on Turbolinks events
* `turbo: true|false Turbo (the follower of Turbolinks) events will be registered, if set to true.
*/
setOptions(newOptions: {traceTurbolinks?: boolean}): void {
setOptions(newOptions: {traceTurbolinks?: boolean, turbo?: boolean }): void {
if (typeof newOptions.traceTurbolinks !== 'undefined') {
this.options.traceTurbolinks = newOptions.traceTurbolinks;

// eslint-disable-next-line no-param-reassign
delete newOptions.traceTurbolinks;
}

if (typeof newOptions.turbo !== 'undefined') {
this.options.turbo = newOptions.turbo;

// eslint-disable-next-line no-param-reassign
delete newOptions.turbo;
}

if (Object.keys(newOptions).length > 0) {
throw new Error(
`Invalid options passed to ReactOnRails.options: ${JSON.stringify(newOptions)}`,
Expand Down
19 changes: 17 additions & 2 deletions node_package/src/clientStartup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ function turbolinksInstalled(): boolean {
return (typeof Turbolinks !== 'undefined');
}

function turboInstalled() {
const context = findContext();
if (context.ReactOnRails) {
return context.ReactOnRails.option('turbo') === true;
}
return false;
}

function reactOnRailsHtmlElements(): HTMLCollectionOf<Element> {
return document.getElementsByClassName('js-react-on-rails-component');
}
Expand Down Expand Up @@ -221,13 +229,20 @@ function renderInit(): void {
// Install listeners when running on the client (browser).
// We must do this check for turbolinks AFTER the document is loaded because we load the
// Webpack bundles first.
if (!turbolinksInstalled() || !turbolinksSupported()) {
if ((!turbolinksInstalled() || !turbolinksSupported()) && !turboInstalled()) {
debugTurbolinks('NOT USING TURBOLINKS: calling reactOnRailsPageLoaded');
reactOnRailsPageLoaded();
return;
}

if (turbolinksVersion5()) {
if (turboInstalled()) {
debugTurbolinks(
'USING TURBO: document added event listeners ' +
'turbo:before-render and turbo:render.');
document.addEventListener('turbo:before-render', reactOnRailsPageUnloaded);
document.addEventListener('turbo:render', reactOnRailsPageLoaded);
reactOnRailsPageLoaded();
} else if (turbolinksVersion5()) {
debugTurbolinks(
'USING TURBOLINKS 5: document added event listeners ' +
'turbolinks:before-render and turbolinks:render.');
Expand Down
7 changes: 6 additions & 1 deletion spec/react_on_rails/react_component/render_options_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,13 @@ def the_attrs(react_component_name: "App", options: {})

it "is memoized" do
opts = described_class.new(the_attrs)
generated_value = opts.dom_id

expect(opts.dom_id).to eq opts.dom_id
expect(opts.instance_variable_get(:@dom_id)).to eq generated_value
expect(opts.instance_variable_get(:@dom_id)).to eq opts.dom_id

opts.instance_variable_set(:@dom_id, "1234")
expect(opts.dom_id).to eq "1234"
end
end

Expand Down

0 comments on commit 4e9570b

Please sign in to comment.