加入transition过度动画

This commit is contained in:
tangly1024
2023-07-05 21:52:31 +08:00
parent 7c89871d98
commit 378a22a6c8
24 changed files with 262 additions and 132 deletions

View File

@@ -4,7 +4,7 @@ import Link from 'next/link'
import TwikooCommentCount from '@/components/TwikooCommentCount'
const BlogPostCard = ({ post }) => {
const showPageCover = CONFIG_EXAMPLE.POST_LIST_COVER
const showPageCover = CONFIG_EXAMPLE.POST_LIST_COVER && post?.pageCoverThumbnail
return <article className={`${showPageCover ? 'flex md:flex-row flex-col-reverse' : ''} replace mb-12 `}>
<div className={`${showPageCover ? 'md:w-7/12' : ''}`}>

View File

@@ -26,7 +26,7 @@ export const MenuItemDrop = ({ link }) => {
{/* 子菜单 */}
{hasSubMenu && <ul className={`${show ? 'visible opacity-100 top-12' : 'invisible opacity-0 top-10'} border-gray-100 bg-white dark:bg-black dark:border-gray-800 transition-all duration-300 z-20 absolute block drop-shadow-lg `}>
{link.subMenus.map((sLink, index) => {
return <li key={index} className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-2'>
return <li key={index} className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-3'>
<Link href={sLink.to}>
<span className='text-sm text-nowrap font-extralight'>{link?.icon && <i className={sLink?.icon} > &nbsp; </i>}{sLink.title}</span>
</Link>

View File

@@ -21,11 +21,11 @@ import ShareBar from '@/components/ShareBar'
import SearchInput from './components/SearchInput'
import Mark from 'mark.js'
import { isBrowser } from '@/lib/utils'
import LoadingCover from './components/LoadingCover'
import BlogListGroupByDate from './components/BlogListGroupByDate'
import CategoryItem from './components/CategoryItem'
import TagItem from './components/TagItem'
import { useRouter } from 'next/router'
import { Transition } from '@headlessui/react'
/**
* 基础布局框架
@@ -38,6 +38,14 @@ const LayoutBase = props => {
const { children, meta, slotTop } = props
const { onLoading } = useGlobal()
// 增加一个状态以触发 Transition 组件的动画
// const [showTransition, setShowTransition] = useState(true)
// useEffect(() => {
// // 当 location 或 children 发生变化时,触发动画
// setShowTransition(false)
// setTimeout(() => setShowTransition(true), 5)
// }, [onLoading])
return (
<div id='theme-example' className='dark:text-gray-300 bg-white dark:bg-black'>
{/* 网页SEO信息 */}
@@ -59,9 +67,21 @@ const LayoutBase = props => {
{/* 内容 */}
<div className='w-full max-w-3xl xl:px-14 lg:px-4 '>
{/* 嵌入模块 */}
{slotTop}
{onLoading ? <LoadingCover /> : children}
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
unmount={false}
>
{/* 嵌入模块 */}
{slotTop}
{children}
</Transition>
</div>
{/* 侧边栏 */}

View File

@@ -28,11 +28,10 @@ export default function ArticleDetail(props) {
<img alt={post.title} src={post?.pageCover} className='object-center w-full' />
</div>
)}
<article itemScope itemType="https://schema.org/Movie"
className="subpixel-antialiased overflow-y-hidden py-10 px-5 lg:pt-24 md:px-32 dark:border-gray-700 bg-white dark:bg-hexo-black-gray"
>
<header className='animate__slideInDown animate__animated'>
<article itemScope itemType="https://schema.org/Movie" className="subpixel-antialiased overflow-y-hidden py-10 px-5 lg:pt-24 md:px-32 dark:border-gray-700 bg-white dark:bg-hexo-black-gray" >
<header>
{/* 文章Title */}
<div className="font-bold text-4xl text-black dark:text-white">
@@ -41,7 +40,6 @@ export default function ArticleDetail(props) {
<section className="flex-wrap flex mt-2 text-gray-400 dark:text-gray-400 font-light leading-8">
<div>
{post?.category && (<>
<Link
href={`/category/${post.category}`}

View File

@@ -37,7 +37,7 @@ const TopNav = props => {
{/* 右侧功能 */}
<div className='mr-1 flex justify-end items-center text-sm space-x-4 font-serif dark:text-gray-200'>
<div onClick={toggleMenuOpen} className='cursor-pointer'>
<div onClick={toggleMenuOpen} className='cursor-pointer text-lg p-2'>
{isOpen ? <i className='fas fa-times' /> : <i className='fas fa-bars' />}
</div>
</div>

View File

@@ -10,7 +10,7 @@ const FUKA_CONFIG = {
MENU_ARCHIVE: true, // 显示归档
MENU_SEARCH: false, // 显示搜索
SIDEBAR_COLLAPSE_DEFAULT: false // 侧边栏默认折叠
SIDEBAR_OPEN_SATUS_DEFAULT: true // 侧边栏默认开启
}
export default FUKA_CONFIG

View File

@@ -8,7 +8,6 @@ import Live2D from '@/components/Live2D'
import BLOG from '@/blog.config'
import { isBrowser, loadExternalResource } from '@/lib/utils'
import { useGlobal } from '@/lib/global'
import LoadingCover from './components/LoadingCover'
import BlogListPage from './components/BlogListPage'
import BlogListScroll from './components/BlogListScroll'
import BlogArchiveItem from './components/BlogPostArchive'
@@ -16,9 +15,10 @@ import ArticleDetail from './components/ArticleDetail'
import { ArticleLock } from './components/ArticleLock'
import TagItemMini from './components/TagItemMini'
import { useRouter } from 'next/router'
import { createContext, useContext, useEffect, useMemo, useState } from 'react'
import { createContext, useContext, useEffect, useState } from 'react'
import Mark from 'mark.js'
import Link from 'next/link'
import { Transition } from '@headlessui/react'
// 主题全局状态
const ThemeGlobalFukasawa = createContext()
@@ -42,21 +42,14 @@ const LayoutBase = (props) => {
const { children, headerSlot, meta } = props
const leftAreaSlot = <Live2D />
const { onLoading } = useGlobal()
// 侧边栏折叠从 本地存储中获取 open 状态的初始值
// 侧边栏折叠从 本地存储中获取 open 状态的初始值
const [open, setOpen] = useState(() => {
if (typeof window !== 'undefined') {
return localStorage.getItem('fukasawa-sidebarOpen') === 'true' || FUKA_CONFIG.SIDEBAR_COLLAPSE_DEFAULT
return localStorage.getItem('fukasawa-sidebarOpen') === 'true' || FUKA_CONFIG.SIDEBAR_OPEN_SATUS_DEFAULT
}
return FUKA_CONFIG.SIDEBAR_COLLAPSE_DEFAULT
return FUKA_CONFIG.SIDEBAR_OPEN_SATUS_DEFAULT
})
const memoizedOpen = useMemo(() => open, [])
console.log('base', FUKA_CONFIG.SIDEBAR_COLLAPSE_DEFAULT, open, memoizedOpen)
if (isBrowser()) {
loadExternalResource('/css/theme-fukasawa.css', 'css')
}
// 在组件卸载时保存 open 状态到本地存储中
useEffect(() => {
@@ -65,6 +58,18 @@ const LayoutBase = (props) => {
}
}, [open])
// 增加一个状态以触发 Transition 组件的动画
const [showTransition, setShowTransition] = useState(true)
useEffect(() => {
// 当 location 或 children 发生变化时,触发动画
setShowTransition(false)
setTimeout(() => setShowTransition(true), 5)
}, [onLoading])
if (isBrowser()) {
loadExternalResource('/css/theme-fukasawa.css', 'css')
}
return (
<ThemeGlobalFukasawa.Provider value={{ open, setOpen }}>
@@ -78,8 +83,23 @@ const LayoutBase = (props) => {
<main id='wrapper' className='relative flex w-full py-8 justify-center bg-day dark:bg-night'>
<div id='container-inner' className='2xl:max-w-6xl md:max-w-4xl w-full relative z-10'>
<div> {headerSlot} </div>
<div> {onLoading ? <LoadingCover /> : children} </div>
<Transition
show={showTransition}
appear={true}
className="w-full"
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
unmount={false}
>
<div> {headerSlot} </div>
<div> {children} </div>
</Transition>
</div>
</main>

View File

@@ -38,7 +38,7 @@ export const MenuItemDrop = ({ link }) => {
{/* 子菜单 */}
{hasSubMenu && <ul className={`${show ? 'visible opacity-100 top-12 ' : 'invisible opacity-0 top-10 '} border-gray-100 bg-white dark:bg-black dark:border-gray-800 transition-all duration-300 z-20 absolute block drop-shadow-lg `}>
{link?.subMenus?.map((sLink, index) => {
return <li key={index} className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-2'>
return <li key={index} className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-3'>
<Link href={sLink.to}>
<span className='text-xs font-extralight'>{link?.icon && <i className={sLink?.icon} > &nbsp; </i>}{sLink.title}</span>
</Link>

View File

@@ -19,7 +19,6 @@ import PageNavDrawer from './components/PageNavDrawer'
import FloatTocButton from './components/FloatTocButton'
import { AdSlot } from '@/components/GoogleAdsense'
import JumpToTopButton from './components/JumpToTopButton'
import LoadingCover from './components/LoadingCover'
import ShareBar from '@/components/ShareBar'
import CategoryItem from './components/CategoryItem'
import TagItemMini from './components/TagItemMini'
@@ -28,6 +27,7 @@ import Comment from '@/components/Comment'
import TocDrawer from './components/TocDrawer'
import NotionPage from '@/components/NotionPage'
import { ArticleLock } from './components/ArticleLock'
import { Transition } from '@headlessui/react'
// 主题全局变量
const ThemeGlobalGitbook = createContext()
@@ -81,7 +81,20 @@ const LayoutBase = (props) => {
<div id='container-inner' className='w-full px-7 max-w-3xl justify-center mx-auto'>
{slotTop}
<AdSlot type='in-article' />
{onLoading ? <LoadingCover /> : children}
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
unmount={false}
>
{children}
</Transition>
<AdSlot type='in-article' />
{/* 回顶按钮 */}
<JumpToTopButton />
@@ -89,7 +102,7 @@ const LayoutBase = (props) => {
{/* 底部 */}
<div className='md:hidden'>
<Footer {...props}/>
<Footer {...props} />
</div>
<div className='text-center'>
<AdSlot type='native' />
@@ -144,22 +157,21 @@ const LayoutBase = (props) => {
*/
const LayoutIndex = (props) => {
const router = useRouter()
useEffect(() => {
router.push(CONFIG_GITBOOK.INDEX_PAGE).then(() => {
// console.log('跳转到指定首页', CONFIG_GITBOOK.INDEX_PAGE)
setTimeout(() => {
if (isBrowser()) {
const article = document.getElementById('notion-article')
if (!article) {
console.log('请检查您的Notion数据库中是否包含此slug页面 ', CONFIG_GITBOOK.INDEX_PAGE)
const containerInner = document.getElementById('container-inner')
const newHTML = `<h1 class="text-3xl pt-12 dark:text-gray-300">配置有误</h1><blockquote class="notion-quote notion-block-ce76391f3f2842d386468ff1eb705b92"><div>请在您的notion中添加一个slug为${CONFIG_GITBOOK.INDEX_PAGE}的文章</div></blockquote>`
containerInner?.insertAdjacentHTML('afterbegin', newHTML)
}
router.push(CONFIG_GITBOOK.INDEX_PAGE).then(() => {
// console.log('跳转到指定首页', CONFIG_GITBOOK.INDEX_PAGE)
setTimeout(() => {
if (isBrowser()) {
const article = document.getElementById('notion-article')
if (!article) {
console.log('请检查您的Notion数据库中是否包含此slug页面 ', CONFIG_GITBOOK.INDEX_PAGE)
const containerInner = document.getElementById('container-inner')
const newHTML = `<h1 class="text-3xl pt-12 dark:text-gray-300">配置有误</h1><blockquote class="notion-quote notion-block-ce76391f3f2842d386468ff1eb705b92"><div>请在您的notion中添加一个slug为${CONFIG_GITBOOK.INDEX_PAGE}的文章</div></blockquote>`
containerInner?.insertAdjacentHTML('afterbegin', newHTML)
}
}, 7 * 1000)
})
}, [])
}
}, 7 * 1000)
})
return <LayoutBase {...props}></LayoutBase>
}

View File

@@ -21,18 +21,10 @@ export default function HeaderArticle({ post, siteInfo }) {
return (
<div
id="header"
data-aos="fade-down"
data-aos-duration="300"
data-aos-once="true"
data-aos-anchor-placement="top-bottom"
className="w-full h-96 relative md:flex-shrink-0 overflow-hidden bg-cover bg-center bg-no-repeat z-10"
style={{ backgroundImage: headerImage }}
>
<header id='article-header-cover'
data-aos="fade-down"
data-aos-duration="300"
data-aos-once="true"
data-aos-anchor-placement="top-bottom"
className="bg-black bg-opacity-70 absolute top-0 w-full h-96 py-10 flex justify-center items-center ">
<div className='mt-10'>

View File

@@ -3,22 +3,30 @@ import { useRouter } from 'next/router'
import Card from './Card'
import SocialButton from './SocialButton'
import MenuGroupCard from './MenuGroupCard'
export function InfoCard (props) {
/**
* 社交信息卡
* @param {*} props
* @returns
*/
export function InfoCard(props) {
const { className, siteInfo } = props
const router = useRouter()
return <Card className={className}>
<div
className='justify-center items-center flex py-6 dark:text-gray-100 transform duration-200 cursor-pointer'
onClick={() => {
router.push('/')
}}
>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={siteInfo?.icon} className='rounded-full' width={120} alt={BLOG.AUTHOR}/>
</div>
<div className='font-medium text-center text-xl pb-4'>{BLOG.AUTHOR}</div>
<div className='text-sm text-center'>{BLOG.BIO}</div>
<MenuGroupCard {...props}/>
<SocialButton />
</Card>
return (
<Card className={className}>
<div
className='justify-center items-center flex py-6 dark:text-gray-100 transform duration-200 cursor-pointer'
onClick={() => {
router.push('/')
}}
>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={siteInfo?.icon} className='rounded-full' width={120} alt={BLOG.AUTHOR} />
</div>
<div className='font-medium text-center text-xl pb-4'>{BLOG.AUTHOR}</div>
<div className='text-sm text-center'>{BLOG.BIO}</div>
<MenuGroupCard {...props} />
<SocialButton />
</Card>
)
}

View File

@@ -29,7 +29,7 @@ export const MenuItemDrop = ({ link }) => {
{/* 子菜单 */}
{hasSubMenu && <ul style={{ backdropFilter: 'blur(3px)' }} className={`${show ? 'visible opacity-100 top-12' : 'invisible opacity-0 top-20'} drop-shadow-md overflow-hidden rounded-md bg-white transition-all duration-300 z-20 absolute block `}>
{link.subMenus.map((sLink, index) => {
return <li key={index} className='cursor-pointer hover:bg-indigo-300 text-gray-900 hover:text-black tracking-widest transition-all duration-200 dark:border-gray-800 py-1 pr-6 pl-2'>
return <li key={index} className='cursor-pointer hover:bg-indigo-300 text-gray-900 hover:text-black tracking-widest transition-all duration-200 dark:border-gray-800 py-1 pr-6 pl-3'>
<Link href={sLink.to}>
<span className='text-sm text-nowrap font-extralight'>{link?.icon && <i className={sLink?.icon} > &nbsp; </i>}{sLink.title}</span>
</Link>

View File

@@ -5,7 +5,6 @@ import { useEffect, useRef } from 'react'
import Footer from './components/Footer'
import SideRight from './components/SideRight'
import TopNav from './components/TopNav'
import LoadingCover from './components/LoadingCover'
import { useGlobal } from '@/lib/global'
import BLOG from '@/blog.config'
import { isBrowser, loadExternalResource } from '@/lib/utils'
@@ -32,6 +31,7 @@ import ShareBar from '@/components/ShareBar'
import TagItemMini from './components/TagItemMini'
import Link from 'next/link'
import SlotBar from './components/SlotBar'
import { Transition } from '@headlessui/react'
/**
* 基础布局 采用左右两侧布局,移动端使用顶部导航栏
@@ -57,16 +57,41 @@ const LayoutBase = props => {
<TopNav {...props} />
{/* 顶部嵌入 */}
{headerSlot}
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 -translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-16"
unmount={false}
>
{headerSlot}
</Transition>
{/* 主区块 */}
<main id="wrapper" className={`${CONFIG_HEXO.HOME_BANNER_ENABLE ? '' : 'pt-16'} bg-hexo-background-gray dark:bg-black w-full py-8 md:px-8 lg:px-24 min-h-screen relative`}>
<div id="container-inner" className={(BLOG.LAYOUT_SIDEBAR_REVERSE ? 'flex-row-reverse' : '') + ' w-full mx-auto lg:flex lg:space-x-4 justify-center relative z-10'} >
<div className={`${className || ''} w-full max-w-4xl h-full `}>
{/* 主区上部嵌入 */}
{slotTop}
{onLoading ? <LoadingCover /> : children}
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
unmount={false}
>
{/* 主区上部嵌入 */}
{slotTop}
{children}
</Transition>
</div>
{/* 右侧栏 */}

View File

@@ -4,23 +4,15 @@ export default function HeaderArticle({ post, siteInfo }) {
const headerImage = post?.pageCoverThumbnail ? post?.pageCoverThumbnail : siteInfo?.pageCover
const title = post?.title
return (
<div
data-aos="fade-down"
data-aos-duration="300"
data-aos-once="true"
data-aos-anchor-placement="top-center"
id='header' className="flex h-96 justify-center align-middle items-center w-full relative bg-black">
<div id='header' className="flex h-96 justify-center align-middle items-center w-full relative bg-black">
{/* eslint-disable-next-line @next/next/no-img-element */}
{/* <img
src={headerImage}
alt={title}
className="opacity-50 dark:opacity-40 h-full w-full object-cover"
/> */}
<Image alt={title} src={headerImage} fill
style={{ objectFit: 'cover' }}
className='opacity-50'
placeholder='blur'
blurDataURL='/bg_image.jpg' />
<Image alt={title} src={headerImage} fill style={{ objectFit: 'cover' }} className='opacity-50'
placeholder='blur' blurDataURL='/bg_image.jpg' />
<div className="leading-snug font-bold xs:text-4xl sm:text-4xl md:text-5xl md:leading-snug text-4xl shadow-text-md flex justify-center text-center text-white">
{title}
</div>

View File

@@ -29,7 +29,7 @@ export const MenuItemDrop = ({ link }) => {
{/* 子菜单 */}
{hasSubMenu && <ul style={{ backdropFilter: 'blur(3px)' }} className={`${show ? 'visible opacity-100 top-12' : 'invisible opacity-0 top-20'} drop-shadow-md overflow-hidden rounded-md bg-white transition-all duration-300 z-20 absolute block `}>
{link.subMenus.map(sLink => {
return <li key={sLink.id} className='cursor-pointer hover:bg-indigo-300 text-gray-900 hover:text-black tracking-widest transition-all duration-200 dark:border-gray-800 py-1 pr-6 pl-2'>
return <li key={sLink.id} className='cursor-pointer hover:bg-indigo-300 text-gray-900 hover:text-black tracking-widest transition-all duration-200 dark:border-gray-800 py-1 pr-6 pl-3'>
<Link href={sLink.to}>
<span className='text-sm text-nowrap font-extralight'>{link?.icon && <i className={sLink?.icon} > &nbsp; </i>}{sLink.title}</span>
</Link>

View File

@@ -2,7 +2,6 @@ import CONFIG_MATERY from './config_matery'
import CommonHead from '@/components/CommonHead'
import TopNav from './components/TopNav'
import Live2D from '@/components/Live2D'
import LoadingCover from './components/LoadingCover'
import { useGlobal } from '@/lib/global'
import BLOG from '@/blog.config'
import { isBrowser, loadExternalResource } from '@/lib/utils'
@@ -31,6 +30,7 @@ import BlogPostArchive from './components/BlogPostArchive'
import Card from './components/Card'
import JumpToCommentButton from './components/JumpToCommentButton'
import BlogListBar from './components/BlogListBar'
import { Transition } from '@headlessui/react'
/**
* 基础布局
@@ -56,7 +56,19 @@ const LayoutBase = props => {
<TopNav {...props} />
{/* 顶部嵌入 */}
{headerSlot}
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 -translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-16"
unmount={false}
>
{headerSlot}
</Transition>
<main id="wrapper" className={`${CONFIG_MATERY.HOME_BANNER_ENABLE ? '' : 'pt-16'} flex-1 w-full py-8 md:px-8 lg:px-24 relative`}>
{/* 嵌入区域 */}
@@ -64,8 +76,21 @@ const LayoutBase = props => {
{containerSlot}
</div>
<div id="container-inner" className="w-full max-w-6xl mx-auto lg:flex lg:space-x-4 justify-center relative z-10">
{onLoading ? <LoadingCover /> : children}
<div id="container-inner" className="w-full min-h-fit max-w-6xl mx-auto lg:flex lg:space-x-4 justify-center relative z-10">
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
unmount={false}
>
{children}
</Transition>
</div>
</main>

View File

@@ -38,7 +38,7 @@ export const MenuItemDrop = ({ link }) => {
{/* 子菜单 */}
{hasSubMenu && <ul className={`${show ? 'visible opacity-100 top-12 ' : 'invisible opacity-0 top-10 '} border-gray-100 bg-white dark:bg-black dark:border-gray-800 transition-all duration-300 z-20 absolute block drop-shadow-lg `}>
{link?.subMenus?.map(sLink => {
return <li key={sLink.id} className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-2'>
return <li key={sLink.id} className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-3'>
<Link href={sLink.to}>
<span className='text-xs font-extralight'>{link?.icon && <i className={sLink?.icon} > &nbsp; </i>}{sLink.title}</span>
</Link>

View File

@@ -15,7 +15,6 @@ import Live2D from '@/components/Live2D'
import BLOG from '@/blog.config'
import Announcement from './components/Announcement'
import JumpToTopButton from './components/JumpToTopButton'
import LoadingCover from './components/LoadingCover'
import BlogPostListPage from './components/BlogPostListPage'
import BlogPostListScroll from './components/BlogPostListScroll'
import Catalog from './components/Catalog'
@@ -34,6 +33,7 @@ import CategoryItem from './components/CategoryItem'
import TagItemMini from './components/TagItemMini'
import ShareBar from '@/components/ShareBar'
import Link from 'next/link'
import { Transition } from '@headlessui/react'
// 主题全局状态
const ThemeGlobalMedium = createContext()
@@ -69,9 +69,20 @@ const LayoutBase = props => {
<TopNavBar {...props} />
<div id='container-inner' className='px-7 max-w-5xl justify-center mx-auto min-h-screen'>
{slotTop}
{onLoading ? <LoadingCover /> : children}
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
unmount={false}
>
{slotTop}
{children}
</Transition>
<JumpToTopButton />
</div>

View File

@@ -5,7 +5,6 @@ import FloatDarkModeButton from './components/FloatDarkModeButton'
import Footer from './components/Footer'
import JumpToBottomButton from './components/JumpToBottomButton'
import JumpToTopButton from './components/JumpToTopButton'
import LoadingCover from './components/LoadingCover'
import SideAreaLeft from './components/SideAreaLeft'
import SideAreaRight from './components/SideAreaRight'
import TopNav from './components/TopNav'
@@ -27,6 +26,7 @@ import { useRouter } from 'next/router'
import ArticleDetail from './components/ArticleDetail'
import Link from 'next/link'
import BlogListBar from './components/BlogListBar'
import { Transition } from '@headlessui/react'
/**
* 基础布局 采用左中右三栏布局,移动端使用顶部导航栏
@@ -88,7 +88,19 @@ const LayoutBase = (props) => {
{/* 中央内容 */}
<section id='container-inner' className={`${CONFIG_NEXT.NAV_TYPE !== 'normal' ? 'mt-24' : ''} lg:max-w-3xl xl:max-w-4xl flex-grow md:mt-0 min-h-screen w-full relative z-10`} ref={targetRef}>
{onLoading ? <LoadingCover /> : <> {children}</>}
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
unmount={false}
>
{children}
</Transition>
</section>
{/* 右侧栏样式 */}

View File

@@ -31,7 +31,7 @@ export const MenuItemDrop = ({ link }) => {
{/* 子菜单 */}
{hasSubMenu && <ul className={`${show ? 'visible opacity-100 top-12 ' : 'invisible opacity-0 top-10 '} border-gray-100 bg-white dark:bg-black dark:border-gray-800 transition-all duration-300 z-20 absolute block drop-shadow-lg `}>
{link.subMenus.map(sLink => {
return <li key={sLink.id} className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-2'>
return <li key={sLink.id} className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-3'>
<Link href={sLink.to}>
<span className='text-sm text-nowrap font-extralight'>{link?.icon && <i className={sLink?.icon} > &nbsp; </i>}{sLink.title}</span>
</Link>

View File

@@ -44,7 +44,7 @@ const Nav = props => {
<div className="flex items-center">
<Link href="/" aria-label={BLOG.title}>
<div className="h-6">
<div className="h-6 w-6">
{/* <SvgIcon/> */}
{CONFIG_NOBELIUM.NAV_NOTION_ICON
/* eslint-disable-next-line @next/next/no-img-element */

View File

@@ -18,16 +18,15 @@ import Mark from 'mark.js'
import { deepClone, isBrowser } from '@/lib/utils'
import SearchNavBar from './components/SearchNavBar'
import BlogArchiveItem from './components/BlogArchiveItem'
import { ArticleLock } from './components/ArticleLock'
import NotionPage from '@/components/NotionPage'
import { ArticleInfo } from './components/ArticleInfo'
import Comment from '@/components/Comment'
import { ArticleFooter } from './components/ArticleFooter'
import ShareBar from '@/components/ShareBar'
import Link from 'next/link'
import BlogListBar from './components/BlogListBar'
import { Transition } from '@headlessui/react'
/**
* 基础布局 采用左右两侧布局,移动端使用顶部导航栏
@@ -41,11 +40,6 @@ const LayoutBase = props => {
const fullWidth = post?.fullWidth ?? false
const { onLoading } = useGlobal()
const LoadingCover = <div id='cover-loading' className={`${onLoading ? 'z-50 opacity-50' : '-z-10 opacity-0'} pointer-events-none transition-all duration-300`}>
<div className='w-full h-screen flex justify-center items-center'>
<i className="fa-solid fa-spinner text-2xl text-black dark:text-white animate-spin"> </i>
</div>
</div>
return (
<div id='theme-nobelium' className='nobelium relative dark:text-gray-300 w-full bg-white dark:bg-black min-h-screen'>
{/* SEO相关 */}
@@ -56,10 +50,22 @@ const LayoutBase = props => {
{/* 主区 */}
<main id='out-wrapper' className={`relative m-auto flex-grow w-full transition-all ${!fullWidth ? 'max-w-2xl px-4' : 'px-4 md:px-24'}`}>
{/* 顶部插槽 */}
{topSlot}
{onLoading ? LoadingCover : children}
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
unmount={false}
>
{/* 顶部插槽 */}
{topSlot}
{children}
</Transition>
</main>
@@ -114,7 +120,7 @@ const LayoutPostList = props => {
return (
<LayoutBase {...props} topSlot={<BlogListBar {...props} setFilterKey={setFilterKey} />}>
{BLOG.POST_LIST_STYLE === 'page' ? <BlogListPage {...props} posts={filteredBlogPosts}/> : <BlogListScroll {...props} posts={filteredBlogPosts}/>}
{BLOG.POST_LIST_STYLE === 'page' ? <BlogListPage {...props} posts={filteredBlogPosts} /> : <BlogListScroll {...props} posts={filteredBlogPosts} />}
</LayoutBase>
)
}

View File

@@ -1,14 +1,11 @@
import CONFIG_SIMPLE from './config_simple'
import { BlogListPage } from './components/BlogListPage'
import { BlogListScroll } from './components/BlogListScroll'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import Mark from 'mark.js'
import { isBrowser, loadExternalResource } from '@/lib/utils'
import BlogArchiveItem from './components/BlogArchiveItem'
import { ArticleLock } from './components/ArticleLock'
import NotionPage from '@/components/NotionPage'
import { ArticleInfo } from './components/ArticleInfo'
@@ -27,6 +24,7 @@ import JumpToTopButton from './components/JumpToTopButton'
import { Footer } from './components/Footer'
import { useGlobal } from '@/lib/global'
import SearchInput from './components/SearchInput'
import { Transition } from '@headlessui/react'
/**
* 基础布局
@@ -38,15 +36,6 @@ const LayoutBase = props => {
const { children, meta, slotTop } = props
const { onLoading } = useGlobal()
/**
* 路由跳转时的遮罩
*/
const LoadingCover = <div id='cover-loading' className={`${onLoading ? 'z-50 opacity-50' : '-z-10 opacity-0'} pointer-events-none transition-all duration-300`}>
<div className='w-full h-96 flex justify-center items-center'>
<i className="fa-solid fa-spinner text-2xl text-black dark:text-white animate-spin"> </i>
</div>
</div>
if (isBrowser()) {
loadExternalResource('/css/theme-simple.css', 'css')
}
@@ -64,9 +53,22 @@ const LayoutBase = props => {
{/* 主体 */}
<div id='container-wrapper' className={(BLOG.LAYOUT_SIDEBAR_REVERSE ? 'flex-row-reverse' : '') + ' w-full flex-1 flex items-start max-w-9/10 mx-auto pt-12'}>
<div id='container-inner ' className='w-full flex-grow'>
{slotTop}
{onLoading ? LoadingCover : children}
<div id='container-inner ' className='w-full flex-grow min-h-fit'>
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-16"
unmount={false}
>
{slotTop}
{children}
</Transition>
<AdSlot type='native' />
</div>