turbo_overlay 0.3.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 (57) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +436 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +330 -0
  5. data/Rakefile +35 -0
  6. data/app/assets/stylesheets/turbo_overlay.css +234 -0
  7. data/app/javascript/turbo_overlay/dialog_utils.js +46 -0
  8. data/app/javascript/turbo_overlay/hint.js +670 -0
  9. data/app/javascript/turbo_overlay/history.js +184 -0
  10. data/app/javascript/turbo_overlay/index.js +53 -0
  11. data/app/javascript/turbo_overlay/options.js +152 -0
  12. data/app/javascript/turbo_overlay/overlay_controller.js +882 -0
  13. data/app/javascript/turbo_overlay/popover_position.js +64 -0
  14. data/app/javascript/turbo_overlay/setup.js +885 -0
  15. data/app/javascript/turbo_overlay/stack_controller.js +131 -0
  16. data/app/javascript/turbo_overlay/submit_close.js +49 -0
  17. data/app/javascript/turbo_overlay/visit.js +52 -0
  18. data/app/views/layouts/turbo_overlay/drawer.html.erb +5 -0
  19. data/app/views/layouts/turbo_overlay/hint.html.erb +10 -0
  20. data/app/views/layouts/turbo_overlay/modal.html.erb +5 -0
  21. data/app/views/layouts/turbo_overlay/popover.html.erb +5 -0
  22. data/app/views/turbo_overlay/_drawer.html.erb +49 -0
  23. data/app/views/turbo_overlay/_hint.html.erb +6 -0
  24. data/app/views/turbo_overlay/_loading.html.erb +12 -0
  25. data/app/views/turbo_overlay/_modal.html.erb +46 -0
  26. data/app/views/turbo_overlay/_popover.html.erb +54 -0
  27. data/config/importmap.rb +11 -0
  28. data/lib/generators/turbo_overlay/eject_generator.rb +115 -0
  29. data/lib/generators/turbo_overlay/install_generator.rb +443 -0
  30. data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_confirm.html.erb +13 -0
  31. data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_drawer.html.erb +50 -0
  32. data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_hint.html.erb +9 -0
  33. data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_loading.html.erb +9 -0
  34. data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_modal.html.erb +49 -0
  35. data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_popover.html.erb +54 -0
  36. data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_confirm.html.erb +13 -0
  37. data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_drawer.html.erb +55 -0
  38. data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_hint.html.erb +9 -0
  39. data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_loading.html.erb +9 -0
  40. data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_modal.html.erb +58 -0
  41. data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_popover.html.erb +53 -0
  42. data/lib/generators/turbo_overlay/templates/chrome/plain/_confirm.html.erb +14 -0
  43. data/lib/generators/turbo_overlay/templates/chrome/tailwind/_confirm.html.erb +17 -0
  44. data/lib/generators/turbo_overlay/templates/chrome/tailwind/_drawer.html.erb +55 -0
  45. data/lib/generators/turbo_overlay/templates/chrome/tailwind/_hint.html.erb +6 -0
  46. data/lib/generators/turbo_overlay/templates/chrome/tailwind/_loading.html.erb +9 -0
  47. data/lib/generators/turbo_overlay/templates/chrome/tailwind/_modal.html.erb +46 -0
  48. data/lib/generators/turbo_overlay/templates/chrome/tailwind/_popover.html.erb +54 -0
  49. data/lib/generators/turbo_overlay/templates/initializer.rb.tt +67 -0
  50. data/lib/turbo_overlay/configuration.rb +226 -0
  51. data/lib/turbo_overlay/controller.rb +405 -0
  52. data/lib/turbo_overlay/engine.rb +52 -0
  53. data/lib/turbo_overlay/helpers/stream_helper.rb +77 -0
  54. data/lib/turbo_overlay/helpers/view_helper.rb +651 -0
  55. data/lib/turbo_overlay/version.rb +3 -0
  56. data/lib/turbo_overlay.rb +20 -0
  57. metadata +161 -0
@@ -0,0 +1,55 @@
1
+ <% loading = local_assigns.fetch(:loading, false) %>
2
+ <% position = turbo_overlay_position || TurboOverlay.configuration.drawer.position %>
3
+ <% offcanvas_class = {
4
+ right: "offcanvas-end",
5
+ left: "offcanvas-start",
6
+ top: "offcanvas-top",
7
+ bottom: "offcanvas-bottom"
8
+ }.fetch(position) %>
9
+ <% backdrop = turbo_overlay_backdrop? %>
10
+ <% close_button = local_assigns.fetch(:close) { overlay_close? } %>
11
+ <dialog class="<%= class_names("turbo-overlay", "turbo-overlay--drawer", "turbo-overlay--drawer-#{position}", "turbo-overlay-scaffold", "turbo-overlay--loading": loading, "turbo-overlay--no-backdrop": !backdrop) %>"
12
+ <% if loading %>
13
+ role="status"
14
+ aria-live="polite"
15
+ aria-label="Loading"
16
+ <% else %>
17
+ data-controller="turbo-overlay"
18
+ data-turbo-overlay-id-value="<%= turbo_overlay_id %>"
19
+ data-turbo-overlay-type-value="drawer"
20
+ data-turbo-overlay-backdrop-value="<%= backdrop %>"
21
+ <% if turbo_overlay_keep_open_on_redirect? %>data-turbo-overlay-keep-open-on-redirect="true"<% end %>
22
+ data-action="cancel->turbo-overlay#cancel click->turbo-overlay#backdropClick"
23
+ aria-labelledby="turbo-drawer-title-<%= turbo_overlay_id %>"
24
+ <% end %>>
25
+ <div class="offcanvas <%= offcanvas_class %> show position-relative" tabindex="-1">
26
+ <% if !loading && content_for?(:overlay_title) %>
27
+ <div class="offcanvas-header">
28
+ <h5 id="turbo-drawer-title-<%= turbo_overlay_id %>" class="offcanvas-title">
29
+ <%= yield(:overlay_title) %>
30
+ </h5>
31
+ <% if close_button %>
32
+ <button type="button"
33
+ class="btn-close"
34
+ data-action="turbo-overlay#close"
35
+ aria-label="Close"></button>
36
+ <% end %>
37
+ </div>
38
+ <% elsif !loading && close_button %>
39
+ <button type="button"
40
+ class="btn-close position-absolute top-0 end-0 m-3"
41
+ data-action="turbo-overlay#close"
42
+ aria-label="Close"></button>
43
+ <% end %>
44
+
45
+ <div class="offcanvas-body">
46
+ <%= yield %>
47
+ </div>
48
+
49
+ <% if !loading && content_for?(:overlay_footer) %>
50
+ <div class="offcanvas-footer p-3 border-top d-flex justify-content-end gap-2">
51
+ <%= yield(:overlay_footer) %>
52
+ </div>
53
+ <% end %>
54
+ </div>
55
+ </dialog>
@@ -0,0 +1,9 @@
1
+ <% loading = local_assigns.fetch(:loading, false) %>
2
+ <div popover="manual"
3
+ class="<%= class_names("turbo-overlay-hint", "popover position-fixed d-block shadow-sm", "turbo-overlay--loading": loading) %>"
4
+ style="max-width: 20rem;"
5
+ <% if loading %>role="status" aria-live="polite" aria-label="Loading"<% else %>role="tooltip"<% end %>>
6
+ <div class="popover-body">
7
+ <%= yield %>
8
+ </div>
9
+ </div>
@@ -0,0 +1,9 @@
1
+ <%# Body content for an overlay's loading placeholder. Wrapped in the
2
+ matching chrome at template-emission time by `overlay_stack_tag`.
3
+ Sizing comes from the gem's CSS so the same partial fits modal,
4
+ drawer, popover, and hint contexts. Add `_loading.html+<variant>.erb`
5
+ if you need chrome-specific markup.
6
+ %>
7
+ <div class="turbo-overlay-loading__body d-flex align-items-center justify-content-center">
8
+ <span class="turbo-overlay-loading__spinner" aria-hidden="true"></span>
9
+ </div>
@@ -0,0 +1,58 @@
1
+ <% loading = local_assigns.fetch(:loading, false) %>
2
+ <% close_button = local_assigns.fetch(:close) { overlay_close? } %>
3
+ <dialog class="<%= class_names("turbo-overlay", "turbo-overlay--modal", "turbo-overlay-scaffold", "turbo-overlay--loading": loading) %>"
4
+ <% if loading %>
5
+ role="status"
6
+ aria-live="polite"
7
+ aria-label="Loading"
8
+ <% else %>
9
+ data-controller="turbo-overlay"
10
+ data-turbo-overlay-id-value="<%= turbo_overlay_id %>"
11
+ data-turbo-overlay-type-value="modal"
12
+ <% if turbo_overlay_keep_open_on_redirect? %>data-turbo-overlay-keep-open-on-redirect="true"<% end %>
13
+ data-action="cancel->turbo-overlay#cancel click->turbo-overlay#backdropClick"
14
+ aria-labelledby="turbo-modal-title-<%= turbo_overlay_id %>"
15
+ <% end %>>
16
+ <%# .modal wrapper scopes the --bs-modal-* CSS variables that
17
+ .modal-content reads for background, border, and padding.
18
+ d-block overrides Bootstrap's display:none; position-static
19
+ neutralizes its position:fixed so the native <dialog>'s own
20
+ top-layer positioning still drives placement.
21
+ data-turbo-overlay-backdrop-zone tells backdropClick that the
22
+ wrapper counts as a backdrop click — without it, the wrapper
23
+ would intercept the click that used to hit the dialog's ::backdrop. %>
24
+ <div class="modal d-block position-static" data-turbo-overlay-backdrop-zone>
25
+ <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
26
+ <div class="modal-content position-relative">
27
+ <% if !loading && content_for?(:overlay_title) %>
28
+ <div class="modal-header">
29
+ <h5 id="turbo-modal-title-<%= turbo_overlay_id %>" class="modal-title">
30
+ <%= yield(:overlay_title) %>
31
+ </h5>
32
+ <% if close_button %>
33
+ <button type="button"
34
+ class="btn-close"
35
+ data-action="turbo-overlay#close"
36
+ aria-label="Close"></button>
37
+ <% end %>
38
+ </div>
39
+ <% elsif !loading && close_button %>
40
+ <button type="button"
41
+ class="btn-close position-absolute top-0 end-0 m-3"
42
+ data-action="turbo-overlay#close"
43
+ aria-label="Close"></button>
44
+ <% end %>
45
+
46
+ <div class="modal-body">
47
+ <%= yield %>
48
+ </div>
49
+
50
+ <% if !loading && content_for?(:overlay_footer) %>
51
+ <div class="modal-footer">
52
+ <%= yield(:overlay_footer) %>
53
+ </div>
54
+ <% end %>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </dialog>
@@ -0,0 +1,53 @@
1
+ <% loading = local_assigns.fetch(:loading, false) %>
2
+ <% position = turbo_overlay_position || TurboOverlay.configuration.popover.position %>
3
+ <% align = turbo_overlay_align || TurboOverlay.configuration.popover.align %>
4
+ <% offset = turbo_overlay_offset || TurboOverlay.configuration.popover.offset %>
5
+ <% close_button = local_assigns.fetch(:close) { defined?(@_overlay_close) && @_overlay_close != false } %>
6
+ <dialog popover="manual"
7
+ class="<%= class_names("turbo-overlay", "turbo-overlay--popover", "turbo-overlay--no-backdrop", "popover position-fixed m-0 p-0 d-block", "turbo-overlay--loading": loading) %>"
8
+ style="max-width: 22rem;"
9
+ <% if loading %>
10
+ role="status"
11
+ aria-live="polite"
12
+ aria-label="Loading"
13
+ <% else %>
14
+ data-controller="turbo-overlay"
15
+ data-turbo-overlay-id-value="<%= turbo_overlay_id %>"
16
+ data-turbo-overlay-type-value="popover"
17
+ data-turbo-overlay-backdrop-value="false"
18
+ data-turbo-overlay-position-value="<%= position %>"
19
+ data-turbo-overlay-align-value="<%= align %>"
20
+ data-turbo-overlay-offset-value="<%= offset %>"
21
+ <% if turbo_overlay_keep_open_on_redirect? %>data-turbo-overlay-keep-open-on-redirect="true"<% end %>
22
+ data-action="cancel->turbo-overlay#cancel"
23
+ aria-labelledby="turbo-popover-title-<%= turbo_overlay_id %>"
24
+ <% end %>>
25
+ <div class="position-relative">
26
+ <% if !loading && content_for?(:overlay_title) %>
27
+ <div class="popover-header d-flex align-items-center justify-content-between">
28
+ <span id="turbo-popover-title-<%= turbo_overlay_id %>"><%= yield(:overlay_title) %></span>
29
+ <% if close_button %>
30
+ <button type="button"
31
+ class="btn-close btn-close-sm"
32
+ data-action="turbo-overlay#close"
33
+ aria-label="Close"></button>
34
+ <% end %>
35
+ </div>
36
+ <% elsif !loading && close_button %>
37
+ <button type="button"
38
+ class="btn-close position-absolute top-0 end-0 m-2"
39
+ data-action="turbo-overlay#close"
40
+ aria-label="Close"></button>
41
+ <% end %>
42
+
43
+ <div class="popover-body">
44
+ <%= yield %>
45
+ </div>
46
+
47
+ <% if !loading && content_for?(:overlay_footer) %>
48
+ <div class="popover-footer border-top px-3 py-2 d-flex justify-content-end gap-2">
49
+ <%= yield(:overlay_footer) %>
50
+ </div>
51
+ <% end %>
52
+ </div>
53
+ </dialog>
@@ -0,0 +1,14 @@
1
+ <%# Confirm dialog body, wrapped in the matching chrome at template-
2
+ emission time by `overlay_stack_tag`. Used for both modal- and
3
+ popover-style confirms; add `_confirm.html+<variant>.erb` for
4
+ chrome-specific tuning. Edit freely — JS only depends on the data
5
+ attributes below:
6
+ [data-turbo-overlay-confirm-message] — text insertion point
7
+ [data-turbo-overlay-confirm-cancel] — cancels (resolves false)
8
+ [data-turbo-overlay-confirm-accept] — accepts (resolves true)
9
+ %>
10
+ <p data-turbo-overlay-confirm-message></p>
11
+ <div style="display:flex;justify-content:flex-end;gap:0.5rem;margin-top:1rem;">
12
+ <button type="button" data-turbo-overlay-confirm-cancel>Cancel</button>
13
+ <button type="button" data-turbo-overlay-confirm-accept>OK</button>
14
+ </div>
@@ -0,0 +1,17 @@
1
+ <%# Confirm dialog body, wrapped in the matching chrome at template-
2
+ emission time by `overlay_stack_tag`. Used for both modal- and
3
+ popover-style confirms; add `_confirm.html+<variant>.erb` for
4
+ chrome-specific tuning. JS only depends on:
5
+ [data-turbo-overlay-confirm-message] — text insertion point
6
+ [data-turbo-overlay-confirm-cancel] — cancels (resolves false)
7
+ [data-turbo-overlay-confirm-accept] — accepts (resolves true)
8
+ %>
9
+ <p class="text-gray-900 dark:text-gray-100" data-turbo-overlay-confirm-message></p>
10
+ <div class="mt-5 flex items-center justify-end gap-2">
11
+ <button type="button"
12
+ class="px-3 py-1.5 rounded border border-gray-300 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-200 dark:hover:bg-gray-800"
13
+ data-turbo-overlay-confirm-cancel>Cancel</button>
14
+ <button type="button"
15
+ class="px-3 py-1.5 rounded bg-blue-600 text-white hover:bg-blue-700"
16
+ data-turbo-overlay-confirm-accept>OK</button>
17
+ </div>
@@ -0,0 +1,55 @@
1
+ <% loading = local_assigns.fetch(:loading, false) %>
2
+ <% position = turbo_overlay_position || TurboOverlay.configuration.drawer.position %>
3
+ <% position_classes = {
4
+ right: "inset-y-0 right-0 left-auto h-screen w-96 max-w-full",
5
+ left: "inset-y-0 left-0 right-auto h-screen w-96 max-w-full",
6
+ top: "inset-x-0 top-0 bottom-auto w-screen max-h-[50vh]",
7
+ bottom: "inset-x-0 bottom-0 top-auto w-screen max-h-[50vh]"
8
+ }.fetch(position) %>
9
+ <% backdrop = turbo_overlay_backdrop? %>
10
+ <% close_button = local_assigns.fetch(:close) { overlay_close? } %>
11
+ <dialog class="<%= class_names("turbo-overlay", "turbo-overlay--drawer", "turbo-overlay--drawer-#{position}", "fixed m-0 p-0 bg-white text-gray-900 shadow-2xl backdrop:bg-black/50 dark:bg-gray-900 dark:text-gray-100 dark:ring-1 dark:ring-white/10", position_classes, "turbo-overlay--loading": loading, "turbo-overlay--no-backdrop": !backdrop) %>"
12
+ <% if loading %>
13
+ role="status"
14
+ aria-live="polite"
15
+ aria-label="Loading"
16
+ <% else %>
17
+ data-controller="turbo-overlay"
18
+ data-turbo-overlay-id-value="<%= turbo_overlay_id %>"
19
+ data-turbo-overlay-type-value="drawer"
20
+ data-turbo-overlay-backdrop-value="<%= backdrop %>"
21
+ <% if turbo_overlay_keep_open_on_redirect? %>data-turbo-overlay-keep-open-on-redirect="true"<% end %>
22
+ data-action="cancel->turbo-overlay#cancel click->turbo-overlay#backdropClick"
23
+ aria-labelledby="turbo-drawer-title-<%= turbo_overlay_id %>"
24
+ <% end %>>
25
+ <div class="relative flex flex-col h-full">
26
+ <% if !loading && content_for?(:overlay_title) %>
27
+ <header class="flex items-center justify-between px-5 py-4 border-b border-gray-200 dark:border-gray-700">
28
+ <h2 id="turbo-drawer-title-<%= turbo_overlay_id %>" class="text-lg font-semibold text-gray-900 dark:text-gray-100">
29
+ <%= yield(:overlay_title) %>
30
+ </h2>
31
+ <% if close_button %>
32
+ <button type="button"
33
+ class="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 text-2xl leading-none"
34
+ data-action="turbo-overlay#close"
35
+ aria-label="Close"><span aria-hidden="true">&times;</span></button>
36
+ <% end %>
37
+ </header>
38
+ <% elsif !loading && close_button %>
39
+ <button type="button"
40
+ class="absolute top-2 right-3 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 text-2xl leading-none z-10"
41
+ data-action="turbo-overlay#close"
42
+ aria-label="Close"><span aria-hidden="true">&times;</span></button>
43
+ <% end %>
44
+
45
+ <div class="flex-1 overflow-y-auto px-5 py-4">
46
+ <%= yield %>
47
+ </div>
48
+
49
+ <% if !loading && content_for?(:overlay_footer) %>
50
+ <footer class="flex items-center justify-end gap-2 px-5 py-4 border-t border-gray-200 dark:border-gray-700">
51
+ <%= yield(:overlay_footer) %>
52
+ </footer>
53
+ <% end %>
54
+ </div>
55
+ </dialog>
@@ -0,0 +1,6 @@
1
+ <% loading = local_assigns.fetch(:loading, false) %>
2
+ <div popover="manual"
3
+ class="<%= class_names("turbo-overlay-hint", "fixed z-50 max-w-xs rounded-md border border-gray-200 bg-white px-3 py-2 text-sm text-gray-900 shadow-lg ring-1 ring-black/5 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:ring-white/10", "turbo-overlay--loading": loading) %>"
4
+ <% if loading %>role="status" aria-live="polite" aria-label="Loading"<% else %>role="tooltip"<% end %>>
5
+ <%= yield %>
6
+ </div>
@@ -0,0 +1,9 @@
1
+ <%# Body content for an overlay's loading placeholder. Wrapped in the
2
+ matching chrome at template-emission time by `overlay_stack_tag`.
3
+ Sizing comes from the gem's CSS so the same partial fits modal,
4
+ drawer, popover, and hint contexts. Add `_loading.html+<variant>.erb`
5
+ if you need chrome-specific markup.
6
+ %>
7
+ <div class="turbo-overlay-loading__body flex items-center justify-center">
8
+ <span class="turbo-overlay-loading__spinner" aria-hidden="true"></span>
9
+ </div>
@@ -0,0 +1,46 @@
1
+ <% loading = local_assigns.fetch(:loading, false) %>
2
+ <% close_button = local_assigns.fetch(:close) { overlay_close? } %>
3
+ <dialog class="<%= class_names("turbo-overlay", "turbo-overlay--modal", "fixed inset-0 m-auto w-full max-w-lg rounded-lg p-0 backdrop:bg-black/50 backdrop:backdrop-blur-sm", "turbo-overlay--loading": loading) %>"
4
+ <% if loading %>
5
+ role="status"
6
+ aria-live="polite"
7
+ aria-label="Loading"
8
+ <% else %>
9
+ data-controller="turbo-overlay"
10
+ data-turbo-overlay-id-value="<%= turbo_overlay_id %>"
11
+ data-turbo-overlay-type-value="modal"
12
+ <% if turbo_overlay_keep_open_on_redirect? %>data-turbo-overlay-keep-open-on-redirect="true"<% end %>
13
+ data-action="cancel->turbo-overlay#cancel click->turbo-overlay#backdropClick"
14
+ aria-labelledby="turbo-modal-title-<%= turbo_overlay_id %>"
15
+ <% end %>>
16
+ <div class="relative flex flex-col bg-white text-gray-900 rounded-lg shadow-xl dark:bg-gray-900 dark:text-gray-100 dark:ring-1 dark:ring-white/10">
17
+ <% if !loading && content_for?(:overlay_title) %>
18
+ <header class="flex items-center justify-between px-5 py-4 border-b border-gray-200 dark:border-gray-700">
19
+ <h2 id="turbo-modal-title-<%= turbo_overlay_id %>" class="text-lg font-semibold text-gray-900 dark:text-gray-100">
20
+ <%= yield(:overlay_title) %>
21
+ </h2>
22
+ <% if close_button %>
23
+ <button type="button"
24
+ class="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 text-2xl leading-none"
25
+ data-action="turbo-overlay#close"
26
+ aria-label="Close"><span aria-hidden="true">&times;</span></button>
27
+ <% end %>
28
+ </header>
29
+ <% elsif !loading && close_button %>
30
+ <button type="button"
31
+ class="absolute top-2 right-3 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 text-2xl leading-none z-10"
32
+ data-action="turbo-overlay#close"
33
+ aria-label="Close"><span aria-hidden="true">&times;</span></button>
34
+ <% end %>
35
+
36
+ <div class="px-5 py-4">
37
+ <%= yield %>
38
+ </div>
39
+
40
+ <% if !loading && content_for?(:overlay_footer) %>
41
+ <footer class="flex items-center justify-end gap-2 px-5 py-4 border-t border-gray-200 dark:border-gray-700">
42
+ <%= yield(:overlay_footer) %>
43
+ </footer>
44
+ <% end %>
45
+ </div>
46
+ </dialog>
@@ -0,0 +1,54 @@
1
+ <% loading = local_assigns.fetch(:loading, false) %>
2
+ <% position = turbo_overlay_position || TurboOverlay.configuration.popover.position %>
3
+ <% align = turbo_overlay_align || TurboOverlay.configuration.popover.align %>
4
+ <% offset = turbo_overlay_offset || TurboOverlay.configuration.popover.offset %>
5
+ <% close_button = local_assigns.fetch(:close) { defined?(@_overlay_close) && @_overlay_close != false } %>
6
+ <dialog popover="manual"
7
+ class="<%= class_names("turbo-overlay", "turbo-overlay--popover", "turbo-overlay--no-backdrop", "fixed m-0 p-0 max-w-sm rounded-md bg-white text-gray-900 shadow-xl ring-1 ring-black/5 dark:bg-gray-800 dark:text-gray-100 dark:ring-white/10", "turbo-overlay--loading": loading) %>"
8
+ <% if loading %>
9
+ role="status"
10
+ aria-live="polite"
11
+ aria-label="Loading"
12
+ <% else %>
13
+ data-controller="turbo-overlay"
14
+ data-turbo-overlay-id-value="<%= turbo_overlay_id %>"
15
+ data-turbo-overlay-type-value="popover"
16
+ data-turbo-overlay-backdrop-value="false"
17
+ data-turbo-overlay-position-value="<%= position %>"
18
+ data-turbo-overlay-align-value="<%= align %>"
19
+ data-turbo-overlay-offset-value="<%= offset %>"
20
+ <% if turbo_overlay_keep_open_on_redirect? %>data-turbo-overlay-keep-open-on-redirect="true"<% end %>
21
+ data-action="cancel->turbo-overlay#cancel"
22
+ aria-labelledby="turbo-popover-title-<%= turbo_overlay_id %>"
23
+ <% end %>>
24
+ <div class="relative flex flex-col">
25
+ <% if !loading && content_for?(:overlay_title) %>
26
+ <header class="flex items-center justify-between px-3 py-2 border-b border-gray-200 dark:border-gray-700">
27
+ <h2 id="turbo-popover-title-<%= turbo_overlay_id %>" class="text-sm font-semibold">
28
+ <%= yield(:overlay_title) %>
29
+ </h2>
30
+ <% if close_button %>
31
+ <button type="button"
32
+ class="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 text-xl leading-none"
33
+ data-action="turbo-overlay#close"
34
+ aria-label="Close"><span aria-hidden="true">&times;</span></button>
35
+ <% end %>
36
+ </header>
37
+ <% elsif !loading && close_button %>
38
+ <button type="button"
39
+ class="absolute top-1 right-2 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 text-xl leading-none z-10"
40
+ data-action="turbo-overlay#close"
41
+ aria-label="Close"><span aria-hidden="true">&times;</span></button>
42
+ <% end %>
43
+
44
+ <div class="px-3 py-2 text-sm">
45
+ <%= yield %>
46
+ </div>
47
+
48
+ <% if !loading && content_for?(:overlay_footer) %>
49
+ <footer class="flex items-center justify-end gap-2 px-3 py-2 border-t border-gray-200 dark:border-gray-700">
50
+ <%= yield(:overlay_footer) %>
51
+ </footer>
52
+ <% end %>
53
+ </div>
54
+ </dialog>
@@ -0,0 +1,67 @@
1
+ TurboOverlay.configure do |config|
2
+ # The DOM id of the host-page stack container that receives
3
+ # appended overlays. Emit it in your application layout via
4
+ # `<%%= overlay_stack_tag %>`.
5
+ # config.stack_id = "turbo_overlay_stack"
6
+
7
+ config.modal do |m|
8
+ # Rails request variant assigned to modal requests. Lets you ship
9
+ # `show.html+modal.erb` next to `show.html.erb`.
10
+ # m.variant = :modal
11
+
12
+ # Layout used to render modal responses.
13
+ # m.layout_name = "turbo_modal"
14
+
15
+ # Push the link's target URL into the browser history bar when a
16
+ # modal opens. Browser-back closes the top overlay instead of
17
+ # navigating away. Default off. Per-link override:
18
+ # `modal_link_to "Edit", path, advance: true`
19
+ # or a custom URL string, or `advance: false` to opt out when this
20
+ # type default is on. Popovers and hints never advance.
21
+ # m.advance = false
22
+ end
23
+
24
+ config.drawer do |d|
25
+ # Same as modal, plus a position for the shipped layouts:
26
+ # :left, :right (default), :top, :bottom.
27
+ # d.variant = :drawer
28
+ # d.layout_name = "turbo_drawer"
29
+ # d.position = :right
30
+
31
+ # Same URL-advance semantics as the modal config. Default off.
32
+ # d.advance = false
33
+ end
34
+
35
+ config.popover do |p|
36
+ # Popovers anchor to their trigger element (the clicked link).
37
+ # `position` is the side of the trigger to attach to.
38
+ # `align` is the cross-axis alignment relative to the trigger.
39
+ # `offset` is the gap in pixels between trigger and popover edges.
40
+ # `auto_flip` swaps to the opposite side when the preferred
41
+ # placement would overflow the viewport.
42
+ # p.variant = :popover
43
+ # p.layout_name = "turbo_popover"
44
+ # p.position = :bottom # :top, :bottom, :left, :right
45
+ # p.align = :start # :start, :center, :end
46
+ # p.offset = 4
47
+ # p.auto_flip = true
48
+ end
49
+
50
+ config.confirm do |cf|
51
+ # Controls how `data-turbo-confirm` renders when the themed confirm
52
+ # hook is registered via `register(application, { confirm: true })`.
53
+ # `:modal` (default) is centered; `:popover` anchors to the
54
+ # clicked submitter and is often friendlier next to a row's
55
+ # delete button. Per-link override via
56
+ # `data-turbo-confirm-style="popover"` (or "modal") on the link/form.
57
+ # cf.style = :modal
58
+ end
59
+
60
+ config.hint do |h|
61
+ # Hover-triggered preview overlays. Inert without
62
+ # `data-turbo-overlay-hint` (or `hint: true` on an overlay helper)
63
+ # on the link.
64
+ # h.show_delay_ms = 250 # hover must persist this long
65
+ # h.hide_delay_ms = 120 # grace window after mouseleave
66
+ end
67
+ end