diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index f4de696c2..78364ab7b 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -63,7 +63,7 @@ module SettingsHelper previous_setting = adjacent_setting(request.path, -1) next_setting = adjacent_setting(request.path, 1) - content_tag :div, class: "md:hidden flex flex-col gap-4" do + content_tag :div, class: "md:hidden flex flex-col gap-4 pb-[env(safe-area-inset-bottom)]" do concat(previous_setting) concat(next_setting) end diff --git a/app/javascript/controllers/sankey_chart_controller.js b/app/javascript/controllers/sankey_chart_controller.js index 5a1b9bb44..15cbf374b 100644 --- a/app/javascript/controllers/sankey_chart_controller.js +++ b/app/javascript/controllers/sankey_chart_controller.js @@ -349,7 +349,7 @@ export default class extends Controller { const dialog = this.element.closest("dialog"); this.tooltip = d3.select(dialog || document.body) .append("div") - .attr("class", "bg-gray-700 text-white text-sm p-2 rounded pointer-events-none absolute z-50") + .attr("class", "bg-gray-700 text-white text-sm p-2 rounded pointer-events-none absolute z-50 top-0") .style("opacity", 0) .style("pointer-events", "none"); } diff --git a/app/javascript/controllers/viewport_controller.js b/app/javascript/controllers/viewport_controller.js new file mode 100644 index 000000000..c8b9100f4 --- /dev/null +++ b/app/javascript/controllers/viewport_controller.js @@ -0,0 +1,46 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["content", "bottomNav"] + + connect() { + this.updateViewport() + this.updateBottomSpacing() + + window.addEventListener("resize", this.handleResize) + window.addEventListener("orientationchange", this.handleResize) + + if (this.hasBottomNavTarget) { + this.resizeObserver = new ResizeObserver(() => { + this.updateBottomSpacing() + }) + this.resizeObserver.observe(this.bottomNavTarget) + } + } + + disconnect() { + window.removeEventListener("resize", this.handleResize) + window.removeEventListener("orientationchange", this.handleResize) + + if (this.resizeObserver) { + this.resizeObserver.disconnect() + } + } + + handleResize = () => { + this.updateViewport() + this.updateBottomSpacing() + } + + updateViewport() { + const height = window.innerHeight + document.documentElement.style.setProperty("--app-height", `${height}px`) + } + + updateBottomSpacing() { + if (!this.hasBottomNavTarget || !this.hasContentTarget) return + + const navHeight = this.bottomNavTarget.offsetHeight + this.contentTarget.style.paddingBottom = `${navHeight}px` + } +} diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index cd79700e3..32b76a0ae 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -44,7 +44,7 @@ end %> <%# MOBILE - Top nav %> -