mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(site): new home page, docs, and design system (#566)
Co-authored-by: Darius Cepulis <dcepulis@mux.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Darius Cepulis
Claude Opus 4.6
parent
f2f9e6ddc3
commit
351a3e8bda
@@ -1,8 +1,8 @@
|
||||
import { Dialog } from '@base-ui/react/dialog';
|
||||
import clsx from 'clsx';
|
||||
import { ArrowUpRight, Menu, X } from 'lucide-react';
|
||||
import { ArrowUpRight } from 'lucide-react';
|
||||
import { DISCORD_INVITE_URL, GITHUB_REPO_URL } from '@/consts';
|
||||
import FilmGrain from '../FilmGrain';
|
||||
import Logo from '../icons/logo.svg?react';
|
||||
import GetStartedLink from './GetStartedLink';
|
||||
|
||||
interface NavLink {
|
||||
@@ -15,24 +15,26 @@ interface NavLink {
|
||||
export interface MobileNavProps {
|
||||
navLinks: NavLink[];
|
||||
currentPath: string;
|
||||
dark?: boolean;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function MobileNav({ navLinks, currentPath, dark = false, children }: MobileNavProps) {
|
||||
export default function MobileNav({ navLinks, currentPath, children }: MobileNavProps) {
|
||||
return (
|
||||
<Dialog.Root modal>
|
||||
{/* Trigger button - hamburger menu */}
|
||||
<Dialog.Trigger
|
||||
className={clsx(
|
||||
'md:hidden flex items-center justify-center p-3 h-full aspect-square',
|
||||
dark
|
||||
? 'bg-light-80 text-dark-100 intent:bg-light-40'
|
||||
: 'bg-dark-100 dark:bg-light-80 text-light-80 dark:text-dark-100 intent:bg-dark-80 dark:intent:bg-light-40'
|
||||
'md:hidden',
|
||||
'inline-flex items-stretch p-0.75 border-2 border-faded-black dark:border-manila-light rounded-xs'
|
||||
)}
|
||||
aria-label="Open navigation menu"
|
||||
>
|
||||
<Menu size={24} />
|
||||
<span
|
||||
className="font-display tracking-normal leading-none uppercase font-bold text-manila-light bg-faded-black dark:bg-manila-light dark:text-faded-black px-4 py-2.5"
|
||||
style={{ fontSize: '0.75rem' }}
|
||||
>
|
||||
Menu
|
||||
</span>
|
||||
</Dialog.Trigger>
|
||||
|
||||
{/* Portal renders outside DOM hierarchy */}
|
||||
@@ -41,44 +43,38 @@ export default function MobileNav({ navLinks, currentPath, dark = false, childre
|
||||
<Dialog.Popup
|
||||
className={clsx(
|
||||
'fixed inset-0 z-50 flex flex-col',
|
||||
dark ? 'bg-dark-100 text-light-100 dark' : 'bg-light-80 dark:bg-dark-100 text-dark-100 dark:text-light-100'
|
||||
'bg-manila-light dark:bg-faded-black text-faded-black dark:text-manila-light'
|
||||
)}
|
||||
>
|
||||
<FilmGrain currentPath={currentPath} />
|
||||
{/* Header with close button */}
|
||||
<div
|
||||
className={clsx(
|
||||
'flex justify-between items-center pl-3 border-b',
|
||||
dark ? 'border-dark-80' : 'border-light-40 dark:border-dark-80'
|
||||
)}
|
||||
style={{ height: 'var(--nav-h)' }}
|
||||
>
|
||||
<div className={clsx('flex justify-between items-center px-5 py-7')}>
|
||||
<Dialog.Title className="sr-only">Navigation</Dialog.Title>
|
||||
<p className="text-h5 px-3">Video.js v10</p>
|
||||
<Logo width="10rem" />
|
||||
<Dialog.Close
|
||||
className={clsx(
|
||||
'flex items-center justify-center p-3 h-full aspect-square',
|
||||
dark
|
||||
? 'bg-light-80 text-dark-100 intent:bg-light-40'
|
||||
: 'bg-dark-100 text-light-80 intent:bg-dark-80 dark:bg-light-80 dark:text-dark-100 dark:intent:bg-light-40'
|
||||
'inline-flex items-stretch p-0.75 border-2 border-faded-black dark:border-manila-light rounded-xs'
|
||||
)}
|
||||
aria-label="Close navigation menu"
|
||||
>
|
||||
<X size={24} />
|
||||
<span
|
||||
className="font-display tracking-normal leading-none uppercase font-bold text-manila-light bg-faded-black dark:bg-manila-light dark:text-faded-black px-4 py-2.5"
|
||||
style={{ fontSize: '0.75rem' }}
|
||||
>
|
||||
Close
|
||||
</span>
|
||||
</Dialog.Close>
|
||||
</div>
|
||||
|
||||
<div className="overflow-y-scroll">
|
||||
{/* Astro makes it hard to know if we have children, so, we use -mt-px to hide the border-b if we don't */}
|
||||
<div className={clsx('-mt-px border-b', dark ? 'border-dark-80' : 'border-light-40 dark:border-dark-80')}>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
<div className="overflow-y-auto">
|
||||
<div className={clsx('')}>{children}</div>
|
||||
{/* Navigation links */}
|
||||
<nav className="flex flex-col py-3">
|
||||
<nav className="flex flex-col p-5">
|
||||
{navLinks.map((link) => {
|
||||
const isActive = link.matchPath && currentPath.startsWith(link.matchPath);
|
||||
const className = clsx('text-lg px-6 py-3', isActive ? 'underline' : 'intent:underline');
|
||||
const className = clsx(
|
||||
'intent:bg-manila-dark dark:intent:bg-warm-gray flex items-center justify-center px-5 py-3.5 font-display uppercase font-bold text-h5 text-center border-t border-faded-black dark:border-manila-dark',
|
||||
isActive ? 'text-stroke-faded-black dark:text-stroke-manila-light' : ''
|
||||
);
|
||||
|
||||
if (link.href === '/docs') {
|
||||
return (
|
||||
@@ -99,17 +95,28 @@ export default function MobileNav({ navLinks, currentPath, dark = false, childre
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
<a href={GITHUB_REPO_URL} className="text-lg px-6 py-3 inline-flex items-center gap-1 intent:underline">
|
||||
GitHub <ArrowUpRight size="1em" />
|
||||
</a>
|
||||
<a
|
||||
href={DISCORD_INVITE_URL}
|
||||
className="text-lg px-6 py-3 inline-flex items-center gap-1 intent:underline"
|
||||
className={clsx(
|
||||
'intent:bg-manila-dark dark:intent:bg-warm-gray flex items-center justify-center px-5 py-3.5 font-display uppercase font-bold text-h5 text-center border-t border-faded-black dark:border-manila-dark'
|
||||
)}
|
||||
target="_blank"
|
||||
>
|
||||
Discord <ArrowUpRight size="1em" />
|
||||
Discord
|
||||
</a>
|
||||
<a
|
||||
href={GITHUB_REPO_URL}
|
||||
className={clsx(
|
||||
'intent:bg-manila-dark dark:intent:bg-warm-gray flex items-center justify-center px-5 py-3.5 font-display uppercase font-bold text-h5 text-center border-t border-faded-black dark:border-manila-dark',
|
||||
'border-b'
|
||||
)}
|
||||
target="_blank"
|
||||
>
|
||||
GitHub
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
<p className="text-center p-6 mt-auto text-p2">The open source player for the web</p>
|
||||
</Dialog.Popup>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
---
|
||||
|
||||
import clsx from 'clsx';
|
||||
import { ArrowUpRight } from 'lucide-react';
|
||||
import Discord from '@/components/icons/Discord';
|
||||
import GitHub from '@/components/icons/GitHub';
|
||||
import Search from '@/components/Search';
|
||||
import Discord from '@/components/icons/discord.svg?react';
|
||||
import GitHub from '@/components/icons/github.svg?react';
|
||||
import Logo from '@/components/icons/logo.svg?react';
|
||||
import { DISCORD_INVITE_URL, GITHUB_REPO_URL } from '@/consts';
|
||||
import FilmGrain from '../FilmGrain';
|
||||
import Search from '../Search';
|
||||
import GetStartedLink from './GetStartedLink';
|
||||
import MobileNav from './MobileNav';
|
||||
|
||||
@@ -34,30 +33,27 @@ const { class: className, dark = false } = Astro.props;
|
||||
|
||||
<nav
|
||||
class:list={[
|
||||
'pl-3 flex justify-between sticky top-0 z-40 border-b',
|
||||
dark
|
||||
? 'bg-dark-100 text-light-80 border-dark-100 dark:border-dark-80'
|
||||
: 'bg-light-80 border-light-40 dark:bg-dark-100 dark:border-dark-80',
|
||||
"flex justify-between",
|
||||
"mx-auto w-full max-w-305 items-center px-5 py-7 md:py-10",
|
||||
className,
|
||||
]}
|
||||
style="height: var(--nav-h);"
|
||||
>
|
||||
{/* Grain */}
|
||||
<FilmGrain currentPath={Astro.url.pathname} />
|
||||
{/* Logo */}
|
||||
<a href="/" class="flex items-center px-3 text-h5">Video.js v10</a>
|
||||
|
||||
<Search dark={dark} class="ml-auto mr-4 sm:self-center" />
|
||||
|
||||
<a
|
||||
href="/"
|
||||
class="flex w-40 items-center lg:w-56"
|
||||
aria-label="Video.js v10 home"
|
||||
>
|
||||
<Logo width="100%" />
|
||||
</a>
|
||||
<Search class="mr-4 ml-auto sm:self-center" />
|
||||
{/* Desktop nav links */}
|
||||
<div class="hidden md:flex -mb-px pr-3">
|
||||
<div class="hidden md:flex">
|
||||
<GetStartedLink
|
||||
client:idle
|
||||
className={clsx(
|
||||
'h-full flex items-center px-3 border-b gap-1',
|
||||
isDocsActive ? 'border-current' : 'border-transparent intent:border-current',
|
||||
"flex items-center rounded-xs px-5 py-2 font-display font-bold uppercase intent:bg-manila-dark dark:intent:bg-warm-gray",
|
||||
)}
|
||||
aria-current={isDocsActive ? 'page' : undefined}
|
||||
aria-current={isDocsActive ? "page" : undefined}
|
||||
>
|
||||
Docs
|
||||
</GetStartedLink>
|
||||
@@ -66,39 +62,38 @@ const { class: className, dark = false } = Astro.props;
|
||||
<a
|
||||
href={link.href}
|
||||
class:list={[
|
||||
'h-full flex items-center px-3 border-b gap-1',
|
||||
link.matchPath && currentPath.startsWith(link.matchPath)
|
||||
? 'border-current'
|
||||
: 'border-transparent intent:border-current',
|
||||
"flex items-center rounded-xs px-5 py-2 font-display font-bold uppercase intent:bg-manila-dark dark:intent:bg-warm-gray",
|
||||
]}
|
||||
aria-current={link.matchPath && currentPath.startsWith(link.matchPath) ? 'page' : undefined}
|
||||
>
|
||||
{link.label} {link.external ? <ArrowUpRight size="1em" /> : null}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
<a
|
||||
href={GITHUB_REPO_URL}
|
||||
class="h-full flex items-center px-3 border-b border-transparent intent:border-current"
|
||||
aria-label="GitHub"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<GitHub size="1.1em" strokeWidth="0.0625em" />
|
||||
</a>
|
||||
<a
|
||||
href={DISCORD_INVITE_URL}
|
||||
class="h-full flex items-center px-3 border-b border-transparent intent:border-current"
|
||||
class={clsx(
|
||||
"flex items-center rounded-xs px-3 py-2 font-display font-bold uppercase intent:bg-manila-dark dark:intent:bg-warm-gray",
|
||||
)}
|
||||
aria-label="Discord"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Discord size="1.1em" strokeWidth="0.0625em" />
|
||||
<Discord width="1.5em" height="1.5em" />
|
||||
</a>
|
||||
<a
|
||||
href={GITHUB_REPO_URL}
|
||||
class={clsx(
|
||||
"flex items-center rounded-xs px-3 py-2 font-display font-bold uppercase intent:bg-manila-dark dark:intent:bg-warm-gray",
|
||||
)}
|
||||
aria-label="GitHub"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<GitHub width="1.5em" height="1.5em" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Mobile nav */}
|
||||
<MobileNav client:idle navLinks={navLinks} currentPath={currentPath} dark={dark}>
|
||||
<MobileNav client:idle navLinks={navLinks} currentPath={currentPath}>
|
||||
<slot name="mobile-nav" />
|
||||
</MobileNav>
|
||||
</nav>
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
import clsx from 'clsx';
|
||||
import { ArrowUpRight } from 'lucide-react';
|
||||
import Discord from '@/components/icons/discord.svg?react';
|
||||
import GitHub from '@/components/icons/github.svg?react';
|
||||
import LogoDocs from '@/components/icons/logo-docs.svg?react';
|
||||
import Search from '@/components/Search';
|
||||
import { DISCORD_INVITE_URL, GITHUB_REPO_URL } from '@/consts';
|
||||
import GetStartedLink from './GetStartedLink';
|
||||
import MobileNav from './MobileNav';
|
||||
|
||||
export interface Props {
|
||||
class?: string;
|
||||
}
|
||||
|
||||
type NavLink = {
|
||||
href: string;
|
||||
label: string;
|
||||
matchPath: string | null;
|
||||
external?: boolean;
|
||||
};
|
||||
const navLinks: NavLink[] = [
|
||||
{ href: '/docs', label: 'Docs', matchPath: '/docs' },
|
||||
{ href: '/blog', label: 'Blog', matchPath: '/blog' },
|
||||
];
|
||||
|
||||
const currentPath = Astro.url.pathname;
|
||||
const isDocsActive = currentPath.startsWith('/docs');
|
||||
const otherNavLinks = navLinks.filter((link) => link.href !== '/docs');
|
||||
const { class: className } = Astro.props;
|
||||
---
|
||||
|
||||
<nav
|
||||
class:list={[
|
||||
"sticky top-0 z-30 mx-auto flex w-full items-center justify-between border-b border-b-manila-75 bg-manila-light px-5 dark:border-warm-gray dark:bg-faded-black",
|
||||
className,
|
||||
]}
|
||||
style="height:var(--nav-h)"
|
||||
>
|
||||
<a href="/" class="flex items-center" aria-label="Video.js v10 home">
|
||||
<div class="relative w-40 md:w-49.5">
|
||||
<LogoDocs width="100%" />
|
||||
</div>
|
||||
</a>
|
||||
<Search class="mr-4 ml-auto sm:self-center" />
|
||||
{/* Desktop nav links */}
|
||||
<div class="hidden h-full md:flex">
|
||||
<GetStartedLink
|
||||
client:idle
|
||||
className={clsx(
|
||||
"flex items-center rounded-xs px-5 py-2 font-display text-h3 uppercase intent:bg-manila-dark dark:intent:bg-warm-gray",
|
||||
isDocsActive ? "relative z-10 text-orange" : "",
|
||||
)}
|
||||
aria-current={isDocsActive ? "page" : undefined}
|
||||
>
|
||||
Docs
|
||||
<hr class="absolute right-0 -bottom-px left-0 h-px bg-orange" />
|
||||
</GetStartedLink>
|
||||
{
|
||||
otherNavLinks.map((link) => (
|
||||
<a
|
||||
href={link.href}
|
||||
class:list={[
|
||||
"flex items-center rounded-xs px-5 py-2 font-display text-h3 uppercase intent:bg-manila-dark dark:intent:bg-warm-gray",
|
||||
]}
|
||||
>
|
||||
{link.label} {link.external ? <ArrowUpRight size="1em" /> : null}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
<a
|
||||
href={DISCORD_INVITE_URL}
|
||||
class={clsx(
|
||||
"my-1 flex items-center rounded-xs px-3 py-2 font-display font-bold uppercase intent:bg-manila-dark dark:intent:bg-warm-gray",
|
||||
)}
|
||||
aria-label="Discord"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Discord width="1.5em" height="1.5em" />
|
||||
</a>
|
||||
<a
|
||||
href={GITHUB_REPO_URL}
|
||||
class={clsx(
|
||||
"my-1 flex items-center rounded-xs px-3 py-2 font-display font-bold uppercase intent:bg-manila-dark dark:intent:bg-warm-gray",
|
||||
)}
|
||||
aria-label="GitHub"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<GitHub width="1.5em" height="1.5em" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<MobileNav client:idle navLinks={navLinks} currentPath={currentPath}>
|
||||
<slot name="mobile-nav" />
|
||||
</MobileNav>
|
||||
</nav>
|
||||
Reference in New Issue
Block a user