frnak
(Frank Cassata)
July 5, 2024, 4:38pm
1
I have an NSPanel Pro with a simple dashboard, on which there is a paper-buttons-row that is sidescrollable after adding overflow-x: scroll to the styles section.
The most used buttons are on the far left, and it is not reasonable that users scroll it back after accessing buttons out of sight.
So is it possible to have something listen to if it is scrolled, wait a set amount of time, and then scroll it back? ChatGPT was extremely confident but none of that stuff worked. Here is the basic card, and then just buttons repeated…
type: custom:paper-buttons-row
styles:
justify-content: start
align-items: center
flex-direction: row
gap: 12px
margin-top: 32px
overflow-x: scroll
scroll-snap-type: x mandatory
buttons:
- name: ' '
icon: false
entity: switch.esphome_web_a4db24_esp_dyrabjalla
ripple: none
styles:
button:
background-image: url('/local/png/key.png')
background-size: 100px
background-position: center
background-repeat: no-repeat
display: flex
min-width: 120px
height: 120px
border-radius: 34px
background-color: rgba(0,98,98,1)
1 Like
frnak
(Frank Cassata)
July 5, 2024, 8:42pm
2
I was able to do this by adding a custom javascript resource with this script, it looks for the paper-buttons-row, and the flex-box within it, can probably be altered to work for other scrollable containers.
Video, 10 second delay before scrolling back
console.log("Scroll Back Script Loaded");
function findElementInShadowRoot(element, selector) {
return element.shadowRoot ? element.shadowRoot.querySelector(selector) : null;
}
function onDocumentReady(callback) {
document.readyState === 'complete' || document.readyState === 'interactive' ? callback() : document.addEventListener('DOMContentLoaded', callback);
}
onDocumentReady(() => {
function findElementDeep(selector) {
function findDeep(element) {
if (!element) return null;
let found = element.querySelector(selector);
if (found) return found;
if (element.shadowRoot) {
found = element.shadowRoot.querySelector(selector);
if (found) return found;
for (const child of element.shadowRoot.children) {
found = findDeep(child);
if (found) return found;
}
}
for (const child of element.children) {
found = findDeep(child);
if (found) return found;
}
return null;
}
return findDeep(document.body);
}
const intervalId = setInterval(() => {
const paperButtonsRow = findElementDeep("paper-buttons-row");
if (paperButtonsRow) {
const flexBox = findElementInShadowRoot(paperButtonsRow, ".flex-box");
if (flexBox) {
clearInterval(intervalId);
addScrollBackFunctionality(flexBox);
} else {
console.log("Looking for flex-box in shadow DOM...");
}
} else {
console.log("Looking for paper-buttons-row...");
}
}, 1000);
});
function addScrollBackFunctionality(scrollContainer) {
let scrollBackTimeout;
const resetScrollBackTimeout = () => {
clearTimeout(scrollBackTimeout);
scrollBackTimeout = setTimeout(() => {
console.log("Scrolling back to start");
scrollContainer.scrollTo({ left: 0, behavior: 'smooth' });
}, 10000); // 10 seconds of inactivity
};
scrollContainer.addEventListener('scroll', () => {
if (scrollContainer.scrollLeft !== 0) {
resetScrollBackTimeout();
}
});
resetScrollBackTimeout(); // Initialize the timeout when the script runs
}
1 Like