mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
fix(sidebar): align collapsed settings skeletons with actual icon positions
This commit is contained in:
@@ -205,96 +205,101 @@ export function SettingsSidebar({
|
||||
!isCollapsed && 'overflow-y-auto overflow-x-hidden'
|
||||
)}
|
||||
>
|
||||
{sessionLoading || orgsLoading
|
||||
? isCollapsed
|
||||
? Array.from({ length: 7 }, (_, i) => (
|
||||
{sessionLoading || orgsLoading ? (
|
||||
isCollapsed ? (
|
||||
<div className='flex flex-col gap-[2px] px-[8px]'>
|
||||
{Array.from({ length: 7 }, (_, i) => (
|
||||
<div key={i} className='mx-[2px] flex h-[30px] items-center px-[8px]'>
|
||||
<Skeleton className='h-[16px] w-[16px] rounded-[4px]' />
|
||||
</div>
|
||||
))
|
||||
: Array.from({ length: 3 }, (_, i) => (
|
||||
<div key={i} className='sidebar-collapse-hide flex flex-shrink-0 flex-col'>
|
||||
<div className='px-[16px] pb-[6px]'>
|
||||
<Skeleton className='h-[14px] w-[64px] rounded-[4px]' />
|
||||
</div>
|
||||
<div className='flex flex-col gap-[2px] px-[8px]'>
|
||||
{Array.from({ length: i === 0 ? 3 : 2 }, (_, j) => (
|
||||
<div key={j} className='mx-[2px] flex h-[30px] items-center px-[8px]'>
|
||||
<Skeleton className='h-[24px] w-full rounded-[4px]' />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
Array.from({ length: 3 }, (_, i) => (
|
||||
<div key={i} className='sidebar-collapse-hide flex flex-shrink-0 flex-col'>
|
||||
<div className='px-[16px] pb-[6px]'>
|
||||
<Skeleton className='h-[14px] w-[64px] rounded-[4px]' />
|
||||
</div>
|
||||
))
|
||||
: sectionConfig.map(({ key, title }) => {
|
||||
const sectionItems = navigationItems.filter((item) => item.section === key)
|
||||
if (sectionItems.length === 0) return null
|
||||
|
||||
return (
|
||||
<div key={key} className='flex flex-shrink-0 flex-col'>
|
||||
{!isCollapsed && (
|
||||
<div className='sidebar-collapse-remove px-[16px] pb-[6px]'>
|
||||
<div className='font-base text-[var(--text-icon)] text-small'>{title}</div>
|
||||
<div className='flex flex-col gap-[2px] px-[8px]'>
|
||||
{Array.from({ length: i === 0 ? 3 : 2 }, (_, j) => (
|
||||
<div key={j} className='mx-[2px] flex h-[30px] items-center px-[8px]'>
|
||||
<Skeleton className='h-[24px] w-full rounded-[4px]' />
|
||||
</div>
|
||||
)}
|
||||
<div className='flex flex-col gap-[2px] px-[8px]'>
|
||||
{sectionItems.map((item) => {
|
||||
const Icon = item.icon
|
||||
const active = activeSection === item.id
|
||||
const itemClassName = cn(
|
||||
'group mx-[2px] flex h-[30px] items-center gap-[8px] rounded-[8px] px-[8px] text-[14px] hover:bg-[var(--surface-active)]',
|
||||
active && 'bg-[var(--surface-active)]'
|
||||
)
|
||||
const content = (
|
||||
<>
|
||||
<Icon className='h-[16px] w-[16px] flex-shrink-0 text-[var(--text-icon)]' />
|
||||
<span className='truncate font-base text-[var(--text-body)]'>
|
||||
{item.label}
|
||||
</span>
|
||||
</>
|
||||
)
|
||||
|
||||
const element = item.externalUrl ? (
|
||||
<a
|
||||
href={item.externalUrl}
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
className={itemClassName}
|
||||
>
|
||||
{content}
|
||||
</a>
|
||||
) : (
|
||||
<button
|
||||
type='button'
|
||||
className={itemClassName}
|
||||
onMouseEnter={() => handlePrefetch(item.id)}
|
||||
onFocus={() => handlePrefetch(item.id)}
|
||||
onClick={() =>
|
||||
router.replace(
|
||||
getSettingsHref({ section: item.id as SettingsSection }),
|
||||
{ scroll: false }
|
||||
)
|
||||
}
|
||||
>
|
||||
{content}
|
||||
</button>
|
||||
)
|
||||
|
||||
return (
|
||||
<Tooltip.Root key={`${item.id}-${isCollapsed}`}>
|
||||
<Tooltip.Trigger asChild>{element}</Tooltip.Trigger>
|
||||
{showCollapsedContent && (
|
||||
<Tooltip.Content side='right'>
|
||||
<p>{item.label}</p>
|
||||
</Tooltip.Content>
|
||||
)}
|
||||
</Tooltip.Root>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
))
|
||||
)
|
||||
) : (
|
||||
sectionConfig.map(({ key, title }) => {
|
||||
const sectionItems = navigationItems.filter((item) => item.section === key)
|
||||
if (sectionItems.length === 0) return null
|
||||
|
||||
return (
|
||||
<div key={key} className='flex flex-shrink-0 flex-col'>
|
||||
{!isCollapsed && (
|
||||
<div className='sidebar-collapse-remove px-[16px] pb-[6px]'>
|
||||
<div className='font-base text-[var(--text-icon)] text-small'>{title}</div>
|
||||
</div>
|
||||
)}
|
||||
<div className='flex flex-col gap-[2px] px-[8px]'>
|
||||
{sectionItems.map((item) => {
|
||||
const Icon = item.icon
|
||||
const active = activeSection === item.id
|
||||
const itemClassName = cn(
|
||||
'group mx-[2px] flex h-[30px] items-center gap-[8px] rounded-[8px] px-[8px] text-[14px] hover:bg-[var(--surface-active)]',
|
||||
active && 'bg-[var(--surface-active)]'
|
||||
)
|
||||
const content = (
|
||||
<>
|
||||
<Icon className='h-[16px] w-[16px] flex-shrink-0 text-[var(--text-icon)]' />
|
||||
<span className='truncate font-base text-[var(--text-body)]'>
|
||||
{item.label}
|
||||
</span>
|
||||
</>
|
||||
)
|
||||
|
||||
const element = item.externalUrl ? (
|
||||
<a
|
||||
href={item.externalUrl}
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
className={itemClassName}
|
||||
>
|
||||
{content}
|
||||
</a>
|
||||
) : (
|
||||
<button
|
||||
type='button'
|
||||
className={itemClassName}
|
||||
onMouseEnter={() => handlePrefetch(item.id)}
|
||||
onFocus={() => handlePrefetch(item.id)}
|
||||
onClick={() =>
|
||||
router.replace(getSettingsHref({ section: item.id as SettingsSection }), {
|
||||
scroll: false,
|
||||
})
|
||||
}
|
||||
>
|
||||
{content}
|
||||
</button>
|
||||
)
|
||||
|
||||
return (
|
||||
<Tooltip.Root key={`${item.id}-${isCollapsed}`}>
|
||||
<Tooltip.Trigger asChild>{element}</Tooltip.Trigger>
|
||||
{showCollapsedContent && (
|
||||
<Tooltip.Content side='right'>
|
||||
<p>{item.label}</p>
|
||||
</Tooltip.Content>
|
||||
)}
|
||||
</Tooltip.Root>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user