mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
fix(site): site accessibility rough edges (#1330)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
102dfd2971
commit
ddf5622b2f
@@ -55,16 +55,21 @@ export default function CopyButton({ children, copied, copyFrom, className, styl
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
ref={buttonRef}
|
||||
type="button"
|
||||
disabled={disabled}
|
||||
onClick={handleCopy}
|
||||
className={className}
|
||||
style={style}
|
||||
aria-label={isCopied ? 'Copied' : 'Copy to clipboard'}
|
||||
>
|
||||
{isCopied ? copied || children : children}
|
||||
</button>
|
||||
<>
|
||||
<button
|
||||
ref={buttonRef}
|
||||
type="button"
|
||||
disabled={disabled}
|
||||
onClick={handleCopy}
|
||||
className={className}
|
||||
style={style}
|
||||
aria-label={isCopied ? 'Copied' : 'Copy to clipboard'}
|
||||
>
|
||||
{isCopied ? copied || children : children}
|
||||
</button>
|
||||
<span aria-live="polite" className="sr-only">
|
||||
{isCopied ? 'Copied' : ''}
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -82,45 +82,50 @@ export default function CopyMarkdownButton({ className, style }: CopyMarkdownBut
|
||||
const ariaLabel = state.status === 'success' ? 'Copied' : 'Copy markdown to clipboard';
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
disabled={disabled}
|
||||
onClick={handleCopy}
|
||||
className={clsx(
|
||||
'relative border border-manila-75 dark:border-soot bg-manila-50 dark:bg-warm-gray px-3 py-1 rounded-xs whitespace-nowrap text-p3',
|
||||
state.status === 'idle' && 'intent:bg-manila-dark dark:intent:bg-soot',
|
||||
state.status === 'loading' ? 'opacity-70' : 'cursor-100',
|
||||
disabled ? 'cursor-wait' : 'cursor-pointer',
|
||||
className
|
||||
)}
|
||||
style={style}
|
||||
aria-label={ariaLabel}
|
||||
data-llms-ignore
|
||||
>
|
||||
<span
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
disabled={disabled}
|
||||
onClick={handleCopy}
|
||||
className={clsx(
|
||||
state.status !== 'idle' && state.status !== 'loading' ? 'opacity-0 pointer-events-none' : 'opacity-100',
|
||||
'inline-flex items-center justify-center'
|
||||
'relative border border-manila-75 dark:border-soot bg-manila-50 dark:bg-warm-gray px-3 py-1 rounded-xs whitespace-nowrap text-p3',
|
||||
state.status === 'idle' && 'intent:bg-manila-dark dark:intent:bg-soot',
|
||||
state.status === 'loading' ? 'opacity-70' : 'cursor-100',
|
||||
disabled ? 'cursor-wait' : 'cursor-pointer',
|
||||
className
|
||||
)}
|
||||
style={style}
|
||||
aria-label={ariaLabel}
|
||||
data-llms-ignore
|
||||
>
|
||||
Copy Markdown
|
||||
<span
|
||||
className={clsx(
|
||||
state.status !== 'idle' && state.status !== 'loading' ? 'opacity-0 pointer-events-none' : 'opacity-100',
|
||||
'inline-flex items-center justify-center'
|
||||
)}
|
||||
>
|
||||
Copy Markdown
|
||||
</span>
|
||||
<span
|
||||
className={clsx(
|
||||
state.status !== 'success' ? 'opacity-0 pointer-events-none' : 'opacity-100',
|
||||
'absolute inset-0 inline-flex items-center justify-center'
|
||||
)}
|
||||
>
|
||||
Copied <CheckIcon className="ml-1 w-4 h-4" />
|
||||
</span>
|
||||
<span
|
||||
className={clsx(
|
||||
state.status !== 'error' ? 'opacity-0 pointer-events-none' : 'opacity-100',
|
||||
'absolute inset-0 inline-flex items-center justify-center'
|
||||
)}
|
||||
>
|
||||
Error
|
||||
</span>
|
||||
</button>
|
||||
<span aria-live="polite" className="sr-only">
|
||||
{state.status === 'success' ? 'Copied' : state.status === 'error' ? 'Error copying markdown' : ''}
|
||||
</span>
|
||||
<span
|
||||
className={clsx(
|
||||
state.status !== 'success' ? 'opacity-0 pointer-events-none' : 'opacity-100',
|
||||
'absolute inset-0 inline-flex items-center justify-center'
|
||||
)}
|
||||
>
|
||||
Copied <CheckIcon className="ml-1 w-4 h-4" />
|
||||
</span>
|
||||
<span
|
||||
className={clsx(
|
||||
state.status !== 'error' ? 'opacity-0 pointer-events-none' : 'opacity-100',
|
||||
'absolute inset-0 inline-flex items-center justify-center'
|
||||
)}
|
||||
>
|
||||
Error
|
||||
</span>
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ export default function DialNav({ left, right }: DialNavProps) {
|
||||
<DialTag
|
||||
href={left[0].href}
|
||||
onClick={(e) => handleClick(e, left[0])}
|
||||
aria-hidden="true"
|
||||
tabIndex={-1}
|
||||
className="w-20 h-20 md:w-32 md:h-32 shrink-0 relative z-10 text-faded-black dark:text-manila-light [--fill:var(--color-manila-light)] dark:[--fill:var(--color-faded-black)]"
|
||||
>
|
||||
<DialOuter
|
||||
|
||||
@@ -30,7 +30,7 @@ const { class: className } = Astro.props;
|
||||
className,
|
||||
]}
|
||||
>
|
||||
<nav
|
||||
<div
|
||||
class="mb-2 items-start justify-between gap-3 border-faded-black pt-5 sm:mb-0 md:flex-row md:items-start md:border-t dark:border-manila-light"
|
||||
>
|
||||
<nav
|
||||
@@ -51,7 +51,10 @@ const { class: className } = Astro.props;
|
||||
href={link.href}
|
||||
class="flex items-center gap-1.5 rounded-xs px-2 py-2 font-display font-bold uppercase md:px-5 intent:bg-manila-dark dark:intent:bg-warm-gray"
|
||||
>
|
||||
{link.label} {link.external ? <ArrowUpRight size="1em" /> : null}
|
||||
{link.label}{" "}
|
||||
{link.external ? (
|
||||
<ArrowUpRight size="1em" aria-hidden="true" />
|
||||
) : null}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
@@ -109,5 +112,5 @@ const { class: className } = Astro.props;
|
||||
© 2010–{new Date().getFullYear()} Video.js contributors
|
||||
</p>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -30,7 +30,7 @@ const { class: className } = Astro.props;
|
||||
className,
|
||||
]}
|
||||
>
|
||||
<nav
|
||||
<div
|
||||
class="mb-2 items-start justify-between gap-3 border-faded-black px-5 pt-5 sm:mb-0 @4xl:flex-row @4xl:items-start @4xl:border-t @4xl:px-10 dark:border-warm-gray"
|
||||
>
|
||||
<nav
|
||||
@@ -51,7 +51,10 @@ const { class: className } = Astro.props;
|
||||
href={link.href}
|
||||
class="flex items-center gap-1.5 rounded-xs px-2 py-2 font-display font-bold uppercase @4xl:px-5 intent:bg-manila-dark dark:intent:bg-warm-gray"
|
||||
>
|
||||
{link.label} {link.external ? <ArrowUpRight size="1em" /> : null}
|
||||
{link.label}{" "}
|
||||
{link.external ? (
|
||||
<ArrowUpRight size="1em" aria-hidden="true" />
|
||||
) : null}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
@@ -100,5 +103,5 @@ const { class: className } = Astro.props;
|
||||
class="@5xl:hidden"
|
||||
/>© 2010–{new Date().getFullYear()} Video.js contributors
|
||||
</p>
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -96,7 +96,7 @@ export default function MobileNav({ navLinks, currentPath, children }: MobileNav
|
||||
className={className}
|
||||
aria-current={isActive ? 'page' : undefined}
|
||||
>
|
||||
{link.label} {link.external ? <ArrowUpRight size="1em" /> : null}
|
||||
{link.label} {link.external ? <ArrowUpRight size="1em" aria-hidden="true" /> : null}
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
@@ -106,6 +106,7 @@ export default function MobileNav({ navLinks, currentPath, children }: MobileNav
|
||||
'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"
|
||||
rel="noopener"
|
||||
>
|
||||
Discord
|
||||
</a>
|
||||
@@ -116,6 +117,7 @@ export default function MobileNav({ navLinks, currentPath, children }: MobileNav
|
||||
'border-b'
|
||||
)}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
GitHub
|
||||
</a>
|
||||
|
||||
@@ -33,6 +33,7 @@ const { class: className, dark = false } = Astro.props;
|
||||
---
|
||||
|
||||
<nav
|
||||
aria-label="Video.js"
|
||||
class:list={[
|
||||
"flex justify-between",
|
||||
"mx-auto w-full max-w-305 items-center px-5 py-7 md:py-10",
|
||||
@@ -64,7 +65,10 @@ const { class: className, dark = false } = Astro.props;
|
||||
"flex items-center rounded-xs px-5 py-2 font-display font-bold uppercase intent:bg-manila-dark dark:intent:bg-warm-gray",
|
||||
]}
|
||||
>
|
||||
{link.label} {link.external ? <ArrowUpRight size="1em" /> : null}
|
||||
{link.label}{" "}
|
||||
{link.external ? (
|
||||
<ArrowUpRight size="1em" aria-hidden="true" />
|
||||
) : null}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ const { class: className } = Astro.props;
|
||||
---
|
||||
|
||||
<nav
|
||||
aria-label="Video.js"
|
||||
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,
|
||||
@@ -55,7 +56,10 @@ const { class: className } = Astro.props;
|
||||
aria-current={isDocsActive ? "page" : undefined}
|
||||
>
|
||||
Docs
|
||||
<hr class="absolute right-0 -bottom-px left-0 h-px bg-orange" />
|
||||
<hr
|
||||
aria-hidden="true"
|
||||
class="absolute right-0 -bottom-px left-0 h-px bg-orange"
|
||||
/>
|
||||
</GetStartedLink>
|
||||
{
|
||||
otherNavLinks.map((link) => (
|
||||
@@ -65,7 +69,10 @@ const { class: className } = Astro.props;
|
||||
"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}
|
||||
{link.label}{" "}
|
||||
{link.external ? (
|
||||
<ArrowUpRight size="1em" aria-hidden="true" />
|
||||
) : null}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
|
||||
@@ -94,7 +94,8 @@ interface TabsListProps {
|
||||
export function TabsList({ label, children, variant = 'compact' }: TabsListProps) {
|
||||
return (
|
||||
<div className={clsx('w-full flex items-center p-0 h-12', variant === 'compact' ? 'p-0' : 'px-2.5')}>
|
||||
<ul
|
||||
<div
|
||||
role="tablist"
|
||||
data-orientation="horizontal"
|
||||
aria-label={label}
|
||||
className={clsx(
|
||||
@@ -103,7 +104,7 @@ export function TabsList({ label, children, variant = 'compact' }: TabsListProps
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</ul>
|
||||
</div>
|
||||
<CopyButton
|
||||
copyFrom={{
|
||||
container: `[data-tabs-root]`,
|
||||
@@ -219,7 +220,7 @@ export function Tab({ value, children, initial, variant = 'compact' }: TabProps)
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<li key={value} role="presentation" className={clsx('flex', variant === 'compact' && 'border-r border-manila-75')}>
|
||||
<div key={value} className={clsx('flex', variant === 'compact' && 'border-r border-manila-75')}>
|
||||
<button
|
||||
ref={ref}
|
||||
type="button"
|
||||
@@ -252,13 +253,13 @@ export function Tab({ value, children, initial, variant = 'compact' }: TabProps)
|
||||
)}
|
||||
<span className="relative">
|
||||
{/* to prevent layout shift on state change, we have an invisible bold version of the text preserving space */}
|
||||
<span className="font-bold invisible" data-search-ignore data-llms-ignore>
|
||||
<span className="font-bold invisible" aria-hidden="true" data-search-ignore data-llms-ignore>
|
||||
{children}
|
||||
</span>
|
||||
<span className={clsx('absolute top-0 left-0', isActive && 'font-bold')}>{children}</span>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ export function ThemeToggle() {
|
||||
|
||||
return (
|
||||
<ToggleGroup
|
||||
aria-label="Color theme"
|
||||
disabled={preference === null}
|
||||
value={preference ? [preference] : []}
|
||||
onChange={(values) => {
|
||||
|
||||
@@ -16,7 +16,10 @@ function getGuideUrl(framework: SupportedFramework, slug: string): string {
|
||||
}
|
||||
---
|
||||
|
||||
<nav class="mx-auto grid w-full max-w-3xl grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<nav
|
||||
aria-label="Docs pagination"
|
||||
class="mx-auto grid w-full max-w-3xl grid-cols-1 gap-4 md:grid-cols-2"
|
||||
>
|
||||
{
|
||||
prev ? (
|
||||
<a
|
||||
|
||||
@@ -19,7 +19,7 @@ const filteredSidebar = filterSidebar(framework);
|
||||
<div class={clsx("bg-manila-light dark:bg-faded-black", className)}>
|
||||
<slot />
|
||||
<PreferenceUpdater client:idle currentFramework={framework} />
|
||||
<nav class="p-6">
|
||||
<nav aria-label="Docs sidebar" class="p-6">
|
||||
{
|
||||
filteredSidebar.map((item) => (
|
||||
<SidebarItem item={item} framework={framework} docTitles={docTitles} />
|
||||
|
||||
@@ -69,7 +69,11 @@ function getGroupRotate(depth: number) {
|
||||
}
|
||||
>
|
||||
<span class="flex-1">{item.sidebarLabel}</span>
|
||||
<DropdownIcon width={"0.65rem"} className={getGroupRotate(depth)} />
|
||||
<DropdownIcon
|
||||
width={"0.65rem"}
|
||||
className={getGroupRotate(depth)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</summary>
|
||||
<div>
|
||||
{item.contents.map((contentItem) => (
|
||||
|
||||
@@ -38,6 +38,7 @@ import GetStartedLink from '../NavBar/GetStartedLink';
|
||||
|
||||
<GetStartedLink
|
||||
client:idle
|
||||
aria-label="Get started"
|
||||
className={clsx(
|
||||
"relative z-10 ml-auto flex h-15 items-center justify-center text-faded-black lg:h-25 lg:w-40 lg:pr-2.5 dark:text-orange",
|
||||
)}
|
||||
|
||||
@@ -4,21 +4,15 @@ import BetaPill from '@/components/BetaPill';
|
||||
import FrameworkControl from '@/components/home/FrameworkControl';
|
||||
import HeroVideo from '@/components/home/HeroVideo';
|
||||
import SkinControl from '@/components/home/SkinControl';
|
||||
import { MUX_URL, VJS10_DEMO_VIDEO } from '@/consts';
|
||||
import { MUX_URL } from '@/consts';
|
||||
|
||||
const times = [0, 12.9, 17.61, 15.8, 7.72, 4.8, 3.3];
|
||||
const posterTime = times[Math.floor(Math.random() * times.length)];
|
||||
const poster = `${VJS10_DEMO_VIDEO.poster}?time=${posterTime}`;
|
||||
interface Props {
|
||||
poster: string;
|
||||
}
|
||||
|
||||
const { poster } = Astro.props;
|
||||
---
|
||||
|
||||
<link
|
||||
rel="preload"
|
||||
href={poster}
|
||||
as="image"
|
||||
type="image/webp"
|
||||
fetchpriority="high"
|
||||
slot="priority-head"
|
||||
/>
|
||||
<header
|
||||
class="relative mx-auto mb-25 grid w-full max-w-305 grid-cols-1 px-5 pt-19 [grid-template-areas:var(--grid-template-areas)] md:py-0 md:[grid-template-areas:var(--md-grid-template-areas)]"
|
||||
style="--grid-template-areas: 'pill' 'title' 'description' 'video' 'mux' 'control'; --md-grid-template-areas: 'video' 'mux' 'description' 'control'"
|
||||
@@ -60,6 +54,7 @@ const poster = `${VJS10_DEMO_VIDEO.poster}?time=${posterTime}`;
|
||||
href={MUX_URL}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
aria-label="Mux"
|
||||
>
|
||||
<MuxLogoSmall width="100%" />
|
||||
</a>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { MUX_URL } from '@/consts';
|
||||
|
||||
type SponsorItem = {
|
||||
Logo: ComponentType<SVGProps<SVGSVGElement>>;
|
||||
name: string;
|
||||
label: string;
|
||||
href: string;
|
||||
width: string;
|
||||
@@ -17,10 +18,22 @@ type SponsorItem = {
|
||||
};
|
||||
|
||||
const sponsors: SponsorItem[] = [
|
||||
{ Logo: FastlyLogo, label: 'CDN', href: 'https://fastly.com/', width: '7.8rem' },
|
||||
{ Logo: BrightcoveLogo, label: 'Emeritus Sponsor', href: 'https://brightcove.com/', width: '11rem' },
|
||||
{ Logo: BrowserStackLogo, label: 'Device Testing', href: 'https://browserstack.com/', width: '12rem' },
|
||||
{ Logo: NetlifyLogo, label: 'Static Hosting', href: 'https://netlify.com/', width: '11rem' },
|
||||
{ Logo: FastlyLogo, name: 'Fastly', label: 'CDN', href: 'https://fastly.com/', width: '7.8rem' },
|
||||
{
|
||||
Logo: BrightcoveLogo,
|
||||
name: 'Brightcove',
|
||||
label: 'Emeritus Sponsor',
|
||||
href: 'https://brightcove.com/',
|
||||
width: '11rem',
|
||||
},
|
||||
{
|
||||
Logo: BrowserStackLogo,
|
||||
name: 'BrowserStack',
|
||||
label: 'Device Testing',
|
||||
href: 'https://browserstack.com/',
|
||||
width: '12rem',
|
||||
},
|
||||
{ Logo: NetlifyLogo, name: 'Netlify', label: 'Static Hosting', href: 'https://netlify.com/', width: '11rem' },
|
||||
];
|
||||
---
|
||||
|
||||
@@ -41,6 +54,7 @@ const sponsors: SponsorItem[] = [
|
||||
href={MUX_URL}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
aria-label="Mux"
|
||||
class="flex h-45 items-center justify-center bg-faded-black md:h-full md:min-h-74 dark:bg-soot dark:text-manila-light"
|
||||
>
|
||||
<div class="relative w-40 md:w-48">
|
||||
@@ -70,7 +84,7 @@ const sponsors: SponsorItem[] = [
|
||||
class="grid gap-4 md:grid-separator-container md:grid-cols-4 md:gap-0 md:border md:border-manila-light dark:border-faded-black dark:text-manila-light"
|
||||
>
|
||||
{
|
||||
sponsors.map(({ Logo, label, href, width, className }) => (
|
||||
sponsors.map(({ Logo, name, label, href, width, className }) => (
|
||||
<div
|
||||
class={clsx(
|
||||
"h-auto rounded-xs border border-faded-black px-2.5 md:border-0 md:border-manila-dark md:px-0 dark:border-manila-light md:dark:border-warm-gray",
|
||||
@@ -81,6 +95,7 @@ const sponsors: SponsorItem[] = [
|
||||
href={href}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
aria-label={name}
|
||||
class="relative flex h-32.5 items-center justify-center bg-manila-light md:grid-separators md:h-37.5 dark:bg-faded-black"
|
||||
>
|
||||
<div class="mx-2.5 max-w-full" style={{ width }}>
|
||||
|
||||
Reference in New Issue
Block a user