diff --git a/packages/dev/s2-docs/pages/s2/home/Home.tsx b/packages/dev/s2-docs/pages/s2/home/Home.tsx index 90cc29a62e9..fcee0339fe7 100644 --- a/packages/dev/s2-docs/pages/s2/home/Home.tsx +++ b/packages/dev/s2-docs/pages/s2/home/Home.tsx @@ -48,6 +48,10 @@ import bg from 'data-url:./bg.svg'; import { keyframes } from "../../../../../@react-spectrum/s2/style/style-macro" with {type: 'macro'}; // @ts-ignore import { getBaseUrl } from "../../../src/pageUtils"; +// @ts-ignore +import { fontSizeToken } from "../../../../../@react-spectrum/s2/style/tokens" with {type: 'macro'}; +// @ts-ignore +import { letters } from "../../../src/textWidth"; const container = style({ backgroundColor: 'layer-2/80', @@ -67,78 +71,90 @@ const container = style({ const swapWrapper = style({ display: 'inline-block', position: 'relative', - height: '[1em]', + height: '[1.2em]', overflow: 'hidden', verticalAlign: 'baseline', whiteSpace: 'nowrap', - lineHeight: '[1em]', - marginEnd: 12 + lineHeight: '[1.2]' }); // Track that scrolls vertically through all the items. -const slideTrack = keyframes(` +// Use 3D to ensure crisp text rendering. +// With 10x hold time vs transition time: +// Total units: (6 holds × 10) + (6 transitions × 1) = 60 + 6 = 66 units +// Each transition = 100/66 = 1.515% +// Each hold = 10 × 1.515% = 15.152% +const slideTrack: string = keyframes(` 0% { - transform: translateY(0%); + transform: translate3d(0, 0, 0); } - 15% { - transform: translateY(0%); + 15.15% { + transform: translate3d(0, 0, 0); } - 16% { - transform: translateY(-16.666%); + 16.67% { + transform: translate3d(0, -1.2em, 0); } - 31% { - transform: translateY(-16.666%); + 31.82% { + transform: translate3d(0, -1.2em, 0); } - 32% { - transform: translateY(-33.333%); + 33.33% { + transform: translate3d(0, -2.4em, 0); } - 47% { - transform: translateY(-33.333%); + 48.48% { + transform: translate3d(0, -2.4em, 0); } - 48% { - transform: translateY(-50%); + 50% { + transform: translate3d(0, -3.6em, 0); } - 63% { - transform: translateY(-50%); + 65.15% { + transform: translate3d(0, -3.6em, 0); } - 64% { - transform: translateY(-66.666%); + 66.67% { + transform: translate3d(0, -4.8em, 0); } - 79% { - transform: translateY(-66.666%); + 81.82% { + transform: translate3d(0, -4.8em, 0); } - 80% { - transform: translateY(-83.333%); + 83.33% { + transform: translate3d(0, -6em, 0); } - 95% { - transform: translateY(-83.333%); + 98.48% { + transform: translate3d(0, -6em, 0); } 100% { - transform: translateY(0%); + transform: translate3d(0, -7.2em, 0); } `); const swapTrack = style({ - animation: slideTrack, - animationDuration: 15000, - animationTimingFunction: 'linear', - animationIterationCount: 'infinite', - display: 'flex', + position: 'relative', + display: { + default: 'flex', + '@media (prefers-reduced-motion: reduce)': 'none' + }, flexDirection: 'column', - whiteSpace: 'nowrap' + whiteSpace: 'nowrap', + height: '[1.2em]', + overflow: 'hidden', + fontSize: '[1em]', + willChange: 'transform' }); -// for measuring longest word const swapSizer = style({ - opacity: 0, + display: { + default: 'none', + '@media (prefers-reduced-motion: reduce)': 'block' + }, whiteSpace: 'nowrap' }); - const swapRow = style({ - display: 'block', - height: '[1em]', - lineHeight: '[1em]' + animation: slideTrack, + animationDuration: 10000, + animationTimingFunction: 'linear', + animationIterationCount: 'infinite', + lineHeight: '[1.2]', + height: '[1.2em]' }); export function Home() { @@ -197,21 +213,21 @@ export function Home() {
-

- Build apps + + Build apps with  - {/* @ts-ignore */} - - with polish - with speed - with ease - with accessibility - with consistency - with React Spectrum - - with React Spectrum +
+ polish + speed + ease + accessibility + consistency + React Spectrum + polish +
+ React Spectrum
-

+

React Spectrum gives you the power to build high quality, accessible UI with the cohesive look and feel of Adobe.

Get started @@ -386,7 +402,7 @@ export function Home() {

Button.tsx

{`import {style, focusRing} from '@react-spectrum/s2/style' with {type: 'macro'};
 import {hstack} from './style-utils' with {type: 'macro'};
-            
+
 const buttonStyle = style({
   ...focusRing(),
   ...hstack(4)
@@ -439,21 +455,21 @@ const buttonStyle = style({
             description="Comprehensive markdown docs, llms.txt, and an agent-friendly MCP server."
             illustration={}
             styles={style({gridColumnStart: {default: 'span 6', lg: 'span 2'}})}>
-              
+
           
           }
             styles={style({gridColumnStart: {default: 'span 6', lg: 'span 2'}})}>
-              
+
           
           }
             styles={style({gridColumnStart: {default: 'span 6', lg: 'span 2'}})}>
-              
+
           
         
       
@@ -488,6 +504,46 @@ const buttonStyle = style({
   );
 }
 
+function getTitleTextWidth(text: string) {
+  let width = 0;
+  for (let c of text) {
+    let w = letters[c];
+    if (w != null) {
+      width += w;
+    }
+  }
+
+  return width;
+}
+
+function HomeH1(props) {
+  let {children, ...otherProps} = props;
+  return (
+    

+ {children} +

+ ) +} + function Section({title, description, children}: any) { let headingId = useId(); return ( diff --git a/packages/dev/s2-docs/src/textWidth.ts b/packages/dev/s2-docs/src/textWidth.ts index 67315188ee7..480c6d6b0e1 100644 --- a/packages/dev/s2-docs/src/textWidth.ts +++ b/packages/dev/s2-docs/src/textWidth.ts @@ -1,6 +1,6 @@ // Map of characters to width per em, generated from Adobe Clean Spectrum VF. // Multiply by the font size to get the pixel width. -let letters: Record = { +export let letters: Record = { '0': 0.5467998461797813, '1': 0.33863281002940315, '2': 0.4949392889121938,