diff --git a/frappe/public/js/frappe/form/layout.js b/frappe/public/js/frappe/form/layout.js index a4647af480..e070e1db0b 100644 --- a/frappe/public/js/frappe/form/layout.js +++ b/frappe/public/js/frappe/form/layout.js @@ -482,10 +482,37 @@ frappe.ui.form.Layout = class Layout { } setup_events() { + let last_scroll = 0; + let tabs_list = $(".form-tabs-list"); + let tabs_content = this.tabs_content[0]; + if (!tabs_list.length) return; + + $(window).scroll( + frappe.utils.throttle(() => { + let current_scroll = document.documentElement.scrollTop; + if (current_scroll > 0 && last_scroll <= current_scroll) { + tabs_list.removeClass("form-tabs-sticky-down"); + tabs_list.addClass("form-tabs-sticky-up"); + } else { + tabs_list.removeClass("form-tabs-sticky-up"); + tabs_list.addClass("form-tabs-sticky-down"); + } + last_scroll = current_scroll; + }, 500) + ); + this.tab_link_container.off("click").on("click", ".nav-link", (e) => { e.preventDefault(); e.stopImmediatePropagation(); $(e.currentTarget).tab("show"); + if (tabs_content.getBoundingClientRect().top < 100) { + tabs_content.scrollIntoView(); + setTimeout(() => { + $(".page-head").css("top", "-15px"); + $(".form-tabs-list").removeClass("form-tabs-sticky-down"); + $(".form-tabs-list").addClass("form-tabs-sticky-up"); + }, 3); + } }); } diff --git a/frappe/public/js/frappe/ui/page.js b/frappe/public/js/frappe/ui/page.js index 2cb4f41038..b0df2d60fe 100644 --- a/frappe/public/js/frappe/ui/page.js +++ b/frappe/public/js/frappe/ui/page.js @@ -47,8 +47,7 @@ frappe.ui.Page = class Page { setup_scroll_handler() { let last_scroll = 0; - window.addEventListener( - "scroll", + $(window).scroll( frappe.utils.throttle(() => { $(".page-head").toggleClass("drop-shadow", !!document.documentElement.scrollTop); let current_scroll = document.documentElement.scrollTop; @@ -58,8 +57,7 @@ frappe.ui.Page = class Page { $(".page-head").css("top", "var(--navbar-height)"); } last_scroll = current_scroll; - }), - 500 + }, 500) ); } diff --git a/frappe/public/scss/desk/form.scss b/frappe/public/scss/desk/form.scss index 655c0a1539..183c4b9033 100644 --- a/frappe/public/scss/desk/form.scss +++ b/frappe/public/scss/desk/form.scss @@ -319,8 +319,13 @@ } .form-tabs-list { + position: sticky; + background-color: var(--card-bg); + z-index: 5; + transition: 0.5s top; padding-left: var(--padding-xs); - border-bottom: 1px solid var(--border-color); + border-bottom: 2px solid var(--border-color); + border-radius: var(--border-radius-md) var(--border-radius-md) 0 0; .form-tabs { .nav-item { @@ -338,6 +343,15 @@ } } } +.form-tab-content { + scroll-margin-top: calc(var(--navbar-height) + 52px); +} +.form-tabs-sticky-up { + top: calc(var(--navbar-height) - 1px); +} +.form-tabs-sticky-down { + top: calc(var(--navbar-height) + var(--page-head-height) - 1px); +} .progress-area { padding-top: var(--padding-md);