mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
* tip tap version 2 * youtube * menu-bar * refactorng layout * fixed flex layout * fixed flex layout * a lot of ui fixes * optimizing flex layout & styling inputs * markdown styling * fix linting * updated snapshots * layout optimization * flex layout optimizations, text editor fine tuning and markdown rendering * updated snapshots --------- Co-authored-by: Anton Tranelis <mail@antontranelis.de> Co-authored-by: Anton Tranelis <31516529+antontranelis@users.noreply.github.com>
66 lines
1.8 KiB
TypeScript
66 lines
1.8 KiB
TypeScript
/* eslint-disable security/detect-object-injection */
|
|
import { useState, useEffect, useCallback } from 'react'
|
|
import { useLocation, useNavigate } from 'react-router-dom'
|
|
|
|
interface TabItem {
|
|
title: string
|
|
component: React.ReactNode
|
|
}
|
|
|
|
interface TabsProps {
|
|
items: TabItem[]
|
|
setUrlParams: (params: URLSearchParams) => void
|
|
}
|
|
|
|
export const Tabs: React.FC<TabsProps> = ({ items, setUrlParams }: TabsProps) => {
|
|
const location = useLocation()
|
|
const navigate = useNavigate()
|
|
|
|
const [activeIndex, setActiveIndex] = useState<number>(0)
|
|
|
|
useEffect(() => {
|
|
const params = new URLSearchParams(location.search)
|
|
const urlTab = params.get('tab')
|
|
if (urlTab !== null && !isNaN(Number(urlTab))) {
|
|
const index = Number(urlTab)
|
|
if (index >= 0 && index < items.length) {
|
|
setActiveIndex(index)
|
|
}
|
|
}
|
|
}, [items.length, location.search])
|
|
|
|
const updateActiveTab = useCallback(
|
|
(index: number) => {
|
|
setActiveIndex(index)
|
|
|
|
const params = new URLSearchParams(location.search)
|
|
params.set('tab', `${index}`)
|
|
setUrlParams(params)
|
|
const newUrl = location.pathname + '?' + params.toString()
|
|
|
|
navigate(newUrl, { replace: false })
|
|
},
|
|
[location.pathname, location.search, navigate, setUrlParams],
|
|
)
|
|
|
|
return (
|
|
<div className='tw:flex tw:flex-col tw:flex-1 tw:min-h-0'>
|
|
<div role='tablist' className='tw:tabs tw:tabs-lift tw:flex-none'>
|
|
{items.map((item, index) => (
|
|
<div
|
|
key={index}
|
|
role='tab'
|
|
className={`tw:tab ${index === activeIndex ? 'tw:tab-active' : ''}`}
|
|
onClick={() => updateActiveTab(index)}
|
|
>
|
|
{item.title}
|
|
</div>
|
|
))}
|
|
</div>
|
|
<div className='tw:flex-1 tw:flex tw:flex-col tw:min-h-0'>
|
|
{items[activeIndex]?.component}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|