Files
notion-theme/gitbook/components/NavPostItem.js

91 lines
2.7 KiB
JavaScript

import Badge from '@/components/Badge'
import Collapse from '@/components/Collapse'
import { siteConfig } from '@/lib/config'
import { useEffect, useState } from 'react'
import BlogPostCard from './BlogPostCard'
/**
* 導覽列表
* @param posts 所有文章
* @param tags 所有標籤
* @returns {JSX.Element}
* @constructor
*/
const NavPostItem = props => {
const { group, expanded, toggleItem } = props // 接收傳入的展開狀態與切換函式
const hoverExpand = siteConfig('GITBOOK_FOLDER_HOVER_EXPAND')
const [isTouchDevice, setIsTouchDevice] = useState(false)
// 偵測是否為觸控裝置
useEffect(() => {
const checkTouchDevice = () => {
if (window.matchMedia('(pointer: coarse)').matches) {
setIsTouchDevice(true)
}
}
checkTouchDevice()
// 選用:監聽視窗尺寸變化時重新檢測
window.addEventListener('resize', checkTouchDevice)
return () => {
window.removeEventListener('resize', checkTouchDevice)
}
}, [])
// 當展開狀態改變時觸發切換函式並同步內部狀態
const toggleOpenSubMenu = () => {
toggleItem() // 呼叫父元件傳入的切換函式
}
const onHoverToggle = () => {
// 允許滑鼠懸停時自動展開,而非點擊
if (!hoverExpand || isTouchDevice) {
return
}
toggleOpenSubMenu()
}
const groupHasLatest = group?.items?.some(post => post.isLatest)
if (group?.category) {
return (
<>
<div
onMouseEnter={onHoverToggle}
onClick={toggleOpenSubMenu}
className='cursor-pointer relative flex justify-between text-md p-2 hover:bg-gray-50 rounded-md dark:hover:bg-yellow-100 dark:hover:text-yellow-600'
key={group?.category}>
<span className={`${expanded && 'font-semibold'}`}>
{group?.category}
</span>
<div className='inline-flex items-center select-none pointer-events-none '>
<i
className={`px-2 fas fa-chevron-left transition-all opacity-50 duration-700 ${expanded ? '-rotate-90' : ''}`}></i>
</div>
{groupHasLatest &&
siteConfig('GITBOOK_LATEST_POST_RED_BADGE') &&
!expanded && <Badge />}
</div>
<Collapse isOpen={expanded} onHeightChange={props.onHeightChange}>
{group?.items?.map((post, index) => (
<div key={index} className='ml-3 border-l'>
<BlogPostCard className='ml-3' post={post} />
</div>
))}
</Collapse>
</>
)
} else {
return (
<>
{group?.items?.map((post, index) => (
<div key={index}>
<BlogPostCard className='text-md py-2' post={post} />
</div>
))}
</>
)
}
}
export default NavPostItem