inertia_rails 3.13.0 → 3.14.0

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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/lib/generators/inertia/install/frameworks.yml +3 -18
  4. data/lib/generators/inertia/install/install_generator.rb +51 -6
  5. data/lib/generators/inertia/install/templates/assets/rails.svg +9 -0
  6. data/lib/generators/inertia/install/templates/controller.rb +6 -1
  7. data/lib/generators/inertia/install/templates/react/InertiaExample.jsx +42 -46
  8. data/lib/generators/inertia/install/templates/react/InertiaExample.module.css +63 -41
  9. data/lib/generators/inertia/install/templates/react/InertiaExample.tsx +45 -46
  10. data/lib/generators/inertia/install/templates/react/inertia.jsx +1 -1
  11. data/lib/generators/inertia/install/templates/react/inertia.tsx +3 -3
  12. data/lib/generators/inertia/install/templates/svelte/InertiaExample.svelte +103 -69
  13. data/lib/generators/inertia/install/templates/svelte/InertiaExample.ts.svelte +104 -69
  14. data/lib/generators/inertia/install/templates/svelte/inertia.js +1 -1
  15. data/lib/generators/inertia/install/templates/svelte/inertia.ts +1 -1
  16. data/lib/generators/inertia/install/templates/vue/InertiaExample.ts.vue +107 -70
  17. data/lib/generators/inertia/install/templates/vue/InertiaExample.vue +129 -92
  18. data/lib/generators/inertia/install/templates/vue/inertia.js +3 -3
  19. data/lib/generators/inertia/install/templates/vue/inertia.ts +3 -3
  20. data/lib/generators/inertia_templates/scaffold/templates/react/form.tsx.tt +3 -3
  21. data/lib/generators/inertia_templates/scaffold/templates/svelte/form.ts.svelte.tt +3 -3
  22. data/lib/generators/inertia_templates/scaffold/templates/svelte/new.svelte.tt +1 -1
  23. data/lib/generators/inertia_templates/scaffold/templates/svelte/new.ts.svelte.tt +1 -1
  24. data/lib/generators/inertia_templates/scaffold/templates/vue/form.ts.vue.tt +3 -3
  25. data/lib/generators/inertia_tw_templates/scaffold/templates/react/form.tsx.tt +3 -3
  26. data/lib/generators/inertia_tw_templates/scaffold/templates/svelte/form.ts.svelte.tt +3 -3
  27. data/lib/generators/inertia_tw_templates/scaffold/templates/svelte/new.svelte.tt +1 -2
  28. data/lib/generators/inertia_tw_templates/scaffold/templates/svelte/new.ts.svelte.tt +1 -1
  29. data/lib/generators/inertia_tw_templates/scaffold/templates/vue/form.ts.vue.tt +3 -3
  30. data/lib/inertia_rails/version.rb +1 -1
  31. data/lib/inertia_rails.rb +1 -0
  32. metadata +3 -2
@@ -1,117 +1,154 @@
1
1
  <template>
2
- <Head title="Inertia + Vite Ruby + Vue Example" />
2
+ <Head title="Ruby on Rails + Inertia + Vue" />
3
3
 
4
4
  <div class="root">
5
- <h1 class="h1">Hello {{ name }}!</h1>
6
-
7
- <div>
8
- <a href="https://inertia-rails.dev" target="_blank">
9
- <img class="logo" :src="inertiaSvg" alt="Inertia logo" />
5
+ <nav class="subNav">
6
+ <a href="https://rubyonrails.org" target="_blank">
7
+ <img class="logo rails" :src="railsSvg" alt="Ruby on Rails Logo" />
10
8
  </a>
11
- <a href="https://vite-ruby.netlify.app" target="_blank">
12
- <img class="logo vite" :src="viteRubySvg" alt="Vite Ruby logo" />
9
+ <a href="https://inertia-rails.dev" target="_blank">
10
+ <img class="logo inertia" :src="inertiaSvg" alt="Inertia logo" />
13
11
  </a>
14
12
  <a href="https://vuejs.org" target="_blank">
15
- <img class="logo vue" :src="vueSvg" alt="Vue logo" />
13
+ <img class="logo vue" :src="vueSvg" alt="Vue logo"/>
16
14
  </a>
17
- </div>
15
+ </nav>
18
16
 
19
- <h2 class="h2">Inertia + Vite Ruby + Vue</h2>
17
+ <div class="footer">
18
+ <div class="card">
19
+ <p>
20
+ Edit <code><%= js_destination_path %>/pages/inertia_example/index.vue</code> and save to test <abbr title="Hot Module Replacement">HMR</abbr>.
21
+ </p>
22
+ </div>
20
23
 
21
- <div class="card">
22
- <button class="button" type="button" @click="count++">
23
- count is {{ count }}
24
- </button>
25
- <p>
26
- Edit <code>app/frontend/pages/inertia_example/index.vue</code> and save to test
27
- HMR
28
- </p>
24
+ <ul>
25
+ <li>
26
+ <ul>
27
+ <li><strong>Rails version:</strong> {{ rails_version }}</li>
28
+ <li><strong>Rack version:</strong> {{ rack_version }}</li>
29
+ </ul>
30
+ </li>
31
+ <li><strong>Ruby version:</strong> {{ ruby_version }}</li>
32
+ <li>
33
+ <ul>
34
+ <li><strong>Inertia Rails version:</strong> {{ inertia_rails_version }}</li>
35
+ <li><strong>Vue version:</strong> {{ vue_version }}</li>
36
+ </ul>
37
+ </li>
38
+ </ul>
29
39
  </div>
30
- <p class="readTheDocs">
31
- Click on the Inertia, Vite Ruby, and Vue logos to learn more
32
- </p>
33
40
  </div>
34
41
  </template>
35
42
 
36
43
  <script setup>
37
44
  import { Head } from '@inertiajs/vue3'
38
- import { ref } from 'vue'
45
+ import { version as vue_version } from 'vue';
39
46
 
47
+ import railsSvg from '/assets/rails.svg'
40
48
  import inertiaSvg from '/assets/inertia.svg'
41
- import viteRubySvg from '/assets/vite_ruby.svg'
42
49
  import vueSvg from '/assets/vue.svg'
43
50
 
44
51
  defineProps({
45
- name: String,
52
+ rails_version: String,
53
+ rack_version: String,
54
+ ruby_version: String,
55
+ inertia_rails_version: String,
46
56
  })
47
-
48
- const count = ref(0)
49
57
  </script>
50
58
 
59
+ <style global>
60
+ body {
61
+ margin: 0;
62
+ padding: 0;
63
+ }
64
+ </style>
65
+
51
66
  <style scoped>
52
- .root {
53
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
54
- line-height: 1.5;
55
- font-weight: 400;
56
- color: #213547;
57
- background-color: #ffffff;
58
- max-width: 1280px;
59
- margin: 0 auto;
60
- padding: 2rem;
61
- text-align: center;
62
- }
63
-
64
- .h1 {
65
- font-size: 3.2em;
66
- line-height: 1.1;
67
- }
68
-
69
- .h2 {
70
- font-size: 2.6em;
71
- line-height: 1.1;
72
- }
73
-
74
- .button {
75
- border-radius: 8px;
76
- border: 1px solid transparent;
77
- padding: 0.6em 1.2em;
78
- font-size: 1em;
79
- font-weight: 500;
80
- font-family: inherit;
81
- background-color: #f9f9f9;
82
- cursor: pointer;
83
- transition: border-color 0.25s;
84
- }
85
- .button:hover {
86
- border-color: #646cff;
87
- }
88
- .button:focus,
89
- .button:focus-visible {
90
- outline: 4px auto -webkit-focus-ring-color;
91
- }
92
-
93
- .logo {
94
- display: inline-block;
95
- height: 6em;
96
- padding: 1.5em;
97
- will-change: filter;
98
- transition: filter 300ms;
99
- }
100
- .logo:hover {
101
- filter: drop-shadow(0 0 2em #646cffaa);
102
- }
103
- .logo.vite:hover {
104
- filter: drop-shadow(0 0 2em #e4023baa);
105
- }
106
- .logo.vue:hover {
107
- filter: drop-shadow(0 0 2em #41b883aa);
108
- }
109
-
110
- .card {
111
- padding: 2em;
112
- }
113
-
114
- .readTheDocs {
115
- color: #888;
116
- }
67
+ .root {
68
+ box-sizing: border-box;
69
+ margin: 0;
70
+ padding: 0;
71
+ align-items: center;
72
+ background-color: #F0E7E9;
73
+ background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEwMjQiIHZpZXdCb3g9IjAgMCAxNDQwIDEwMjQiIHdpZHRoPSIxNDQwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xNDQwIDUxMC4wMDA2NDh2LTUxMC4wMDA2NDhoLTE0NDB2Mzg0LjAwMDY0OGM0MTcuMzExOTM5IDEzMS4xNDIxNzkgODkxIDE3MS41MTMgMTQ0MCAxMjZ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+);
74
+ background-position: center center;
75
+ background-repeat: no-repeat;
76
+ background-size: cover;
77
+ color: #261B23;
78
+ display: flex;
79
+ flex-direction: column;
80
+ font-family: Sans-Serif;
81
+ font-size: calc(0.9em + 0.5vw);
82
+ font-style: normal;
83
+ font-weight: 400;
84
+ justify-content: center;
85
+ line-height: 1.25;
86
+ min-height: 100vh;
87
+ text-align: center;
88
+ }
89
+
90
+ @media (prefers-color-scheme: dark) {
91
+ .root {
92
+ background-color: #1a1a1a;
93
+ background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEwMjQiIHZpZXdCb3g9IjAgMCAxNDQwIDEwMjQiIHdpZHRoPSIxNDQwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xNDQwIDUxMC4wMDA2NDh2LTUxMC4wMDA2NDhoLTE0NDB2Mzg0LjAwMDY0OGM0MTcuMzExOTM5IDEzMS4xNDIxNzkgODkxIDE3MS41MTMgMTQ0MCAxMjZ6IiBmaWxsPSIjMzMzIi8+PC9zdmc+);
94
+ color: #e0e0e0;
95
+ }
96
+ }
97
+
98
+ .logo {
99
+ display: inline-block;
100
+ height: 9.8vw;
101
+ min-height: 130px;
102
+ padding: 1.5em;
103
+ will-change: filter;
104
+ transition: filter 300ms;
105
+ filter: drop-shadow(0 20px 13px rgb(0 0 0 / 0.03)) drop-shadow(0 8px 5px rgb(0 0 0 / 0.08));
106
+ }
107
+ .logo.inertia:hover {
108
+ filter: drop-shadow(0 0 2em #646cffaa);
109
+ }
110
+ .logo.vue:hover {
111
+ filter: drop-shadow(0 0 2em #61dafbaa);
112
+ }
113
+ .logo.rails:hover {
114
+ filter: drop-shadow(0 0 2em rgb(211 0 1 / 0.6));
115
+ }
116
+
117
+ @media (prefers-color-scheme: dark) {
118
+ .logo {
119
+ filter: drop-shadow(0 20px 13px rgb(255 255 255 / 0.03)) drop-shadow(0 8px 5px rgb(255 255 255 / 0.08));
120
+ }
121
+ }
122
+
123
+ .card {
124
+ padding: 2em;
125
+ font-size: 0.7em;
126
+ color: #948e90;
127
+ }
128
+
129
+ .footer {
130
+ bottom: 0;
131
+ left: 0;
132
+ margin: 0 2rem 2rem 2rem;
133
+ position: absolute;
134
+ right: 0;
135
+ }
136
+
137
+ .footer ul {
138
+ list-style: none;
139
+ }
140
+
141
+ .footer ul li {
142
+ display: inline;
143
+ }
144
+
145
+ .footer ul ul li:after {
146
+ content: " | ";
147
+ font-weight: 300;
148
+ color: #948e90;
149
+ }
150
+
151
+ .footer ul ul li:last-child:after {
152
+ content: "";
153
+ }
117
154
  </style>
@@ -37,14 +37,14 @@ createInertiaApp({
37
37
  },
38
38
 
39
39
  defaults: {
40
+ form: {
41
+ forceIndicesArrayFormatInFormData: false,
42
+ },
40
43
  future: {
41
44
  useDataInertiaHeadAttribute: true,
42
45
  useDialogForErrorModal: true,
43
46
  preserveEqualProps: true,
44
47
  },
45
- visitOptions: () => {
46
- return { queryStringArrayFormat: "brackets" }
47
- },
48
48
  },
49
49
  }).catch((error) => {
50
50
  // This ensures this entrypoint is only loaded on Inertia pages
@@ -37,14 +37,14 @@ createInertiaApp({
37
37
  },
38
38
 
39
39
  defaults: {
40
+ form: {
41
+ forceIndicesArrayFormatInFormData: false,
42
+ },
40
43
  future: {
41
44
  useDataInertiaHeadAttribute: true,
42
45
  useDialogForErrorModal: true,
43
46
  preserveEqualProps: true,
44
47
  },
45
- visitOptions: () => {
46
- return { queryStringArrayFormat: "brackets" }
47
- },
48
48
  },
49
49
  }).catch((error) => {
50
50
  // This ensures this entrypoint is only loaded on Inertia pages
@@ -28,7 +28,7 @@ export default function Form({ <%= singular_table_name %>, submitText, ...formPr
28
28
  id="password"
29
29
  />
30
30
  {errors.password && (
31
- <div style={{ color: 'red' }}>{errors.password}</div>
31
+ <div style={{ color: 'red' }}>{errors.password.join(', ')}</div>
32
32
  )}
33
33
  </div>
34
34
 
@@ -42,7 +42,7 @@ export default function Form({ <%= singular_table_name %>, submitText, ...formPr
42
42
  id="password_confirmation"
43
43
  />
44
44
  {errors.password_confirmation && (
45
- <div style={{ color: 'red' }}>{errors.password_confirmation}</div>
45
+ <div style={{ color: 'red' }}>{errors.password_confirmation.join(', ')}</div>
46
46
  )}
47
47
  </div>
48
48
  <% else -%>
@@ -92,7 +92,7 @@ export default function Form({ <%= singular_table_name %>, submitText, ...formPr
92
92
  />
93
93
  <% end -%>
94
94
  {errors.<%= attribute.column_name %> && (
95
- <div style={{ color: 'red' }}>{errors.<%= attribute.column_name %>}</div>
95
+ <div style={{ color: 'red' }}>{errors.<%= attribute.column_name %>.join(', ')}</div>
96
96
  )}
97
97
  </div>
98
98
  <% end -%>
@@ -29,7 +29,7 @@
29
29
  id="password"
30
30
  />
31
31
  {#if errors.password}
32
- <div class="error">{errors.password}</div>
32
+ <div class="error">{errors.password.join(', ')}</div>
33
33
  {/if}
34
34
  </div>
35
35
 
@@ -41,7 +41,7 @@
41
41
  id="password_confirmation"
42
42
  />
43
43
  {#if errors.password_confirmation}
44
- <div class="error">{errors.password_confirmation}</div>
44
+ <div class="error">{errors.password_confirmation.join(', ')}</div>
45
45
  {/if}
46
46
  </div>
47
47
  <% else -%>
@@ -82,7 +82,7 @@
82
82
  />
83
83
  <% end -%>
84
84
  {#if errors.<%= attribute.column_name %>}
85
- <div class="error">{errors.<%= attribute.column_name %>}</div>
85
+ <div class="error">{errors.<%= attribute.column_name %>.join(', ')}</div>
86
86
  {/if}
87
87
  </div>
88
88
  <% end -%>
@@ -15,7 +15,7 @@
15
15
  <Form
16
16
  {<%= singular_table_name %>}
17
17
  submitText="Create <%= human_name %>"
18
- action="<%= js_resource_path %>"
18
+ action="<%= js_resources_path %>"
19
19
  method="post"
20
20
  />
21
21
 
@@ -16,7 +16,7 @@
16
16
  <Form
17
17
  {<%= singular_table_name %>}
18
18
  submitText="Create <%= human_name %>"
19
- action="<%= js_resource_path %>"
19
+ action="<%= js_resources_path %>"
20
20
  method="post"
21
21
  />
22
22
 
@@ -14,7 +14,7 @@
14
14
  id="password"
15
15
  />
16
16
  <div v-if="errors.password" class="error">
17
- {{ errors.password }}
17
+ {{ errors.password.join(', ') }}
18
18
  </div>
19
19
  </div>
20
20
 
@@ -28,7 +28,7 @@
28
28
  id="password_confirmation"
29
29
  />
30
30
  <div v-if="errors.password_confirmation" class="error">
31
- {{ errors.password_confirmation }}
31
+ {{ errors.password_confirmation.join(', ') }}
32
32
  </div>
33
33
  </div>
34
34
  <% else -%>
@@ -69,7 +69,7 @@
69
69
  />
70
70
  <% end -%>
71
71
  <div v-if="errors.<%= attribute.column_name %>" class="error">
72
- {{ errors.<%= attribute.column_name %> }}
72
+ {{ errors.<%= attribute.column_name %>.join(', ') }}
73
73
  </div>
74
74
  </div>
75
75
  <% end -%>
@@ -29,7 +29,7 @@ export default function Form({ <%= singular_table_name %>, submitText, ...formPr
29
29
  />
30
30
  {errors.password && (
31
31
  <div className="text-red-500 px-3 py-2 font-medium">
32
- {errors.password}
32
+ {errors.password.join(', ')}
33
33
  </div>
34
34
  )}
35
35
  </div>
@@ -44,7 +44,7 @@ export default function Form({ <%= singular_table_name %>, submitText, ...formPr
44
44
  />
45
45
  {errors.password_confirmation && (
46
46
  <div className="text-red-500 px-3 py-2 font-medium">
47
- {errors.password_confirmation}
47
+ {errors.password_confirmation.join(', ')}
48
48
  </div>
49
49
  )}
50
50
  <% else -%>
@@ -99,7 +99,7 @@ export default function Form({ <%= singular_table_name %>, submitText, ...formPr
99
99
  <% end -%>
100
100
  {errors.<%= attribute.column_name %> && (
101
101
  <div className="text-red-500 px-3 py-2 font-medium">
102
- {errors.<%= attribute.column_name %>}
102
+ {errors.<%= attribute.column_name %>.join(', ')}
103
103
  </div>
104
104
  )}
105
105
  <% end -%>
@@ -31,7 +31,7 @@
31
31
  />
32
32
  {#if errors.password}
33
33
  <div class="text-red-500 px-3 py-2 font-medium">
34
- {errors.password}
34
+ {errors.password.join(', ')}
35
35
  </div>
36
36
  {/if}
37
37
  </div>
@@ -46,7 +46,7 @@
46
46
  />
47
47
  {#if errors.password_confirmation}
48
48
  <div class="text-red-500 px-3 py-2 font-medium">
49
- {errors.password_confirmation}
49
+ {errors.password_confirmation.join(', ')}
50
50
  </div>
51
51
  {/if}
52
52
  </div>
@@ -95,7 +95,7 @@
95
95
  <% end -%>
96
96
  {#if errors.<%= attribute.column_name %>}
97
97
  <div class="text-red-500 px-3 py-2 font-medium">
98
- {errors.<%= attribute.column_name %>}
98
+ {errors.<%= attribute.column_name %>.join(', ')}
99
99
  </div>
100
100
  {/if}
101
101
  </div>
@@ -16,8 +16,7 @@
16
16
  <Form
17
17
  {<%= singular_table_name %>}
18
18
  submitText="Create <%= human_name %>"
19
- onSubmit={handleSubmit}
20
- action="<%= js_resource_path %>"
19
+ action="<%= js_resources_path %>"
21
20
  method="post"
22
21
  />
23
22
 
@@ -17,7 +17,7 @@
17
17
  <Form
18
18
  {<%= singular_table_name %>}
19
19
  submitText="Create <%= human_name %>"
20
- action="<%= js_resource_path %>"
20
+ action="<%= js_resources_path %>"
21
21
  method="post"
22
22
  />
23
23
 
@@ -19,7 +19,7 @@
19
19
  v-if="errors.password"
20
20
  class="text-red-500 px-3 py-2 font-medium"
21
21
  >
22
- {{ errors.password }}
22
+ {{ errors.password.join(', ') }}
23
23
  </div>
24
24
  </div>
25
25
 
@@ -35,7 +35,7 @@
35
35
  v-if="errors.password_confirmation"
36
36
  class="text-red-500 px-3 py-2 font-medium"
37
37
  >
38
- {{ errors.password_confirmation }}
38
+ {{ errors.password_confirmation.join(', ') }}
39
39
  </div>
40
40
  </div>
41
41
  <% else -%>
@@ -82,7 +82,7 @@
82
82
  />
83
83
  <% end -%>
84
84
  <div v-if="errors.<%= attribute.column_name %>" class="text-red-500 px-3 py-2 font-medium">
85
- {{ errors.<%= attribute.column_name %> }}
85
+ {{ errors.<%= attribute.column_name %>.join(', ') }}
86
86
  </div>
87
87
  </div>
88
88
  <% end -%>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module InertiaRails
4
- VERSION = '3.13.0'
4
+ VERSION = '3.14.0'
5
5
  end
data/lib/inertia_rails.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'inertia_rails/version'
3
4
  require 'inertia_rails/renderer'
4
5
  require 'inertia_rails/engine'
5
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inertia_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.13.0
4
+ version: 3.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Knoles
@@ -9,7 +9,7 @@ authors:
9
9
  - Eugene Granovsky
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-11-19 00:00:00.000000000 Z
12
+ date: 2025-11-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
@@ -47,6 +47,7 @@ files:
47
47
  - lib/generators/inertia/install/install_generator.rb
48
48
  - lib/generators/inertia/install/js_package_manager.rb
49
49
  - lib/generators/inertia/install/templates/assets/inertia.svg
50
+ - lib/generators/inertia/install/templates/assets/rails.svg
50
51
  - lib/generators/inertia/install/templates/assets/react.svg
51
52
  - lib/generators/inertia/install/templates/assets/svelte.svg
52
53
  - lib/generators/inertia/install/templates/assets/vite_ruby.svg