I haven't been able to find an answer to this question but I have seen this exact behaviour in many apps (calendars, agendas etc.). As you can see in the snippet below my container expands with scrolling to both sides - new divs are being inserted inside. When you scroll to the right it feels okay and natural, however, when you scroll to the left, it always adds the element and you stay at 0px needing to scroll a bit back and then to the left again to expand some more. Best if you try below:
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom/client';
function Test() {
const [span, setSpan] = useState<Array<number>>([-1, 0, 1]);
// Append item to the array - scrolling right
const append = () => {
setSpan([
...span,
span[span.length - 1] + 1,
]);
};
// Prepend item to the array - scrolling left
const prepend = () => {
setSpan([
span[0] - 1,
...span,
]);
};
// Center view on load - to the middle of element '0' - e.i. the center
useEffect(() => {
const element = document.getElementById('element-0');
if (element) {
element.scrollIntoView({ behavior: 'auto', inline: 'center' });
}
}, []);
// Register 'scroll' listener
useEffect(() => {
const element = document.getElementById('container');
const scrolling = () => {
if (element) {
if (element.scrollLeft === 0) {
prepend();
}
if (element.offsetWidth + element.scrollLeft >= (element.scrollWidth - 100)) {
append();
}
}
};
element.addEventListener('scroll', scrolling);
return () => {
element.removeEventListener('scroll', scrolling);
};
}, [span.length]);
return (
<div style={{
display: 'flex', alignItems: 'center', justifyContent: 'center',
}}
>
<div
id="container"
style={{
maxWidth: '50vw', maxHeight: '50vh', overflowX: 'auto', whiteSpace: 'nowrap', backgroundColor: 'red',
}}
>
<div style={{ width: 'fit-content' }}>
<div style={{ width: 'fit-content' }}>
<div style={{ display: 'flex' }}>
{span.map((element) => (
<div key={`element-${element}`} id={`element-${element}`} style={{ minWidth: '40vw', minHeight: '100vh', border: '1px solid black' }}>
{ element }
</div>
))}
</div>
</div>
</div>
</div>
</div>
);
}
const root = ReactDOM.createRoot(
document.getElementById('root')
);
root.render(
<React.StrictMode>
<Test />
</React.StrictMode>
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I tried programatically scrolling a bit to the right before prepending new item, but it only created more issues. Is there an easy way to solve it?

