I have a list of items (Example names). I am trying to show the selected item in the list.
.Selected items have a selected class which will add a border to that element.
.selected {
border: 1px solid blue;
}
selected Item decide with a variable const selectedItem = 1; if it 1 it will select second item .If const selectedItem = 0; it will select first element.
Problem & statement
- I have wrapper div
className="container"which has width200px. It will contain as much as list element it can. It depends on Item width.
Example list Item (see example 1 it only shows three Items as all text are small.)
const data = [
{ title: "xahsdha" },
{ title: "hello" },
{ title: "hessllo" },
{ title: "hesslssslo" },
{ title: "navveiii" }
];
Example 2 with new data: See Item first text is big. It shows only one item.
const data = [
{ title: "xahsdhaadasdasdasdass" },
{ title: "hello" },
{ title: "hessllo" },
{ title: "hesslssslo" },
{ title: "navveiii" }
];
Issue:
I am not able to select that item that goes outside the container.
Example given data
const data = [
{ title: "xahsdh" },
{ title: "hello" },
{ title: "hessllo" },
{ title: "hesslssslo" },
{ title: "navveiii" }
];
if I give const selectedItem = 1;
my output and expected out are the same. see I am able to show selected Item

but if I give const selectedItem = 3; with same data set my output is this
But the expected output is this

can we move forward the hidden element if it is selected ?
Scenario 2
- we need to take care of hidden element width also .so selected item width depends on how many items I will show in the container.
example if we pass const selectedItem = 3;
with this data set
const data = [
{ title: "xahsdh" },
{ title: "hello" },
{ title: "hessllo" },
{ title: "hesslsssloasdasdasdasdasdsa" },
{ title: "navveiii" }
];
is this functionality feasible?
here is my code https://codesandbox.io/s/unruffled-hellman-hswdl?file=/src/App.js
import "./styles.css";
import React, { createRef, useMemo, useRef } from "react";
const data = [
{ title: "xahsdh" },
{ title: "hello" },
{ title: "hessllo" },
{ title: "hesslssslo" },
{ title: "navveiii" }
];
const selectedItem = 1;
export default function App() {
const arrLength = data.length;
const [defaultState, setDefaultState] = React.useState(true);
const elRefs = useMemo(
() => Array.from({ length: data.length }).map(() => createRef()),
[]
);
const [state, setState] = React.useState({
total: 0,
tabWidth: 0,
dimension: {}
});
const ulRef = useRef(null);
React.useEffect(() => {
setDimention();
}, []);
const setDimention = () => {
let total = ulRef.current.offsetWidth,
dimension = {},
tabWidth = 0;
console.log(total);
elRefs.forEach((item, i) => {
dimension[i] = item.current?.offsetWidth || 0;
tabWidth += item.current?.offsetWidth || 0;
});
console.log({
total,
dimension,
tabWidth
});
setDefaultState(false);
setState({
total,
dimension,
tabWidth
});
};
const getTabs = () => {
const { tabWidth, dimension, total } = state;
var visible = [],
avaiable = total,
hidden = [];
if (defaultState) {
return {
visible,
hidden
};
}
data.forEach((element, index) => {
if (avaiable - dimension[index] > 0) {
visible.push(element);
avaiable = avaiable - dimension[index];
} else {
hidden.push(element);
}
});
return {
visible,
hidden
};
};
const { visible = [], hidden = [] } = getTabs();
return (
<div className="container" ref={ulRef}>
<ul id="dummy">
{visible.length === 0 &&
hidden.length === 0 &&
data.map((el, i) => (
<li
className={i === selectedItem ? "selected" : ""}
ref={elRefs[i]}
key={i}
>
{el.title}
</li>
))}
</ul>
<ul id="visible">
{visible.map((el, i) => (
<li className={i === selectedItem ? "selected" : ""} key={i}>
{el.title}
</li>
))}
</ul>
<ul id="hidden">
{hidden.map((el, i) => (
<li className="hide" key={i}>
{el.title}
</li>
))}
</ul>
</div>
);
}
NOTE & update:I don't want scrollable list . I want first priority given to "selected" item and if space available add other element in front .
Any suggestion ?
In jQuery it is possible .so sure whether we achieve this in react or not.I checked this jQuery example selected item is in last but still it come in view



