diff --git a/bun.lockb b/bun.lockb index c9aae63b8..8f708ea6f 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 0e220c362..73d078fe5 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,8 @@ }, "dependencies": { "@geist-ui/icons": "^1.0.2", + "@gitbook/api": "^0.15.0", "@radix-ui/react-popover": "^1.0.7", - "@gitbook/api": "^0.17.0", "@readme/openapi-parser": "^2.5.0", "@upstash/redis": "^1.25.1", "ajv": "^8.12.0", @@ -23,14 +23,15 @@ "bun-types": "^1.0.7", "jsontoxml": "^1.0.1", "katex": "^0.16.9", - "next": "^14.0.4-canary.25", + "next": "^14.0.3", "react": "^18", "react-dom": "^18", "react-hotkeys-hook": "^4.4.1", "recoil": "^0.7.7", "server-only": "^0.0.1", "shiki": "^0.14.5", - "tailwind-merge": "^1.14.0" + "tailwind-merge": "^1.14.0", + "tailwind-shades": "^1.1.2" }, "devDependencies": { "@cloudflare/next-on-pages": "^1.7.3", diff --git a/src/app/[spaceId]/globals.css b/src/app/[spaceId]/globals.css index fefb83f39..6589c7547 100644 --- a/src/app/[spaceId]/globals.css +++ b/src/app/[spaceId]/globals.css @@ -31,10 +31,63 @@ p { @apply text-dark/9 dark:text-light/8; } + + /* Light mode */ + ::-webkit-scrollbar { + @apply bg-transparent; + width: 8px; + } + + ::-webkit-scrollbar-thumb { + @apply bg-dark/4; + border-radius: 8px; + } + + ::-webkit-scrollbar-thumb:hover { + @apply bg-dark/5; + } + + /* Dark mode */ + .dark ::-webkit-scrollbar { + @apply bg-light/1; + } + + .dark ::-webkit-scrollbar-thumb { + @apply bg-light/3; + } + + .dark ::-webkit-scrollbar-thumb:hover { + @apply bg-light/4; + } + + /* Inverted theme light mode */ + .inverted-theme-scroll::-webkit-scrollbar { + @apply bg-transparent; + } + + .inverted-theme-scroll::-webkit-scrollbar-thumb { + @apply bg-dark/5; + } + + .inverted-theme-scroll::-webkit-scrollbar-thumb:hover { + @apply bg-dark/6; + } } @layer utilities { .linear-mask-gradient { mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 96px, rgba(0, 0, 0, 0)); } + .grid-area-1-1 { + grid-area: 1/1; + } + .gutter-stable { + scrollbar-gutter: stable; + } + .textwrap-balance { + text-wrap: balance; + } + .textwrap-pretty { + text-wrap: pretty; + } } diff --git a/src/components/DocumentView/File.tsx b/src/components/DocumentView/File.tsx index e715840b9..ac987e67b 100644 --- a/src/components/DocumentView/File.tsx +++ b/src/components/DocumentView/File.tsx @@ -28,8 +28,8 @@ export async function File(props: BlockProps) { 'hover:border-slate-300', 'px-5', 'py-2', - 'text-slate-500', - 'hover:text-slate-700', + /* 'text-slate-500', */ + /* 'hover:text-slate-700', */ style, )} > diff --git a/src/components/DocumentView/Hint.tsx b/src/components/DocumentView/Hint.tsx index 79289f213..f58767493 100644 --- a/src/components/DocumentView/Hint.tsx +++ b/src/components/DocumentView/Hint.tsx @@ -3,6 +3,7 @@ import IconAlertTriangle from '@geist-ui/icons/alertTriangle'; import IconCheckInCircle from '@geist-ui/icons/checkInCircle'; import IconInfo from '@geist-ui/icons/info'; import { DocumentBlockHint } from '@gitbook/api'; +import React from 'react'; import { ClassValue, tcls } from '@/lib/tailwind'; @@ -14,6 +15,7 @@ export function Hint(props: BlockProps) { const { block, style, ancestorBlocks, ...contextProps } = props; const hintStyle = HINT_STYLES[block.data.style]; const firstLine = getBlockTextStyle(block.nodes[0]); + const RenderIcon = HINT_STYLES[block.data.style].icon; return (
) { 'py-4', 'transition-colors', 'rounded', - 'border-l-4', + 'border-b-[1px]', + 'dark:border-t-[1px]', + 'dark:border-b-0', + + /* 'shadow-1xs', */ hintStyle.style, style, )} @@ -40,7 +46,9 @@ export function Hint(props: BlockProps) { hintStyle.iconStyle, )} > - + {/* */} + +
) { ); } +const SuccessIcon = () => ( +
+
+
+
+
+
+
+); +const WarningIcon = () => SuccessIcon(); +const DangerIcon = () => SuccessIcon(); +const InfoIcon = () => SuccessIcon(); + const HINT_STYLES: { [style in DocumentBlockHint['data']['style']]: { - icon: React.ComponentType<{ className?: string }>; + icon: React.ComponentType; iconStyle: ClassValue; style: ClassValue; }; } = { info: { - icon: IconInfo, + icon: SuccessIcon, iconStyle: ['text-current'], - style: ['border-dark/2', 'bg-dark/2', 'dark:bg-light/1', 'dark:border-light/3'], + style: ['border-dark/1', 'bg-dark/2', 'dark:bg-light/1', 'dark:border-light/1'], }, warning: { - icon: IconAlertCircle, + icon: WarningIcon, iconStyle: ['text-yellow, dark:text-yellow/1, dark:text-yellow/8'], - style: ['border-yellow/4', 'bg-yellow', 'dark:bg-yellow/1'], + style: ['border-yellow/6', 'bg-yellow/6', 'dark:bg-yellow/1', 'dark:border-yellow/2'], }, danger: { - icon: IconAlertTriangle, + icon: DangerIcon, iconStyle: ['text-pomegranate'], - style: ['border-pomegranate/4', 'bg-pomegranate/2', 'dark:bg-pomegranate/1'], + style: [ + 'border-pomegranate/2', + 'bg-pomegranate/2', + 'dark:bg-pomegranate/1', + 'dark:border-pomegranate/3', + ], }, success: { - icon: IconCheckInCircle, + icon: InfoIcon, iconStyle: ['text-teal'], - style: ['border-teal/4', 'bg-teal/2', 'dark:bg-teal/2'], + style: ['border-teal/2', 'bg-teal/2', 'dark:bg-teal/2'], }, }; diff --git a/src/components/DocumentView/Images.tsx b/src/components/DocumentView/Images.tsx index 8535887d5..4786470d5 100644 --- a/src/components/DocumentView/Images.tsx +++ b/src/components/DocumentView/Images.tsx @@ -21,7 +21,7 @@ export function Images(props: BlockProps) { block.data.align === 'right' && 'justify-end', block.data.align === 'left' && 'justify-start', style, - block.data.fullWidth ? 'max-w-full' : null, + block.data.fullWidth ? 'max-w-screen-2xl' : null, 'justify-center', )} > diff --git a/src/components/Header/CompactHeader.tsx b/src/components/Header/CompactHeader.tsx index 1a1735e47..025ff2e54 100644 --- a/src/components/Header/CompactHeader.tsx +++ b/src/components/Header/CompactHeader.tsx @@ -1,6 +1,7 @@ import { Collection, CustomizationSettings, Space } from '@gitbook/api'; import React from 'react'; +import { t } from '@/lib/intl'; import { tcls } from '@/lib/tailwind'; import { HeaderLogo } from './HeaderLogo'; @@ -18,8 +19,17 @@ export function CompactHeader(props: { const { space, collection, customization } = props; return ( -
-
+
+
-
+
- + + {t({ space }, 'search')} +
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index d44d124ec..c96774c7b 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -91,8 +91,8 @@ export function Header(props: {
- - {t({ space }, 'search')} + + {t({ space }, 'search')}
diff --git a/src/components/Header/HeaderLogo.tsx b/src/components/Header/HeaderLogo.tsx index e5697a259..4dc14f934 100644 --- a/src/components/Header/HeaderLogo.tsx +++ b/src/components/Header/HeaderLogo.tsx @@ -1,6 +1,7 @@ import { Collection, CustomizationSettings, Space } from '@gitbook/api'; import Link from 'next/link'; +import { HeaderMobileMenu } from '@/components/Header/HeaderMobileMenu'; import { Image } from '@/components/utils'; import { absoluteHref } from '@/lib/links'; import { ClassValue, tcls } from '@/lib/tailwind'; @@ -20,21 +21,24 @@ export function HeaderLogo(props: HeaderLogoProps) { const { customization } = props; return ( - - {customization.header.logo ? ( - Logo - ) : ( - - )} - +
+ + + {customization.header.logo ? ( + Logo + ) : ( + + )} + +
); } @@ -56,7 +60,21 @@ function LogoFallback(props: HeaderLogoProps) { style={['w-8', 'h-8']} /> -

+

{collection ? collection.title : space.title}

diff --git a/src/components/Header/HeaderMobileMenu.tsx b/src/components/Header/HeaderMobileMenu.tsx new file mode 100644 index 000000000..fe1e83f46 --- /dev/null +++ b/src/components/Header/HeaderMobileMenu.tsx @@ -0,0 +1,33 @@ +'use client'; + +import { IconMenu } from '@/components/icons/IconMenu'; +import { tcls } from '@/lib/tailwind'; + +export const HeaderMobileMenu = (props: Partial>) => { + const toggleNavigation = () => { + if (document.body.classList.contains('navigation-visible')) { + document.body.classList.remove('navigation-visible'); + } else { + document.body.classList.add('navigation-visible'); + } + }; + return ( + + ); +}; diff --git a/src/components/PageAside/ScrollSectionsList.tsx b/src/components/PageAside/ScrollSectionsList.tsx index f4a7d9858..2681aecc5 100644 --- a/src/components/PageAside/ScrollSectionsList.tsx +++ b/src/components/PageAside/ScrollSectionsList.tsx @@ -25,11 +25,10 @@ export function ScrollSectionsList(props: { sections: DocumentSection[] }) { 'flex', 'flex-row', 'text-sm', - section.depth > 1 - ? ['font-light', 'ps-3', 'py-1', 'text-light/5'] - : ['py-2', 'text-light/7'], + 'hover:text-primary', + section.depth > 1 ? ['ps-3', 'py-1', 'opacity-8'] : ['py-2'], - activeId === section.id ? 'text-primary' : 'hover:text-light/9', + activeId === section.id ? 'text-primary' : '', )} > {section.depth > 1 ? ( diff --git a/src/components/Search/SearchButton.tsx b/src/components/Search/SearchButton.tsx index 488a849f9..dc2758539 100644 --- a/src/components/Search/SearchButton.tsx +++ b/src/components/Search/SearchButton.tsx @@ -26,21 +26,29 @@ export function SearchButton(props: { children?: React.ReactNode; style?: ClassV 'flex', 'flex-1', 'flex-row', + 'justify-center', 'items-center', - 'px-4', - 'py-1', - 'rounded', - 'dark:bg-vanta/4', - 'hover:bg-light', + 'px-2', + 'min-h-[2.5rem]', + 'w-[2.5rem]', + 'rounded-lg', + 'bg-dark/2', + 'hover:bg-dark/3', 'border', - 'border-dark/2', - 'shadow-lg', - 'dark:border-light/3', + 'border-dark/1', + 'dark:bg-light/1', + 'dark:border-light/1', + 'dark:hover:bg-light/2', + '[&>span]:hidden', + 'sm:justify-between', + 'sm:[&>span]:flex', + 'sm:w-full', + 'sm:px-4', style, )} > - {children} + ); } diff --git a/src/components/Search/SearchModal.tsx b/src/components/Search/SearchModal.tsx index 101904cd1..0b053c87b 100644 --- a/src/components/Search/SearchModal.tsx +++ b/src/components/Search/SearchModal.tsx @@ -20,7 +20,8 @@ export function SearchModal(props: SearchModalProps) { useHotkeys( 'ctrl+k, command+k', - () => { + (e) => { + e.preventDefault(); //might be inadvisable as it interferes with expected browser behavior. setQuery(''); }, [], @@ -51,7 +52,9 @@ export function SearchModal(props: SearchModalProps) { 'dark:bg-dark/9', 'opacity-100', 'z-30', - 'pt-24', + 'px-4', + 'pt-4', + 'md:pt-[min(12vw,_10rem)]', )} onClick={onClose} > diff --git a/src/components/Search/SearchResults.tsx b/src/components/Search/SearchResults.tsx index c27890aff..decddec8b 100644 --- a/src/components/Search/SearchResults.tsx +++ b/src/components/Search/SearchResults.tsx @@ -100,7 +100,7 @@ export const SearchResults = React.forwardRef(function SearchResults( } return ( -
+
{results.length === 0 ? (
{noResultsMessage} diff --git a/src/components/SpaceContent/SpaceContent.tsx b/src/components/SpaceContent/SpaceContent.tsx index 5a226140e..7ff68708c 100644 --- a/src/components/SpaceContent/SpaceContent.tsx +++ b/src/components/SpaceContent/SpaceContent.tsx @@ -76,7 +76,8 @@ export function SpaceContent(props: {
+
    {pages.map((page) => { if (page.type === 'group') { return ( diff --git a/src/components/TableOfContents/TableOfContents.tsx b/src/components/TableOfContents/TableOfContents.tsx index 84fede9da..4944d2968 100644 --- a/src/components/TableOfContents/TableOfContents.tsx +++ b/src/components/TableOfContents/TableOfContents.tsx @@ -34,24 +34,34 @@ export function TableOfContents( return ( ); } diff --git a/src/components/TableOfContents/ToggleableLinkItem.tsx b/src/components/TableOfContents/ToggleableLinkItem.tsx index 19a333a8d..86737c287 100644 --- a/src/components/TableOfContents/ToggleableLinkItem.tsx +++ b/src/components/TableOfContents/ToggleableLinkItem.tsx @@ -30,6 +30,7 @@ export function ToggleableLinkItem( {children} >) { + return ( + + + + ); +} diff --git a/tailwind.config.ts b/tailwind.config.ts index 41350895d..7e0ec6f0e 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,4 +1,5 @@ import type { Config } from 'tailwindcss'; +import plugin from 'tailwindcss/plugin'; export const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]; export const opacities = [4, 8, 12, 16, 24, 40, 64, 72, 88, 96]; @@ -46,9 +47,31 @@ const config: Config = { 'header-background': generateShades('header-background'), 'header-link': generateShades('header-link'), }, + keyframes: { + pingAlt: { + '0%': { + transform: 'scale(0.5)', + opacity: '0', + }, + '20%': { + opacity: '1', + }, + '30%, 100%': { + transform: 'scale(2.5)', + opacity: '0', + }, + }, + }, + boxShadow: { + '1xs': '0px 1.54px 1px rgba(0, 0, 0, 0.09), 0px 3.267px 2.754px rgb(0, 0, 0, 0.05), 0px 6.278px 6.63px rgb(0, 0, 0, 0.05), 0px 14px 22px rgb(0, 0, 0, 0.04)', + }, }, opacity: opacity(), }, - plugins: [], + plugins: [ + plugin(function ({ addVariant }) { + addVariant('navigation-visible', 'body.navigation-visible &'); + }), + ], }; export default config;