turbo_turbo 0.2.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 (48) hide show
  1. checksums.yaml +7 -0
  2. data/.claude/settings.local.json +14 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +96 -0
  5. data/CHANGELOG.md +50 -0
  6. data/LICENSE +21 -0
  7. data/README.md +498 -0
  8. data/Rakefile +12 -0
  9. data/app/assets/stylesheets/turbo_turbo/alerts.css +7 -0
  10. data/app/assets/stylesheets/turbo_turbo/base.css +4 -0
  11. data/app/assets/stylesheets/turbo_turbo/button.css +24 -0
  12. data/app/assets/stylesheets/turbo_turbo/modal.css +81 -0
  13. data/app/components/turbo_turbo/alerts/alert_component.html.erb +36 -0
  14. data/app/components/turbo_turbo/alerts/alert_component.rb +12 -0
  15. data/app/components/turbo_turbo/alerts/error_component.html.erb +36 -0
  16. data/app/components/turbo_turbo/alerts/error_component.rb +12 -0
  17. data/app/components/turbo_turbo/alerts/info_component.html.erb +36 -0
  18. data/app/components/turbo_turbo/alerts/info_component.rb +12 -0
  19. data/app/components/turbo_turbo/alerts/success_component.html.erb +47 -0
  20. data/app/components/turbo_turbo/alerts/success_component.rb +12 -0
  21. data/app/components/turbo_turbo/alerts/warning_component.html.erb +36 -0
  22. data/app/components/turbo_turbo/alerts/warning_component.rb +12 -0
  23. data/app/components/turbo_turbo/modal_component.html.erb +20 -0
  24. data/app/components/turbo_turbo/modal_component.rb +9 -0
  25. data/app/components/turbo_turbo/modal_footer_component.html.erb +6 -0
  26. data/app/components/turbo_turbo/modal_footer_component.rb +10 -0
  27. data/config/locales/en.yml +15 -0
  28. data/config/routes/turbo_turbo_routes.rb +20 -0
  29. data/lib/generators/turbo_turbo/install_generator.rb +351 -0
  30. data/lib/generators/turbo_turbo/layout_generator.rb +221 -0
  31. data/lib/generators/turbo_turbo/templates/config/routes/turbo_turbo_routes.rb +20 -0
  32. data/lib/generators/turbo_turbo/templates/turbo_turbo/_error_message.html.erb +15 -0
  33. data/lib/generators/turbo_turbo/templates/turbo_turbo/_flashes.html.erb +8 -0
  34. data/lib/generators/turbo_turbo/templates/turbo_turbo/_modal_background.html.erb +2 -0
  35. data/lib/generators/turbo_turbo/templates/turbo_turbo/flash_controller.js +28 -0
  36. data/lib/generators/turbo_turbo/templates/turbo_turbo/modal_controller.js +114 -0
  37. data/lib/generators/turbo_turbo/views_generator.rb +57 -0
  38. data/lib/turbo_turbo/controller_helpers.rb +157 -0
  39. data/lib/turbo_turbo/engine.rb +19 -0
  40. data/lib/turbo_turbo/form_helper.rb +135 -0
  41. data/lib/turbo_turbo/parameter_sanitizer.rb +69 -0
  42. data/lib/turbo_turbo/standard_actions.rb +96 -0
  43. data/lib/turbo_turbo/test_helpers.rb +64 -0
  44. data/lib/turbo_turbo/version.rb +5 -0
  45. data/lib/turbo_turbo.rb +15 -0
  46. data/sig/turbo_turbo.rbs +4 -0
  47. data/turbo_turbo.gemspec +42 -0
  48. metadata +136 -0
@@ -0,0 +1,7 @@
1
+ #flashes_turbo_turbo {
2
+ position: absolute;
3
+ top: 0;
4
+ right: 0;
5
+ z-index: 10000;
6
+ width: 100%;
7
+ }
@@ -0,0 +1,4 @@
1
+ /* TurboTurbo CSS - Import from gem */
2
+ @import "alerts";
3
+ @import "button";
4
+ @import "modal";
@@ -0,0 +1,24 @@
1
+ .turbo-turbo-buttons {
2
+ @apply relative inline-flex items-center;
3
+ }
4
+
5
+ .turbo-turbo-button {
6
+ @apply relative inline-flex items-center rounded-md font-normal h-9 bg-primary-700 text-white focus:z-10 text-sm px-4 py-2.5 hover:bg-primary-900 drop-shadow-none shadow-none border-0 !important;
7
+
8
+ &:not(:first-child) {
9
+ @apply ml-3;
10
+ }
11
+
12
+ &.--cancel {
13
+ @apply bg-gray-200 text-gray-700 hover:bg-gray-300 !important;
14
+ }
15
+
16
+ &.--secondary {
17
+ @apply leading-6 rounded bg-white py-2.5 px-3.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 block text-center font-normal
18
+ }
19
+ }
20
+
21
+ /* Legacy class names for backwards compatibility */
22
+ .Buttons { @apply turbo-turbo-buttons; }
23
+ .Button { @apply turbo-turbo-button; }
24
+
@@ -0,0 +1,81 @@
1
+ .ModalBackground-turbo-turbo {
2
+ @apply fixed inset-0 bg-gray-500 bg-opacity-70 invisible;
3
+ transition: opacity 300ms ease-out;
4
+ opacity: 0;
5
+ z-index: 99998;
6
+ }
7
+
8
+ .ModalBackground-turbo-turbo.show {
9
+ @apply visible;
10
+ opacity: 1;
11
+ }
12
+
13
+ .ModalBackdrop-turbo-turbo {
14
+ z-index: 99999;
15
+ @apply fixed inset-0 w-full h-full overflow-y-auto items-end justify-center p-4 text-center sm:items-center sm:p-0;
16
+ display: flex;
17
+ transform: translateY(100%);
18
+ transition: transform 300ms ease-out;
19
+ }
20
+
21
+ .ModalBackdrop-turbo-turbo.show {
22
+ transform: translateY(0);
23
+ }
24
+
25
+ .Modal-turbo-turbo {
26
+ z-index: 100000;
27
+ @apply relative transform rounded-lg bg-white m-8 text-left;
28
+ transition: transform 300ms ease-out, opacity 300ms ease-out;
29
+ transform: translateY(1rem);
30
+ min-width: 320px;
31
+
32
+ & .input.radio_buttons, .input.check_boxes {
33
+ @apply grow-0 !important;
34
+ }
35
+
36
+ & .radio input, .checkbox input {
37
+ @apply p-2.5 mr-2 !important;
38
+ }
39
+
40
+ & .radio input {
41
+ @apply rounded-full;
42
+ }
43
+
44
+ & .checkbox input {
45
+ @apply rounded-md;
46
+ }
47
+
48
+ & input.radio_buttons {
49
+ @apply text-primary-700;
50
+ }
51
+
52
+ & textarea, trix-editor, input.string {
53
+ @apply grow border-0 rounded-md ring-1 ring-inset ring-gray-300 w-full !important;
54
+
55
+ &:focus {
56
+ @apply ring-primary-600 !important;
57
+ }
58
+ }
59
+
60
+ & .radio label, .checkbox label {
61
+ @apply flex items-center;
62
+ }
63
+ }
64
+
65
+ .Modal-turbo-turbo.show {
66
+ transform: translateY(0);
67
+ }
68
+
69
+ .ModalTitle-turbo-turbo {
70
+ @apply text-base rounded-t-lg leading-6 text-white bg-primary-300 p-4 mb-2;
71
+ }
72
+
73
+ .ModalBody-turbo-turbo {
74
+ @apply flex-auto overflow-auto flex flex-col;
75
+ padding-top: 0;
76
+ }
77
+
78
+ .ModalContent-turbo-turbo {
79
+ @apply flex flex-col grow overflow-auto px-4;
80
+ overflow-y: auto;
81
+ }
@@ -0,0 +1,36 @@
1
+ <div class="flash rounded-md p-4 bg-red-50" data-controller="turbo-turbo--flash">
2
+ <div class="flex">
3
+ <div class="flex-shrink-0">
4
+ <svg class="w-5 h-5 text-red-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
5
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd"></path>
6
+ </svg>
7
+ </div>
8
+ <div class="ml-3">
9
+ <% if @header %>
10
+ <h3 class="text-sm font-medium text-red-800"><%= @header %></h3>
11
+
12
+ <% if @message.is_a?(Array) %>
13
+ <ul role="list">
14
+ <% @message.each do |item| %>
15
+ <li class="mt-2 text-sm text-red-700"><%= item %></li>
16
+ <% end %>
17
+ </ul>
18
+ <% else %>
19
+ <p class="mt-2 text-sm text-red-700"><%= @message %></p>
20
+ <% end %>
21
+ <% else %>
22
+ <h3 class="text-sm font-medium text-red-800"><%= @message %></h3>
23
+ <% end %>
24
+ </div>
25
+ <div class="ml-auto pl-3">
26
+ <div class="-mx-1.5 -my-1.5">
27
+ <button class="inline-flex rounded-md p-1.5 focus:outline-none focus:ring-2 focus:ring-offset-2 bg-red-50 text-red-500 hover:bg-red-100 focus:ring-red-600 focus:ring-offset-red-50" type="button" data-action="turbo-turbo--flash#dismiss">
28
+ <span class="sr-only">Dismiss</span>
29
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
30
+ <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"></path>
31
+ </svg>
32
+ </button>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboTurbo
4
+ module Alerts
5
+ class AlertComponent < ViewComponent::Base
6
+ def initialize(flash_contents)
7
+ @header = flash_contents[:header]
8
+ @message = flash_contents[:message]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ <div class="flash rounded-md p-4 bg-red-50" data-controller="turbo-turbo--flash">
2
+ <div class="flex">
3
+ <div class="flex-shrink-0">
4
+ <svg class="w-5 h-5 text-red-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
5
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd"></path>
6
+ </svg>
7
+ </div>
8
+ <div class="ml-3">
9
+ <% if @header %>
10
+ <h3 class="text-sm font-medium text-red-800"><%= @header %></h3>
11
+
12
+ <% if @message.is_a?(Array) %>
13
+ <ul role="list">
14
+ <% @message.each do |item| %>
15
+ <li class="mt-2 text-sm text-red-700"><%= item %></li>
16
+ <% end %>
17
+ </ul>
18
+ <% else %>
19
+ <p class="mt-2 text-sm text-red-700"><%= @message %></p>
20
+ <% end %>
21
+ <% else %>
22
+ <h3 class="text-sm font-medium text-red-800"><%= @message %></h3>
23
+ <% end %>
24
+ </div>
25
+ <div class="ml-auto pl-3">
26
+ <div class="-mx-1.5 -my-1.5">
27
+ <button class="inline-flex rounded-md p-1.5 focus:outline-none focus:ring-2 focus:ring-offset-2 bg-red-50 text-red-500 hover:bg-red-100 focus:ring-red-600 focus:ring-offset-red-50" type="button" data-action="turbo-turbo--flash#dismiss">
28
+ <span class="sr-only">Dismiss</span>
29
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
30
+ <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"></path>
31
+ </svg>
32
+ </button>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboTurbo
4
+ module Alerts
5
+ class ErrorComponent < ViewComponent::Base
6
+ def initialize(flash_contents)
7
+ @header = flash_contents[:header]
8
+ @message = flash_contents[:message]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ <div class="flash rounded-md p-4 bg-blue-50" data-controller="turbo-turbo--flash">
2
+ <div class="flex">
3
+ <div class="flex-shrink-0">
4
+ <svg class="w-5 h-5 text-blue-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
5
+ <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z" clip-rule="evenodd"></path>
6
+ </svg>
7
+ </div>
8
+ <div class="ml-3">
9
+ <% if @header %>
10
+ <h3 class="text-sm font-medium text-blue-800"><%= @header %></h3>
11
+
12
+ <% if @message.is_a?(Array) %>
13
+ <ul role="list">
14
+ <% @message.each do |item| %>
15
+ <li class="mt-2 text-sm text-blue-700"><%= item %></li>
16
+ <% end %>
17
+ </ul>
18
+ <% else %>
19
+ <p class="mt-2 text-sm text-blue-700"><%= @message %></p>
20
+ <% end %>
21
+ <% else %>
22
+ <h3 class="text-sm font-medium text-blue-800"><%= @message %></h3>
23
+ <% end %>
24
+ </div>
25
+ <div class="ml-auto pl-3">
26
+ <div class="-mx-1.5 -my-1.5">
27
+ <button class="inline-flex rounded-md p-1.5 focus:outline-none focus:ring-2 focus:ring-offset-2 bg-blue-50 text-blue-500 hover:bg-blue-100 focus:ring-blue-600 focus:ring-offset-blue-50" type="button" data-action="turbo-turbo--flash#dismiss">
28
+ <span class="sr-only">Dismiss</span>
29
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
30
+ <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"></path>
31
+ </svg>
32
+ </button>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboTurbo
4
+ module Alerts
5
+ class InfoComponent < ViewComponent::Base
6
+ def initialize(flash_contents)
7
+ @header = flash_contents[:header]
8
+ @message = flash_contents[:message]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,47 @@
1
+ <div class="pointer-events-none fixed inset-0 flex items-end px-4 py-6 sm:items-start sm:p-6" aria-live="assertive" data-controller="turbo-turbo--flash">
2
+ <div class="flex w-full flex-col items-center space-y-4 sm:items-end">
3
+ <div class="pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5">
4
+ <div class="p-4">
5
+ <div class="flex items-start">
6
+ <div class="flex-shrink-0">
7
+ <svg class="w-5 h-5 text-green-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
8
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd"></path>
9
+ </svg>
10
+ </div>
11
+ <div class="ml-3 w-0 flex-1 pt-0.5">
12
+ <% if @header %>
13
+ <p class="text-sm font-medium text-gray-900"><%= @header %></p>
14
+ <% if @message.is_a?(Array) %>
15
+ <ul role="list">
16
+ <% @message.each do |item| %>
17
+ <li class="mt-1 text-sm text-gray-500"><%= item %></li>
18
+ <% end %>
19
+ </ul>
20
+ <% else %>
21
+ <p class="text-sm font-medium text-gray-500"><%= @message %></p>
22
+ <% end %>
23
+ <% else %>
24
+ <% if @message.is_a?(Array) %>
25
+ <ul role="list">
26
+ <% @message.each do |item| %>
27
+ <li class="mt-1 text-sm text-gray-700"><%= item %></li>
28
+ <% end %>
29
+ </ul>
30
+ <% else %>
31
+ <p class="text-sm font-medium text-gray-900"><%= @message %></p>
32
+ <% end %>
33
+ <% end %>
34
+ </div>
35
+ <div class="ml-4 flex flex-shrink-0">
36
+ <button class="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2" type="button" data-action="turbo-turbo--flash#dismiss">
37
+ <span class="sr-only">Close</span>
38
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
39
+ <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"></path>
40
+ </svg>
41
+ </button>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </div>
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboTurbo
4
+ module Alerts
5
+ class SuccessComponent < ViewComponent::Base
6
+ def initialize(flash_contents)
7
+ @header = flash_contents[:header]
8
+ @message = flash_contents[:message]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ <div class="flash rounded-md p-4 bg-yellow-50" data-controller="turbo-turbo--flash">
2
+ <div class="flex">
3
+ <div class="flex-shrink-0">
4
+ <svg class="w-5 h-5 text-yellow-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
5
+ <path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"></path>
6
+ </svg>
7
+ </div>
8
+ <div class="ml-3">
9
+ <% if @header %>
10
+ <h3 class="text-sm font-medium text-yellow-800"><%= @header %></h3>
11
+
12
+ <% if @message.is_a?(Array) %>
13
+ <ul role="list">
14
+ <% @message.each do |item| %>
15
+ <li class="mt-2 text-sm text-yellow-700"><%= item %></li>
16
+ <% end %>
17
+ </ul>
18
+ <% else %>
19
+ <p class="mt-2 text-sm text-yellow-700"><%= @message %></p>
20
+ <% end %>
21
+ <% else %>
22
+ <h3 class="text-sm font-medium text-yellow-800"><%= @message %></h3>
23
+ <% end %>
24
+ </div>
25
+ <div class="ml-auto pl-3">
26
+ <div class="-mx-1.5 -my-1.5">
27
+ <button class="inline-flex rounded-md p-1.5 focus:outline-none focus:ring-2 focus:ring-offset-2 bg-yellow-50 text-yellow-500 hover:bg-yellow-100 focus:ring-yellow-600 focus:ring-offset-yellow-50" type="button" data-action="turbo-turbo--flash#dismiss">
28
+ <span class="sr-only">Dismiss</span>
29
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
30
+ <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"></path>
31
+ </svg>
32
+ </button>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboTurbo
4
+ module Alerts
5
+ class WarningComponent < ViewComponent::Base
6
+ def initialize(flash_contents)
7
+ @header = flash_contents[:header]
8
+ @message = flash_contents[:message]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ <div class="ModalBackdrop-turbo-turbo" data-turbo-turbo--modal-target="modalBackdrop" data-action="click->turbo-turbo--modal#closeModal">
2
+ <div class="Modal-turbo-turbo border border-gray-200 bg-white py-5 rounded-lg flex flex-col max-h-[95vh]" data-turbo-turbo--modal-target="modal">
3
+ <div class="absolute right-0 top-0 pr-4 pt-4 sm:block">
4
+ <button class="rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2" type="button" data-action="turbo-turbo--modal#closeModal">
5
+ <span class="sr-only">Close</span>
6
+ <svg class="h-6 w-6 pointer-events-none" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
7
+ <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path>
8
+ </svg>
9
+ </button>
10
+ </div>
11
+ <div id="modal_title_bar_turbo_turbo">
12
+ <div class="border-b border-gray-200 bg-white px-4 py-5 sm:px-6">
13
+ <h3 class="text-base font-semibold leading-6 text-gray-900" data-turbo-turbo--modal-target="title"></h3>
14
+ <p class="mt-1 text-sm text-gray-500" data-turbo-turbo--modal-target="subtitle"></p>
15
+ </div>
16
+ </div>
17
+ <div id="modal_body_turbo_turbo" class="ModalBody-turbo-turbo p-4 max-w-full md:min-w-128" data-turbo-turbo--modal-target="body"></div>
18
+ <div id="modal_footer_turbo_turbo" class="mt-6 flex flex-row items-center justify-end gap-x-6 px-4 py-2" data-turbo-turbo--modal-target="footer"></div>
19
+ </div>
20
+ </div>
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboTurbo
4
+ class ModalComponent < ViewComponent::Base
5
+ def initialize(show_close: false)
6
+ @show_close = show_close
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ <div id="modal_footer" class="ModalFooterActions flex-shrink-0" data-turbo-turbo--modal-target="footer">
2
+ <% unless @skip_close %>
3
+ <%= link_to @close_label, "", data: { action: "turbo-turbo--modal#closeModal" }, class: "Button --cancel flex-1 justify-center" %>
4
+ <% end %>
5
+ <%= content %>
6
+ </div>
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboTurbo
4
+ class ModalFooterComponent < ViewComponent::Base
5
+ def initialize(skip_close: false, close_label: "Cancel")
6
+ @skip_close = skip_close
7
+ @close_label = close_label
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ en:
2
+ turbo_turbo:
3
+ flash:
4
+ success:
5
+ create: "%{resource} created!"
6
+ update: "%{resource} updated!"
7
+ destroy: "%{resource} deleted!"
8
+ archive: "%{resource} archived!"
9
+ restore: "%{resource} restored!"
10
+ upload: "%{resource} uploaded!"
11
+ toggle_resolved: "%{resource} resolved!"
12
+ email_modal: "%{resource} updated!"
13
+ default: "%{resource} %{action}d!"
14
+ error:
15
+ default: "We encountered an error trying to %{action} %{resource}."
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # TurboTurbo routes for modal-based CRUD operations
4
+ # Add `draw(:turbo_turbo_routes)` to your main routes.rb file to include these routes
5
+
6
+ namespace :turbo_turbo do
7
+ # Admin namespace for administrative modal operations
8
+ namespace :admin do
9
+ # Add your admin resources here
10
+ # Example: resources :pathways, only: [:new, :create, :show, :edit, :update, :destroy]
11
+ end
12
+
13
+ # Provider namespace for provider modal operations
14
+ namespace :provider do
15
+ # Add your provider resources here
16
+ # Example: resources :pathways, only: [:new, :create, :show, :edit, :update, :destroy]
17
+ end
18
+
19
+ # Add other namespaces as needed
20
+ end