From 382b9351f97ace8560050997f94fe655ae0ff8ca Mon Sep 17 00:00:00 2001 From: Reid Barber Date: Fri, 14 Nov 2025 16:21:26 -0600 Subject: [PATCH 1/2] docs: S2 docs skeleton loading improvements (#9186) * add delay for showing page skeleton * use fake image for SkeletonVisualExample in PageSkeleton * fix optimistic rendering of the sidenav * move delay into skeleton and fix clicking already selected link --------- Co-authored-by: Devon Govett --- packages/dev/s2-docs/src/Layout.tsx | 162 +++++++++--------- packages/dev/s2-docs/src/Nav.tsx | 62 +------ .../dev/s2-docs/src/NavigationSuspense.tsx | 35 +++- packages/dev/s2-docs/src/OptimisticToc.tsx | 8 +- packages/dev/s2-docs/src/PageSkeleton.tsx | 41 ++--- packages/dev/s2-docs/src/client.tsx | 8 +- 6 files changed, 143 insertions(+), 173 deletions(-) diff --git a/packages/dev/s2-docs/src/Layout.tsx b/packages/dev/s2-docs/src/Layout.tsx index 43757368e28..a466d175b84 100644 --- a/packages/dev/s2-docs/src/Layout.tsx +++ b/packages/dev/s2-docs/src/Layout.tsx @@ -1,5 +1,5 @@ import {ExampleList} from './ExampleList'; -import {Nav, PendingPageProvider} from '../src/Nav'; +import {Nav} from '../src/Nav'; import {OptimisticMobileToc, OptimisticToc} from './OptimisticToc'; import type {Page, PageProps} from '@parcel/rsc'; import React, {ReactElement} from 'react'; @@ -254,93 +254,91 @@ export function Layout(props: PageProps & {children: ReactElement}) { } })}>
- - } - pages={pages} - currentPage={currentPage} /> -
- {currentPage.exports?.hideNav ? null :
diff --git a/packages/dev/s2-docs/src/Nav.tsx b/packages/dev/s2-docs/src/Nav.tsx index cd1c00c64d1..2e5116d482f 100644 --- a/packages/dev/s2-docs/src/Nav.tsx +++ b/packages/dev/s2-docs/src/Nav.tsx @@ -2,36 +2,11 @@ import {focusRing, size, style} from '@react-spectrum/s2/style' with {type: 'macro'}; import {getLibraryFromPage} from './library'; +import {getPageFromPathname, getSnapshot, subscribe} from './NavigationSuspense'; import {Link} from 'react-aria-components'; import type {Page, PageProps} from '@parcel/rsc'; import {Picker, pressScale} from '@react-spectrum/s2'; -import React, {createContext, startTransition, useContext, useEffect, useOptimistic, useRef, useState} from 'react'; - -export function PendingPageProvider({children, currentPage}: {children: React.ReactNode, currentPage: Page}) { - let [displayPage, setDisplayPage] = useOptimistic( - currentPage, - (_, pendingPage: Page) => pendingPage - ); - - useEffect(() => { - const unsubscribe = subscribeToClearPendingPage(() => { - startTransition(() => { - setDisplayPage(currentPage); - }); - }); - return unsubscribe; - }, [currentPage, setDisplayPage]); - - let pendingPage = displayPage.url !== currentPage.url ? displayPage : null; - - return ( - - - {children} - - - ); -} +import React, {createContext, useContext, useEffect, useRef, useState, useSyncExternalStore} from 'react'; export function Nav({pages, currentPage}: PageProps) { let currentLibrary = getLibraryFromPage(currentPage); @@ -56,7 +31,8 @@ export function Nav({pages, currentPage}: PageProps) { } let [maskSize, setMaskSize] = useState(0); - let pendingPage = usePendingPage(); + const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot); + const pendingPage = snapshot.pathname ? getPageFromPathname(pages, snapshot.pathname) : null; let displayUrl = pendingPage?.url ?? currentPage.url; let sortedSections = [...sections].sort((a, b) => { @@ -137,24 +113,10 @@ function SideNavSection({title, children}) { } const SideNavContext = createContext(''); -const PendingNavContext = createContext | null>(null); -const PendingPageContext = createContext(null); - -let clearPendingPageListeners = new Set<() => void>(); - -function subscribeToClearPendingPage(callback: () => void): () => void { - clearPendingPageListeners.add(callback); - return () => { - void clearPendingPageListeners.delete(callback); - }; -} -export function clearPendingPage() { - clearPendingPageListeners.forEach(callback => callback()); -} - -export function usePendingPage() { - return useContext(PendingPageContext); +export function usePendingPage(pages: Page[]): Page | null { + const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot); + return snapshot.pathname ? getPageFromPathname(pages, snapshot.pathname) : null; } export function SideNav({children, isNested = false}) { @@ -194,8 +156,7 @@ export function SideNavItem(props) { export function SideNavLink(props) { let linkRef = useRef(null); let selected = useContext(SideNavContext); - let setPendingPage = useContext(PendingNavContext); - let {page, ...linkProps} = props; + let {...linkProps} = props; return ( { - if (setPendingPage && page) { - startTransition(() => { - setPendingPage(page); - }); - } - }} className={style({ ...focusRing(), minHeight: 32, diff --git a/packages/dev/s2-docs/src/NavigationSuspense.tsx b/packages/dev/s2-docs/src/NavigationSuspense.tsx index 9cc4461df43..f06d0c2d979 100644 --- a/packages/dev/s2-docs/src/NavigationSuspense.tsx +++ b/packages/dev/s2-docs/src/NavigationSuspense.tsx @@ -2,19 +2,21 @@ import type {Page} from '@parcel/rsc'; import {PageSkeleton} from './PageSkeleton'; -import React, {Suspense, use, useSyncExternalStore} from 'react'; +import React, {Suspense, use, useEffect, useState, useSyncExternalStore} from 'react'; + +const SKELETON_DELAY = 150; let navigationPromise: Promise | null = null; let targetPathname: string | null = null; let listeners = new Set<() => void>(); let cachedSnapshot: {promise: Promise | null, pathname: string | null} = {promise: null, pathname: null}; -function subscribe(callback: () => void) { +export function subscribe(callback: () => void) { listeners.add(callback); return () => listeners.delete(callback); } -function getSnapshot() { +export function getSnapshot() { if (cachedSnapshot.promise !== navigationPromise || cachedSnapshot.pathname !== targetPathname) { cachedSnapshot = {promise: navigationPromise, pathname: targetPathname}; } @@ -66,9 +68,9 @@ function getPageTitle(page: Page): string { return page.exports?.title ?? page.tableOfContents?.[0]?.title ?? page.name; } -function getPageInfo(pages: Page[], pathname: string | null): {title?: string, section?: string, hasToC?: boolean} { +export function getPageFromPathname(pages: Page[], pathname: string | null): Page | null { if (!pathname) { - return {}; + return null; } let publicUrl = process.env.PUBLIC_URL || '/'; @@ -85,6 +87,12 @@ function getPageInfo(pages: Page[], pathname: string | null): {title?: string, s normalizedPageUrl === normalizedPathname + '.html'; }); + return targetPage ?? null; +} + +function getPageInfo(pages: Page[], pathname: string | null): {title?: string, section?: string, hasToC?: boolean} { + const targetPage = getPageFromPathname(pages, pathname); + if (!targetPage) { return {}; } @@ -99,9 +107,22 @@ function getPageInfo(pages: Page[], pathname: string | null): {title?: string, s function NavigationContent({children}: {children: React.ReactNode}) { // Subscribe to navigation promise changes to ensure React re-renders when setNavigationPromise() is called. const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot); - if (snapshot.promise) { - use(snapshot.promise); + let [delayedPromise, setDelayedPromise] = useState | null>(null); + useEffect(() => { + let promise = snapshot.promise; + if (!promise) { + return; + } + let timeout = setTimeout(() => { + setDelayedPromise(promise); + }, SKELETON_DELAY); + return () => clearTimeout(timeout); + }, [snapshot]); + + if (delayedPromise) { + use(delayedPromise); } + return <>{children}; } diff --git a/packages/dev/s2-docs/src/OptimisticToc.tsx b/packages/dev/s2-docs/src/OptimisticToc.tsx index 6a75d0c2135..340c18845bd 100644 --- a/packages/dev/s2-docs/src/OptimisticToc.tsx +++ b/packages/dev/s2-docs/src/OptimisticToc.tsx @@ -43,8 +43,8 @@ function renderMobileToc(toc: TocNode[], seen = new Map()) { }); } -export function OptimisticToc({currentPage}: {currentPage: Page}) { - let pendingPage = usePendingPage(); +export function OptimisticToc({currentPage, pages}: {currentPage: Page, pages: Page[]}) { + let pendingPage = usePendingPage(pages); let displayPage = pendingPage ?? currentPage; return ( @@ -61,8 +61,8 @@ export function OptimisticToc({currentPage}: {currentPage: Page}) { ); } -export function OptimisticMobileToc({currentPage}: {currentPage: Page}) { - let pendingPage = usePendingPage(); +export function OptimisticMobileToc({currentPage, pages}: {currentPage: Page, pages: Page[]}) { + let pendingPage = usePendingPage(pages); let displayPage = pendingPage ?? currentPage; if ((displayPage.tableOfContents?.[0]?.children?.length ?? 0) <= 1) { diff --git a/packages/dev/s2-docs/src/PageSkeleton.tsx b/packages/dev/s2-docs/src/PageSkeleton.tsx index 2c59cff79c6..ba149d626a1 100644 --- a/packages/dev/s2-docs/src/PageSkeleton.tsx +++ b/packages/dev/s2-docs/src/PageSkeleton.tsx @@ -1,8 +1,8 @@ 'use client'; import {getTextWidth} from './textWidth'; +import {Image, Skeleton, Text} from '@react-spectrum/s2'; import React from 'react'; -import {Skeleton, Text} from '@react-spectrum/s2'; import {style} from '@react-spectrum/s2/style' with {type: 'macro'}; const h1 = style({ @@ -34,27 +34,28 @@ const skeletonH2 = style({ width: '40%' }); -const skeletonVisualExample = style({ - backgroundColor: 'layer-1', - padding: { - default: 12, - lg: 24 - }, - marginTop: { - default: 20 - }, - borderRadius: 'xl', - width: 'full', - boxSizing: 'border-box', - minHeight: { - default: 200, - lg: 300 - } -}); - function SkeletonVisualExample() { return ( -
+ Loading example ); } diff --git a/packages/dev/s2-docs/src/client.tsx b/packages/dev/s2-docs/src/client.tsx index d58afb25a64..eb8d26f77da 100644 --- a/packages/dev/s2-docs/src/client.tsx +++ b/packages/dev/s2-docs/src/client.tsx @@ -1,6 +1,5 @@ 'use client-entry'; -import {clearPendingPage} from './Nav'; import {fetchRSC, hydrate} from '@parcel/rsc/client'; import {getPrefetchedPromise, prefetchRoute} from './prefetch'; import {type ReactElement} from 'react'; @@ -14,7 +13,6 @@ let isClientLink = (link: HTMLAnchorElement, pathname: string) => { link.href && (!link.target || link.target === '_self') && link.origin === location.origin && - (link.pathname !== location.pathname || link.hash) && !link.hasAttribute('download') && link.pathname.startsWith(pathname) ); @@ -124,7 +122,6 @@ async function navigate(pathname: string, push = false) { return; } - clearPendingPage(); try { let errorRes = await fetchRSC('/error.rsc'); @@ -151,7 +148,6 @@ async function navigate(pathname: string, push = false) { } })(); - // Store the promise for NavigationSuspense to use setNavigationPromise(navigationPromise, pathname); } @@ -177,7 +173,7 @@ document.addEventListener('pointerover', e => { // Clear any pending prefetch clearPrefetchTimeout(); - if (link && isClientLink(link, publicUrlPathname)) { + if (link && isClientLink(link, publicUrlPathname) && link.pathname !== location.pathname) { currentPrefetchLink = link; prefetchTimeout = setTimeout(() => { prefetchRoute(link.pathname + link.search + link.hash); @@ -202,7 +198,7 @@ document.addEventListener('focus', e => { // Clear any pending prefetch clearPrefetchTimeout(); - if (link && isClientLink(link, publicUrlPathname)) { + if (link && isClientLink(link, publicUrlPathname) && link.pathname !== location.pathname) { currentPrefetchLink = link; prefetchTimeout = setTimeout(() => { prefetchRoute(link.pathname + link.search + link.hash); From 93d39fd65807488680ee3ba1a5c233789ab42567 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Fri, 14 Nov 2025 14:38:07 -0800 Subject: [PATCH 2/2] chore: Update Spectrum fonts for Arabic and Hebrew (#9187) * chore: Update Spectrum fonts for Arabic and Hebrew * lint --- .../@react-spectrum/s2/src/font-faces.css | 69 +++++++++++++------ .../s2/stories/ActionButton.stories.tsx | 4 +- .../s2/style/spectrum-theme.ts | 15 ++-- 3 files changed, 53 insertions(+), 35 deletions(-) diff --git a/packages/@react-spectrum/s2/src/font-faces.css b/packages/@react-spectrum/s2/src/font-faces.css index 56445ff5946..b177ee76f01 100644 --- a/packages/@react-spectrum/s2/src/font-faces.css +++ b/packages/@react-spectrum/s2/src/font-faces.css @@ -16,8 +16,7 @@ font-stretch: normal; } -/* There are currently no italics in Spectrum. Uncomment these if needed. */ -/* +/* Italics are not used by Spectrum components, but may be used in user-generated content. */ @font-face { font-family: "adobe-clean-spectrum-vf"; src: url("https://use.typekit.net/af/8a3244/0000000000000000775c55a2/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=i1&v=3") format("woff2"), url("https://use.typekit.net/af/8a3244/0000000000000000775c55a2/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=i1&v=3") format("woff"), url("https://use.typekit.net/af/8a3244/0000000000000000775c55a2/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=i1&v=3") format("opentype"); @@ -35,38 +34,46 @@ font-weight: 100 1000; font-stretch: normal; } -*/ @font-face { - font-family: "myriad-arabic"; - src: url("https://use.typekit.net/af/dfb464/00000000000000007735a2f9/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("woff2"), url("https://use.typekit.net/af/dfb464/00000000000000007735a2f9/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("woff"), url("https://use.typekit.net/af/dfb464/00000000000000007735a2f9/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("opentype"); + font-family: "adobe-clean-arabic"; + src: url("https://use.typekit.net/af/ce4383/0000000000000000775e72dc/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("woff2"), url("https://use.typekit.net/af/ce4383/0000000000000000775e72dc/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("woff"), url("https://use.typekit.net/af/ce4383/0000000000000000775e72dc/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("opentype"); font-display: auto; font-style: normal; - font-weight: 700; + font-weight: 400; font-stretch: normal; } @font-face { - font-family: "myriad-arabic"; - src: url("https://use.typekit.net/af/560a53/00000000000000007735a300/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("woff2"), url("https://use.typekit.net/af/560a53/00000000000000007735a300/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("woff"), url("https://use.typekit.net/af/560a53/00000000000000007735a300/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("opentype"); + font-family: "adobe-clean-arabic"; + src: url("https://use.typekit.net/af/502696/0000000000000000775e72d7/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n5&v=3") format("woff2"), url("https://use.typekit.net/af/502696/0000000000000000775e72d7/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n5&v=3") format("woff"), url("https://use.typekit.net/af/502696/0000000000000000775e72d7/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n5&v=3") format("opentype"); font-display: auto; font-style: normal; - font-weight: 400; + font-weight: 500; font-stretch: normal; } @font-face { - font-family: "myriad-arabic"; - src: url("https://use.typekit.net/af/0f9162/00000000000000007735a307/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n6&v=3") format("woff2"), url("https://use.typekit.net/af/0f9162/00000000000000007735a307/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n6&v=3") format("woff"), url("https://use.typekit.net/af/0f9162/00000000000000007735a307/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n6&v=3") format("opentype"); + font-family: "adobe-clean-arabic"; + src: url("https://use.typekit.net/af/756050/0000000000000000775e72db/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("woff2"), url("https://use.typekit.net/af/756050/0000000000000000775e72db/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("woff"), url("https://use.typekit.net/af/756050/0000000000000000775e72db/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("opentype"); font-display: auto; font-style: normal; - font-weight: 600; + font-weight: 700; font-stretch: normal; } @font-face { - font-family: "myriad-arabic"; - src: url("https://use.typekit.net/af/ab2792/00000000000000007735a309/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n9&v=3") format("woff2"), url("https://use.typekit.net/af/ab2792/00000000000000007735a309/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n9&v=3") format("woff"), url("https://use.typekit.net/af/ab2792/00000000000000007735a309/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n9&v=3") format("opentype"); + font-family: "adobe-clean-arabic"; + src: url("https://use.typekit.net/af/6adae5/0000000000000000775e72d9/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n8&v=3") format("woff2"), url("https://use.typekit.net/af/6adae5/0000000000000000775e72d9/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n8&v=3") format("woff"), url("https://use.typekit.net/af/6adae5/0000000000000000775e72d9/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n8&v=3") format("opentype"); + font-display: auto; + font-style: normal; + font-weight: 800; + font-stretch: normal; +} + +@font-face { + font-family: "adobe-clean-arabic"; + src: url("https://use.typekit.net/af/cccd38/0000000000000000775e72dd/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n9&v=3") format("woff2"), url("https://use.typekit.net/af/cccd38/0000000000000000775e72dd/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n9&v=3") format("woff"), url("https://use.typekit.net/af/cccd38/0000000000000000775e72dd/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n9&v=3") format("opentype"); font-display: auto; font-style: normal; font-weight: 900; @@ -74,8 +81,26 @@ } @font-face { - font-family: "myriad-hebrew"; - src: url("https://use.typekit.net/af/ffca46/00000000000000007735a30a/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("woff2"), url("https://use.typekit.net/af/ffca46/00000000000000007735a30a/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("woff"), url("https://use.typekit.net/af/ffca46/00000000000000007735a30a/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("opentype"); + font-family: "adobe-clean-hebrew"; + src: url("https://use.typekit.net/af/6c5b6b/0000000000000000775e7343/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("woff2"), url("https://use.typekit.net/af/6c5b6b/0000000000000000775e7343/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("woff"), url("https://use.typekit.net/af/6c5b6b/0000000000000000775e7343/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("opentype"); + font-display: auto; + font-style: normal; + font-weight: 400; + font-stretch: normal; +} + +@font-face { + font-family: "adobe-clean-hebrew"; + src: url("https://use.typekit.net/af/6d4553/0000000000000000775e7345/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n5&v=3") format("woff2"), url("https://use.typekit.net/af/6d4553/0000000000000000775e7345/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n5&v=3") format("woff"), url("https://use.typekit.net/af/6d4553/0000000000000000775e7345/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n5&v=3") format("opentype"); + font-display: auto; + font-style: normal; + font-weight: 500; + font-stretch: normal; +} + +@font-face { + font-family: "adobe-clean-hebrew"; + src: url("https://use.typekit.net/af/f7ca66/0000000000000000775e7341/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("woff2"), url("https://use.typekit.net/af/f7ca66/0000000000000000775e7341/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("woff"), url("https://use.typekit.net/af/f7ca66/0000000000000000775e7341/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n7&v=3") format("opentype"); font-display: auto; font-style: normal; font-weight: 700; @@ -83,20 +108,20 @@ } @font-face { - font-family: "myriad-hebrew"; - src: url("https://use.typekit.net/af/e90860/00000000000000007735a313/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("woff2"), url("https://use.typekit.net/af/e90860/00000000000000007735a313/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("woff"), url("https://use.typekit.net/af/e90860/00000000000000007735a313/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n4&v=3") format("opentype"); + font-family: "adobe-clean-hebrew"; + src: url("https://use.typekit.net/af/329f4d/0000000000000000775e7342/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n8&v=3") format("woff2"), url("https://use.typekit.net/af/329f4d/0000000000000000775e7342/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n8&v=3") format("woff"), url("https://use.typekit.net/af/329f4d/0000000000000000775e7342/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n8&v=3") format("opentype"); font-display: auto; font-style: normal; - font-weight: 400; + font-weight: 800; font-stretch: normal; } @font-face { - font-family: "myriad-hebrew"; - src: url("https://use.typekit.net/af/619974/00000000000000007735a31f/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n6&v=3") format("woff2"), url("https://use.typekit.net/af/619974/00000000000000007735a31f/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n6&v=3") format("woff"), url("https://use.typekit.net/af/619974/00000000000000007735a31f/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n6&v=3") format("opentype"); + font-family: "adobe-clean-hebrew"; + src: url("https://use.typekit.net/af/34b661/0000000000000000775e733f/31/l?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n9&v=3") format("woff2"), url("https://use.typekit.net/af/34b661/0000000000000000775e733f/31/d?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n9&v=3") format("woff"), url("https://use.typekit.net/af/34b661/0000000000000000775e733f/31/a?primer=f592e0a4b9356877842506ce344308576437e4f677d7c9b78ca2162e6cad991a&fvd=n9&v=3") format("opentype"); font-display: auto; font-style: normal; - font-weight: 600; + font-weight: 900; font-stretch: normal; } diff --git a/packages/@react-spectrum/s2/stories/ActionButton.stories.tsx b/packages/@react-spectrum/s2/stories/ActionButton.stories.tsx index f0af9092a47..ac6e630ffd4 100644 --- a/packages/@react-spectrum/s2/stories/ActionButton.stories.tsx +++ b/packages/@react-spectrum/s2/stories/ActionButton.stories.tsx @@ -127,14 +127,14 @@ export const Fonts: Story = { {messages['en-US'].cut} {messages['en-US'].paste} - Arabic (myriad-arabic) + Arabic (adobe-clean-arabic) {messages['ar-AR'].button} {messages['ar-AR'].copy} {messages['ar-AR'].cut} {messages['ar-AR'].paste} - Hebrew (myriad-hebrew) + Hebrew (adobe-clean-hebrew) {messages['he-IL'].button} {messages['he-IL'].copy} diff --git a/packages/@react-spectrum/s2/style/spectrum-theme.ts b/packages/@react-spectrum/s2/style/spectrum-theme.ts index 281c759c421..2db0fe14fa6 100644 --- a/packages/@react-spectrum/s2/style/spectrum-theme.ts +++ b/packages/@react-spectrum/s2/style/spectrum-theme.ts @@ -434,8 +434,7 @@ let durationValue = (value: number | string) => typeof value === 'number' ? valu const fontWeightBase = { normal: '400', medium: { - default: '500', - ':lang(ar, he)': '600' // Myriad does not have a 500 weight + default: '500' }, bold: { default: '700', @@ -443,8 +442,7 @@ const fontWeightBase = { }, 'extra-bold': { default: '800', - ':lang(ja, ko, zh)': '700', // Adobe Clean Han uses 700 as the extra bold weight. - ':lang(ar, he)': '700' // Myriad does not have a 800 weight + ':lang(ja, ko, zh)': '700' // Adobe Clean Han uses 700 as the extra bold weight. }, black: '900' } as const; @@ -466,8 +464,8 @@ const fontWeight = { } as const; const i18nFonts = { - ':lang(ar)': 'myriad-arabic, ui-sans-serif, system-ui, sans-serif', - ':lang(he)': 'myriad-hebrew, ui-sans-serif, system-ui, sans-serif', + ':lang(ar)': 'adobe-clean-arabic, myriad-arabic, ui-sans-serif, system-ui, sans-serif', + ':lang(he)': 'adobe-clean-hebrew, myriad-hebrew, ui-sans-serif, system-ui, sans-serif', ':lang(ja)': "adobe-clean-han-japanese, 'Hiragino Kaku Gothic ProN', 'ヒラギノ角ゴ ProN W3', Osaka, YuGothic, 'Yu Gothic', 'メイリオ', Meiryo, 'MS Pゴシック', 'MS PGothic', sans-serif", ':lang(ko)': "adobe-clean-han-korean, source-han-korean, 'Malgun Gothic', 'Apple Gothic', sans-serif", ':lang(zh)': "adobe-clean-han-traditional, source-han-traditional, 'MingLiu', 'Heiti TC Light', sans-serif", @@ -780,19 +778,15 @@ export const style = createTheme({ ui: { // Calculate line-height based on font size. default: lineHeightCalc, - // Arabic and hebrew use the old line-height for now since they are on Myriad instead of Adobe Clean. - ':lang(ar, he)': getToken('line-height-100'), // CJK fonts use a larger line-height. ':lang(ja, ko, zh, zh-Hant, zh-Hans, zh-CN, zh-SG)': getToken('line-height-200') }, heading: { default: lineHeightCalc, - ':lang(ar, he)': getToken('line-height-100'), ':lang(ja, ko, zh, zh-Hant, zh-Hans, zh-CN, zh-SG)': getToken('heading-cjk-line-height') }, title: { default: lineHeightCalc, - ':lang(ar, he)': getToken('line-height-100'), ':lang(ja, ko, zh, zh-Hant, zh-Hans, zh-CN, zh-SG)': getToken('title-cjk-line-height') }, body: { @@ -802,7 +796,6 @@ export const style = createTheme({ }, detail: { default: lineHeightCalc, - ':lang(ar, he)': getToken('line-height-100'), ':lang(ja, ko, zh, zh-Hant, zh-Hans, zh-CN, zh-SG)': getToken('detail-cjk-line-height') }, code: {