From a146a5032ad359e8f6d40ead8c6d943d36ce9465 Mon Sep 17 00:00:00 2001 From: Reid Barber Date: Thu, 9 Oct 2025 16:30:16 -0500 Subject: [PATCH 1/6] docs: fix og images and descriptions (#8990) * fix og:image links * fix font in SVG rendering * make logo dynamic * more name aliases for illustrations * Revert "fix font in SVG rendering" This reverts commit dd53fbc5c3d3847d3defb3dbde7a61731743b0a7. * try inlining fonts in svg * Revert "try inlining fonts in svg" This reverts commit 8b3fa87dcf05f6a6086f581a7a713cba93e01197. * generate images for index pages * generate images for pages without illustrations * try installing fonts in CI * switch fonts * remove font install from CI * try inlining font-face and pre-rendering illustration as png * Revert "try inlining font-face and pre-rendering illustration as png" This reverts commit 5b6c0029d30ee4323d31053c1c31dace7be6a440. * try using fontconfig in CI * update command * more CI updates * strip out version badge from title * remove illustration SVGs for now * improve gap * layout improvements * skip error page * add Internationalized to library in name * fix page title in Internationalized * improve titles and descriptions * improve titles for index pages and explicit custom titles --- packages/dev/s2-docs/pages/error.mdx | 1 + .../pages/internationalized/date/index.mdx | 2 + .../pages/internationalized/number/index.mdx | 2 + .../s2-docs/pages/react-aria/collections.mdx | 1 + packages/dev/s2-docs/pages/react-aria/dnd.mdx | 1 + .../s2-docs/pages/react-aria/selection.mdx | 1 + .../dev/s2-docs/pages/react-aria/styling.mdx | 1 + packages/dev/s2-docs/pages/s2/collections.mdx | 2 +- packages/dev/s2-docs/pages/s2/dnd.mdx | 2 +- .../dev/s2-docs/pages/s2/getting-started.mdx | 1 + packages/dev/s2-docs/pages/s2/migrating.mdx | 1 + .../dev/s2-docs/pages/s2/release-notes.mdx | 1 + packages/dev/s2-docs/pages/s2/selection.mdx | 1 + packages/dev/s2-docs/pages/s2/styling.mdx | 1 + .../dev/s2-docs/scripts/generateOGImages.mjs | 406 +++++++++++------- packages/dev/s2-docs/src/Layout.tsx | 37 +- 16 files changed, 287 insertions(+), 174 deletions(-) diff --git a/packages/dev/s2-docs/pages/error.mdx b/packages/dev/s2-docs/pages/error.mdx index 82201a6dc99..fbffab8eeab 100644 --- a/packages/dev/s2-docs/pages/error.mdx +++ b/packages/dev/s2-docs/pages/error.mdx @@ -5,5 +5,6 @@ export default Layout; import docs from 'docs:@react-spectrum/s2'; export const hideFromSearch = true; +export const description = 'Page not found'; diff --git a/packages/dev/s2-docs/pages/internationalized/date/index.mdx b/packages/dev/s2-docs/pages/internationalized/date/index.mdx index 338e75aae47..a1b76f4d827 100644 --- a/packages/dev/s2-docs/pages/internationalized/date/index.mdx +++ b/packages/dev/s2-docs/pages/internationalized/date/index.mdx @@ -13,6 +13,8 @@ export default Layout; import {InstallCommand} from '../../../src/InstallCommand'; export const section = 'Date and Time'; +export const pageTitle = 'Internationalized | Date and Time'; +export const description = 'Introduction to @internationalized/date'; # Introduction diff --git a/packages/dev/s2-docs/pages/internationalized/number/index.mdx b/packages/dev/s2-docs/pages/internationalized/number/index.mdx index 67db911d372..4d91a1c507d 100644 --- a/packages/dev/s2-docs/pages/internationalized/number/index.mdx +++ b/packages/dev/s2-docs/pages/internationalized/number/index.mdx @@ -13,6 +13,8 @@ export default Layout; import {InstallCommand} from '../../../src/InstallCommand'; export const section = 'Numbers'; +export const pageTitle = 'Internationalized | Numbers'; +export const description = 'Introduction to @internationalized/number'; # Introduction diff --git a/packages/dev/s2-docs/pages/react-aria/collections.mdx b/packages/dev/s2-docs/pages/react-aria/collections.mdx index 820768f3fc7..733241582e9 100644 --- a/packages/dev/s2-docs/pages/react-aria/collections.mdx +++ b/packages/dev/s2-docs/pages/react-aria/collections.mdx @@ -5,6 +5,7 @@ import docs from 'docs:react-aria-components'; import {InlineAlert, Heading, Content} from '@react-spectrum/s2' export const section = 'Guides'; +export const description = 'Implementing collections in React Aria'; # Collections diff --git a/packages/dev/s2-docs/pages/react-aria/dnd.mdx b/packages/dev/s2-docs/pages/react-aria/dnd.mdx index ef95686aefd..7c4eea7874c 100644 --- a/packages/dev/s2-docs/pages/react-aria/dnd.mdx +++ b/packages/dev/s2-docs/pages/react-aria/dnd.mdx @@ -13,6 +13,7 @@ import {PokemonListBox} from './PokemonListBox'; import {PokemonGridList} from './PokemonGridList'; export const section = 'Guides'; +export const description = 'Implementing drag and drop in React Aria'; # Drag and Drop diff --git a/packages/dev/s2-docs/pages/react-aria/selection.mdx b/packages/dev/s2-docs/pages/react-aria/selection.mdx index 44ee6a777f8..c7800d9ed3e 100644 --- a/packages/dev/s2-docs/pages/react-aria/selection.mdx +++ b/packages/dev/s2-docs/pages/react-aria/selection.mdx @@ -4,6 +4,7 @@ export default Layout; import docs from 'docs:react-aria-components'; export const section = 'Guides'; +export const description = 'Implementing selection in React Aria'; # Selection diff --git a/packages/dev/s2-docs/pages/react-aria/styling.mdx b/packages/dev/s2-docs/pages/react-aria/styling.mdx index bbe1422e335..1c11d96bf68 100644 --- a/packages/dev/s2-docs/pages/react-aria/styling.mdx +++ b/packages/dev/s2-docs/pages/react-aria/styling.mdx @@ -5,6 +5,7 @@ export default Layout; import {Disclosure, DisclosureTitle, DisclosurePanel} from '@react-spectrum/s2'; export const section = 'Guides'; +export const description = 'Styling in React Aria'; # Styling diff --git a/packages/dev/s2-docs/pages/s2/collections.mdx b/packages/dev/s2-docs/pages/s2/collections.mdx index 8dacb61c5c7..8c41d643502 100644 --- a/packages/dev/s2-docs/pages/s2/collections.mdx +++ b/packages/dev/s2-docs/pages/s2/collections.mdx @@ -3,8 +3,8 @@ import {InlineAlert, Heading, Content} from '@react-spectrum/s2'; export default Layout; export const section = 'Guides'; - export const tags = ['lists']; +export const description = 'Implementing collections in React Spectrum'; # Collections diff --git a/packages/dev/s2-docs/pages/s2/dnd.mdx b/packages/dev/s2-docs/pages/s2/dnd.mdx index 63b2ecfd2df..f96c8231499 100644 --- a/packages/dev/s2-docs/pages/s2/dnd.mdx +++ b/packages/dev/s2-docs/pages/s2/dnd.mdx @@ -3,8 +3,8 @@ import {InlineAlert, Heading, Content} from '@react-spectrum/s2'; export default Layout; export const section = 'Guides'; - export const tags = ['drag', 'drop']; +export const description = 'Implementing drag and drop in React Spectrum'; # Drag and Drop diff --git a/packages/dev/s2-docs/pages/s2/getting-started.mdx b/packages/dev/s2-docs/pages/s2/getting-started.mdx index 87741997513..13ea383c07f 100644 --- a/packages/dev/s2-docs/pages/s2/getting-started.mdx +++ b/packages/dev/s2-docs/pages/s2/getting-started.mdx @@ -6,6 +6,7 @@ import {SegmentedControl, SegmentedControlItem} from '@react-spectrum/s2'; export const section = 'Getting started'; export const tags = ['introduction', 'installation']; +export const description = 'Getting started with React Spectrum'; # Getting started diff --git a/packages/dev/s2-docs/pages/s2/migrating.mdx b/packages/dev/s2-docs/pages/s2/migrating.mdx index 1b42d053070..be6cd9cb4c9 100644 --- a/packages/dev/s2-docs/pages/s2/migrating.mdx +++ b/packages/dev/s2-docs/pages/s2/migrating.mdx @@ -6,6 +6,7 @@ export default Layout; export const section = 'Guides'; export const tags = ['codemod', 'upgrade', 'update']; +export const description = 'Migrating to Spectrum 2 in React Spectrum'; # Migrating to Spectrum 2 diff --git a/packages/dev/s2-docs/pages/s2/release-notes.mdx b/packages/dev/s2-docs/pages/s2/release-notes.mdx index 1f6cc33097d..70f73c8765e 100644 --- a/packages/dev/s2-docs/pages/s2/release-notes.mdx +++ b/packages/dev/s2-docs/pages/s2/release-notes.mdx @@ -3,6 +3,7 @@ export default Layout; export const section = 'Releases'; export const tags = ['changelog', 'versions', 'updates']; +export const description = 'Release notes for React Spectrum'; # Release Notes diff --git a/packages/dev/s2-docs/pages/s2/selection.mdx b/packages/dev/s2-docs/pages/s2/selection.mdx index 2bc589dd40e..7a54a0897d4 100644 --- a/packages/dev/s2-docs/pages/s2/selection.mdx +++ b/packages/dev/s2-docs/pages/s2/selection.mdx @@ -4,6 +4,7 @@ export default Layout; export const section = 'Guides'; export const tags = ['collections']; +export const description = 'Implementing selection in React Spectrum'; # Selection diff --git a/packages/dev/s2-docs/pages/s2/styling.mdx b/packages/dev/s2-docs/pages/s2/styling.mdx index 59e257b206d..3735835c868 100644 --- a/packages/dev/s2-docs/pages/s2/styling.mdx +++ b/packages/dev/s2-docs/pages/s2/styling.mdx @@ -7,6 +7,7 @@ export default Layout; export const section = 'Guides'; export const tags = ['style', 'macro', 'spectrum', 'custom']; +export const description = 'Styling in React Spectrum'; # Styling diff --git a/packages/dev/s2-docs/scripts/generateOGImages.mjs b/packages/dev/s2-docs/scripts/generateOGImages.mjs index 3d99587262b..aac8b044589 100644 --- a/packages/dev/s2-docs/scripts/generateOGImages.mjs +++ b/packages/dev/s2-docs/scripts/generateOGImages.mjs @@ -10,26 +10,6 @@ const __dirname = path.dirname(__filename); const pagesDir = path.resolve(__dirname, '../pages'); const outputDir = path.resolve(__dirname, '../dist/og'); -const illustrationsDir = path.resolve(__dirname, '../../docs/pages/assets/component-illustrations'); - -const cssVariables = { - '--anatomy-gray-50': '#FFFFFF', - '--anatomy-gray-75': '#FDFDFE', - '--anatomy-gray-100': '#f4f6fc', - '--anatomy-gray-200': '#E5EBF7', - '--anatomy-gray-300': '#DAE2F4', - '--anatomy-gray-400': '#beccea', - '--anatomy-gray-500': '#a2b6e1', - '--anatomy-gray-600': '#718dcf', - '--anatomy-gray-700': '#4a6fc3', - '--anatomy-gray-800': '#496EC2', - '--anatomy-gray-900': '#486EC2', - '--spectrum-global-color-gray-300': '#d3d3d3', - '--spectrum-global-color-gray-400': '#bcbcbc', - '--spectrum-global-color-gray-700': '#464646', - '--spectrum-alias-border-color-focus': '#0f62fe', - '--anatomy-font': 'adobe-clean' -}; async function getMdxFiles(dir) { let entries = await fs.readdir(dir, {withFileTypes: true}); @@ -53,7 +33,11 @@ async function getTitle(filePath) { } let match = parsed.content.match(/^#\s+(.+)$/m); if (match) { - return match[1].trim(); + let title = match[1].trim(); + // Strip out any React components (like ) + title = title.replace(/<[A-Z]\w*[^>]*\/>/g, '').trim(); + title = title.replace(/<[A-Z]\w*[^>]*>.*?<\/[A-Z]\w*>/g, '').trim(); + return title; } return path.basename(filePath, path.extname(filePath)); } @@ -89,42 +73,149 @@ const [adobeCleanRegular, adobeCleanBold] = await Promise.all([ loadFont('https://use.typekit.net/af/eaf09c/000000000000000000017703/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3') ]); -// Mappings for components that don't match their SVG file names -const componentSvgExceptions = { - 'GridList': 'ListView.svg', - 'Select': 'Picker.svg', - 'Drag and Drop': 'DragAndDrop.svg' -}; - -async function getComponentSvg(title) { - // First try exception mappings - let svgFileName = componentSvgExceptions[title]; - - // If no exception mapping, try automatic name matching - if (!svgFileName) { - svgFileName = `${title}.svg`; - } - - try { - const svgPath = path.join(illustrationsDir, svgFileName); - let svgContent = await fs.readFile(svgPath, 'utf8'); - - // Replace CSS variables with actual colors - for (const [variable, color] of Object.entries(cssVariables)) { - svgContent = svgContent.replace(new RegExp(`var\\(${variable.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\)`, 'g'), color); - } - - // Replace SVG background to match container background - svgContent = svgContent.replace(/background:\s*var\(--anatomy-gray-100\)/g, 'background: #f8f8f8'); - svgContent = svgContent.replace(/background:\s*#f4f6fc/g, 'background: #f8f8f8'); - svgContent = svgContent.replace(/var\(--anatomy-font\)/g, 'adobe-clean'); - - // Convert SVG to data URI for use as image source - const svgBase64 = Buffer.from(svgContent).toString('base64'); - return `data:image/svg+xml;base64,${svgBase64}`; - } catch (error) { - console.warn(`Could not load SVG for ${title}: ${error.message}`); - return null; +function getLibraryLogo(subtitle) { + if (subtitle === 'React Aria') { + return { + type: 'svg', + props: { + width: 156, + height: 150, + viewBox: '15.79 17.64 131.21 126.14', + xmlns: 'http://www.w3.org/2000/svg', + children: [ + { + type: 'defs', + props: { + children: { + type: 'clipPath', + props: { + id: 'a', + children: { + type: 'path', + props: { + d: 'M80 136c30.93 0 56-25.07 56-56s-25.07-56-56-56-56 25.07-56 56 25.07 56 56 56Zm8.48-86.3c0 4.69-3.8 8.48-8.48 8.48s-8.48-3.8-8.48-8.48 3.8-8.48 8.48-8.48 8.48 3.8 8.48 8.48ZM51.09 61.78c.52-1.8 2.39-2.85 4.2-2.33a89.865 89.865 0 0 0 48.82.17l.64-.18c1.81-.5 3.68.55 4.18 2.36a3.39 3.39 0 0 1-2.36 4.18l-.64.18a97.139 97.139 0 0 1-15.51 2.98c-1.03.11-1.82.97-1.82 2.01v14.89c0 .18.03.37.08.55 1.37 4.83 2.94 10.39 4.32 15.27.98 3.46 1.86 6.58 2.49 8.85.32 1.14.58 2.06.76 2.71l.04.15c.13.48.27.97.31 1.16a3.38 3.38 0 0 1-2.66 3.99 3.38 3.38 0 0 1-3.99-2.66c.02.09 0 .04-.08-.27-.04-.13-.09-.31-.15-.54-.18-.65-.44-1.57-.76-2.7-.64-2.27-1.52-5.39-2.49-8.85l-3.74-13.21a1.992 1.992 0 0 0-1.92-1.45h-1.6c-.89 0-1.68.59-1.92 1.45-1.22 4.3-2.55 9.01-3.74 13.21-.98 3.46-1.85 6.58-2.49 8.85-.32 1.13-.58 2.06-.76 2.7-.06.23-.11.41-.15.54-.09.31-.1.36-.08.27a3.39 3.39 0 1 1-6.65-1.33c.04-.18.18-.68.31-1.16l.04-.15c.18-.65.44-1.58.76-2.71.64-2.27 1.52-5.39 2.49-8.85 1.38-4.88 2.95-10.44 4.32-15.27.05-.18.08-.36.08-.55V71.16c0-1.04-.79-1.9-1.82-2.01a96.504 96.504 0 0 1-16.17-3.17 3.395 3.395 0 0 1-2.33-4.2Z', + fill: 'none' + } + } + } + } + } + }, + { + type: 'circle', + props: { + cx: 80, + cy: 80, + r: 50.83, + fill: '#fff' + } + }, + { + type: 'g', + props: { + clipPath: 'url(#a)', + children: { + type: 'path', + props: { + d: 'M15.79 17.64H147v126.14H15.79z', + fill: '#269ff4' + } + } + } + } + ] + } + }; + } else if (subtitle === 'Internationalized') { + return { + type: 'svg', + props: { + width: 156, + height: 148, + viewBox: '15 17 135 128', + xmlns: 'http://www.w3.org/2000/svg', + children: [ + { + type: 'defs', + props: { + children: [ + { + type: 'clipPath', + props: { + id: 'b', + children: { + type: 'path', + props: { + d: 'M23.98 79.99c0-17.01 7.58-32.25 19.54-42.52.92 2.02 2.32 4.67 4 7.13 1.05 1.54 2.28 3.1 3.65 4.41 1.33 1.27 3.04 2.55 5.08 3.13 3.29.94 7.1.8 9.98.7l.88-.03c1.63-.05 2.94-.07 4.03.05 1.11.11 1.57.33 1.71.42.31.2.39.37.41.43.03.08.07.22.03.46-.09.52-.53 1.28-1.4 1.76-2.07 1.15-4.14 2.6-5.69 4.59-1.63 2.09-2.54 4.6-2.54 7.55 0 .86-.07 1.4-.15 1.72v.03c-.28.06-.81.1-1.7.03-.27-.02-.55-.05-.86-.07-2.32-.21-5.69-.5-8.87-.17-3.54.37-8.1 1.64-10.56 5.96-1.08 1.89-2.33 5.04-2.03 8.8.31 3.92 2.27 7.99 6.71 11.55 5.12 4.1 10.75 4.98 18.12 5.8 4.2.47 6.58 1.37 7.94 2.33 1.19.84 1.85 1.9 2.18 3.55.58 2.88-.4 7.19-2.43 12.45-.97 2.52-2.11 5.05-3.24 7.52-.25.54-.5 1.08-.74 1.61-.81 1.76-1.61 3.47-2.27 5.03C41.73 127.9 24 106.03 24 80.02Zm26.36-46.91c-.07-.17-.15-.33-.24-.49a55.64 55.64 0 0 1 12.37-5.84c.05.3.14.6.26.89 2.06 4.9 8.3 10.94 16.68 10.94 4.33 0 7.8-1.86 10.35-3.97 2.53-2.1 4.34-4.6 5.47-6.33.41-.63.62-1.34.65-2.04.69.2 1.37.42 2.05.65-.06.18-.1.37-.13.57-.67 4.46-1.44 10.7-.74 16.34.69 5.54 3.01 11.91 9.76 14.25 5.36 1.86 10.66.94 14.8-.9 2.74-1.22 5.23-2.96 7.07-4.9 2.11 3.7 3.81 7.65 5.04 11.81l-1.75-.36c-3.01-.59-7.06-1.26-11.28-1.54-4.16-.28-8.77-.19-12.78.91-4.02 1.1-8.1 3.44-9.84 8.13-4.86 13.11 1.7 21.06 3.39 22.75 2.55 2.55 5.17 3.75 7.1 4.62.23.11.46.21.67.31 1.86.87 3.19 1.63 4.54 3.58.47.67.94 1.89 1.3 3.74.34 1.8.52 3.89.58 6.11.07 2.2.02 4.41-.04 6.43l-.06 1.63c-.04 1.08-.07 2.1-.09 2.95a55.775 55.775 0 0 1-35.48 12.67c-2.09 0-4.15-.11-6.18-.34.44-.97.91-1.99 1.41-3.08.26-.55.52-1.12.79-1.71 1.15-2.49 2.37-5.21 3.44-7.97 2.05-5.28 3.89-11.54 2.82-16.9-.67-3.35-2.3-6.32-5.41-8.51-2.94-2.07-6.85-3.21-11.67-3.74-7.46-.83-10.89-1.6-14.01-4.09-2.9-2.32-3.62-4.43-3.74-5.93-.13-1.67.44-3.21 1-4.2.51-.9 1.72-1.68 4.44-1.97 2.35-.25 4.9-.03 7.3.18.31.03.62.05.93.08 2.86.24 5.98-.1 8.18-2.42 2.06-2.18 2.33-5.13 2.33-7.33 0-1.17.32-1.95.86-2.64.61-.79 1.63-1.6 3.26-2.51 2.83-1.57 4.87-4.32 5.4-7.4.56-3.26-.64-6.73-3.89-8.9-1.72-1.14-3.68-1.55-5.33-1.72-1.68-.17-3.48-.13-5.1-.08-.22 0-.44.01-.65.02-3.22.11-5.75.19-7.75-.38-.27-.08-.86-.38-1.74-1.22-.84-.8-1.72-1.89-2.58-3.15-1.73-2.53-3.12-5.37-3.79-7Zm73.36 81.97a55.79 55.79 0 0 0 12.32-35.06c0-2.49-.16-4.94-.48-7.34-.05 0-.09-.02-.12-.02-.14-.03-.29-.06-.42-.09-.2-.04-.45-.1-.74-.16l-.35-.08c-.87-.2-2.06-.46-3.47-.73-2.84-.56-6.52-1.16-10.27-1.41-3.81-.25-7.38-.11-10.13.64-2.73.75-3.97 1.89-4.45 3.2-3.38 9.13 1.14 13.91 1.55 14.32 1.49 1.49 2.84 2.11 4.77 3 .23.11.47.22.73.34 2.42 1.13 5.22 2.64 7.73 6.27 1.39 2 2.14 4.47 2.58 6.79.46 2.38.65 4.94.72 7.37.03 1 .04 1.99.03 2.96Zm.28-69.78a56.276 56.276 0 0 0-18.47-15.18c-.57 4.1-.99 8.75-.5 12.73.56 4.56 2.1 6.86 4.44 7.68 2.96 1.03 6.11.6 8.92-.65 2.91-1.3 4.85-3.21 5.46-4.32.05-.09.1-.18.16-.26ZM80 23.96c2.75 0 5.46.2 8.11.58-.9 1.31-2.06 2.75-3.46 3.91-1.61 1.33-3.33 2.13-5.24 2.13-4.39 0-7.99-3.27-9.19-5.78 3.17-.56 6.44-.85 9.78-.85Z', + fill: 'none' + } + } + } + }, + { + type: 'clipPath', + props: { + id: 'c', + children: { + type: 'path', + props: { + d: 'M23.98 80c0-17.01 7.58-32.25 19.54-42.52.92 2.02 2.32 4.67 4 7.13 1.05 1.54 2.28 3.1 3.65 4.41 1.33 1.27 3.04 2.55 5.08 3.13 3.29.94 7.1.8 9.98.7l.88-.03c1.63-.05 2.94-.07 4.03.05 1.11.11 1.57.33 1.71.42.31.2.39.37.41.43.03.08.07.22.03.46-.09.52-.53 1.28-1.4 1.76-2.07 1.15-4.14 2.6-5.69 4.59-1.63 2.09-2.54 4.6-2.54 7.55 0 .86-.07 1.4-.15 1.72v.03c-.28.06-.81.1-1.7.03-.27-.02-.55-.05-.86-.07-2.32-.21-5.69-.5-8.87-.17-3.54.37-8.1 1.64-10.56 5.96-1.08 1.89-2.33 5.04-2.03 8.8.31 3.92 2.27 7.99 6.71 11.55 5.12 4.1 10.75 4.98 18.12 5.8 4.2.47 6.58 1.37 7.94 2.33 1.19.84 1.85 1.9 2.18 3.55.58 2.88-.4 7.19-2.43 12.45-.97 2.52-2.11 5.05-3.24 7.52-.25.54-.5 1.08-.74 1.61-.81 1.76-1.61 3.47-2.27 5.03C41.73 127.91 24 106.04 24 80.03Zm99.72 35.06A55.79 55.79 0 0 0 136.02 80c0-2.49-.16-4.94-.48-7.34-.05 0-.09-.02-.12-.02-.14-.03-.29-.06-.42-.09-.2-.04-.45-.1-.74-.16l-.35-.08c-.87-.2-2.06-.46-3.47-.73-2.84-.56-6.52-1.16-10.27-1.41-3.81-.25-7.38-.11-10.13.64-2.73.75-3.97 1.89-4.45 3.2-3.38 9.13 1.14 13.91 1.55 14.32 1.49 1.49 2.84 2.11 4.77 3 .23.11.47.22.73.34 2.42 1.13 5.22 2.64 7.73 6.27 1.39 2 2.14 4.47 2.58 6.79.46 2.38.65 4.94.72 7.37.03 1 .04 1.99.03 2.96Zm.28-69.77a56.276 56.276 0 0 0-18.47-15.18c-.57 4.1-.99 8.75-.5 12.73.56 4.56 2.1 6.86 4.44 7.68 2.96 1.03 6.11.6 8.92-.65 2.91-1.3 4.85-3.21 5.46-4.32.05-.09.1-.18.16-.26ZM80 23.98c2.75 0 5.46.2 8.11.58-.9 1.31-2.06 2.75-3.46 3.91-1.61 1.33-3.33 2.13-5.24 2.13-4.39 0-7.99-3.27-9.19-5.78 3.17-.56 6.44-.85 9.78-.85Z', + fill: 'none' + } + } + } + } + ] + } + }, + { + type: 'g', + props: { + clipPath: 'url(#b)', + children: { + type: 'path', + props: { + d: 'M15 17h135v128H15z', + fill: '#6995fe' + } + } + } + }, + { + type: 'g', + props: { + clipPath: 'url(#c)', + children: { + type: 'path', + props: { + d: 'M15 17.01h135v128H15z', + fill: '#099d59' + } + } + } + } + ] + } + }; + } else { + // Adobe logo for React Spectrum + return { + type: 'svg', + props: { + width: 156, + height: 138, + viewBox: '0 0 501.71 444.05', + xmlns: 'http://www.w3.org/2000/svg', + children: { + type: 'polygon', + props: { + fill: '#eb1000', + strokeWidth: 0, + points: '297.58 444.05 261.13 342.65 169.67 342.65 246.54 149.12 363.19 444.05 501.71 444.05 316.8 0 186.23 0 0 444.05 297.58 444.05 297.58 444.05' + } + } + } + }; } } @@ -138,137 +229,130 @@ for (let file of files) { .relative(pagesDir, file) .replace(/\\/g, '/') .replace(/\.mdx?$/, ''); - let subtitle = getSubtitle(slug); - - // Get component SVG if available - const componentSvg = await getComponentSvg(title); - if (!componentSvg) { + + // Skip the error page + if (slug === 'error') { continue; } + + let subtitle = getSubtitle(slug); + let isIndexPage = slug === 'index' || slug.endsWith('/index'); - let svg = await satori( - { + // Determine layout type + let layout; + if (isIndexPage) { + // Index page layout: Centered logo and library name + layout = { type: 'div', props: { style: { display: 'flex', - flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', width: '100%', height: '100%', backgroundColor: '#ffffff', fontFamily: 'adobe-clean', color: '#000000' }, - children: [ - // Top section: Component illustration - { - type: 'div', - props: { - style: { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - width: '100%', - height: '394px', // 10/16 of 630px total height - backgroundColor: '#f8f8f8', - padding: '40px', - borderBottom: '1px solid #e5e5e5' - }, - children: componentSvg ? { - type: 'img', + children: { + type: 'div', + props: { + style: { + display: 'flex', + alignItems: 'center', + gap: 44 + }, + children: [ + // Library logo + getLibraryLogo(subtitle), + // Library name + { + type: 'div', props: { - src: componentSvg, style: { - width: '340px', - height: '320px', - objectFit: 'contain' - } + fontSize: 84, + fontWeight: 700, + lineHeight: 1.1 + }, + children: subtitle } - } : { + } + ] + } + } + } + }; + } else { + // Regular page layout: Centered logo + page title + library name + layout = { + type: 'div', + props: { + style: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + width: '100%', + height: '100%', + backgroundColor: '#ffffff', + fontFamily: 'adobe-clean', + color: '#000000' + }, + children: { + type: 'div', + props: { + style: { + display: 'flex', + alignItems: 'center', + gap: 44 + }, + children: [ + // Library logo + getLibraryLogo(subtitle), + // Text content + { type: 'div', props: { style: { - fontSize: 72, - fontWeight: 400, - color: '#464646' + display: 'flex', + flexDirection: 'column', + gap: 0 }, - children: title - } - } - } - }, - // Bottom section: Adobe logo + text - { - type: 'div', - props: { - style: { - display: 'flex', - alignItems: 'center', - width: '100%', - height: '236px', // 6/16 of 630px total height - padding: '0 60px', - gap: 40 - }, - children: [ - // Adobe logo - { - type: 'svg', - props: { - width: 156, - height: 138, - viewBox: '0 0 501.71 444.05', - xmlns: 'http://www.w3.org/2000/svg', - children: { - type: 'polygon', + children: [ + { + type: 'div', props: { - fill: '#eb1000', - strokeWidth: 0, - points: '297.58 444.05 261.13 342.65 169.67 342.65 246.54 149.12 363.19 444.05 501.71 444.05 316.8 0 186.23 0 0 444.05 297.58 444.05 297.58 444.05' + style: { + fontSize: 84, + fontWeight: 700, + lineHeight: 1.1 + }, + children: title } - } - } - }, - // Text content - { - type: 'div', - props: { - style: { - display: 'flex', - flexDirection: 'column', - gap: 8 }, - children: [ - { - type: 'div', - props: { - style: { - fontSize: 84, - fontWeight: 700, - lineHeight: 1.1 - }, - children: title - } - }, - { - type: 'div', - props: { - style: { - fontSize: 56, - fontWeight: 400, - color: '#464646' - }, - children: subtitle - } + { + type: 'div', + props: { + style: { + fontSize: 56, + fontWeight: 400, + color: '#464646' + }, + children: subtitle } - ] - } + } + ] } - ] - } + } + ] } - ] + } } - }, + }; + } + + let svg = await satori( + layout, { width: 1200, height: 630, diff --git a/packages/dev/s2-docs/src/Layout.tsx b/packages/dev/s2-docs/src/Layout.tsx index 4a1d57ec982..66ba59a9936 100644 --- a/packages/dev/s2-docs/src/Layout.tsx +++ b/packages/dev/s2-docs/src/Layout.tsx @@ -7,6 +7,7 @@ import {ClassAPI} from './ClassAPI'; import {Code} from './Code'; import {CodeBlock} from './CodeBlock'; import {ExampleSwitcher} from './ExampleSwitcher'; +import {getLibraryFromPage, getLibraryLabel} from './library'; import {H2, H3, H4} from './Headings'; import Header from './Header'; import {Link} from './Link'; @@ -46,31 +47,45 @@ function anchorId(children) { return children.replace(/\s/g, '-').replace(/[^a-zA-Z0-9-_]/g, '').toLowerCase(); } -const getLibraryName = (currentPage: Page): string => { - if (currentPage.name.startsWith('react-aria/')) { - return 'React Aria'; - } - return 'React Spectrum'; -}; - const getTitle = (currentPage: Page): string => { - let library = getLibraryName(currentPage); - const pageTitle = currentPage.exports?.title ?? currentPage.tableOfContents?.[0]?.title ?? currentPage.name; - return library ? `${pageTitle} - ${library}` : pageTitle; + const explicitTitle = (currentPage as any).pageTitle || currentPage.exports?.pageTitle; + if (explicitTitle && explicitTitle !== currentPage.tableOfContents?.[0]?.title && explicitTitle !== currentPage.name) { + return explicitTitle as string; + } + + let library = getLibraryLabel(getLibraryFromPage(currentPage)); + const pageTitle = currentPage.tableOfContents?.[0]?.title ?? currentPage.name; + + if (currentPage.name === 'index.html' || currentPage.name.endsWith('/index.html')) { + return library || 'React Spectrum'; + } + + return library ? `${pageTitle} | ${library}` : pageTitle; }; const getOgImageUrl = (currentPage: Page): string => { const slug = currentPage.url.replace(/^\//, '').replace(/\.html$/, ''); + + if (slug.includes('s2-docs/')) { + // For build links, use the full URL + const ogPath = slug.replace(/s2-docs\//, 's2-docs/og/'); + return `https://reactspectrum.blob.core.windows.net/${ogPath}.png`; + } + + // For production, use relative path with /og/ prefix return `/og/${slug}.png`; }; const getDescription = (currentPage: Page): string => { - let library = getLibraryName(currentPage); + let library = getLibraryLabel(getLibraryFromPage(currentPage)); const pageTitle = currentPage.exports?.title ?? currentPage.tableOfContents?.[0]?.title ?? currentPage.name; const explicitDescription = (currentPage as any).description || currentPage.exports?.description; if (explicitDescription) { return explicitDescription as string; } + if (currentPage.name === 'index.html' || currentPage.name.endsWith('/index.html')) { + return `Documentation for ${library || 'React Spectrum'}`; + } return library ? `Documentation for ${pageTitle} in ${library}.` : `Documentation for ${pageTitle}.`; }; From d3de908b51c0c28d8f5783f8699a9f4cde5f6691 Mon Sep 17 00:00:00 2001 From: Reid Barber Date: Thu, 9 Oct 2025 17:21:10 -0500 Subject: [PATCH 2/6] chore: fix starters build typescript error (#9006) * fix starters type build * fix other example --- starters/docs/src/ColorPicker.tsx | 2 +- starters/tailwind/src/ColorPicker.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/starters/docs/src/ColorPicker.tsx b/starters/docs/src/ColorPicker.tsx index 6e6c83f6715..218ee783c10 100644 --- a/starters/docs/src/ColorPicker.tsx +++ b/starters/docs/src/ColorPicker.tsx @@ -13,7 +13,7 @@ import {Popover} from './Popover'; import './ColorPicker.css'; -export interface ColorPickerProps extends AriaColorPickerProps { +export interface ColorPickerProps extends Omit { label?: string; children?: React.ReactNode; } diff --git a/starters/tailwind/src/ColorPicker.tsx b/starters/tailwind/src/ColorPicker.tsx index 30391f433d7..3ae89717e28 100644 --- a/starters/tailwind/src/ColorPicker.tsx +++ b/starters/tailwind/src/ColorPicker.tsx @@ -15,7 +15,7 @@ const buttonStyles = tv({ base: 'border-0 bg-transparent flex gap-2 items-center cursor-default rounded-xs text-sm text-gray-800 dark:text-gray-200' }); -export interface ColorPickerProps extends AriaColorPickerProps { +export interface ColorPickerProps extends Omit { label?: string; children?: React.ReactNode; } From a6f0d45d5dca3913bf0938dfe8acc1fc9c6b93a4 Mon Sep 17 00:00:00 2001 From: Reid Barber Date: Thu, 9 Oct 2025 17:52:55 -0500 Subject: [PATCH 3/6] fix(S2): fix Modal position and S2 docs modal style (#9007) * revert S2 modal position change * fix S2 docs menu modal position * s2: fix ModalProps types --- packages/@react-spectrum/s2/src/Modal.tsx | 6 +++--- packages/dev/s2-docs/src/MobileHeader.tsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/@react-spectrum/s2/src/Modal.tsx b/packages/@react-spectrum/s2/src/Modal.tsx index fdf5bcb831f..ad55a2b3b24 100644 --- a/packages/@react-spectrum/s2/src/Modal.tsx +++ b/packages/@react-spectrum/s2/src/Modal.tsx @@ -12,13 +12,13 @@ import {colorScheme} from './style-utils' with {type: 'macro'}; import {ColorSchemeContext} from './Provider'; -import {DOMRef} from '@react-types/shared'; +import {DOMRef, GlobalDOMAttributes} from '@react-types/shared'; import {forwardRef, MutableRefObject, useCallback, useContext} from 'react'; import {ModalOverlay, ModalOverlayProps, Modal as RACModal, useLocale} from 'react-aria-components'; import {style} from '../style' with {type: 'macro'}; import {useDOMRef} from '@react-spectrum/utils'; -interface ModalProps extends ModalOverlayProps { +interface ModalProps extends Omit { /** * The size of the Modal. * @@ -29,7 +29,7 @@ interface ModalProps extends ModalOverlayProps { const modalOverlayStyles = style({ ...colorScheme(), - position: 'fixed', + position: 'absolute', top: 0, left: 0, width: 'full', diff --git a/packages/dev/s2-docs/src/MobileHeader.tsx b/packages/dev/s2-docs/src/MobileHeader.tsx index dc8e34a8c6f..b282ea81512 100644 --- a/packages/dev/s2-docs/src/MobileHeader.tsx +++ b/packages/dev/s2-docs/src/MobileHeader.tsx @@ -162,7 +162,7 @@ export function MobileHeader({toc, pages, currentPage}) { - + From 1a4647da731cb8a28a01e5246cf1c1f93f387e6e Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Thu, 9 Oct 2025 16:15:44 -0700 Subject: [PATCH 4/6] docs: Prepare S2 docs deploy (#8969) --- .circleci/config.yml | 35 ++++++++++++++++++++++++++++++++ .github/workflows/beta-docs.yaml | 15 ++++++++++++++ Makefile | 22 +++++++++++++------- 3 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/beta-docs.yaml diff --git a/.circleci/config.yml b/.circleci/config.yml index b7665dbc8f5..8e55af664ea 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -478,6 +478,21 @@ jobs: paths: - '*/docs/' + docs-beta: + executor: rsp-xlarge + steps: + - restore_cache: + key: react-spectrum-{{ .Environment.CACHE_VERSION }}-{{ .Environment.CIRCLE_SHA1 }} + + - run: + name: build docs + command: make s2-docs-production + + - persist_to_workspace: + root: dist + paths: + - '*/docs/' + s2-docs: executor: rsp-xlarge steps: @@ -1018,6 +1033,26 @@ workflows: requires: - docs-production + + beta-docs: + when: + and: + - equal: [ "beta-docs", << pipeline.parameters.GHA_Action >> ] + jobs: + - install + - docs-beta: + filters: + branches: + only: beta-docs + requires: + - install + - deploy-production: + filters: + branches: + only: beta-docs + requires: + - docs-beta + nightly: triggers: - schedule: diff --git a/.github/workflows/beta-docs.yaml b/.github/workflows/beta-docs.yaml new file mode 100644 index 00000000000..5ecf301ef2c --- /dev/null +++ b/.github/workflows/beta-docs.yaml @@ -0,0 +1,15 @@ +name: Beta docs deploy +on: + release: + types: [published] + workflow_dispatch: + +jobs: + trigger-circleci: + runs-on: ubuntu-latest + steps: + - name: Run CircleCI + id: beta-docs + uses: CircleCI-Public/trigger-circleci-pipeline-action@v1.0.5 + env: + CCI_TOKEN: ${{ secrets.CCI_TOKEN }} diff --git a/Makefile b/Makefile index b73134edfeb..ff0cea55c58 100644 --- a/Makefile +++ b/Makefile @@ -109,6 +109,8 @@ website: website-production: node scripts/buildWebsite.js $$PUBLIC_URL cp packages/dev/docs/pages/robots.txt dist/production/docs/robots.txt + # Uncomment this when we are ready to release. + # $(MAKE) s2-docs-production $(MAKE) starter-zip $(MAKE) tailwind-starter $(MAKE) s2-storybook-docs @@ -144,12 +146,18 @@ s2-api-diff: node scripts/api-diff.js --skip-same --skip-style-props s2-docs: + BASE_URL=https://reactspectrum.blob.core.windows.net PUBLIC_URL=/reactspectrum/$$(git rev-parse HEAD)/s2-docs DIST_DIR=dist/$$(git rev-parse HEAD)/s2-docs $(MAKE) build-s2-docs + +s2-docs-production: + BASE_URL=https://react-spectrum.adobe.com PUBLIC_URL=/beta DIST_DIR=dist/production/docs/beta $(MAKE) build-s2-docs + +build-s2-docs: yarn workspace @react-spectrum/s2-docs generate:md yarn workspace @react-spectrum/s2-docs generate:og - REGISTRY_URL=https://reactspectrum.blob.core.windows.net/reactspectrum/$$(git rev-parse HEAD)/s2-docs/registry node scripts/buildRegistry.mjs - REGISTRY_URL=https://reactspectrum.blob.core.windows.net/reactspectrum/$$(git rev-parse HEAD)/s2-docs/registry yarn build:s2-docs --public-url /reactspectrum/$$(git rev-parse HEAD)/s2-docs/ - mkdir -p dist/$$(git rev-parse HEAD) - mv packages/dev/s2-docs/dist dist/$$(git rev-parse HEAD)/s2-docs - mkdir -p dist/$$(git rev-parse HEAD)/s2-docs/registry - mv starters/docs/registry dist/$$(git rev-parse HEAD)/s2-docs/registry/vanilla - mv starters/tailwind/registry dist/$$(git rev-parse HEAD)/s2-docs/registry/tailwind + REGISTRY_URL=$(BASE_URL)$(PUBLIC_URL)/registry node scripts/buildRegistry.mjs + REGISTRY_URL=$(BASE_URL)$(PUBLIC_URL)/registry yarn build:s2-docs --public-url $(PUBLIC_URL) + mkdir -p $(DIST_DIR) + mv packages/dev/s2-docs/dist/* $(DIST_DIR) + mkdir -p $(DIST_DIR)/registry + mv starters/docs/registry $(DIST_DIR)/registry/vanilla + mv starters/tailwind/registry $(DIST_DIR)/registry/tailwind From 6d8af92a4f7f9226e7e84630870e684139e46f3e Mon Sep 17 00:00:00 2001 From: Robert Snow Date: Fri, 10 Oct 2025 11:20:29 +1100 Subject: [PATCH 5/6] fix: S2 docs Skeleton page (#9008) --- packages/dev/s2-docs/pages/s2/Skeleton.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dev/s2-docs/pages/s2/Skeleton.mdx b/packages/dev/s2-docs/pages/s2/Skeleton.mdx index becbeda279e..2f20dcbcde1 100644 --- a/packages/dev/s2-docs/pages/s2/Skeleton.mdx +++ b/packages/dev/s2-docs/pages/s2/Skeleton.mdx @@ -22,7 +22,7 @@ import Select from '@react-spectrum/s2/icons/Select'; src={preview} width={1600} height={1200} - styles={style({height: 160, borderRadius: 'default', flexShrink: 0})} /> + styles={style({height: 160, borderRadius: 'default', flexShrink: 0, aspectRatio: '4 / 3'})} />
Placeholder title This is placeholder content approximating the length of the real content to avoid layout shifting when the real content appears. From d04c28f7a67147176ed27338a4d6773f9388cd27 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Thu, 9 Oct 2025 17:41:15 -0700 Subject: [PATCH 6/6] docs: Improve root page (#9009) --- .../wallpaper_collaborative_S2_desktop.webp | Bin 0 -> 50894 bytes packages/dev/s2-docs/pages/WelcomeHeader.tsx | 71 ++++++++++++++++++ packages/dev/s2-docs/pages/index.mdx | 9 ++- packages/dev/s2-docs/src/Layout.tsx | 4 +- packages/dev/s2-docs/src/Nav.tsx | 4 + 5 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 packages/dev/s2-docs/assets/wallpaper_collaborative_S2_desktop.webp create mode 100644 packages/dev/s2-docs/pages/WelcomeHeader.tsx diff --git a/packages/dev/s2-docs/assets/wallpaper_collaborative_S2_desktop.webp b/packages/dev/s2-docs/assets/wallpaper_collaborative_S2_desktop.webp new file mode 100644 index 0000000000000000000000000000000000000000..14a94ca9b04c4acd859ead1e083e2dd825742f1b GIT binary patch literal 50894 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 literal 0 HcmV?d00001 diff --git a/packages/dev/s2-docs/pages/WelcomeHeader.tsx b/packages/dev/s2-docs/pages/WelcomeHeader.tsx new file mode 100644 index 00000000000..186eb60a5c8 --- /dev/null +++ b/packages/dev/s2-docs/pages/WelcomeHeader.tsx @@ -0,0 +1,71 @@ +import {ProductCard, Content, Footer, Text, LinkButton} from '@react-spectrum/s2'; +import {style} from '@react-spectrum/s2/style' with {type: 'macro'}; +import {TAB_DEFS} from '../src/constants'; +// @ts-ignore +import url from 'url:../assets/wallpaper_collaborative_S2_desktop.webp'; + +export function WelcomeHeader() { + return ( +
+

+ React Spectrum Libraries +

+
+ ); +} + +export function LibraryCards() { + return ( +
+ + {TAB_DEFS['react-spectrum'].icon} + + {TAB_DEFS['react-spectrum'].label} + {TAB_DEFS['react-spectrum'].description} + +
+ Get started +
+
+ + + {TAB_DEFS['react-aria'].icon} + + {TAB_DEFS['react-aria'].label} + {TAB_DEFS['react-aria'].description} + +
+ Explore +
+
+ + + {TAB_DEFS['internationalized'].icon} + + {TAB_DEFS['internationalized'].label} + {TAB_DEFS['internationalized'].description} + +
+ Show Packages +
+
+
+ ); +} diff --git a/packages/dev/s2-docs/pages/index.mdx b/packages/dev/s2-docs/pages/index.mdx index 4d27ba3323c..e8578e91c72 100644 --- a/packages/dev/s2-docs/pages/index.mdx +++ b/packages/dev/s2-docs/pages/index.mdx @@ -1,14 +1,15 @@ import {Layout} from '../src/Layout'; -import {LinkButton} from '@react-spectrum/s2'; +import {WelcomeHeader, LibraryCards} from './WelcomeHeader'; export default Layout; export const section = 'Getting started'; +export const hideNav = true; -# Welcome! + The React Spectrum docs have a new look! This is a **beta preview** so keep in mind that we will be continuing to make improvements before the full release. -Get Started with Spectrum 2 + ## What's new? @@ -22,4 +23,4 @@ The React Spectrum docs have a new look! This is a **beta preview** so keep in m ## Roadmap -The existing docs are still available [here](https://react-spectrum.adobe.com/react-spectrum/index.html). We plan to do a full release of the new docs site by early 2026, so we welcome any and all feedback! +The existing docs are still available [here](https://react-spectrum.adobe.com/index.html). We plan to do a full release of the new docs site by early 2026, so we welcome any and all feedback! diff --git a/packages/dev/s2-docs/src/Layout.tsx b/packages/dev/s2-docs/src/Layout.tsx index 66ba59a9936..d408c529322 100644 --- a/packages/dev/s2-docs/src/Layout.tsx +++ b/packages/dev/s2-docs/src/Layout.tsx @@ -101,7 +101,7 @@ let articleStyles = style({ export function Layout(props: PageProps & {children: ReactElement}) { let {pages, currentPage, children} = props; - let hasToC = currentPage.tableOfContents?.[0]?.children && currentPage.tableOfContents[0].children.length > 0; + let hasToC = !currentPage.exports?.hideNav && currentPage.tableOfContents?.[0]?.children && currentPage.tableOfContents?.[0]?.children?.length > 0; return ( @@ -150,7 +150,7 @@ export function Layout(props: PageProps & {children: ReactElement}) { pages={pages} currentPage={currentPage} />
-