mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 07:26:52 +00:00
Merge pull request #2498 from tangly1024/feat/theme-example-custom-config
Example主题支持配置:标题栏背景、文章页布局
This commit is contained in:
@@ -4,12 +4,13 @@ import { MenuList } from './MenuList'
|
||||
|
||||
/**
|
||||
* 网站顶部
|
||||
* LOGO 和 菜单
|
||||
* @returns
|
||||
*/
|
||||
export const Header = props => {
|
||||
return (
|
||||
<header className='w-full px-6 bg-white dark:bg-black relative z-20'>
|
||||
<div className='container mx-auto max-w-4xl md:flex justify-between items-center'>
|
||||
<div className='mx-auto max-w-4xl md:flex justify-between items-center'>
|
||||
<Link
|
||||
href='/'
|
||||
className='py-6 w-full text-center md:text-left md:w-auto text-gray-dark no-underline flex justify-center items-center'>
|
||||
|
||||
@@ -58,7 +58,7 @@ export const MenuList = props => {
|
||||
|
||||
return (
|
||||
<nav className='w-full bg-white md:pt-0 px-6 relative z-20 border-t border-b border-gray-light dark:border-hexo-black-gray dark:bg-black'>
|
||||
<div className='container mx-auto max-w-4xl md:flex justify-between items-center text-sm md:text-md md:justify-start'>
|
||||
<div className='mx-auto max-w-4xl md:flex justify-between items-center text-sm md:text-md md:justify-start'>
|
||||
<ul className='w-full text-center md:text-left flex flex-wrap justify-center items-stretch md:justify-start md:items-start'>
|
||||
{links.map((link, index) => (
|
||||
<MenuItemDrop key={index} link={link} />
|
||||
|
||||
@@ -3,6 +3,7 @@ import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
import CONFIG from '../config'
|
||||
import Announcement from './Announcement'
|
||||
const ExampleRecentComments = dynamic(
|
||||
() => import('./RecentCommentListForExample')
|
||||
@@ -13,10 +14,26 @@ const ExampleRecentComments = dynamic(
|
||||
*/
|
||||
export const SideBar = props => {
|
||||
const { locale } = useGlobal()
|
||||
const { latestPosts, categoryOptions, notice } = props
|
||||
const { latestPosts, categoryOptions, notice, post } = props
|
||||
// 评论相关
|
||||
const COMMENT_WALINE_SERVER_URL = siteConfig(
|
||||
'COMMENT_WALINE_SERVER_URL',
|
||||
false
|
||||
)
|
||||
const COMMENT_WALINE_RECENT = siteConfig('COMMENT_WALINE_RECENT', false)
|
||||
|
||||
// 文章详情页特殊布局
|
||||
const HIDDEN_NOTIFICATION =
|
||||
post && siteConfig('EXAMPLE_ARTICLE_HIDDEN_NOTIFICATION', false, CONFIG)
|
||||
|
||||
// 文章详情页左右布局改为上下布局
|
||||
const LAYOUT_VERTICAL =
|
||||
post && siteConfig('EXAMPLE_ARTICLE_LAYOUT_VERTICAL', false, CONFIG)
|
||||
|
||||
return (
|
||||
<div className='w-full md:w-64 sticky top-8'>
|
||||
<aside className='rounded shadow overflow-hidden mb-6'>
|
||||
<>
|
||||
{/* 分类 */}
|
||||
<aside className='w-full rounded shadow overflow-hidden mb-6'>
|
||||
<h3 className='text-sm bg-gray-100 text-gray-700 dark:bg-hexo-black-gray dark:text-gray-200 py-3 px-4 dark:border-hexo-black-gray border-b'>
|
||||
{locale.COMMON.CATEGORY}
|
||||
</h3>
|
||||
@@ -34,7 +51,7 @@ export const SideBar = props => {
|
||||
{' '}
|
||||
<a
|
||||
href={`/category/${category.name}`}
|
||||
className='text-gray-darkest text-sm'>
|
||||
className='text-gray-darkest text-sm hover:underline'>
|
||||
{category.name}({category.count})
|
||||
</a>
|
||||
</li>
|
||||
@@ -44,7 +61,9 @@ export const SideBar = props => {
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
<aside className='rounded shadow overflow-hidden mb-6'>
|
||||
|
||||
{/* 最新文章 */}
|
||||
<aside className='w-full rounded shadow overflow-hidden mb-6'>
|
||||
<h3 className='text-sm bg-gray-100 text-gray-700 dark:bg-hexo-black-gray dark:text-gray-200 py-3 px-4 dark:border-hexo-black-gray border-b'>
|
||||
{locale.COMMON.LATEST_POSTS}
|
||||
</h3>
|
||||
@@ -58,7 +77,7 @@ export const SideBar = props => {
|
||||
{' '}
|
||||
<a
|
||||
href={`/${p.slug}`}
|
||||
className='text-gray-darkest text-sm'>
|
||||
className='text-gray-darkest text-sm hover:underline'>
|
||||
{p.title}
|
||||
</a>
|
||||
</li>
|
||||
@@ -68,25 +87,29 @@ export const SideBar = props => {
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
{/* 公告 */}
|
||||
{/* 公告栏 */}
|
||||
<Announcement post={notice} />
|
||||
{!HIDDEN_NOTIFICATION && <Announcement post={notice} />}
|
||||
|
||||
{/* 最近评论 */}
|
||||
{siteConfig('COMMENT_WALINE_SERVER_URL') &&
|
||||
siteConfig('COMMENT_WALINE_RECENT') && (
|
||||
<aside className='rounded shadow overflow-hidden mb-6'>
|
||||
<h3 className='text-sm bg-gray-100 text-gray-700 dark:bg-hexo-black-gray dark:text-gray-200 py-3 px-4 dark:border-hexo-black-gray border-b'>
|
||||
{locale.COMMON.RECENT_COMMENTS}
|
||||
</h3>
|
||||
{COMMENT_WALINE_SERVER_URL && COMMENT_WALINE_RECENT && (
|
||||
<aside className='w-full rounded shadow overflow-hidden mb-6'>
|
||||
<h3 className='text-sm bg-gray-100 text-gray-700 dark:bg-hexo-black-gray dark:text-gray-200 py-3 px-4 dark:border-hexo-black-gray border-b'>
|
||||
{locale.COMMON.RECENT_COMMENTS}
|
||||
</h3>
|
||||
|
||||
<div className='p-4'>
|
||||
<ExampleRecentComments />
|
||||
</div>
|
||||
</aside>
|
||||
)}
|
||||
<aside className='rounded overflow-hidden mb-6'>
|
||||
<div className='p-4'>
|
||||
<ExampleRecentComments />
|
||||
</div>
|
||||
</aside>
|
||||
)}
|
||||
|
||||
{/* 宠物挂件 */}
|
||||
<aside
|
||||
className={`rounded overflow-hidden mb-6 ${LAYOUT_VERTICAL ? 'hidden md:fixed right-4 bottom-20' : ''}`}>
|
||||
<Live2D />
|
||||
</aside>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
48
themes/example/components/TitleBar.js
Normal file
48
themes/example/components/TitleBar.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import CONFIG from '../config'
|
||||
|
||||
/**
|
||||
* 标题栏
|
||||
*/
|
||||
export default function TitleBar(props) {
|
||||
const { post } = props
|
||||
const { fullWidth, siteInfo } = useGlobal()
|
||||
|
||||
const title = post?.title || siteConfig('TITLE')
|
||||
const description = post?.description || siteConfig('AUTHOR')
|
||||
const headerImage = post?.pageCoverThumbnail
|
||||
? post.pageCoverThumbnail
|
||||
: siteInfo?.pageCover
|
||||
|
||||
const TITLE_BG = siteConfig('EXAMPLE_TITLE_IMAGE', false, CONFIG)
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* 标题栏 */}
|
||||
{!fullWidth && (
|
||||
<div className='relative overflow-hidden text-center px-6 py-12 mb-6 bg-gray-100 dark:bg-hexo-black-gray dark:border-hexo-black-gray border-b'>
|
||||
<h1 className='title-1 relative text-xl md:text-4xl pb-4 z-10'>
|
||||
{siteConfig('POST_TITLE_ICON') && (
|
||||
<NotionIcon icon={post?.pageIcon} />
|
||||
)}
|
||||
{title}
|
||||
</h1>
|
||||
<p className='title-2 relative leading-loose text-gray-dark z-10'>
|
||||
{description}
|
||||
</p>
|
||||
{TITLE_BG && (
|
||||
<>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={headerImage}
|
||||
className='absolute object-cover top-0 left-0 w-full h-full select-none opacity-70 z-0'
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -8,7 +8,12 @@ const CONFIG = {
|
||||
EXAMPLE_MENU_ARCHIVE: true, // 显示归档
|
||||
EXAMPLE_MENU_SEARCH: true, // 显示搜索
|
||||
|
||||
EXAMPLE_POST_LIST_COVER: true // 列表显示文章封面
|
||||
EXAMPLE_POST_LIST_COVER: true, // 列表显示文章封面
|
||||
|
||||
EXAMPLE_TITLE_IMAGE: false, // 标题栏,是否背景图片
|
||||
|
||||
// 文章页面布局
|
||||
EXAMPLE_ARTICLE_LAYOUT_VERTICAL: false, // 文章详情,左右布局改为上下布局
|
||||
EXAMPLE_ARTICLE_HIDDEN_NOTIFICATION: false // 文章详情隐藏公告
|
||||
}
|
||||
export default CONFIG
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import Comment from '@/components/Comment'
|
||||
import replaceSearchResult from '@/components/Mark'
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import NotionPage from '@/components/NotionPage'
|
||||
import ShareBar from '@/components/ShareBar'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
@@ -21,6 +20,7 @@ import { PostLock } from './components/PostLock'
|
||||
import { PostMeta } from './components/PostMeta'
|
||||
import SearchInput from './components/SearchInput'
|
||||
import { SideBar } from './components/SideBar'
|
||||
import TitleBar from './components/TitleBar'
|
||||
import CONFIG from './config'
|
||||
import { Style } from './style'
|
||||
|
||||
@@ -32,36 +32,15 @@ import { Style } from './style'
|
||||
* @constructor
|
||||
*/
|
||||
const LayoutBase = props => {
|
||||
const { children } = props
|
||||
const { children, post } = props
|
||||
const { onLoading, fullWidth, locale } = useGlobal()
|
||||
const router = useRouter()
|
||||
const { post, category, tag } = props
|
||||
|
||||
const title = post?.title || siteConfig('TITLE')
|
||||
const description = post?.description || siteConfig('AUTHOR')
|
||||
// 文章详情页左右布局改为上下布局
|
||||
const LAYOUT_VERTICAL =
|
||||
post && siteConfig('EXAMPLE_ARTICLE_LAYOUT_VERTICAL', false, CONFIG)
|
||||
|
||||
// 顶部如果是按照分类或标签查看文章列表,列表顶部嵌入一个横幅
|
||||
// 如果是搜索,则列表顶部嵌入 搜索框
|
||||
let slotTop = null
|
||||
if (category) {
|
||||
slotTop = (
|
||||
<div className='pb-12'>
|
||||
<i className='mr-1 fas fa-folder-open' />
|
||||
{category}
|
||||
</div>
|
||||
)
|
||||
} else if (tag) {
|
||||
slotTop = <div className='pb-12'>#{tag}</div>
|
||||
} else if (props.slotTop) {
|
||||
slotTop = props.slotTop
|
||||
} else if (router.route === '/search') {
|
||||
// 嵌入一个搜索框在顶部
|
||||
slotTop = (
|
||||
<div className='pb-12'>
|
||||
<SearchInput {...props} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
// 网站左右布局颠倒
|
||||
const LAYOUT_SIDEBAR_REVERSE = siteConfig('LAYOUT_SIDEBAR_REVERSE', false)
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -71,33 +50,20 @@ const LayoutBase = props => {
|
||||
|
||||
{/* 页头 */}
|
||||
<Header {...props} />
|
||||
{/* 标题栏 */}
|
||||
<TitleBar {...props} />
|
||||
|
||||
{/* 主体 */}
|
||||
<div id='container-inner' className='w-full relative z-10'>
|
||||
{/* 标题栏 */}
|
||||
{!fullWidth && (
|
||||
<div className='text-center px-6 py-12 mb-6 bg-gray-100 dark:bg-hexo-black-gray dark:border-hexo-black-gray border-b'>
|
||||
<h1 className='text-xl md:text-4xl pb-4'>
|
||||
{siteConfig('POST_TITLE_ICON') && (
|
||||
<NotionIcon icon={post?.pageIcon} />
|
||||
)}
|
||||
{title}
|
||||
</h1>
|
||||
<p className='leading-loose text-gray-dark'>{description}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
id='container-wrapper'
|
||||
className={
|
||||
(JSON.parse(siteConfig('LAYOUT_SIDEBAR_REVERSE'))
|
||||
? 'flex-row-reverse'
|
||||
: '') +
|
||||
'relative container mx-auto justify-center md:flex items-start py-8 px-2'
|
||||
}>
|
||||
className={`relative mx-auto justify-center md:flex py-8 px-2
|
||||
${LAYOUT_SIDEBAR_REVERSE ? 'flex-row-reverse' : ''}
|
||||
${LAYOUT_VERTICAL ? 'items-center flex-col' : 'items-start'}
|
||||
`}>
|
||||
{/* 内容 */}
|
||||
<div
|
||||
className={`w-full ${fullWidth ? '' : 'max-w-3xl'} xl:px-14 lg:px-4`}>
|
||||
className={`${fullWidth ? '' : LAYOUT_VERTICAL ? 'max-w-5xl' : 'max-w-3xl'} w-full xl:px-14 lg:px-4`}>
|
||||
<Transition
|
||||
show={!onLoading}
|
||||
appear={true}
|
||||
@@ -109,13 +75,22 @@ const LayoutBase = props => {
|
||||
leaveTo='opacity-0 -translate-y-16'
|
||||
unmount={false}>
|
||||
{/* 嵌入模块 */}
|
||||
{slotTop}
|
||||
{props.slotTop}
|
||||
{children}
|
||||
</Transition>
|
||||
</div>
|
||||
|
||||
{/* 侧边栏 */}
|
||||
{!fullWidth && <SideBar {...props} />}
|
||||
{!fullWidth && (
|
||||
<div
|
||||
className={`${
|
||||
LAYOUT_VERTICAL
|
||||
? 'flex space-x-0 md:space-x-2 md:flex-row flex-col w-full max-w-5xl justify-center xl:px-14 lg:px-4'
|
||||
: 'md:w-64 sticky top-8'
|
||||
}`}>
|
||||
<SideBar {...props} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -150,8 +125,20 @@ const LayoutIndex = props => {
|
||||
* @returns
|
||||
*/
|
||||
const LayoutPostList = props => {
|
||||
const { category, tag } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* 显示分类 */}
|
||||
{category && (
|
||||
<div className='pb-12'>
|
||||
<i className='mr-1 fas fa-folder-open' />
|
||||
{category}
|
||||
</div>
|
||||
)}
|
||||
{/* 显示标签 */}
|
||||
{tag && <div className='pb-12'>#{tag}</div>}
|
||||
|
||||
{siteConfig('POST_LIST_STYLE') === 'page' ? (
|
||||
<BlogListPage {...props} />
|
||||
) : (
|
||||
@@ -192,7 +179,7 @@ const LayoutSlug = props => {
|
||||
{lock ? (
|
||||
<PostLock validPassword={validPassword} />
|
||||
) : (
|
||||
<div id='article-wrapper' className='px-2'>
|
||||
<div id='article-wrapper'>
|
||||
<PostMeta post={post} />
|
||||
<NotionPage post={post} />
|
||||
<ShareBar post={post} />
|
||||
@@ -237,7 +224,14 @@ const LayoutSearch = props => {
|
||||
}
|
||||
}, [router])
|
||||
|
||||
return <LayoutPostList {...props} />
|
||||
return (
|
||||
<>
|
||||
<div className='pb-12'>
|
||||
<SearchInput {...props} />
|
||||
</div>
|
||||
<LayoutPostList {...props} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user