matestack-ui-vuejs 3.0.0.rc1

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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +492 -0
  4. data/Rakefile +64 -0
  5. data/lib/matestack/ui/component.rb +1 -0
  6. data/lib/matestack/ui/isolated_component.rb +1 -0
  7. data/lib/matestack/ui/vue_js/components/action.js +70 -0
  8. data/lib/matestack/ui/vue_js/components/action.rb +46 -0
  9. data/lib/matestack/ui/vue_js/components/app.js +122 -0
  10. data/lib/matestack/ui/vue_js/components/app.rb +46 -0
  11. data/lib/matestack/ui/vue_js/components/async.js +104 -0
  12. data/lib/matestack/ui/vue_js/components/async.rb +84 -0
  13. data/lib/matestack/ui/vue_js/components/cable.js +96 -0
  14. data/lib/matestack/ui/vue_js/components/cable.rb +69 -0
  15. data/lib/matestack/ui/vue_js/components/collection/content.js +96 -0
  16. data/lib/matestack/ui/vue_js/components/collection/content.rb +32 -0
  17. data/lib/matestack/ui/vue_js/components/collection/filter.js +45 -0
  18. data/lib/matestack/ui/vue_js/components/collection/filter.rb +29 -0
  19. data/lib/matestack/ui/vue_js/components/collection/filter_reset.rb +19 -0
  20. data/lib/matestack/ui/vue_js/components/collection/helper.rb +128 -0
  21. data/lib/matestack/ui/vue_js/components/collection/next.rb +19 -0
  22. data/lib/matestack/ui/vue_js/components/collection/order.js +45 -0
  23. data/lib/matestack/ui/vue_js/components/collection/order.rb +28 -0
  24. data/lib/matestack/ui/vue_js/components/collection/order_toggle.rb +21 -0
  25. data/lib/matestack/ui/vue_js/components/collection/order_toggle_indicator.rb +30 -0
  26. data/lib/matestack/ui/vue_js/components/collection/page.rb +21 -0
  27. data/lib/matestack/ui/vue_js/components/collection/previous.rb +19 -0
  28. data/lib/matestack/ui/vue_js/components/form/base.rb +179 -0
  29. data/lib/matestack/ui/vue_js/components/form/checkbox.js +13 -0
  30. data/lib/matestack/ui/vue_js/components/form/checkbox.rb +109 -0
  31. data/lib/matestack/ui/vue_js/components/form/checkbox_mixin.js +90 -0
  32. data/lib/matestack/ui/vue_js/components/form/context.rb +15 -0
  33. data/lib/matestack/ui/vue_js/components/form/fields_for_add_item.js +50 -0
  34. data/lib/matestack/ui/vue_js/components/form/fields_for_add_item.rb +35 -0
  35. data/lib/matestack/ui/vue_js/components/form/fields_for_remove_item.rb +19 -0
  36. data/lib/matestack/ui/vue_js/components/form/form.js +276 -0
  37. data/lib/matestack/ui/vue_js/components/form/form.rb +77 -0
  38. data/lib/matestack/ui/vue_js/components/form/input.js +13 -0
  39. data/lib/matestack/ui/vue_js/components/form/input.rb +54 -0
  40. data/lib/matestack/ui/vue_js/components/form/input_mixin.js +79 -0
  41. data/lib/matestack/ui/vue_js/components/form/nested_form.js +153 -0
  42. data/lib/matestack/ui/vue_js/components/form/nested_form.rb +57 -0
  43. data/lib/matestack/ui/vue_js/components/form/radio.js +13 -0
  44. data/lib/matestack/ui/vue_js/components/form/radio.rb +85 -0
  45. data/lib/matestack/ui/vue_js/components/form/radio_mixin.js +75 -0
  46. data/lib/matestack/ui/vue_js/components/form/select.js +13 -0
  47. data/lib/matestack/ui/vue_js/components/form/select.rb +96 -0
  48. data/lib/matestack/ui/vue_js/components/form/select_mixin.js +76 -0
  49. data/lib/matestack/ui/vue_js/components/form/textarea.js +13 -0
  50. data/lib/matestack/ui/vue_js/components/form/textarea.rb +37 -0
  51. data/lib/matestack/ui/vue_js/components/form/textarea_mixin.js +54 -0
  52. data/lib/matestack/ui/vue_js/components/helpers.js +5 -0
  53. data/lib/matestack/ui/vue_js/components/isolated.js +105 -0
  54. data/lib/matestack/ui/vue_js/components/isolated.rb +86 -0
  55. data/lib/matestack/ui/vue_js/components/mixin.js +66 -0
  56. data/lib/matestack/ui/vue_js/components/onclick.js +18 -0
  57. data/lib/matestack/ui/vue_js/components/onclick.rb +37 -0
  58. data/lib/matestack/ui/vue_js/components/page_switch.js +24 -0
  59. data/lib/matestack/ui/vue_js/components/page_switch.rb +35 -0
  60. data/lib/matestack/ui/vue_js/components/runtime_render.js +17 -0
  61. data/lib/matestack/ui/vue_js/components/toggle.js +70 -0
  62. data/lib/matestack/ui/vue_js/components/toggle.rb +38 -0
  63. data/lib/matestack/ui/vue_js/components/transition.js +44 -0
  64. data/lib/matestack/ui/vue_js/components/transition.rb +40 -0
  65. data/lib/matestack/ui/vue_js/components/transition_handling_mixin.js +100 -0
  66. data/lib/matestack/ui/vue_js/components.rb +118 -0
  67. data/lib/matestack/ui/vue_js/event_hub.js +12 -0
  68. data/lib/matestack/ui/vue_js/helpers/query_params_helper.js +56 -0
  69. data/lib/matestack/ui/vue_js/index.js +94 -0
  70. data/lib/matestack/ui/vue_js/initialize.rb +10 -0
  71. data/lib/matestack/ui/vue_js/utils.rb +67 -0
  72. data/lib/matestack/ui/vue_js/version.rb +7 -0
  73. data/lib/matestack/ui/vue_js/vue.rb +75 -0
  74. data/lib/matestack/ui/vue_js/vue_attributes.rb +13 -0
  75. data/lib/matestack/ui/vue_js.rb +52 -0
  76. data/lib/matestack/ui/vue_js_component.rb +1 -0
  77. metadata +150 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c794def649692d36847b14964ae62336f5caef8b6176c54dca0527933f699ef1
4
+ data.tar.gz: 6e588a4b84523a77133927ea8dd139e21cd8cb4f32fdff7a426613d50cd4d5ef
5
+ SHA512:
6
+ metadata.gz: fb1e2b903e3a37fe6d99608496d44bf946716ea6562bea64a9a61fd6867b8fe2b380e5732c44a37675d51004bb6f01f4e071a1ea4e410a6750f003b825683d20
7
+ data.tar.gz: 3a0a48ed03ffbb7241acda5908be725f827d859fa0ff83fc886df7841b9cddb35df4aa4521a6d49ef72bec080b415ba27e3f520b2096fb27ca6fab17c84a18b8
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) MateLab GmbH
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,492 @@
1
+ [![Specs](https://github.com/matestack/matestack-ui-vuejs/workflows/specs/badge.svg)](https://github.com/matestack/matestack-ui-vuejs/actions)
2
+ [![Discord](https://img.shields.io/discord/771413294136426496.svg)](https://discord.com/invite/c6tQxFG)
3
+ [![Gem Version](https://badge.fury.io/rb/matestack-ui-vuejs.svg)](https://badge.fury.io/rb/matestack-ui-vuejs)
4
+ [![Docs](https://img.shields.io/badge/docs-matestack-blue.svg)](https://docs.matestack.io)
5
+ [![Twitter Follow](https://img.shields.io/twitter/follow/matestack.svg?style=social)](https://twitter.com/matestack)
6
+
7
+ ![matestack logo](./logo.png)
8
+
9
+ # matestack-ui-vuejs | Vue.js 3 based reactivity system for Rails
10
+
11
+ Boost your productivity & easily create reactive web UIs in pure Ruby. Easily extend with pure JavaScript if required. No Opal involved.
12
+
13
+ ## About
14
+
15
+ `matestack-ui-vuejs` ships all you need to build **reactive** UIs in **pure Ruby** orchestrating prebuilt Vue.js components with a simple Ruby DSL.
16
+
17
+ The prebuilt reactive components built **on top of Vue.js** are covering typical features of a reactive web UI, such as async form submission, dynamic page transitions or async partial UI updates. **No Opal involved**
18
+
19
+ If required, it can be easily extended with pure JavaScript.
20
+
21
+ ### Why matestack-ui-vuejs?
22
+
23
+ `matestack-ui-vuejs` was created because modern web app development became more and more complex due to the rise of JavaScript frontend frameworks and the SPA frontend/REST API/JSON backend architecture. This sophisticated approach might be suitable for big teams and applications but is way to complex for most of small to medium sized teams and application scopes.
24
+
25
+ In contrast, `matestack-ui-vuejs` helps Rails developers creating modern, reactive web apps while focusing on **simplicity**, **developer happiness** and **productivity**:
26
+
27
+ * [x] Use Ruby’s amazing language features while creating your UI
28
+ * [x] Skip using templating engine syntax and write pure Ruby instead
29
+ * [x] Reduce the amount of required JavaScript in order to build reactive web UIs
30
+ * [x] Create a single application, managing the full stack from database to a reactive UI in pure Ruby
31
+ * [x] **Drastically reduce the complexity of building reactive web applications**
32
+
33
+ ### What makes matestack-ui-vuejs different?
34
+
35
+ [Hotwire](https://hotwire.dev) and [Stimulus Reflex](https://docs.stimulusreflex.com) are awesome gems. They reduce the amount of required JavaScript when implementing reactive web UIs. They allow us to use more Rails and less JavaScript. **Great!**
36
+
37
+ Matestack, developed since 2018, goes even one step further: **Use more Ruby and less of everything else** (JavaScript, ERB/HAML/SLIM, CSS).
38
+
39
+ **Why?** Because Ruby is just beautiful! More Ruby = More developer happiness = Higher productivity
40
+
41
+ Additionally, most of `matestack-ui-vuejs` does not require Action Cable or Redis, but can optionally use the power of these tools.
42
+
43
+ ## Compatibility
44
+
45
+ `matestack-ui-vuejs` requires `matestack-ui-core`
46
+
47
+ `matestack-ui-vuejs` is tested against:
48
+
49
+ * Rails 7.0.1 + Ruby 3.0.0 + Vue.js 3.2.26
50
+ * Rails 6.1.1 + Ruby 3.0.0 + Vue.js 3.2.26
51
+ * Rails 6.1.1 + Ruby 2.7.2 + Vue.js 3.2.26
52
+ * Rails 6.0.3.4 + Ruby 2.6.6 + Vue.js 3.2.26
53
+ * Rails 5.2.4.4 + Ruby 2.6.6 + Vue.js 3.2.26
54
+
55
+ Rails versions below 5.2 are not officially supported.
56
+
57
+ Vue.js 2.x is supported when using the Compat build of Vue.js
58
+
59
+ ## Documentation/Installation
60
+
61
+ Documentation can be found [here](https://docs.matestack.io/matestack-ui-vuejs)
62
+
63
+ ## Getting started
64
+
65
+ A getting started guide can be found [here](https://docs.matestack.io/matestack-ui-vuejs/getting-started/hello-world)
66
+
67
+ ## Changelog
68
+
69
+ Changelog can be found [here](./CHANGELOG.md)
70
+
71
+ ## Community
72
+
73
+ As a low-barrier feedback channel for our early users, we have set up a Discord server that can be found [here](https://discord.com/invite/c6tQxFG). You are very welcome to ask questions and send us feedback there!
74
+
75
+ ## Contribution
76
+
77
+ We are happy to accept contributors of any kind! In order to make it as easy and fun as possible to contribute to `matestack-ui-vuejs`, we would like to onboard contributors personally! Best way to become a contributor: Ping us on Discord! We will schedule a video call with you and show you, how and what to work on :)
78
+
79
+ ## Feature walk-through
80
+
81
+ ### 1. Use reactive UI components in pure Ruby
82
+
83
+ Matestack's generic, reactive components can be placed on your UI with a simple Ruby DSL. While putting these generic components in your UI code, you inject some configuration in order to adjust the behaviour to your needs. This enables you to create reactive UIs without touching JavaScript!
84
+
85
+ *Behind the scenes:* When calling a reactive component with the Ruby DSL, Matestack will render a special component tag with a bunch of attributes to the resulting, server-side rendered HTML. Within the browser, Vue.js will pick up these component tags and mount the JavaScript driven components on it.
86
+
87
+ **Toggle parts of the UI based on events**
88
+
89
+ `matestack-ui-vuejs` offers an event hub. Reactive components can emit and receive events through this event hub. "onclick" and "toggle" calling two of these reactive core components. "onclick" emits an event which causes the body of the "toggle" component to be visible for 5 seconds in this example.
90
+
91
+ `app/matestack/components/some_component.rb`
92
+
93
+ ```ruby
94
+ class Components::SomeComponent < Matestack::Ui::Component
95
+
96
+ def response
97
+ onclick emit: "some_event" do
98
+ button "click me"
99
+ end
100
+ toggle show_on: "some_event", hide_after: 5000 do
101
+ plain "Oh yes! You clicked me!"
102
+ end
103
+ end
104
+
105
+ end
106
+ ```
107
+
108
+ **Call controller actions without JavaScript**
109
+
110
+ Core components offer basic dynamic behaviour and let you easily call controller actions and react to server responses on the client side without full page reload. The "action" component is configured to emit an event after successfully performed an HTTP request against a Rails controller action, which is received by the "toggle" component, displaying the success message.
111
+
112
+ `app/matestack/components/some_component.rb`
113
+
114
+ ```ruby
115
+ class Components::SomeComponent < Matestack::Ui::Component
116
+
117
+ def response
118
+ action my_action_config do
119
+ button "click me"
120
+ end
121
+ toggle show_on: "some_event", hide_after: 5000 do
122
+ plain "Success!"
123
+ end
124
+ end
125
+
126
+ def my_action_config
127
+ {
128
+ path: some_rails_route_path,
129
+ method: :post,
130
+ success: {
131
+ emit: "some_event"
132
+ }
133
+ }
134
+ end
135
+
136
+ end
137
+ ```
138
+
139
+ #### Dynamically handle form input without JavaScript
140
+
141
+ Create dynamic forms for ActiveRecord Models (or plain objects) and display server side responses, like validation errors or success messages, without relying on a full page reload. Events emitted by the "form" component can be used to toggle parts of the UI.
142
+
143
+ `app/matestack/components/some_component.rb`
144
+
145
+ ```ruby
146
+ class Components::SomeComponent < Matestack::Ui::Component
147
+
148
+ def response
149
+ matestack_form my_form_config do
150
+ form_input key: :some_model_attribute, type: :text
151
+ button "click me", type: :submit
152
+ end
153
+ toggle show_on: "submitted", hide_after: 5000 do
154
+ span class: "message success" do
155
+ plain "created successfully"
156
+ end
157
+ end
158
+ toggle show_on: "failed", hide_after: 5000 do
159
+ span class: "message failure" do
160
+ plain "data was not saved, please check form"
161
+ end
162
+ end
163
+ end
164
+
165
+ def my_form_config
166
+ {
167
+ for: MyActiveRecordModel.new,
168
+ path: some_rails_route_path,
169
+ method: :post,
170
+ success: {
171
+ emit: "submitted"
172
+ },
173
+ failure: {
174
+ emit: "failed"
175
+ }
176
+ }
177
+ end
178
+
179
+ end
180
+ ```
181
+
182
+ **Implement asynchronous, event-based UI rerendering in pure Ruby**
183
+
184
+ Using Matestack's built-in event system, you can rerender parts of the UI on client side events, such as form or action submissions. Even server side events pushed via ActionCable may be received! The "async" component requests a new version of its body at the server via an HTTP GET request after receiving the configured event. After successful server response, the DOM of the "async" component gets updated. Everything else stays untouched.
185
+
186
+ `app/matestack/components/some_component.rb`
187
+
188
+ ```ruby
189
+ class Components::SomeComponent < Matestack::Ui::Component
190
+
191
+ def response
192
+ matestack_form my_form_config do
193
+ #...
194
+ end
195
+ #...
196
+ async rerender_on: "submitted", id: "my-model-list" do
197
+ ul do
198
+ MyActiveRecordModel.last(5).each do |model|
199
+ li model.some_attribute
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ def my_form_config
206
+ {
207
+ #...
208
+ success: {
209
+ emit: "submitted"
210
+ },
211
+ failure: {
212
+ emit: "failed"
213
+ }
214
+ }
215
+ end
216
+
217
+ end
218
+ ```
219
+
220
+ **Manipulate parts of the UI via ActionCable**
221
+
222
+ "async" rerenders its whole body - but what about just appending the element to the list after successful form submission? The "cable" component can be configured to receive events and data pushed via ActionCable from the server side and just append/prepend new chunks of HTML (ideally rendered through a component) to the current "cable" component body. Updating and deleting is also supported!
223
+
224
+ `app/matestack/components/some_component.rb`
225
+
226
+ ```ruby
227
+ class Components::SomeComponent < Matestack::Ui::Component
228
+
229
+ def response
230
+ matestack_form my_form_config do
231
+ #...
232
+ end
233
+ #...
234
+ cable prepend_on: "new_element_created", id: "some-cable-driven-list" do
235
+ MyActiveRecordModel.last(5).each do |model|
236
+ Components::SomeListItemComponent.call(content: model.some_content)
237
+ end
238
+ end
239
+ end
240
+
241
+ end
242
+ ```
243
+
244
+ `app/controllers/some_controller.rb`
245
+
246
+ ```ruby
247
+ # within your controller action handling the form input
248
+ ActionCable.server.broadcast("matestack_ui_core", {
249
+ event: "new_element_created",
250
+ data: Components::SomeListItemComponent.call(content: model.some_content) # or plain HTML
251
+ })
252
+ ```
253
+
254
+ ### **2. Easily extend with Vue.js**
255
+
256
+ Matestack's dynamic parts are built on Vue.js. If you want to implement custom dynamic behaviour, you can simply create your own Vue components and use them along Matestack's components. It's even possible to interact with Matestack's components using the built-in event bus.
257
+
258
+ `app/matestack/components/some_component.rb`
259
+
260
+ ```ruby
261
+ class Components::SomeComponent < Matestack::Ui::Component
262
+
263
+ def response
264
+ Components::MyVueJsComponent.call()
265
+ toggle show_on: "some_event", hide_after: "3000" do
266
+ span class: "message success" do
267
+ plain "event triggered from custom vuejs component"
268
+ end
269
+ end
270
+ end
271
+
272
+ end
273
+ ```
274
+
275
+ `app/matestack/components/my_vue_js_component.rb`
276
+
277
+ ```ruby
278
+ class Components::MyVueJsComponent < Matestack::Ui::VueJsComponent
279
+
280
+ vue_name "my-vue-js-component"
281
+
282
+ def response
283
+ div class: "my-vue-js-component" do
284
+ button "@click": "vc.increaseValue"
285
+ br
286
+ plain "{{ vc.dynamicValue }}!"
287
+ end
288
+ end
289
+
290
+ end
291
+ ```
292
+
293
+ `app/matestack/components/my_vue_js_component.js`
294
+
295
+ ```javascript
296
+ import MatestackUiVueJs from 'matestack-ui-vuejs'
297
+
298
+ const myComponent = {
299
+ mixins: [MatestackUiVueJs.componentMixin],
300
+ template: MatestackUiVueJs.componentHelpers.inlineTemplate,
301
+ data: () => {
302
+ return {
303
+ dynamicValue: 0
304
+ };
305
+ },
306
+ methods: {
307
+ increaseValue(){
308
+ this.dynamicValue++
309
+ MatestackUiVueJs.eventHub.$emit("some_event")
310
+ }
311
+ }
312
+ }
313
+
314
+ export default myComponent
315
+
316
+ // and then in your application pack file you register the component like:
317
+
318
+ appInstance.component('my-vue-js-component', myComponent) /
319
+ ```
320
+
321
+ ### 3. Create whole SPA-like apps in pure Ruby
322
+
323
+ The last step in order to leverage the full Matestack power: Create a Matestack layout (\~Rails layout) and Matestack page (Rails \~view) classes (as seen on `matestack-ui-core`) and implement dynamic page transitions with components coming from `matestack-ui-vuejs` without any custom JavaScript implementation required.
324
+
325
+ **Create your layouts and views in pure Ruby**
326
+
327
+ The layout class is used to define a layout, usually containing some kind of header, footer and navigation. The page class is used to define a view. Following the same principles as seen on components, you can use components (core or your own) in order to create the UI. The `matestack_vue_js_app` `page_switch` and `transition` components enable dynamic page transition, replacing the yielded content with new serverside rendered content rendered by the requested page.
328
+
329
+ `app/matestack/some_app/some_layout.rb`
330
+
331
+ ```ruby
332
+ class SomeApp::SomeLayout < Matestack::Ui::Layout
333
+
334
+ def response
335
+ h1 "My App"
336
+ matestack_vue_js_app do
337
+ nav do
338
+ transition path: page1_path do
339
+ button "Page 1"
340
+ end
341
+ transition path: page2_path do
342
+ button "Page 2"
343
+ end
344
+ end
345
+ main do
346
+ div class: "container" do
347
+ page_switch do
348
+ yield
349
+ end
350
+ end
351
+ end
352
+ end
353
+ end
354
+
355
+ end
356
+ ```
357
+
358
+ `app/matestack/some_app/pages/page1.rb`
359
+
360
+ ```ruby
361
+ class SomeApp::Pages::Page1 < Matestack::Ui::Page
362
+
363
+ def response
364
+ div class: "row" do
365
+ div class: "col" do
366
+ plain "Page 1"
367
+ end
368
+ end
369
+ end
370
+
371
+ end
372
+ ```
373
+
374
+ `app/matestack/some_app/pages/page2.rb`
375
+
376
+ ```ruby
377
+ class SomeApp::Pages::Page2 < Matestack::Ui::Page
378
+
379
+ def response
380
+ div class: "row" do
381
+ div class: "col" do
382
+ plain "Page 2"
383
+ end
384
+ end
385
+ end
386
+
387
+ end
388
+ ```
389
+
390
+ **Layouts and pages are referenced in your Rails controllers and actions**
391
+
392
+ Instead of referencing Rails layouts and views on your controllers, you just use apps and pages as substitutes. Work with controllers, actions and routing as you're used to! Controller hooks (e.g. devise's authenticate\_user) would still work!
393
+
394
+ `app/controllers/some_controller.rb`
395
+
396
+ ```ruby
397
+ class SomeController < ApplicationController
398
+
399
+ include Matestack::Ui::Core::Helper
400
+
401
+ matestack_layout SomeApp::SomeLayout
402
+
403
+ def page1
404
+ render SomeApp::Page1
405
+ end
406
+
407
+ def page2
408
+ render SomeApp::Page2
409
+ end
410
+
411
+ end
412
+ ```
413
+
414
+ `app/config/routes.rb`
415
+
416
+ ```ruby
417
+ Rails.application.routes.draw do
418
+
419
+ root to: 'some#page1'
420
+
421
+ get :page1, to: 'some#page1'
422
+ get :page2, to: 'some#page2'
423
+
424
+ end
425
+ ```
426
+
427
+ **Use CSS animations for fancy page transition animations**
428
+
429
+ Use Matestack's css classes applied to the wrapping DOM structure of a page in order to add CSS animiations, whenever a page transition is performed. You can even inject a loading state element, enriching your page transition effect.
430
+
431
+ `app/matestack/some_app/some_layout.rb`
432
+
433
+ ```ruby
434
+ class SomeApp::SomeLayout < Matestack::Ui::Layout
435
+
436
+ def response
437
+ h1 "My App"
438
+ matestack_vue_js_app do
439
+ nav do
440
+ transition path: page1_path do
441
+ button "Page 1"
442
+ end
443
+ transition path: page2_path do
444
+ button "Page 2"
445
+ end
446
+ end
447
+ main do
448
+ div class: "container" do
449
+ page_switch do
450
+ yield
451
+ end
452
+ end
453
+ end
454
+ end
455
+ end
456
+
457
+ def loading_state_element
458
+ div class: 'some-loading-element-styles'
459
+ end
460
+
461
+ end
462
+ ```
463
+
464
+ `app/assets/stylesheets/application.scss`
465
+
466
+ ```scss
467
+ .matestack-page-container{
468
+
469
+ .matestack-page-wrapper {
470
+ opacity: 1;
471
+ transition: opacity 0.2s ease-in-out;
472
+
473
+ &.loading {
474
+ opacity: 0;
475
+ }
476
+ }
477
+
478
+ .loading-state-element-wrapper{
479
+ opacity: 0;
480
+ transition: opacity 0.3s ease-in-out;
481
+
482
+ &.loading {
483
+ opacity: 1;
484
+ }
485
+ }
486
+
487
+ }
488
+ ```
489
+
490
+ ## License
491
+
492
+ `matestack-ui-vuejs` is an Open Source project licensed under the terms of the [MIT license](./LICENSE)
data/Rakefile ADDED
@@ -0,0 +1,64 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Matestack::Ui::Core'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ # Rake::TestTask.new(:test) do |t|
27
+ # t.libs << 'test'
28
+ # t.pattern = 'test/**/*_test.rb'
29
+ # t.verbose = false
30
+ # end
31
+ #
32
+ # task default: :test
33
+
34
+ task :webpack => 'webpack:build'
35
+
36
+ namespace :webpack do
37
+ task :build => ['build:development', 'build:production']
38
+
39
+ namespace :build do
40
+ task :development => 'yarn:install' do
41
+ Bundler.with_unbundled_env do
42
+ sh "cd builder && bin/webpack"
43
+ end
44
+ end
45
+ task :production => 'yarn:install' do
46
+ Bundler.with_unbundled_env do
47
+ sh "cd builder && bin/rake webpacker:compile"
48
+ end
49
+ end
50
+ end
51
+
52
+ task :watch => 'yarn:install' do
53
+ Bundler.with_unbundled_env do
54
+ sh "cd builder && bin/webpack --watch"
55
+ end
56
+ end
57
+
58
+ namespace :yarn do
59
+ task :install do
60
+ sh "yarn install && cd builder && yarn install"
61
+ end
62
+ end
63
+ end
64
+
@@ -0,0 +1 @@
1
+ Matestack::Ui::Component = Matestack::Ui::Core::Component
@@ -0,0 +1 @@
1
+ Matestack::Ui::IsolatedComponent = Matestack::Ui::VueJs::Components::Isolated
@@ -0,0 +1,70 @@
1
+ import { inject } from 'vue'
2
+
3
+ import axios from 'axios'
4
+ import matestackEventHub from '../event_hub'
5
+ import componentMixin from './mixin'
6
+ import componentHelpers from './helpers'
7
+
8
+ import transitionHandlingMixin from './transition_handling_mixin'
9
+
10
+ const componentDef = {
11
+ mixins: [componentMixin, transitionHandlingMixin],
12
+ template: componentHelpers.inlineTemplate,
13
+ data: function(){
14
+ return {}
15
+ },
16
+ setup() {
17
+ // conditionally inject appNavigateTo
18
+ // action component has to work in context without wrapping app as well!
19
+ const appNavigateTo = inject('appNavigateTo', undefined)
20
+ return {
21
+ appNavigateTo
22
+ }
23
+ },
24
+ methods: {
25
+ perform: function(){
26
+ const self = this
27
+ if (
28
+ (self.props["confirm"] == undefined) || confirm(self.props["confirm_text"])
29
+ )
30
+ {
31
+ if (self.props["emit"] != undefined) {
32
+ matestackEventHub.$emit(self.props["emit"]);
33
+ }
34
+ if (self.props["delay"] != undefined) {
35
+ setTimeout(function () {
36
+ self.sendRequest()
37
+ }, parseInt(self.props["delay"]));
38
+ } else {
39
+ this.sendRequest()
40
+ }
41
+ }
42
+ },
43
+ sendRequest: function(){
44
+ const self = this
45
+ axios({
46
+ method: self.props["method"],
47
+ url: self.props["action_path"],
48
+ data: self.props["data"],
49
+ headers: {
50
+ 'X-CSRF-Token': self.getXcsrfToken()
51
+ }
52
+ }
53
+ )
54
+ .then(function(response){
55
+ if (self.props["success"] != undefined && self.props["success"]["emit"] != undefined) {
56
+ matestackEventHub.$emit(self.props["success"]["emit"], response.data);
57
+ }
58
+ self.successTransitionHandling(response)
59
+ })
60
+ .catch(function(error){
61
+ if (self.props["failure"] != undefined && self.props["failure"]["emit"] != undefined) {
62
+ matestackEventHub.$emit(self.props["failure"]["emit"], error.response.data);
63
+ }
64
+ self.failureTransitionHandling(error)
65
+ })
66
+ }
67
+ }
68
+ }
69
+
70
+ export default componentDef