tombolo 0.9.0 → 0.9.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 +4 -4
- data/README.md +114 -42
- data/lib/tombolo/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c83c9dbdab6b8ff99150d3fa57531514628e2c4c98ed68f655cd4cc557553429
|
|
4
|
+
data.tar.gz: 18ce866491063647ae333e0f4cb6e768cef06c843139f97df077d4301aebd1d4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aff5dfca04cf8bd500be3cc099b36a7a85f4d65a4b138e99f7a44ec9feb47c02ee7e65bcae57ae458ab31884d0e6ffe06eed1d6787522b54eac9a7fd248ab940
|
|
7
|
+
data.tar.gz: 16d329db50843678dacc5d8b8d50a1c20d6c453b3dec5ca5a7b98cf1058c85d3a1c1f0987c179ed22edf3d85451d52f166c881e4116a886deab1dadfb89c570c
|
data/README.md
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
# Tombolo
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
[](https://badge.fury.io/rb/tombolo)
|
|
4
|
+
[](https://www.npmjs.com/package/tombolo)
|
|
5
|
+
[](https://github.com/elektronaut/tombolo/actions/workflows/build.yml)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
Tombolo is a lightweight alternative to
|
|
9
|
+
[react-rails](https://github.com/reactjs/react-rails) for mounting React
|
|
10
|
+
[islands](https://www.patterns.dev/posts/islands-architecture) in your Rails
|
|
11
|
+
views. It provides a `react_component` view helper, client-side mounting via a
|
|
12
|
+
component map, and optional server-side rendering through ExecJS.
|
|
13
|
+
|
|
14
|
+
Built for React 18+, Tombolo targets modern Rails apps using
|
|
15
|
+
[jsbundling-rails](https://github.com/rails/jsbundling-rails) (or any JS
|
|
16
|
+
bundler) and [propshaft](https://github.com/rails/propshaft), with no asset
|
|
17
|
+
pipeline integration — just register your components and write a few lines of
|
|
18
|
+
JavaScript.
|
|
19
|
+
|
|
20
|
+
## Compatibility
|
|
21
|
+
|
|
22
|
+
| Dependency | Versions |
|
|
23
|
+
|------------|----------|
|
|
24
|
+
| Ruby | >= 3.2 |
|
|
25
|
+
| Rails | >= 7.0 |
|
|
26
|
+
| React | 18, 19 |
|
|
10
27
|
|
|
11
28
|
## Installation
|
|
12
29
|
|
|
@@ -25,8 +42,9 @@ npm install tombolo
|
|
|
25
42
|
pnpm add tombolo
|
|
26
43
|
```
|
|
27
44
|
|
|
28
|
-
|
|
29
|
-
point
|
|
45
|
+
Optionally, run the install generator to create a config initializer
|
|
46
|
+
(`config/initializers/tombolo.rb`) and an SSR entry point
|
|
47
|
+
(`app/javascript/prerender.ts`):
|
|
30
48
|
|
|
31
49
|
```sh
|
|
32
50
|
bin/rails generate tombolo:install
|
|
@@ -42,11 +60,14 @@ Render a React component from any view or partial:
|
|
|
42
60
|
<%= react_component("Greeting", props: { name: "World" }) %>
|
|
43
61
|
```
|
|
44
62
|
|
|
63
|
+
This renders a `<div>` with `data-react-component` and `data-react-props`
|
|
64
|
+
attributes that the JavaScript side picks up.
|
|
65
|
+
|
|
45
66
|
### Client-side mounting
|
|
46
67
|
|
|
47
68
|
Tombolo takes a component map — an object mapping component names to React
|
|
48
|
-
components. The easiest way to create one is a barrel file that
|
|
49
|
-
|
|
69
|
+
components. The easiest way to create one is a barrel file (a module that
|
|
70
|
+
re-exports from other modules):
|
|
50
71
|
|
|
51
72
|
```typescript
|
|
52
73
|
// app/javascript/components/index.ts
|
|
@@ -54,36 +75,44 @@ export { Greeting } from "./Greeting";
|
|
|
54
75
|
export { SearchForm } from "./SearchForm";
|
|
55
76
|
```
|
|
56
77
|
|
|
57
|
-
|
|
78
|
+
#### With Turbo
|
|
79
|
+
|
|
80
|
+
For apps using Turbo, use `Tombolo.mount` and `Tombolo.unmount` directly:
|
|
58
81
|
|
|
59
82
|
```typescript
|
|
60
83
|
import * as Tombolo from "tombolo";
|
|
61
84
|
import * as components from "./components";
|
|
62
85
|
|
|
63
|
-
Tombolo.
|
|
86
|
+
document.addEventListener("turbo:load", () => Tombolo.mount(components));
|
|
87
|
+
document.addEventListener("turbo:before-cache", () => Tombolo.unmount());
|
|
64
88
|
```
|
|
65
89
|
|
|
66
|
-
|
|
67
|
-
|
|
90
|
+
#### Without Turbo
|
|
91
|
+
|
|
92
|
+
For apps without Turbo, `Tombolo.start` mounts components on
|
|
93
|
+
`DOMContentLoaded` (or immediately if the DOM is already loaded):
|
|
68
94
|
|
|
69
95
|
```typescript
|
|
70
|
-
Tombolo
|
|
96
|
+
import * as Tombolo from "tombolo";
|
|
97
|
+
import * as components from "./components";
|
|
98
|
+
|
|
99
|
+
Tombolo.start(components);
|
|
71
100
|
```
|
|
72
101
|
|
|
73
|
-
####
|
|
102
|
+
#### Scoped mounting
|
|
74
103
|
|
|
75
|
-
|
|
104
|
+
Both `Tombolo.mount` and `Tombolo.unmount` accept an optional `scope`
|
|
105
|
+
parameter to limit operations to a subtree of the DOM:
|
|
76
106
|
|
|
77
107
|
```typescript
|
|
78
|
-
|
|
79
|
-
import * as components from "./components";
|
|
80
|
-
|
|
81
|
-
document.addEventListener("turbo:load", () => Tombolo.mount(components));
|
|
82
|
-
document.addEventListener("turbo:before-cache", () => Tombolo.unmount());
|
|
108
|
+
Tombolo.mount(components, document.getElementById("sidebar"));
|
|
83
109
|
```
|
|
84
110
|
|
|
85
111
|
### Server-side rendering
|
|
86
112
|
|
|
113
|
+
SSR is optional and requires the [execjs](https://github.com/rails/execjs)
|
|
114
|
+
gem.
|
|
115
|
+
|
|
87
116
|
Create a server entry point that registers your components:
|
|
88
117
|
|
|
89
118
|
```typescript
|
|
@@ -94,8 +123,12 @@ import * as components from "./components";
|
|
|
94
123
|
registerServerRenderer(components);
|
|
95
124
|
```
|
|
96
125
|
|
|
97
|
-
Build it with esbuild (or your bundler of choice)
|
|
98
|
-
|
|
126
|
+
Build it with esbuild (or your bundler of choice) as a CommonJS bundle that
|
|
127
|
+
ExecJS can evaluate:
|
|
128
|
+
|
|
129
|
+
```sh
|
|
130
|
+
esbuild app/javascript/prerender.ts --bundle --platform=neutral --outfile=app/assets/builds/prerender.js
|
|
131
|
+
```
|
|
99
132
|
|
|
100
133
|
Then use `prerender: true` in your views:
|
|
101
134
|
|
|
@@ -103,6 +136,10 @@ Then use `prerender: true` in your views:
|
|
|
103
136
|
<%= react_component("Greeting", props: { name: "World" }, prerender: true) %>
|
|
104
137
|
```
|
|
105
138
|
|
|
139
|
+
When a component is prerendered, the server-rendered HTML is placed inside the
|
|
140
|
+
div and Tombolo uses `hydrateRoot` instead of `createRoot` on the client.
|
|
141
|
+
This preserves interactivity without a full re-render.
|
|
142
|
+
|
|
106
143
|
The default server bundle path is `app/assets/builds/prerender.js`. To
|
|
107
144
|
customize it, add an initializer:
|
|
108
145
|
|
|
@@ -113,29 +150,50 @@ Tombolo.configure do |config|
|
|
|
113
150
|
end
|
|
114
151
|
```
|
|
115
152
|
|
|
116
|
-
##
|
|
153
|
+
## Configuration
|
|
154
|
+
|
|
155
|
+
```ruby
|
|
156
|
+
Tombolo.configure do |config|
|
|
157
|
+
# Convert snake_case prop keys to camelCase (default: false)
|
|
158
|
+
config.camelize_props = true
|
|
117
159
|
|
|
118
|
-
|
|
160
|
+
# Path to the server-side JS bundle for SSR
|
|
161
|
+
# (default: "app/assets/builds/prerender.js")
|
|
162
|
+
config.server_bundle = "app/assets/builds/prerender.js"
|
|
163
|
+
end
|
|
164
|
+
```
|
|
119
165
|
|
|
120
|
-
|
|
166
|
+
`camelize_props` can also be overridden per-call:
|
|
121
167
|
|
|
122
|
-
|
|
123
|
-
|
|
168
|
+
```erb
|
|
169
|
+
<%= react_component("Greeting", props: { first_name: "World" }, camelize_props: true) %>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## API reference
|
|
173
|
+
|
|
174
|
+
### JavaScript
|
|
124
175
|
|
|
125
|
-
#### `
|
|
176
|
+
#### `mount(components, scope?)`
|
|
126
177
|
|
|
127
178
|
Scans `scope` (default: `document`) for elements with a
|
|
128
|
-
`data-react-component` attribute. For each element, looks up the component
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
179
|
+
`data-react-component` attribute. For each element, looks up the component by
|
|
180
|
+
name, parses props from `data-react-props`, and mounts it. Elements with a
|
|
181
|
+
`data-react-prerender` attribute are hydrated with `hydrateRoot`; all others
|
|
182
|
+
use `createRoot`. Already-mounted elements are skipped.
|
|
132
183
|
|
|
133
|
-
#### `
|
|
184
|
+
#### `unmount(scope?)`
|
|
134
185
|
|
|
135
186
|
Unmounts all tracked React roots within `scope` (default: `document`).
|
|
136
187
|
|
|
188
|
+
#### `start(components)`
|
|
189
|
+
|
|
190
|
+
Calls `mount` on `DOMContentLoaded`, or immediately if the DOM is already
|
|
191
|
+
loaded.
|
|
192
|
+
|
|
137
193
|
#### `registerServerRenderer(components)`
|
|
138
194
|
|
|
195
|
+
*Imported from `tombolo/server`.*
|
|
196
|
+
|
|
139
197
|
Assigns a `renderComponent(name, propsJson)` function to `globalThis`,
|
|
140
198
|
making it callable from ExecJS. Used in server entry points for SSR.
|
|
141
199
|
|
|
@@ -151,15 +209,12 @@ configuration.
|
|
|
151
209
|
|
|
152
210
|
#### `Tombolo.configure { |config| ... }`
|
|
153
211
|
|
|
154
|
-
|
|
155
|
-
Default: `false`
|
|
156
|
-
- `config.server_bundle` — Path to the server-side JS bundle for SSR.
|
|
157
|
-
Default: `"app/assets/builds/prerender.js"`
|
|
212
|
+
See [Configuration](#configuration) above.
|
|
158
213
|
|
|
159
214
|
## Migrating from react-rails
|
|
160
215
|
|
|
161
|
-
|
|
162
|
-
|
|
216
|
+
**Helper signature.** react-rails passes props as a positional argument,
|
|
217
|
+
Tombolo uses a keyword argument:
|
|
163
218
|
|
|
164
219
|
```ruby
|
|
165
220
|
# react-rails
|
|
@@ -169,6 +224,23 @@ react_component("Name", { title: "Hello" })
|
|
|
169
224
|
react_component("Name", props: { title: "Hello" })
|
|
170
225
|
```
|
|
171
226
|
|
|
227
|
+
**No html_options argument.** react-rails accepts a third argument for HTML
|
|
228
|
+
attributes on the wrapper div. Tombolo does not support this — wrap the helper
|
|
229
|
+
call in your own tag if you need custom attributes.
|
|
230
|
+
|
|
231
|
+
**No asset pipeline integration.** Tombolo does not ship a component generator
|
|
232
|
+
or integrate with Sprockets/Webpacker. You manage your JavaScript build
|
|
233
|
+
yourself with jsbundling-rails or an equivalent.
|
|
234
|
+
|
|
235
|
+
**SSR setup.** Replace any `server_rendering.js` pack with a
|
|
236
|
+
`prerender.ts` entry point that calls `registerServerRenderer`. See
|
|
237
|
+
[Server-side rendering](#server-side-rendering) above.
|
|
238
|
+
|
|
239
|
+
## Contributing
|
|
240
|
+
|
|
241
|
+
Bug reports and pull requests are welcome on
|
|
242
|
+
[GitHub](https://github.com/elektronaut/tombolo).
|
|
243
|
+
|
|
172
244
|
## License
|
|
173
245
|
|
|
174
246
|
MIT
|
data/lib/tombolo/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tombolo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Inge Jørgensen
|
|
@@ -23,8 +23,8 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '7.0'
|
|
26
|
-
description:
|
|
27
|
-
|
|
26
|
+
description: Lightweight alternative to react-rails for mounting React components
|
|
27
|
+
in Rails views with optional server-side rendering via ExecJS.
|
|
28
28
|
email:
|
|
29
29
|
- inge@elektronaut.no
|
|
30
30
|
executables: []
|
|
@@ -64,5 +64,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
64
64
|
requirements: []
|
|
65
65
|
rubygems_version: 4.0.3
|
|
66
66
|
specification_version: 4
|
|
67
|
-
summary:
|
|
67
|
+
summary: Mount React components in Rails views with optional SSR
|
|
68
68
|
test_files: []
|