I am working on one small part where I have to show some divs
horizontally, so when it goes out of the space I am using css as overflow-x:auto
so that it becomes scrollable.
What I did
<div className="App d-flex">
{data.map((li) => {
return (
<div key={li.id} className="boxes">
{li.name}
</div>
);
})}
</div>
My CSS below
.d-flex {
display: flex;
}
.boxes {
padding: 12px;
margin: 4px;
background-color: rgb(196, 218, 243);
min-width: 150px;
overflow-x: auto;
text-align: center;
border-radius: 6px;
}
What I am trying to do
- I want to put dots there so that when user clicks on dots it should scroll.
- the dots should trigger only when exceeded a number of items, means if there are less items which can be shown on one screen then no dots or else dots.
- Here I am not getting the idea how can I do this using react-hooks.
I want to show number of dots for each page , suppose on one page there are four divs so these can be shown in one page and no dots will be there, but when divs are 8 so it will come in two pages or three so 2-3 dots will come and when i click it should scroll to respective page as shown in picture.
4
Answers
Solve the problem first. Code next.
Solution
Observe the container div, the first box’s div, and the last box’s div and change the UI accordingly.
Keep booleans (simple variables are fine, state not needed) to check if the left button and right button are visible or not, by comparing against the container (if they are sticking or not).
Code (idea)
Use
ref
to get the DOM nodes, (instead ofdocument.getElem...
, you know). Get their position and dimensions usingmyRef.current.getBoundingClientRect()
.Pseudocode:
You’ll need to add the buttons,
overflow
,max-width
properties and the onClick scroll, of course.PS: One purpose of
ref
is to act as an alternative todocument.getElementById
.You’ll need:
CSS is as follows
Use the Resive Observer API to listen for when either container gets resized. The outer container will be resized when the viewport size changes, while the inner container will be resized when the content changes.
Then just show the navigation menu if the inner container is larger than the outer container.
In the example below, I use arrows and just scroll left and right to simplify. Making those dots is more complex since it involves calculating how many dots to show, and keeping track of their state. I’m sure you can figure it out from there.
Snippet Example
Stackblitz Typescript example
https://stackblitz.com/edit/react-ts-rq7fnm?file=App.tsx
Try using Swiper, it covers this use case with its web components.
Here is the samples:
Using dots:
https://codesandbox.io/p/sandbox/uney2m?file=%2Findex.html
Using dynamic dots:
https://codesandbox.io/p/sandbox/49kqyp?file=%2Findex.html
Use the pagination clickable props to enable the functionality of moving to respective slide as shown in this example
https://codesandbox.io/p/sandbox/xp5tzz?file=%2Findex.html
Feel free to explore other types
https://swiperjs.com/demos
You can use a
react-magic-slider-dots
npm package and use your own CSS to match your design.I have implemented this for your reference. Please have a look at the working code sandbox example.