aboutsummaryrefslogtreecommitdiff
path: root/p
diff options
context:
space:
mode:
authorGravatar Inverle <inverle@proton.me> 2025-12-21 14:02:27 +0100
committerGravatar GitHub <noreply@github.com> 2025-12-21 14:02:27 +0100
commitf387abe2c4b6668cb507ba2377f8b141e5818ca9 (patch)
tree74e6bc47f86d63e7ab741566037195d506e58020 /p
parentaf1e5cb9bc0c81e36a095b70073f0d23cf4554a9 (diff)
Display sidebar dropdowns above if no space below (#8335)
Closes https://github.com/FreshRSS/FreshRSS/issues/7801
Diffstat (limited to 'p')
-rw-r--r--p/scripts/main.js25
-rw-r--r--p/themes/base-theme/frss.css5
-rw-r--r--p/themes/base-theme/frss.rtl.css5
3 files changed, 34 insertions, 1 deletions
diff --git a/p/scripts/main.js b/p/scripts/main.js
index 570785832..0cdc4d387 100644
--- a/p/scripts/main.js
+++ b/p/scripts/main.js
@@ -1083,7 +1083,7 @@ function init_column_categories() {
a = ev.target.closest('.tree-folder-items > .feed .dropdown-toggle');
if (a) {
const div = a.parentElement;
- const dropdownMenu = div.querySelector('.dropdown-menu');
+ let dropdownMenu = div.querySelector('.dropdown-menu');
if (!dropdownMenu) {
loadJs('extra.js');
@@ -1095,6 +1095,8 @@ function init_column_categories() {
const template = document.getElementById(templateId)
.innerHTML.replace(/------/g, id).replace('http://example.net/', feed_web);
div.insertAdjacentHTML('beforeend', template);
+ dropdownMenu = div.querySelector('.dropdown-menu');
+ dropdownMenu.style.opacity = '0%'; // Hide initially to prevent dropdown flashing
if (feed_web == '') {
const website = div.querySelector('.item.link.website');
if (website) {
@@ -1106,6 +1108,27 @@ function init_column_categories() {
b.disabled = false;
}
}
+
+ window.addEventListener('hashchange', () => {
+ const dropdownBottom = dropdownMenu.getBoundingClientRect().bottom;
+ const toggleHeight = a.getBoundingClientRect().height;
+
+ // If there is no space to display the dropdown below, display it above
+ if (dropdownBottom > window.innerHeight) {
+ dropdownMenu.style.bottom = `${toggleHeight + 2}px`;
+ dropdownMenu.classList.add('arrow-bottom');
+ }
+
+ dropdownMenu.style.opacity = '';
+
+ // Wait for dropdown to be closed so it can be removed
+ // Dropdown visibility is based on CSS :target
+ window.addEventListener('hashchange', () => {
+ dropdownMenu.nextElementSibling.remove(); // dropdown close
+ dropdownMenu.remove();
+ }, { once: true });
+ }, { once: true });
+
return true;
}
diff --git a/p/themes/base-theme/frss.css b/p/themes/base-theme/frss.css
index b02ba9305..4d3dac4ea 100644
--- a/p/themes/base-theme/frss.css
+++ b/p/themes/base-theme/frss.css
@@ -829,6 +829,11 @@ input[type="checkbox"]:focus-visible {
transform: rotate(45deg);
}
+.dropdown-menu.arrow-bottom::after {
+ top: unset;
+ transform: rotate(225deg);
+}
+
.horizontal-list.bottom .dropdown-menu::after {
left: 0.5rem;
right: auto;
diff --git a/p/themes/base-theme/frss.rtl.css b/p/themes/base-theme/frss.rtl.css
index 2a386588c..774baff49 100644
--- a/p/themes/base-theme/frss.rtl.css
+++ b/p/themes/base-theme/frss.rtl.css
@@ -829,6 +829,11 @@ input[type="checkbox"]:focus-visible {
transform: rotate(-45deg);
}
+.dropdown-menu.arrow-bottom::after {
+ top: unset;
+ transform: rotate(-225deg);
+}
+
.horizontal-list.bottom .dropdown-menu::after {
right: 0.5rem;
left: auto;