turbo-mount 0.2.0 → 0.2.3
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/CHANGELOG.md +18 -1
- data/README.md +100 -18
- data/app/assets/javascripts/turbo-mount/react.js +11 -4
- data/app/assets/javascripts/turbo-mount/react.min.js +1 -1
- data/app/assets/javascripts/turbo-mount/react.min.js.map +1 -1
- data/app/assets/javascripts/turbo-mount/svelte.js +11 -4
- data/app/assets/javascripts/turbo-mount/svelte.min.js +1 -1
- data/app/assets/javascripts/turbo-mount/svelte.min.js.map +1 -1
- data/app/assets/javascripts/turbo-mount/vue.js +11 -4
- data/app/assets/javascripts/turbo-mount/vue.min.js +1 -1
- data/app/assets/javascripts/turbo-mount/vue.min.js.map +1 -1
- data/app/assets/javascripts/turbo-mount.js +21 -11
- data/app/assets/javascripts/turbo-mount.min.js +1 -1
- data/app/assets/javascripts/turbo-mount.min.js.map +1 -1
- data/lib/turbo/mount/helpers.rb +13 -10
- data/lib/turbo/mount/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0318ba2497956b4a56bc035a5a39e617bf0b171b039823fd61fe131294ca5815'
|
4
|
+
data.tar.gz: 6a078a433b9766915496ac9d86d9df81782eec209c495ccefcb978643c810a39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75dd9c6f8b0760791c40d3db5b07cf95056bc199550d95c5a86cec1686a8f11eb0594ad7e1d4d4c015867289371f18e2b1cc7f1ccb6738e24b8342a42e7b8f1c
|
7
|
+
data.tar.gz: 1ac86acfbb7d0e5c01e61c791e6ba058d78ae01092bdd1dc5cdd0059a5309922888a59cd0afad63541c2c517c478f159d351ef2e0da326ddddf1b48d6c9de534
|
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning].
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [0.2.3] - 2024-05-12
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- Add a mount target to the base controller. ([@skryukov])
|
15
|
+
- Add `registerComponents` helper for vite. ([@skryukov])
|
16
|
+
- Allow to omit the `application` property in the constructor. ([@skryukov])
|
17
|
+
`TurboMount` will try to find the application in the `window.Stimulus` and will initialize new one if not found.
|
18
|
+
|
19
|
+
## [0.2.2] - 2024-05-09
|
20
|
+
|
21
|
+
### Fixed
|
22
|
+
|
23
|
+
- Export plugins. ([@skryukov])
|
24
|
+
|
10
25
|
## [0.2.0] - 2024-05-09
|
11
26
|
|
12
27
|
### Added
|
@@ -21,7 +36,9 @@ and this project adheres to [Semantic Versioning].
|
|
21
36
|
|
22
37
|
[@skryukov]: https://github.com/skryukov
|
23
38
|
|
24
|
-
[Unreleased]: https://github.com/skryukov/turbo-mount/compare/v0.2.
|
39
|
+
[Unreleased]: https://github.com/skryukov/turbo-mount/compare/v0.2.3...HEAD
|
40
|
+
[0.2.3]: https://github.com/skryukov/turbo-mount/commits/v0.2.3
|
41
|
+
[0.2.2]: https://github.com/skryukov/turbo-mount/commits/v0.2.2
|
25
42
|
[0.2.0]: https://github.com/skryukov/turbo-mount/commits/v0.2.0
|
26
43
|
[0.1.0]: https://github.com/skryukov/turbo-mount/commits/v0.1.0
|
27
44
|
|
data/README.md
CHANGED
@@ -6,35 +6,72 @@
|
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
9
|
-
|
9
|
+
Add the following line to your Gemfile:
|
10
10
|
|
11
|
-
|
11
|
+
```ruby
|
12
|
+
gem "turbo-mount"
|
13
|
+
```
|
12
14
|
|
13
|
-
|
15
|
+
For projects utilizing build tools such as [Vite](http://vite-ruby.netlify.app), also install `turbo-mount` package:
|
14
16
|
|
15
|
-
|
17
|
+
```bash
|
18
|
+
npm install turbo-mount
|
19
|
+
# or with yarn
|
20
|
+
yarn add turbo-mount
|
21
|
+
```
|
16
22
|
|
17
23
|
## Usage
|
18
24
|
|
19
|
-
|
25
|
+
### Initialization
|
26
|
+
|
27
|
+
To begin using `TurboMount`, start by initializing the library and registering the components you intend to use. Below are the steps to set up `TurboMount` with different configurations.
|
28
|
+
|
29
|
+
#### Standard Initialization
|
30
|
+
|
31
|
+
Import the necessary modules and initialize ```TurboMount``` with your application and the desired plugin. Here's how to set it up with a React plugin:
|
32
|
+
|
33
|
+
```js
|
34
|
+
import { Application } from "@hotwired/stimulus";
|
35
|
+
import { TurboMount } from "turbo-mount";
|
36
|
+
import plugin from "turbo-mount/react";
|
37
|
+
import { SketchPicker } from 'react-color';
|
38
|
+
|
39
|
+
const application = Application.start();
|
40
|
+
const turboMount = new TurboMount({ application, plugin });
|
41
|
+
|
42
|
+
turboMount.register('SketchPicker', SketchPicker);
|
43
|
+
```
|
44
|
+
|
45
|
+
#### Simplified Initialization
|
46
|
+
|
47
|
+
If you prefer not to specify the `application` explicitly, `TurboMount` can automatically detect or initialize it. This approach uses the `window.Stimulus` if available; otherwise, it initializes a new Stimulus application:
|
20
48
|
|
21
49
|
```js
|
22
|
-
import {
|
50
|
+
import { TurboMount } from "turbo-mount";
|
51
|
+
import plugin from "turbo-mount/react";
|
52
|
+
import { SketchPicker } from 'react-color';
|
53
|
+
|
54
|
+
const turboMount = new TurboMount({ plugin });
|
55
|
+
|
56
|
+
turboMount.register('SketchPicker', SketchPicker);
|
57
|
+
```
|
23
58
|
|
24
|
-
|
59
|
+
#### Plugin-Specific Initialization
|
25
60
|
|
26
|
-
import
|
27
|
-
import plugin from "turbo-mount/react"
|
61
|
+
For a more streamlined setup, you can directly import a specialized version of `TurboMount`:
|
28
62
|
|
29
|
-
|
30
|
-
|
63
|
+
```js
|
64
|
+
import { TurboMountReact } from "turbo-mount/react";
|
65
|
+
import { SketchPicker } from 'react-color';
|
66
|
+
|
67
|
+
const turboMount = new TurboMountReact();
|
31
68
|
|
32
|
-
// Register the components you want to use
|
33
|
-
import { SketchPicker } from 'react-color'
|
34
69
|
turboMount.register('SketchPicker', SketchPicker);
|
35
70
|
```
|
36
71
|
|
37
|
-
|
72
|
+
### View Helpers
|
73
|
+
|
74
|
+
Use the following helpers to mount components in your views:
|
38
75
|
|
39
76
|
```erb
|
40
77
|
<%= turbo_mount_component("SketchPicker", framework: "react", props: {color: "#034"}) %>
|
@@ -44,11 +81,21 @@ Now you can use view helpers to mount the components:
|
|
44
81
|
<%= turbo_mount_react_component("SketchPicker", props: {color: "#430"}) %>
|
45
82
|
```
|
46
83
|
|
47
|
-
|
84
|
+
### Supported Frameworks
|
48
85
|
|
49
|
-
|
50
|
-
|
86
|
+
`TurboMount` supports the following frameworks:
|
87
|
+
|
88
|
+
- React `"turbo-mount/react"`
|
89
|
+
- Vue `"turbo-mount/vue"`
|
90
|
+
- Svelte `"turbo-mount/svelte"`
|
91
|
+
|
92
|
+
It's possible to add support for other frameworks by creating custom controller class extending `TurboMountController` and providing a plugin. See included plugins for examples.
|
93
|
+
|
94
|
+
### Custom Controllers
|
95
|
+
|
96
|
+
To customize component behavior or pass functions as props, create a custom controller:
|
51
97
|
|
98
|
+
```js
|
52
99
|
import { TurboMountReactController } from "turbo-mount"
|
53
100
|
|
54
101
|
export default class extends TurboMountReactController {
|
@@ -68,7 +115,42 @@ export default class extends TurboMountReactController {
|
|
68
115
|
Then pass this controller the register method:
|
69
116
|
|
70
117
|
```js
|
71
|
-
|
118
|
+
import SketchController from "controllers/turbo_mount/sketch_picker_controller"
|
119
|
+
|
120
|
+
turboMount.register('SketchPicker', SketchPicker, SketchController);
|
121
|
+
```
|
122
|
+
|
123
|
+
### Vite Integration
|
124
|
+
|
125
|
+
`TurboMount` includes a `registerComponents` function that automates the loading of components (requires `stimulus-vite-helpers` package). It also accepts an optional `controllers` property to autoload customized controllers:
|
126
|
+
|
127
|
+
```js
|
128
|
+
import { TurboMount } from "turbo-mount/react";
|
129
|
+
import { registerComponents } from "turbo-mount/vite";
|
130
|
+
|
131
|
+
const controllers = import.meta.glob("./**/*_controller.js", { eager: true });
|
132
|
+
const components = import.meta.glob(`/components/**/*.jsx`, { eager: true });
|
133
|
+
|
134
|
+
const turboMount = new TurboMount();
|
135
|
+
registerComponents({ turboMount, components, controllers });
|
136
|
+
```
|
137
|
+
|
138
|
+
The `registerComponents` helper searches for controllers in the following paths:
|
139
|
+
- `controllers/turbo-mount/${framework}/${controllerName}`
|
140
|
+
- `controllers/turbo-mount/${framework}-${controllerName}`
|
141
|
+
- `controllers/turbo-mount-${framework}-${controllerName}`
|
142
|
+
- `controllers/turbo-mount/${controllerName}`
|
143
|
+
- `controllers/turbo-mount-${controllerName}`
|
144
|
+
|
145
|
+
### Mount target
|
146
|
+
|
147
|
+
To specify a non-root mount target, use the `data-<%= controller_name %>-target="mount"` attribute:
|
148
|
+
|
149
|
+
```erb
|
150
|
+
<%= turbo_mount_react_component("SketchPicker", props: {color: "#430"}) do |controller_name| %>
|
151
|
+
<h3>Color picker</h3>
|
152
|
+
<div data-<%= controller_name %>-target="mount"></div>
|
153
|
+
<% end %>
|
72
154
|
```
|
73
155
|
|
74
156
|
## Development
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import { TurboMountController, TurboMount } from 'turbo-mount';
|
1
2
|
import { createElement } from 'react';
|
2
3
|
import { createRoot } from 'react-dom/client';
|
3
|
-
import { TurboMountController } from 'turbo-mount';
|
4
4
|
|
5
5
|
class TurboMountReactController extends TurboMountController {
|
6
6
|
constructor() {
|
@@ -10,13 +10,20 @@ class TurboMountReactController extends TurboMountController {
|
|
10
10
|
mountComponent(el, Component, props) {
|
11
11
|
const root = createRoot(el);
|
12
12
|
root.render(createElement(Component, props));
|
13
|
-
return () => {
|
13
|
+
return () => {
|
14
|
+
root.unmount();
|
15
|
+
};
|
14
16
|
}
|
15
17
|
}
|
16
18
|
|
17
19
|
const plugin = {
|
18
20
|
framework: "react",
|
19
|
-
controller: TurboMountReactController
|
21
|
+
controller: TurboMountReactController,
|
20
22
|
};
|
23
|
+
class TurboMountReact extends TurboMount {
|
24
|
+
constructor(props) {
|
25
|
+
super(Object.assign(Object.assign({}, props), { plugin }));
|
26
|
+
}
|
27
|
+
}
|
21
28
|
|
22
|
-
export { plugin as default };
|
29
|
+
export { TurboMountReact as TurboMount, TurboMountReact, plugin as default };
|
@@ -1,2 +1,2 @@
|
|
1
|
-
import{
|
1
|
+
import{TurboMountController as r,TurboMount as t}from"turbo-mount";import{createElement as o}from"react";import{createRoot as e}from"react-dom/client";const n={framework:"react",controller:class extends r{constructor(){super(...arguments),this.framework="react"}mountComponent(r,t,n){const s=e(r);return s.render(o(t,n)),()=>{s.unmount()}}}};class s extends t{constructor(r){super(Object.assign(Object.assign({},r),{plugin:n}))}}export{s as TurboMount,s as TurboMountReact,n as default};
|
2
2
|
//# sourceMappingURL=react.min.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"react.min.js","sources":["../../src/plugins/react/index.ts","../../src/plugins/react/turbo-mount-react-controller.ts"],"sourcesContent":["import {Plugin} from \"turbo-mount\";\n\nimport {TurboMountReactController} from \"./turbo-mount-react-controller\";\n\nconst plugin: Plugin = {\n
|
1
|
+
{"version":3,"file":"react.min.js","sources":["../../src/plugins/react/index.ts","../../src/plugins/react/turbo-mount-react-controller.ts"],"sourcesContent":["import { Plugin, TurboMount, TurboMountProps } from \"turbo-mount\";\n\nimport { TurboMountReactController } from \"./turbo-mount-react-controller\";\n\nconst plugin: Plugin = {\n framework: \"react\",\n controller: TurboMountReactController,\n};\n\nexport class TurboMountReact<T> extends TurboMount<T> {\n constructor(props: Omit<TurboMountProps, \"plugin\">) {\n super({ ...props, plugin });\n }\n}\n\nexport { TurboMountReact as TurboMount };\n\nexport default plugin;\n","import { ComponentType, createElement } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { TurboMountController } from \"turbo-mount\";\n\nexport class TurboMountReactController extends TurboMountController<ComponentType> {\n framework = \"react\";\n\n mountComponent(el: Element, Component: ComponentType, props: object) {\n const root = createRoot(el);\n root.render(createElement(Component, props));\n\n return () => {\n root.unmount();\n };\n }\n}\n"],"names":["plugin","framework","controller","TurboMountController","constructor","this","mountComponent","el","Component","props","root","createRoot","render","createElement","unmount","TurboMountReact","TurboMount","super","Object","assign"],"mappings":"uJAIA,MAAMA,EAAiB,CACrBC,UAAW,QACXC,WCFI,cAAyCC,EAA/C,WAAAC,uBACEC,KAASJ,UAAG,OAUb,CARC,cAAAK,CAAeC,EAAaC,EAA0BC,GACpD,MAAMC,EAAOC,EAAWJ,GAGxB,OAFAG,EAAKE,OAAOC,EAAcL,EAAWC,IAE9B,KACLC,EAAKI,SAAS,CAEjB,IDLG,MAAOC,UAA2BC,EACtC,WAAAZ,CAAYK,GACVQ,MAAWC,OAAAC,OAAAD,OAAAC,OAAA,GAAAV,GAAO,CAAAT,WACnB"}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { TurboMountController } from 'turbo-mount';
|
1
|
+
import { TurboMountController, TurboMount } from 'turbo-mount';
|
2
2
|
|
3
3
|
class TurboMountSvelteController extends TurboMountController {
|
4
4
|
constructor() {
|
@@ -7,13 +7,20 @@ class TurboMountSvelteController extends TurboMountController {
|
|
7
7
|
}
|
8
8
|
mountComponent(el, Component, props) {
|
9
9
|
const component = new Component({ target: el, props });
|
10
|
-
return () => {
|
10
|
+
return () => {
|
11
|
+
component.$destroy();
|
12
|
+
};
|
11
13
|
}
|
12
14
|
}
|
13
15
|
|
14
16
|
const plugin = {
|
15
17
|
framework: "svelte",
|
16
|
-
controller: TurboMountSvelteController
|
18
|
+
controller: TurboMountSvelteController,
|
17
19
|
};
|
20
|
+
class TurboMountSvelte extends TurboMount {
|
21
|
+
constructor(props) {
|
22
|
+
super(Object.assign(Object.assign({}, props), { plugin }));
|
23
|
+
}
|
24
|
+
}
|
18
25
|
|
19
|
-
export { plugin as default };
|
26
|
+
export { TurboMountSvelte as TurboMount, TurboMountSvelte, plugin as default };
|
@@ -1,2 +1,2 @@
|
|
1
|
-
import{TurboMountController as t}from"turbo-mount";const
|
1
|
+
import{TurboMountController as t,TurboMount as s}from"turbo-mount";const e={framework:"svelte",controller:class extends t{constructor(){super(...arguments),this.framework="svelte"}mountComponent(t,s,e){const o=new s({target:t,props:e});return()=>{o.$destroy()}}}};class o extends s{constructor(t){super(Object.assign(Object.assign({},t),{plugin:e}))}}export{o as TurboMount,o as TurboMountSvelte,e as default};
|
2
2
|
//# sourceMappingURL=svelte.min.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"svelte.min.js","sources":["../../src/plugins/svelte/index.ts","../../src/plugins/svelte/turbo-mount-svelte-controller.ts"],"sourcesContent":["import {Plugin} from \"turbo-mount\";\n\nimport {TurboMountSvelteController} from \"./turbo-mount-svelte-controller\";\n\nconst plugin: Plugin = {\n
|
1
|
+
{"version":3,"file":"svelte.min.js","sources":["../../src/plugins/svelte/index.ts","../../src/plugins/svelte/turbo-mount-svelte-controller.ts"],"sourcesContent":["import { Plugin, TurboMount, TurboMountProps } from \"turbo-mount\";\n\nimport { TurboMountSvelteController } from \"./turbo-mount-svelte-controller\";\n\nconst plugin: Plugin = {\n framework: \"svelte\",\n controller: TurboMountSvelteController,\n};\n\nexport class TurboMountSvelte<T> extends TurboMount<T> {\n constructor(props: Omit<TurboMountProps, \"plugin\">) {\n super({ ...props, plugin });\n }\n}\n\nexport { TurboMountSvelte as TurboMount };\nexport default plugin;\n","import { ComponentType } from \"svelte\";\nimport { TurboMountController } from \"turbo-mount\";\n\nexport class TurboMountSvelteController extends TurboMountController<ComponentType> {\n framework = \"svelte\";\n\n mountComponent(el: Element, Component: ComponentType, props: object) {\n const component = new Component({ target: el, props });\n\n return () => {\n component.$destroy();\n };\n }\n}\n"],"names":["plugin","framework","controller","TurboMountController","constructor","this","mountComponent","el","Component","props","component","target","$destroy","TurboMountSvelte","TurboMount","super","Object","assign"],"mappings":"mEAIA,MAAMA,EAAiB,CACrBC,UAAW,SACXC,WCHI,cAA0CC,EAAhD,WAAAC,uBACEC,KAASJ,UAAG,QASb,CAPC,cAAAK,CAAeC,EAAaC,EAA0BC,GACpD,MAAMC,EAAY,IAAIF,EAAU,CAAEG,OAAQJ,EAAIE,UAE9C,MAAO,KACLC,EAAUE,UAAU,CAEvB,IDHG,MAAOC,UAA4BC,EACvC,WAAAV,CAAYK,GACVM,MAAWC,OAAAC,OAAAD,OAAAC,OAAA,GAAAR,GAAO,CAAAT,WACnB"}
|
@@ -1,5 +1,5 @@
|
|
1
|
+
import { TurboMountController, TurboMount } from 'turbo-mount';
|
1
2
|
import { createApp } from 'vue';
|
2
|
-
import { TurboMountController } from 'turbo-mount';
|
3
3
|
|
4
4
|
class TurboMountVueController extends TurboMountController {
|
5
5
|
constructor() {
|
@@ -9,13 +9,20 @@ class TurboMountVueController extends TurboMountController {
|
|
9
9
|
mountComponent(el, Component, props) {
|
10
10
|
const app = createApp(Component, props);
|
11
11
|
app.mount(el);
|
12
|
-
return () => {
|
12
|
+
return () => {
|
13
|
+
app.unmount();
|
14
|
+
};
|
13
15
|
}
|
14
16
|
}
|
15
17
|
|
16
18
|
const plugin = {
|
17
19
|
framework: "vue",
|
18
|
-
controller: TurboMountVueController
|
20
|
+
controller: TurboMountVueController,
|
19
21
|
};
|
22
|
+
class TurboMountVue extends TurboMount {
|
23
|
+
constructor(props) {
|
24
|
+
super(Object.assign(Object.assign({}, props), { plugin }));
|
25
|
+
}
|
26
|
+
}
|
20
27
|
|
21
|
-
export { plugin as default };
|
28
|
+
export { TurboMountVue as TurboMount, TurboMountVue, plugin as default };
|
@@ -1,2 +1,2 @@
|
|
1
|
-
import{
|
1
|
+
import{TurboMountController as o,TurboMount as t}from"turbo-mount";import{createApp as r}from"vue";const n={framework:"vue",controller:class extends o{constructor(){super(...arguments),this.framework="vue"}mountComponent(o,t,n){const s=r(t,n);return s.mount(o),()=>{s.unmount()}}}};class s extends t{constructor(o){super(Object.assign(Object.assign({},o),{plugin:n}))}}export{s as TurboMount,s as TurboMountVue,n as default};
|
2
2
|
//# sourceMappingURL=vue.min.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"vue.min.js","sources":["../../src/plugins/vue/index.ts","../../src/plugins/vue/turbo-mount-vue-controller.ts"],"sourcesContent":["import {Plugin} from \"turbo-mount\";\n\nimport {TurboMountVueController} from \"./turbo-mount-vue-controller\";\n\nconst plugin: Plugin = {\n
|
1
|
+
{"version":3,"file":"vue.min.js","sources":["../../src/plugins/vue/index.ts","../../src/plugins/vue/turbo-mount-vue-controller.ts"],"sourcesContent":["import { Plugin, TurboMount, TurboMountProps } from \"turbo-mount\";\n\nimport { TurboMountVueController } from \"./turbo-mount-vue-controller\";\n\nconst plugin: Plugin = {\n framework: \"vue\",\n controller: TurboMountVueController,\n};\n\nexport class TurboMountVue<T> extends TurboMount<T> {\n constructor(props: Omit<TurboMountProps, \"plugin\">) {\n super({ ...props, plugin });\n }\n}\n\nexport { TurboMountVue as TurboMount };\n\nexport default plugin;\n","import { createApp, App } from \"vue\";\nimport { TurboMountController } from \"turbo-mount\";\n\nexport class TurboMountVueController extends TurboMountController<App> {\n framework = \"vue\";\n\n mountComponent(el: Element, Component: App, props: object) {\n const app = createApp(Component, props as Record<string, unknown>);\n app.mount(el);\n\n return () => {\n app.unmount();\n };\n }\n}\n"],"names":["plugin","framework","controller","TurboMountController","constructor","this","mountComponent","el","Component","props","app","createApp","mount","unmount","TurboMountVue","TurboMount","super","Object","assign"],"mappings":"mGAIA,MAAMA,EAAiB,CACrBC,UAAW,MACXC,WCHI,cAAuCC,EAA7C,WAAAC,uBACEC,KAASJ,UAAG,KAUb,CARC,cAAAK,CAAeC,EAAaC,EAAgBC,GAC1C,MAAMC,EAAMC,EAAUH,EAAWC,GAGjC,OAFAC,EAAIE,MAAML,GAEH,KACLG,EAAIG,SAAS,CAEhB,IDJG,MAAOC,UAAyBC,EACpC,WAAAX,CAAYK,GACVO,MAAWC,OAAAC,OAAAD,OAAAC,OAAA,GAAAT,GAAO,CAAAT,WACnB"}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Controller } from '@hotwired/stimulus';
|
1
|
+
import { Controller, Application } from '@hotwired/stimulus';
|
2
2
|
|
3
3
|
class TurboMountController extends Controller {
|
4
4
|
connect() {
|
@@ -15,7 +15,7 @@ class TurboMountController extends Controller {
|
|
15
15
|
return this.propsValue;
|
16
16
|
}
|
17
17
|
get mountElement() {
|
18
|
-
return this.element;
|
18
|
+
return this.hasMountTarget ? this.mountTarget : this.element;
|
19
19
|
}
|
20
20
|
get resolvedComponent() {
|
21
21
|
return this.resolveComponent(this.componentValue);
|
@@ -31,22 +31,35 @@ class TurboMountController extends Controller {
|
|
31
31
|
}
|
32
32
|
TurboMountController.values = {
|
33
33
|
props: Object,
|
34
|
-
component: String
|
34
|
+
component: String,
|
35
|
+
};
|
36
|
+
TurboMountController.targets = ["mount"];
|
37
|
+
|
38
|
+
const camelToKebabCase = (str) => {
|
39
|
+
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
35
40
|
};
|
36
41
|
|
37
42
|
class TurboMount {
|
38
|
-
constructor(
|
43
|
+
constructor({ application, plugin }) {
|
39
44
|
var _a;
|
40
45
|
this.components = new Map();
|
41
|
-
this.application =
|
42
|
-
this.framework =
|
43
|
-
this.baseController =
|
46
|
+
this.application = this.findOrStartApplication(application);
|
47
|
+
this.framework = plugin.framework;
|
48
|
+
this.baseController = plugin.controller;
|
44
49
|
(_a = this.application).turboMount || (_a.turboMount = {});
|
45
50
|
this.application.turboMount[this.framework] = this;
|
46
51
|
if (this.baseController) {
|
47
52
|
this.application.register(`turbo-mount-${this.framework}`, this.baseController);
|
48
53
|
}
|
49
54
|
}
|
55
|
+
findOrStartApplication(hydratedApp) {
|
56
|
+
let application = hydratedApp || window.Stimulus;
|
57
|
+
if (!application) {
|
58
|
+
application = Application.start();
|
59
|
+
window.Stimulus = application;
|
60
|
+
}
|
61
|
+
return application;
|
62
|
+
}
|
50
63
|
register(name, component, controller) {
|
51
64
|
controller || (controller = this.baseController);
|
52
65
|
if (this.components.has(name)) {
|
@@ -54,7 +67,7 @@ class TurboMount {
|
|
54
67
|
}
|
55
68
|
this.components.set(name, component);
|
56
69
|
if (controller) {
|
57
|
-
const controllerName = `turbo-mount-${this.framework}-${
|
70
|
+
const controllerName = `turbo-mount-${this.framework}-${camelToKebabCase(name)}`;
|
58
71
|
this.application.register(controllerName, controller);
|
59
72
|
}
|
60
73
|
}
|
@@ -65,9 +78,6 @@ class TurboMount {
|
|
65
78
|
}
|
66
79
|
return component;
|
67
80
|
}
|
68
|
-
camelToKebabCase(str) {
|
69
|
-
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
70
|
-
}
|
71
81
|
}
|
72
82
|
|
73
83
|
export { TurboMount, TurboMountController };
|
@@ -1,2 +1,2 @@
|
|
1
|
-
import{Controller as t}from"@hotwired/stimulus";class
|
1
|
+
import{Controller as t,Application as o}from"@hotwired/stimulus";class n extends t{connect(){this._umountComponentCallback||(this._umountComponentCallback=this.mountComponent(this.mountElement,this.resolvedComponent,this.componentProps))}disconnect(){this.umountComponent()}propsValueChanged(){this.umountComponent(),this._umountComponentCallback||(this._umountComponentCallback=this.mountComponent(this.mountElement,this.resolvedComponent,this.componentProps))}get componentProps(){return this.propsValue}get mountElement(){return this.hasMountTarget?this.mountTarget:this.element}get resolvedComponent(){return this.resolveComponent(this.componentValue)}umountComponent(){this._umountComponentCallback&&this._umountComponentCallback(),this._umountComponentCallback=void 0}resolveComponent(t){return this.application.turboMount[this.framework].resolve(t)}}n.values={props:Object,component:String},n.targets=["mount"];class e{constructor({application:t,plugin:o}){var n;this.components=new Map,this.application=this.findOrStartApplication(t),this.framework=o.framework,this.baseController=o.controller,(n=this.application).turboMount||(n.turboMount={}),this.application.turboMount[this.framework]=this,this.baseController&&this.application.register(`turbo-mount-${this.framework}`,this.baseController)}findOrStartApplication(t){let n=t||window.Stimulus;return n||(n=o.start(),window.Stimulus=n),n}register(t,o,n){if(n||(n=this.baseController),this.components.has(t))throw new Error(`Component '${t}' is already registered.`);if(this.components.set(t,o),n){const o=`turbo-mount-${this.framework}-${e=t,e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}`;this.application.register(o,n)}var e}resolve(t){const o=this.components.get(t);if(!o)throw new Error(`Unknown component: ${t}`);return o}}export{e as TurboMount,n as TurboMountController};
|
2
2
|
//# sourceMappingURL=turbo-mount.min.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"turbo-mount.min.js","sources":["../src/turbo-mount-controller.ts","../src/turbo-mount.ts"],"sourcesContent":["import {Controller} from \"@hotwired/stimulus\"
|
1
|
+
{"version":3,"file":"turbo-mount.min.js","sources":["../src/turbo-mount-controller.ts","../src/turbo-mount.ts","../src/helpers.ts"],"sourcesContent":["import { Controller } from \"@hotwired/stimulus\";\nimport { ApplicationWithTurboMount } from \"./turbo-mount\";\n\nexport abstract class TurboMountController<T> extends Controller {\n static values = {\n props: Object,\n component: String,\n };\n static targets = [\"mount\"];\n\n declare readonly propsValue: object;\n declare readonly componentValue: string;\n declare readonly hasMountTarget: boolean;\n declare readonly mountTarget: Element;\n\n abstract framework: string;\n\n abstract mountComponent(el: Element, Component: T, props: object): () => void;\n\n _umountComponentCallback?: () => void;\n\n connect() {\n this._umountComponentCallback ||= this.mountComponent(\n this.mountElement,\n this.resolvedComponent,\n this.componentProps,\n );\n }\n\n disconnect() {\n this.umountComponent();\n }\n\n propsValueChanged() {\n this.umountComponent();\n this._umountComponentCallback ||= this.mountComponent(\n this.mountElement,\n this.resolvedComponent,\n this.componentProps,\n );\n }\n\n get componentProps() {\n return this.propsValue;\n }\n\n get mountElement() {\n return this.hasMountTarget ? this.mountTarget : this.element;\n }\n\n get resolvedComponent() {\n return this.resolveComponent(this.componentValue);\n }\n\n umountComponent() {\n this._umountComponentCallback && this._umountComponentCallback();\n this._umountComponentCallback = undefined;\n }\n\n resolveComponent(component: string): T {\n const app = this.application as ApplicationWithTurboMount<T>;\n return app.turboMount[this.framework].resolve(component);\n }\n}\n","import { Application, ControllerConstructor } from \"@hotwired/stimulus\";\n\nimport { camelToKebabCase } from \"./helpers\";\n\ndeclare global {\n interface Window {\n Stimulus?: Application;\n }\n}\n\nexport interface ApplicationWithTurboMount<T> extends Application {\n turboMount: { [framework: string]: TurboMount<T> };\n}\n\nexport type Plugin = {\n framework: string;\n controller: ControllerConstructor;\n};\n\nexport type TurboMountProps = {\n application?: Application;\n plugin: Plugin;\n};\n\nexport class TurboMount<T> {\n components: Map<string, T>;\n application: ApplicationWithTurboMount<T>;\n framework: string;\n baseController?: ControllerConstructor;\n\n constructor({ application, plugin }: TurboMountProps) {\n this.components = new Map();\n this.application = this.findOrStartApplication(application);\n this.framework = plugin.framework;\n this.baseController = plugin.controller;\n\n this.application.turboMount ||= {};\n this.application.turboMount[this.framework] = this;\n\n if (this.baseController) {\n this.application.register(\n `turbo-mount-${this.framework}`,\n this.baseController,\n );\n }\n }\n\n private findOrStartApplication(hydratedApp?: Application) {\n let application = hydratedApp || window.Stimulus;\n\n if (!application) {\n application = Application.start();\n window.Stimulus = application;\n }\n return application as ApplicationWithTurboMount<T>;\n }\n\n register(name: string, component: T, controller?: ControllerConstructor) {\n controller ||= this.baseController;\n if (this.components.has(name)) {\n throw new Error(`Component '${name}' is already registered.`);\n }\n this.components.set(name, component);\n\n if (controller) {\n const controllerName = `turbo-mount-${this.framework}-${camelToKebabCase(name)}`;\n this.application.register(controllerName, controller);\n }\n }\n\n resolve(name: string) {\n const component = this.components.get(name);\n if (!component) {\n throw new Error(`Unknown component: ${name}`);\n }\n return component;\n }\n}\n","export const camelToKebabCase = (str: string) => {\n return str.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase();\n};\n"],"names":["TurboMountController","Controller","connect","this","_umountComponentCallback","mountComponent","mountElement","resolvedComponent","componentProps","disconnect","umountComponent","propsValueChanged","propsValue","hasMountTarget","mountTarget","element","resolveComponent","componentValue","undefined","component","application","turboMount","framework","resolve","values","props","Object","String","targets","TurboMount","constructor","plugin","components","Map","findOrStartApplication","baseController","controller","_a","register","hydratedApp","window","Stimulus","Application","start","name","has","Error","set","controllerName","str","replace","toLowerCase","get"],"mappings":"iEAGM,MAAgBA,UAAgCC,EAkBpD,OAAAC,GACEC,KAAKC,2BAALD,KAAKC,yBAA6BD,KAAKE,eACrCF,KAAKG,aACLH,KAAKI,kBACLJ,KAAKK,gBAER,CAED,UAAAC,GACEN,KAAKO,iBACN,CAED,iBAAAC,GACER,KAAKO,kBACLP,KAAKC,2BAALD,KAAKC,yBAA6BD,KAAKE,eACrCF,KAAKG,aACLH,KAAKI,kBACLJ,KAAKK,gBAER,CAED,kBAAIA,GACF,OAAOL,KAAKS,UACb,CAED,gBAAIN,GACF,OAAOH,KAAKU,eAAiBV,KAAKW,YAAcX,KAAKY,OACtD,CAED,qBAAIR,GACF,OAAOJ,KAAKa,iBAAiBb,KAAKc,eACnC,CAED,eAAAP,GACEP,KAAKC,0BAA4BD,KAAKC,2BACtCD,KAAKC,8BAA2Bc,CACjC,CAED,gBAAAF,CAAiBG,GAEf,OADYhB,KAAKiB,YACNC,WAAWlB,KAAKmB,WAAWC,QAAQJ,EAC/C,EA1DMnB,EAAAwB,OAAS,CACdC,MAAOC,OACPP,UAAWQ,QAEN3B,EAAA4B,QAAU,CAAC,eCgBPC,EAMX,WAAAC,EAAYV,YAAEA,EAAWW,OAAEA,UACzB5B,KAAK6B,WAAa,IAAIC,IACtB9B,KAAKiB,YAAcjB,KAAK+B,uBAAuBd,GAC/CjB,KAAKmB,UAAYS,EAAOT,UACxBnB,KAAKgC,eAAiBJ,EAAOK,YAE7BC,EAAAlC,KAAKiB,aAAYC,aAAAgB,EAAAhB,WAAe,CAAA,GAChClB,KAAKiB,YAAYC,WAAWlB,KAAKmB,WAAanB,KAE1CA,KAAKgC,gBACPhC,KAAKiB,YAAYkB,SACf,eAAenC,KAAKmB,YACpBnB,KAAKgC,eAGV,CAEO,sBAAAD,CAAuBK,GAC7B,IAAInB,EAAcmB,GAAeC,OAAOC,SAMxC,OAJKrB,IACHA,EAAcsB,EAAYC,QAC1BH,OAAOC,SAAWrB,GAEbA,CACR,CAED,QAAAkB,CAASM,EAAczB,EAAciB,GAEnC,GADAA,IAAAA,EAAejC,KAAKgC,gBAChBhC,KAAK6B,WAAWa,IAAID,GACtB,MAAM,IAAIE,MAAM,cAAcF,6BAIhC,GAFAzC,KAAK6B,WAAWe,IAAIH,EAAMzB,GAEtBiB,EAAY,CACd,MAAMY,EAAiB,eAAe7C,KAAKmB,aCjEhB2B,EDiE8CL,EChEtEK,EAAIC,QAAQ,kBAAmB,SAASC,gBDiE3ChD,KAAKiB,YAAYkB,SAASU,EAAgBZ,EAC3C,CCnE2B,IAACa,CDoE9B,CAED,OAAA1B,CAAQqB,GACN,MAAMzB,EAAYhB,KAAK6B,WAAWoB,IAAIR,GACtC,IAAKzB,EACH,MAAM,IAAI2B,MAAM,sBAAsBF,KAExC,OAAOzB,CACR"}
|
data/lib/turbo/mount/helpers.rb
CHANGED
@@ -3,27 +3,30 @@
|
|
3
3
|
module Turbo
|
4
4
|
module Mount
|
5
5
|
module Helpers
|
6
|
-
def turbo_mount_component(component_name, framework:, props: {}, tag: "div", **attrs)
|
6
|
+
def turbo_mount_component(component_name, framework:, props: {}, tag: "div", **attrs, &block)
|
7
7
|
raise TypeError, "Component name expected" unless component_name.is_a? String
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
controller_name = "turbo-mount-#{framework}-#{component_name.underscore.dasherize}"
|
10
|
+
attrs["data-controller"] = controller_name
|
11
|
+
prefix = "data-#{controller_name}"
|
11
12
|
attrs["#{prefix}-component-value"] = component_name
|
12
13
|
attrs["#{prefix}-props-value"] = json_escape(props.to_json) if props.present?
|
13
14
|
|
14
|
-
content_tag(tag, nil, attrs)
|
15
|
+
return content_tag(tag, nil, attrs) unless block
|
16
|
+
|
17
|
+
content_tag(tag, nil, attrs) { capture(controller_name, &block) }
|
15
18
|
end
|
16
19
|
|
17
|
-
def turbo_mount_react_component(component_name, **attrs)
|
18
|
-
turbo_mount_component(component_name, framework: "react", **attrs)
|
20
|
+
def turbo_mount_react_component(component_name, **attrs, &block)
|
21
|
+
turbo_mount_component(component_name, framework: "react", **attrs, &block)
|
19
22
|
end
|
20
23
|
|
21
|
-
def turbo_mount_svelte_component(component_name, **attrs)
|
22
|
-
turbo_mount_component(component_name, framework: "svelte", **attrs)
|
24
|
+
def turbo_mount_svelte_component(component_name, **attrs, &block)
|
25
|
+
turbo_mount_component(component_name, framework: "svelte", **attrs, &block)
|
23
26
|
end
|
24
27
|
|
25
|
-
def turbo_mount_vue_component(component_name, **attrs)
|
26
|
-
turbo_mount_component(component_name, framework: "vue", **attrs)
|
28
|
+
def turbo_mount_vue_component(component_name, **attrs, &block)
|
29
|
+
turbo_mount_component(component_name, framework: "vue", **attrs, &block)
|
27
30
|
end
|
28
31
|
end
|
29
32
|
end
|
data/lib/turbo/mount/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbo-mount
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Svyatoslav Kryukov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|