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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +436 -0
- data/LICENSE.txt +21 -0
- data/README.md +330 -0
- data/Rakefile +35 -0
- data/app/assets/stylesheets/turbo_overlay.css +234 -0
- data/app/javascript/turbo_overlay/dialog_utils.js +46 -0
- data/app/javascript/turbo_overlay/hint.js +670 -0
- data/app/javascript/turbo_overlay/history.js +184 -0
- data/app/javascript/turbo_overlay/index.js +53 -0
- data/app/javascript/turbo_overlay/options.js +152 -0
- data/app/javascript/turbo_overlay/overlay_controller.js +882 -0
- data/app/javascript/turbo_overlay/popover_position.js +64 -0
- data/app/javascript/turbo_overlay/setup.js +885 -0
- data/app/javascript/turbo_overlay/stack_controller.js +131 -0
- data/app/javascript/turbo_overlay/submit_close.js +49 -0
- data/app/javascript/turbo_overlay/visit.js +52 -0
- data/app/views/layouts/turbo_overlay/drawer.html.erb +5 -0
- data/app/views/layouts/turbo_overlay/hint.html.erb +10 -0
- data/app/views/layouts/turbo_overlay/modal.html.erb +5 -0
- data/app/views/layouts/turbo_overlay/popover.html.erb +5 -0
- data/app/views/turbo_overlay/_drawer.html.erb +49 -0
- data/app/views/turbo_overlay/_hint.html.erb +6 -0
- data/app/views/turbo_overlay/_loading.html.erb +12 -0
- data/app/views/turbo_overlay/_modal.html.erb +46 -0
- data/app/views/turbo_overlay/_popover.html.erb +54 -0
- data/config/importmap.rb +11 -0
- data/lib/generators/turbo_overlay/eject_generator.rb +115 -0
- data/lib/generators/turbo_overlay/install_generator.rb +443 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_confirm.html.erb +13 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_drawer.html.erb +50 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_hint.html.erb +9 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_loading.html.erb +9 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_modal.html.erb +49 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap3/_popover.html.erb +54 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_confirm.html.erb +13 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_drawer.html.erb +55 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_hint.html.erb +9 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_loading.html.erb +9 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_modal.html.erb +58 -0
- data/lib/generators/turbo_overlay/templates/chrome/bootstrap5/_popover.html.erb +53 -0
- data/lib/generators/turbo_overlay/templates/chrome/plain/_confirm.html.erb +14 -0
- data/lib/generators/turbo_overlay/templates/chrome/tailwind/_confirm.html.erb +17 -0
- data/lib/generators/turbo_overlay/templates/chrome/tailwind/_drawer.html.erb +55 -0
- data/lib/generators/turbo_overlay/templates/chrome/tailwind/_hint.html.erb +6 -0
- data/lib/generators/turbo_overlay/templates/chrome/tailwind/_loading.html.erb +9 -0
- data/lib/generators/turbo_overlay/templates/chrome/tailwind/_modal.html.erb +46 -0
- data/lib/generators/turbo_overlay/templates/chrome/tailwind/_popover.html.erb +54 -0
- data/lib/generators/turbo_overlay/templates/initializer.rb.tt +67 -0
- data/lib/turbo_overlay/configuration.rb +226 -0
- data/lib/turbo_overlay/controller.rb +405 -0
- data/lib/turbo_overlay/engine.rb +52 -0
- data/lib/turbo_overlay/helpers/stream_helper.rb +77 -0
- data/lib/turbo_overlay/helpers/view_helper.rb +651 -0
- data/lib/turbo_overlay/version.rb +3 -0
- data/lib/turbo_overlay.rb +20 -0
- metadata +161 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Pure positioning math for anchored popovers (and, in a later
|
|
2
|
+
// phase, hover hints). Given the anchor and dialog rectangles plus
|
|
3
|
+
// a viewport, returns { top, left, resolvedPosition } in viewport
|
|
4
|
+
// (CSS `position: fixed`) coordinates.
|
|
5
|
+
//
|
|
6
|
+
// Supports:
|
|
7
|
+
// - position: "top" | "bottom" | "left" | "right"
|
|
8
|
+
// - align: "start" | "center" | "end" (cross-axis)
|
|
9
|
+
// - offset: pixel gap between anchor edge and dialog edge
|
|
10
|
+
// - autoFlip: if true, swap to the opposite side when the preferred
|
|
11
|
+
// placement would overflow the viewport AND the opposite
|
|
12
|
+
// side has room.
|
|
13
|
+
//
|
|
14
|
+
// The result is clamped on the cross axis to keep the dialog at
|
|
15
|
+
// least `edgePadding` pixels inside the viewport. The primary axis is
|
|
16
|
+
// not clamped — auto-flip handles that and clamping would defeat the
|
|
17
|
+
// anchor relationship.
|
|
18
|
+
|
|
19
|
+
const DEFAULT_OFFSET = 4
|
|
20
|
+
const DEFAULT_EDGE_PADDING = 8
|
|
21
|
+
|
|
22
|
+
export function computePopoverPosition({
|
|
23
|
+
anchor,
|
|
24
|
+
dialog,
|
|
25
|
+
viewport,
|
|
26
|
+
position = "bottom",
|
|
27
|
+
align = "start",
|
|
28
|
+
offset = DEFAULT_OFFSET,
|
|
29
|
+
autoFlip = true,
|
|
30
|
+
edgePadding = DEFAULT_EDGE_PADDING
|
|
31
|
+
}) {
|
|
32
|
+
const a = anchor
|
|
33
|
+
const d = dialog
|
|
34
|
+
const vw = viewport.width
|
|
35
|
+
const vh = viewport.height
|
|
36
|
+
const off = Number.isFinite(offset) ? offset : DEFAULT_OFFSET
|
|
37
|
+
|
|
38
|
+
let resolved = position
|
|
39
|
+
|
|
40
|
+
if (autoFlip) {
|
|
41
|
+
if (resolved === "bottom" && a.bottom + off + d.height > vh && a.top - off - d.height >= 0) resolved = "top"
|
|
42
|
+
else if (resolved === "top" && a.top - off - d.height < 0 && a.bottom + off + d.height <= vh) resolved = "bottom"
|
|
43
|
+
else if (resolved === "right" && a.right + off + d.width > vw && a.left - off - d.width >= 0) resolved = "left"
|
|
44
|
+
else if (resolved === "left" && a.left - off - d.width < 0 && a.right + off + d.width <= vw) resolved = "right"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let top, left
|
|
48
|
+
if (resolved === "bottom" || resolved === "top") {
|
|
49
|
+
top = resolved === "bottom" ? a.bottom + off : a.top - off - d.height
|
|
50
|
+
if (align === "center") left = a.left + (a.width / 2) - (d.width / 2)
|
|
51
|
+
else if (align === "end") left = a.right - d.width
|
|
52
|
+
else left = a.left
|
|
53
|
+
// Clamp on the parallel (cross) axis.
|
|
54
|
+
left = Math.max(edgePadding, Math.min(left, vw - d.width - edgePadding))
|
|
55
|
+
} else {
|
|
56
|
+
left = resolved === "right" ? a.right + off : a.left - off - d.width
|
|
57
|
+
if (align === "center") top = a.top + (a.height / 2) - (d.height / 2)
|
|
58
|
+
else if (align === "end") top = a.bottom - d.height
|
|
59
|
+
else top = a.top
|
|
60
|
+
top = Math.max(edgePadding, Math.min(top, vh - d.height - edgePadding))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return { top, left, resolvedPosition: resolved }
|
|
64
|
+
}
|