I am trying to add tabs to an app. The tabs get smaller the more I add, how the tab text is just hidden instead of showing ellipses. Can anyone help? enter image description here enter image description here
const Tabs: React.FC = () => {
const [tabs, setTabs] = useState(["Tab 1"]);
const addNewTab = () => {
setTabs([...tabs, `Tab ${tabs.length + 1}`]);
};
return (
// outer div ensures that the tabs take up the remaining space in whatever view we use
<div className="flex-1 overflow-hidden">
<div className="flex overflow-hidden items-center h-8">
{tabs.map((tab, index) => (
// outer div so that when you hover over tab, it does not colour all the way to tab border
<div
key={index}
className="flex basis-40 justify-center items-center h-8 border-r px-1 border-gray-300 whitespace-nowrap overflow-hidden text-ellipsis"
>
<div
className="h-7 basis-36 flex items-center text-sm hover:bg-slate-300 rounded"
title={tab}
>
{tab}
</div>
</div>
))}
{/* add styling to button to ensure */}
<button
className="ml-2 hover:bg-slate-300 rounded flex items-center justify-center h-7 w-7 flex-shrink-0"
onClick={addNewTab}
>
<img src={AddIcon} alt="Add icon" className="h-5 w-5" />
</button>
</div>
</div>
);
};
export default Tabs;
The text truncation does not work in a flex layout context. You'd need to wrap the text in a non-flex layout and have the classes applied to that, like:
<span class="whitespace-nowrap overflow-hidden text-ellipsis">{tab}</span>
Furthermore, you'd want to apply min-width: 0
to override the min-width: min-content
of each of the flex layout children, so that they can properly shrink narrower than the text content, allowing for the truncation effect to be visible:
{tabs.map((tab, index) => (
// outer div so that when you hover over tab, it does not colour all the way to tab border
<div
key={index}
className="… min-w-0"
>
<div
className="… min-w-0"
title={tab}
>
<span class="whitespace-nowrap overflow-hidden text-ellipsis">{tab}</span>
const { useState } = React;
const AddIcon = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor' class='size-6'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M12 4.5v15m7.5-7.5h-15' /%3E%3C/svg%3E%0A";
const Tabs = () => {
const [tabs, setTabs] = useState(Array(20).fill().map((_, i) => `Tab ${i + 1}`));
const addNewTab = () => {
setTabs([...tabs, `Tab ${tabs.length + 1}`]);
};
return (
// outer div ensures that the tabs take up the remaining space in whatever view we use
<div className="flex-1 overflow-hidden">
<div className="flex overflow-hidden items-center h-8">
{tabs.map((tab, index) => (
// outer div so that when you hover over tab, it does not colour all the way to tab border
<div
key={index}
className="flex basis-40 justify-center items-center h-8 border-r px-1 border-gray-300 min-w-0"
>
<div
className="h-7 basis-36 flex items-center text-sm hover:bg-slate-300 rounded min-w-0"
title={tab}
>
<span className="whitespace-nowrap overflow-hidden text-ellipsis">{tab}</span>
</div>
</div>
))}
{/* add styling to button to ensure */}
<button
className="ml-2 hover:bg-slate-300 rounded flex items-center justify-center h-7 w-7 flex-shrink-0"
onClick={addNewTab}
>
<img src={AddIcon} alt="Add icon" className="h-5 w-5" />
</button>
</div>
</div>
);
};
ReactDOM.createRoot(document.getElementById('app')).render(<Tabs/>);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js" integrity="sha512-QVs8Lo43F9lSuBykadDb0oSXDL/BbZ588urWVCRwSIoewQv/Ewg1f84mK3U790bZ0FfhFa1YSQUmIhG+pIRKeg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js" integrity="sha512-6a1107rTlA4gYpgHAqbwLAtxmWipBdJFcq8y5S/aTge3Bp+VAklABm2LO+Kg51vOWR9JMZq1Ovjl5tpluNpTeQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com/3.4.5"></script>
<div id="app"></div>