Skip to content

Commit

Permalink
feat: enhance ui
Browse files Browse the repository at this point in the history
  • Loading branch information
kuizuo committed Jun 15, 2024
1 parent ee140c5 commit 865a239
Show file tree
Hide file tree
Showing 24 changed files with 418 additions and 53 deletions.
9 changes: 5 additions & 4 deletions src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

@layer base {
:root {
--content-background: #fdfdfd;
--ifm-color-primary: #12affa;
--ifm-color-primary-dark: #05a1ec;
--ifm-color-primary-darker: #0598df;
Expand All @@ -16,6 +17,7 @@

--ifm-heading-font-family: ui-sans-serif, system-ui, -apple-system;

--ifm-navbar-background-color: var(--content-background);
--ifm-navbar-shadow: 0 4px 28px rgb(0 0 0 / 10%);

--ifm-menu-color: #0d203a;
Expand Down Expand Up @@ -45,8 +47,6 @@
--ifm-border-color: #e5e7eb;
--ifm-toc-border-color: var(--ifm-border-color);

--content-background: #fdfdfd;

--blog-item-background-color: linear-gradient(180deg, #fcfcfc, #fff);
--blog-item-shadow: 0 10px 18px #f1f5f9dd, 0 0 10px 0 #e4e4e7dd;
--blog-item-shade: #f4f4f5;
Expand All @@ -57,16 +57,18 @@
}

html[data-theme='dark'] {
--content-background: #18181b;
--ifm-color-primary: hsl(214deg 100% 60%);
--ifm-color-primary-light: hsl(214deg 100% 75%);
--ifm-heading-color: hsl(0deg 0% 100%);
--ifm-menu-color: #eceef1;
--ifm-text-color: var(--ifm-menu-color);
--ifm-secondary-text-color: #eee;
--ifm-border-color: #313131;

--ifm-navbar-background-color: var(--content-background);
--ifm-toc-border-color: var(--ifm-border-color);

--content-background: #18181b;
--blog-item-background-color: linear-gradient(180deg, #171717, #18181b);
--blog-item-shadow: 0 10px 18px #25374833, 0 0 8px #25374866;
--blog-item-shade: #27272a;
Expand Down Expand Up @@ -174,7 +176,6 @@ article p > span > a {

.navbar {
box-shadow: none;
background-color: transparent;
}

.navbar-sidebar__items {
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useReadPercent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const useReadPercent = () => {
postRef.current = document.getElementById('__blog-post-container')
}, [])

useMotionValueEvent(scrollYProgress, 'change', latest => {
useMotionValueEvent(scrollYProgress, 'change', (latest) => {
setScrollProgress(latest)
})

Expand Down
2 changes: 1 addition & 1 deletion src/theme/BlogPostGridItems/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default function BlogPostGridItems({ items }: BlogPostItemsProps): JSX.El
onMouseEnter={() => setHoveredIndex(idx)}
onMouseLeave={() => setHoveredIndex(null)}
>
<Link href={item.link}>
<Link href={item.link} className="hover:no-underline">
<AnimatePresence>
{hoveredIndex === idx && (
<motion.span
Expand Down
16 changes: 10 additions & 6 deletions src/theme/BlogPostItem/Container/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,30 @@ import { useBlogPost } from '@docusaurus/theme-common/internal'
import { useBaseUrlUtils } from '@docusaurus/useBaseUrl'
import { cn } from '@site/src/lib/utils'
import type { Props } from '@theme/BlogPostItem/Container'
import React from 'react'

import styles from './styles.module.css'

export default function BlogPostItemContainer({ children, className }: Props): JSX.Element {
const { frontMatter, assets } = useBlogPost()
const { withBaseUrl } = useBaseUrlUtils()
const image = assets.image ?? frontMatter.image
return (
<article
className={cn(className, styles.article)}
className={cn('relative px-4 pt-4 pb-3 lg:px-4', className)}
itemProp="blogPost"
itemScope
itemType="http://schema.org/BlogPosting"
>
{image && (
<>
<meta itemProp="image" content={withBaseUrl(image, { absolute: true })} />
<div className={styles.cover}>
<div className={styles.coverMask} style={{ backgroundImage: `url("${image}")` }} />
<div className={'absolute inset-0 z-1 h-[224px]'}>
<div
className="size-full rounded-[var(--ifm-pagination-nav-border-radius)] bg-center bg-cover bg-no-repeat"
style={{
WebkitMaskImage: 'linear-gradient(180deg, #fff -17.19%, #00000000 92.43%)',
maskImage: 'linear-gradient(180deg, #fff -17.19%, #00000000 92.43%)',
backgroundImage: `url("${image}")`,
}}
/>
</div>
<div style={{ height: '120px' }} />
</>
Expand Down
34 changes: 0 additions & 34 deletions src/theme/BlogPostItem/Container/styles.module.css

This file was deleted.

2 changes: 1 addition & 1 deletion src/theme/BlogPostPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { Props } from '@theme/BlogPostPage'
import BlogPostPageMetadata from '@theme/BlogPostPage/Metadata'
import BlogPostPaginator from '@theme/BlogPostPaginator'
import TOC from '@theme/TOC'
import React, { type ReactNode } from 'react'
import { type ReactNode } from 'react'

function BlogPostPageContent({
sidebar,
Expand Down
28 changes: 28 additions & 0 deletions src/theme/Navbar/ColorModeToggle/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import {useColorMode, useThemeConfig} from '@docusaurus/theme-common';
import ColorModeToggle from '@theme/ColorModeToggle';
import type {Props} from '@theme/Navbar/ColorModeToggle';
import styles from './styles.module.css';

export default function NavbarColorModeToggle({
className,
}: Props): JSX.Element | null {
const navbarStyle = useThemeConfig().navbar.style;
const disabled = useThemeConfig().colorMode.disableSwitch;
const {colorMode, setColorMode} = useColorMode();

if (disabled) {
return null;
}

return (
<ColorModeToggle
className={className}
buttonClassName={
navbarStyle === 'dark' ? styles.darkNavbarColorModeToggle : undefined
}
value={colorMode}
onChange={setColorMode}
/>
);
}
3 changes: 3 additions & 0 deletions src/theme/Navbar/ColorModeToggle/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.darkNavbarColorModeToggle:hover {
background: var(--ifm-color-gray-800);
}
90 changes: 90 additions & 0 deletions src/theme/Navbar/Content/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, {type ReactNode} from 'react';
import {useThemeConfig, ErrorCauseBoundary} from '@docusaurus/theme-common';
import {
splitNavbarItems,
useNavbarMobileSidebar,
} from '@docusaurus/theme-common/internal';
import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem';
import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
import SearchBar from '@theme/SearchBar';
import NavbarMobileSidebarToggle from '@theme/Navbar/MobileSidebar/Toggle';
import NavbarLogo from '@theme/Navbar/Logo';
import NavbarSearch from '@theme/Navbar/Search';

import styles from './styles.module.css';

function useNavbarItems() {
// TODO temporary casting until ThemeConfig type is improved
return useThemeConfig().navbar.items as NavbarItemConfig[];
}

function NavbarItems({items}: {items: NavbarItemConfig[]}): JSX.Element {
return (
<>
{items.map((item, i) => (
<ErrorCauseBoundary
key={i}
onError={(error) =>
new Error(
`A theme navbar item failed to render.
Please double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:
${JSON.stringify(item, null, 2)}`,
{cause: error},
)
}>
<NavbarItem {...item} />
</ErrorCauseBoundary>
))}
</>
);
}

function NavbarContentLayout({
left,
right,
}: {
left: ReactNode;
right: ReactNode;
}) {
return (
<div className="navbar__inner">
<div className="navbar__items">{left}</div>
<div className="navbar__items navbar__items--right">{right}</div>
</div>
);
}

export default function NavbarContent(): JSX.Element {
const mobileSidebar = useNavbarMobileSidebar();

const items = useNavbarItems();
const [leftItems, rightItems] = splitNavbarItems(items);

const searchBarItem = items.find((item) => item.type === 'search');

return (
<NavbarContentLayout
left={
// TODO stop hardcoding items?
<>
{!mobileSidebar.disabled && <NavbarMobileSidebarToggle />}
<NavbarLogo />
<NavbarItems items={leftItems} />
</>
}
right={
// TODO stop hardcoding items?
// Ask the user to add the respective navbar items => more flexible
<>
<NavbarItems items={rightItems} />
<NavbarColorModeToggle className={styles.colorModeToggle} />
{!searchBarItem && (
<NavbarSearch>
<SearchBar />
</NavbarSearch>
)}
</>
}
/>
);
}
8 changes: 8 additions & 0 deletions src/theme/Navbar/Content/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Hide color mode toggle in small viewports
*/
@media (max-width: 996px) {
.colorModeToggle {
display: none;
}
}
51 changes: 51 additions & 0 deletions src/theme/Navbar/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { translate } from '@docusaurus/Translate'
import { useThemeConfig } from '@docusaurus/theme-common'
import { useHideableNavbar, useNavbarMobileSidebar } from '@docusaurus/theme-common/internal'
import type { Props } from '@theme/Navbar/Layout'
import NavbarMobileSidebar from '@theme/Navbar/MobileSidebar'
import clsx from 'clsx'
import { type ComponentProps } from 'react'
import { useLocation } from 'react-router-dom'

import styles from './styles.module.css'

function NavbarBackdrop(props: ComponentProps<'div'>) {
return <div role="presentation" {...props} className={clsx('navbar-sidebar__backdrop', props.className)} />
}

export default function NavbarLayout({ children }: Props): JSX.Element {
const {
navbar: { hideOnScroll, style },
} = useThemeConfig()
const mobileSidebar = useNavbarMobileSidebar()
const { navbarRef, isNavbarVisible } = useHideableNavbar(hideOnScroll)

const location = useLocation()
const isHomePage = location.pathname === '/'

return (
<nav
ref={navbarRef}
aria-label={translate({
id: 'theme.NavBar.navAriaLabel',
message: 'Main',
description: 'The ARIA label for the main navigation',
})}
className={clsx(
'navbar',
'navbar--fixed-top',
isHomePage && 'bg-transparent',
hideOnScroll && [styles.navbarHideable, !isNavbarVisible && styles.navbarHidden],
{
'navbar--dark': style === 'dark',
'navbar--primary': style === 'primary',
'navbar-sidebar--show': mobileSidebar.shown,
},
)}
>
{children}
<NavbarBackdrop onClick={mobileSidebar.toggle} />
<NavbarMobileSidebar />
</nav>
)
}
7 changes: 7 additions & 0 deletions src/theme/Navbar/Layout/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.navbarHideable {
transition: transform var(--ifm-transition-fast) ease;
}

.navbarHidden {
transform: translate3d(0, calc(-100% - 2px), 0);
}
12 changes: 12 additions & 0 deletions src/theme/Navbar/Logo/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import Logo from '@theme/Logo';

export default function NavbarLogo(): JSX.Element {
return (
<Logo
className="navbar__brand"
imageClassName="navbar__logo"
titleClassName="navbar__title text--truncate"
/>
);
}
33 changes: 33 additions & 0 deletions src/theme/Navbar/MobileSidebar/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import {useNavbarMobileSidebar} from '@docusaurus/theme-common/internal';
import {translate} from '@docusaurus/Translate';
import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
import IconClose from '@theme/Icon/Close';
import NavbarLogo from '@theme/Navbar/Logo';

function CloseButton() {
const mobileSidebar = useNavbarMobileSidebar();
return (
<button
type="button"
aria-label={translate({
id: 'theme.docs.sidebar.closeSidebarButtonAriaLabel',
message: 'Close navigation bar',
description: 'The ARIA label for close button of mobile sidebar',
})}
className="clean-btn navbar-sidebar__close"
onClick={() => mobileSidebar.toggle()}>
<IconClose color="var(--ifm-color-emphasis-600)" />
</button>
);
}

export default function NavbarMobileSidebarHeader(): JSX.Element {
return (
<div className="navbar-sidebar__brand">
<NavbarLogo />
<NavbarColorModeToggle className="margin-right--md" />
<CloseButton />
</div>
);
}
1 change: 0 additions & 1 deletion src/theme/Navbar/MobileSidebar/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useNavbarSecondaryMenu } from '@docusaurus/theme-common/internal'
import UserCard from '@site/src/components/UserCard'
import { cn } from '@site/src/lib/utils'
import type { Props } from '@theme/Navbar/MobileSidebar/Layout'
import React from 'react'

export default function NavbarMobileSidebarLayout({ header, primaryMenu, secondaryMenu }: Props): JSX.Element {
const { shown: secondaryMenuShown } = useNavbarSecondaryMenu()
Expand Down
Loading

0 comments on commit 865a239

Please sign in to comment.