diff --git a/.circleci/comment.js b/.circleci/comment.js index 361b908421c..5af50c1c865 100644 --- a/.circleci/comment.js +++ b/.circleci/comment.js @@ -61,7 +61,9 @@ async function run() { [Size diff since last release](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/verdaccio/publish-stats/size-diff.txt) [Docs](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/verdaccio/docs/index.html) [Storybook](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/storybook/index.html?path=/story/accordion--default) - [S2 Storybook](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/storybook-s2/index.html)` + [S2 Storybook](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/storybook-s2/index.html) + [S2 docs](https://d1pzu54gtk2aed.cloudfront.net/main/${process.env.CIRCLE_SHA1}/) + [React Aria docs](https://d5iwopk28bdhl.cloudfront.net/main/${process.env.CIRCLE_SHA1}/)` }); } } catch (error) { @@ -81,8 +83,9 @@ async function run() { * [View the storybook](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/storybook/index.html?path=/story/accordion--default) * [View the S2 storybook](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/storybook-s2/index.html) - * [View the documentation](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/docs/index.html) - * [View the S2 docs](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/s2-docs/index.html)` + * [View the v3 docs](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/docs/index.html) + * [View the S2 docs](https://d1pzu54gtk2aed.cloudfront.net/pr/${process.env.CIRCLE_SHA1}/) + * [View the React Aria docs](https://d5iwopk28bdhl.cloudfront.net/pr/${process.env.CIRCLE_SHA1}/)` }); } catch (err) { console.error(err); diff --git a/.circleci/config.yml b/.circleci/config.yml index 953bf7bb03c..78b2778ab61 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,6 +13,10 @@ parameters: type: string default: "" +orbs: + aws-cli: circleci/aws-cli@5.4.1 + aws-s3: circleci/aws-s3@4.1 + executors: rsp: docker: @@ -45,6 +49,30 @@ executors: CACHE_VERSION: v1 working_directory: ~/react-spectrum +commands: + deploy-s3: + parameters: + dir: + type: string + bucket: + type: string + steps: + - attach_workspace: + at: /tmp/dist + - aws-cli/install + - aws-s3/sync: + arguments: --cache-control public,max-age=300,stale-while-revalidate=300 --exclude * --include *.html --include *.txt --include *.json --include *.md --include *.xml + from: /tmp/dist/s2-docs/<< parameters.dir >> + to: << parameters.bucket >> + - aws-s3/sync: + arguments: --cache-control public,max-age=300,stale-while-revalidate=300 --content-type text/x-component;charset=utf-8 --exclude * --include *.rsc + from: /tmp/dist/s2-docs/<< parameters.dir >> + to: << parameters.bucket >> + - aws-s3/sync: + arguments: --cache-control public,max-age=31536000,immutable --include * --exclude *.html --exclude *.rsc --exclude *.txt --exclude *.json --exclude *.md --exclude *.xml + from: /tmp/dist/s2-docs/<< parameters.dir >> + to: << parameters.bucket >> + jobs: install: executor: rsp-large @@ -480,22 +508,22 @@ jobs: paths: - '*/docs/' - docs-beta: + s2-docs: executor: rsp-xlarge steps: - restore_cache: key: react-spectrum-{{ .Environment.CACHE_VERSION }}-{{ .Environment.CIRCLE_SHA1 }} - run: - name: build docs - command: make s2-docs-production + name: build s2 docs + command: make s2-docs - persist_to_workspace: root: dist paths: - - '*/docs/' + - 's2-docs/' - s2-docs: + s2-docs-production: executor: rsp-xlarge steps: - restore_cache: @@ -503,12 +531,12 @@ jobs: - run: name: build s2 docs - command: make s2-docs + command: make s2-docs-production - persist_to_workspace: root: dist paths: - - '*/s2-docs/' + - 's2-docs/' verdaccio: executor: rsp-xlarge @@ -823,6 +851,16 @@ jobs: azcopy copy "/tmp/dist/production/docs/*" "https://reactspectrum.blob.core.windows.net/\$web${AZURE_STORAGE_SAS_TOKEN}" --recursive --include-pattern "*.txt" --content-type "text/plain; charset=utf-8" --cache-control "max-age=300" azcopy copy "/tmp/dist/production/docs/*" "https://reactspectrum.blob.core.windows.net/\$web${AZURE_STORAGE_SAS_TOKEN}" --recursive --include-pattern "*.html;*.rsc" --cache-control "max-age=300" + deploy-s3-stage: + executor: rsp + steps: + - deploy-s3: + dir: react-aria + bucket: s3://react-aria-stage + - deploy-s3: + dir: s2 + bucket: s3://react-spectrum-stage + comment: executor: rsp steps: @@ -934,6 +972,12 @@ workflows: - s2-docs: requires: - install + - s2-docs-production: + requires: + - install + filters: + branches: + only: main - verdaccio: filters: branches: @@ -988,7 +1032,21 @@ workflows: - storybook - storybook-s2 - docs + - deploy-s3-stage: + name: deploy-s3-commit + requires: - s2-docs + filters: + branches: + ignore: main + - deploy-s3-stage: + name: deploy-s3-main + requires: + - s2-docs + - s2-docs-production + filters: + branches: + only: main - deploy-verdaccio: requires: - v-docs @@ -1009,6 +1067,7 @@ workflows: requires: - ts-diff - deploy + - deploy-s3-commit - comment: name: comment-verdaccio requires: @@ -1036,26 +1095,6 @@ 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/Makefile b/Makefile index ffd71f5e5a1..8ee3b3a4bb3 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,9 @@ SHELL := /bin/bash PATH := ./node_modules/.bin:$(PATH) +BRANCH := $(or $(CIRCLE_BRANCH),$(shell git rev-parse --abbrev-ref HEAD)) +BRANCH_TYPE := $(if $(filter $(BRANCH),main),main,pr) +HASH := $(shell git rev-parse HEAD) all: node_modules @@ -146,19 +149,25 @@ s2-api-diff: node scripts/api-diff.js --skip-same --skip-style-props s2-docs: - PUBLIC_URL=https://reactspectrum.blob.core.windows.net/reactspectrum/$$(git rev-parse HEAD)/s2-docs DIST_DIR=dist/$$(git rev-parse HEAD)/s2-docs $(MAKE) build-s2-docs + DOCS_ENV=stage PUBLIC_URL=/$(BRANCH_TYPE)/$(HASH) $(MAKE) build-s2-docs + cp packages/dev/docs/pages/disallow-robots.txt dist/s2-docs/react-aria/$(BRANCH_TYPE)/$(HASH)/robots.txt + cp packages/dev/docs/pages/disallow-robots.txt dist/s2-docs/s2/$(BRANCH_TYPE)/$(HASH)/robots.txt s2-docs-production: - PUBLIC_URL=https://react-spectrum.adobe.com/beta DIST_DIR=dist/production/docs/beta $(MAKE) build-s2-docs + DOCS_ENV=prod PUBLIC_URL=/ $(MAKE) build-s2-docs + cp packages/dev/docs/pages/robots.txt dist/s2-docs/react-aria/robots.txt + cp packages/dev/docs/pages/robots.txt dist/s2-docs/s2/robots.txt build-s2-docs: yarn workspace @react-spectrum/s2-docs generate:md yarn workspace @react-spectrum/s2-docs generate:og - REGISTRY_URL=$(PUBLIC_URL)/registry node scripts/buildRegistry.mjs - REGISTRY_URL=$(PUBLIC_URL)/registry yarn build:s2-docs --public-url $(PUBLIC_URL) + node scripts/buildRegistry.mjs + yarn build:s2-docs node scripts/createFeedS2.mjs - 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 + mkdir -p dist/s2-docs/react-aria/$(PUBLIC_URL) + mkdir -p dist/s2-docs/s2/$(PUBLIC_URL) + mv packages/dev/s2-docs/dist/react-aria/* dist/s2-docs/react-aria/$(PUBLIC_URL) + mv packages/dev/s2-docs/dist/s2/* dist/s2-docs/s2/$(PUBLIC_URL) + mkdir -p dist/s2-docs/react-aria/$(PUBLIC_URL)/registry + mv starters/docs/registry dist/s2-docs/react-aria/$(PUBLIC_URL)/registry/vanilla + mv starters/tailwind/registry dist/s2-docs/react-aria/$(PUBLIC_URL)/registry/tailwind diff --git a/packages/dev/s2-docs/.parcelrc-s2-docs b/packages/dev/s2-docs/.parcelrc-s2-docs index 079f9cee00d..5a95c73d857 100644 --- a/packages/dev/s2-docs/.parcelrc-s2-docs +++ b/packages/dev/s2-docs/.parcelrc-s2-docs @@ -1,6 +1,6 @@ { "extends": "@parcel/config-default", - "resolvers": ["@react-aria/parcel-resolver-optimize-locales", "@parcel/resolver-glob", "parcel-resolver-docs", "..."], + "resolvers": ["@react-aria/parcel-resolver-optimize-locales", "@parcel/resolver-glob", "./S2DocsResolver", "parcel-resolver-docs", "..."], "transformers": { "docs:*.{js,ts,tsx,json}": ["parcel-transformer-docs", "@parcel/transformer-inline"], "docs-json:*.{js,ts,tsx,json}": ["parcel-transformer-docs"], diff --git a/packages/dev/s2-docs/S2DocsResolver.js b/packages/dev/s2-docs/S2DocsResolver.js new file mode 100644 index 00000000000..277958116dd --- /dev/null +++ b/packages/dev/s2-docs/S2DocsResolver.js @@ -0,0 +1,10 @@ +const {Resolver} = require('@parcel/plugin'); + +module.exports = new Resolver({ + resolve({dependency}) { + // Ignore URL dependencies in MDX files. + if (dependency.sourcePath?.endsWith('.mdx') && dependency.isOptional) { + return {isExcluded: true}; + } + } +}); diff --git a/packages/dev/s2-docs/package.json b/packages/dev/s2-docs/package.json index b18d1bfa16e..8d3f72dacc1 100644 --- a/packages/dev/s2-docs/package.json +++ b/packages/dev/s2-docs/package.json @@ -3,14 +3,17 @@ "version": "1.0.0", "private": true, "scripts": { - "start": "DOCS_ENV=dev parcel --config .parcelrc-s2-docs", - "build": "DOCS_ENV=staging parcel build --config .parcelrc-s2-docs", + "start": "parcel 'pages/**/*.mdx' --config .parcelrc-s2-docs", + "start:s2": "DOCS_ENV=dev LIBRARY=s2 parcel 'pages/s2/**/*.mdx' -p 4321 --config .parcelrc-s2-docs --dist-dir dist/s2 --cache-dir ../../../.parcel-cache/s2", + "start:react-aria": "DOCS_ENV=dev LIBRARY=react-aria parcel 'pages/react-aria/**/*.mdx' -p 1234 --config .parcelrc-s2-docs --dist-dir dist/react-aria --cache-dir ../../../.parcel-cache/react-aria", + "build": "yarn build:s2 --public-url $PUBLIC_URL && yarn build:react-aria --public-url $PUBLIC_URL", + "build:s2": "LIBRARY=s2 parcel build 'pages/s2/**/*.mdx' --config .parcelrc-s2-docs --dist-dir dist/s2 --cache-dir ../../../.parcel-cache/s2", + "build:react-aria": "LIBRARY=react-aria parcel build 'pages/react-aria/**/*.mdx' --config .parcelrc-s2-docs --dist-dir dist/react-aria --cache-dir ../../../.parcel-cache/react-aria", "generate:og": "node scripts/generateOGImages.mjs", "generate:md": "node scripts/generateMarkdownDocs.mjs" }, "targets": { "react-static": { - "source": "pages/**/*.mdx", "context": "react-server", "engines": { "browsers": [ @@ -22,7 +25,8 @@ "includeNodeModules": { "tree-sitter-highlight": false, "json5": false, - "globals-docs": false + "globals-docs": false, + "@parcel/rust": false } } }, diff --git a/packages/dev/s2-docs/pages/WelcomeHeader.tsx b/packages/dev/s2-docs/pages/WelcomeHeader.tsx index 186eb60a5c8..ef6be1a146c 100644 --- a/packages/dev/s2-docs/pages/WelcomeHeader.tsx +++ b/packages/dev/s2-docs/pages/WelcomeHeader.tsx @@ -41,7 +41,7 @@ export function LibraryCards() { {TAB_DEFS['react-spectrum'].description} @@ -52,7 +52,7 @@ export function LibraryCards() { {TAB_DEFS['react-aria'].description} @@ -63,7 +63,7 @@ export function LibraryCards() { {TAB_DEFS['internationalized'].description} diff --git a/packages/dev/s2-docs/pages/index.mdx b/packages/dev/s2-docs/pages/index.mdx index 4ea5026be6f..fa803b4756f 100644 --- a/packages/dev/s2-docs/pages/index.mdx +++ b/packages/dev/s2-docs/pages/index.mdx @@ -16,7 +16,7 @@ The React Spectrum docs have a new look! This is a **beta preview** so keep in m ## What's new? - Docs for [Spectrum 2](https://s2.spectrum.adobe.com) components -- New docs for [React Aria](react-aria/Autocomplete.html) and [Internationalized](internationalized/date/index.html) +- New docs for [React Aria](react-aria/Autocomplete) and [Internationalized](internationalized/date/) - A new search menu experience - Interactive controls for examples - New concept guides @@ -25,4 +25,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/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/). 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/pages/react-aria/Autocomplete.mdx b/packages/dev/s2-docs/pages/react-aria/Autocomplete.mdx index 7c4dfe74a78..8d7710cedcb 100644 --- a/packages/dev/s2-docs/pages/react-aria/Autocomplete.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Autocomplete.mdx @@ -111,9 +111,9 @@ export const description = 'Allows users to search or filter a list of suggestio ## Content -Autocomplete filters a collection component using a [TextField](TextField.html) or [SearchField](SearchField.html). It can be used to build UI patterns such as command palettes, searchable menus, filterable selects, and more. +Autocomplete filters a collection component using a [TextField](TextField) or [SearchField](SearchField). It can be used to build UI patterns such as command palettes, searchable menus, filterable selects, and more. -[Menu](Menu.html) and [ListBox](ListBox.html) support **virtual focus**, which allows arrow key navigation within the list while the text input is focused. Use `disableVirtualFocus` to require the user to tab between the input and list. +[Menu](Menu) and [ListBox](ListBox) support **virtual focus**, which allows arrow key navigation within the list while the text input is focused. Use `disableVirtualFocus` to require the user to tab between the input and list. @@ -1108,7 +1108,7 @@ function AsyncLoadingExample() { ## API -```tsx links={{Autocomplete: '#autocomplete', SearchField: 'SearchField.html', TextField: 'TextField.html', Menu: 'Menu.html', ListBox: 'ListBox.html', TagGroup: 'TagGroup.html', GridList: 'GridList.html', Table: 'Table.html'}} +```tsx links={{Autocomplete: '#autocomplete', SearchField: 'SearchField', TextField: 'TextField', Menu: 'Menu', ListBox: 'ListBox', TagGroup: 'TagGroup', GridList: 'GridList', Table: 'Table'}} or , , , , or diff --git a/packages/dev/s2-docs/pages/react-aria/Breadcrumbs.mdx b/packages/dev/s2-docs/pages/react-aria/Breadcrumbs.mdx index 8f46e6623da..ca5f3d68530 100644 --- a/packages/dev/s2-docs/pages/react-aria/Breadcrumbs.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Breadcrumbs.mdx @@ -41,7 +41,7 @@ export const description = 'Displays a hierarchy of links to the current page or ## Content -`Breadcrumbs` follows the [Collection Components API](collections.html?component=Breadcrumbs), accepting both static and dynamic collections. This example shows a dynamic collection, passing a list of objects to the `items` prop, and a function to render the children. The `onAction` event is called when a user presses a breadcrumb. +`Breadcrumbs` follows the [Collection Components API](collections?component=Breadcrumbs), accepting both static and dynamic collections. This example shows a dynamic collection, passing a list of objects to the `items` prop, and a function to render the children. The `onAction` event is called when a user presses a breadcrumb. ```tsx render "use client"; @@ -80,7 +80,7 @@ function Example() { -```tsx links={{Breadcrumbs: '#breadcrumbs', Breadcrumb: '#breadcrumb', Link: 'Link.html'}} +```tsx links={{Breadcrumbs: '#breadcrumbs', Breadcrumb: '#breadcrumb', Link: 'Link'}} diff --git a/packages/dev/s2-docs/pages/react-aria/Button.mdx b/packages/dev/s2-docs/pages/react-aria/Button.mdx index afdbb7bd056..9e97fbed462 100644 --- a/packages/dev/s2-docs/pages/react-aria/Button.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Button.mdx @@ -10,6 +10,7 @@ import vanillaDocs from 'docs:vanilla-starter/Button'; import tailwindDocs from 'docs:tailwind-starter/Button'; import '../../tailwind/tailwind.css'; import typesDocs from 'docs:@react-types/shared/src/events.d.ts'; +import {getBaseUrl} from '../../src/pageUtils'; export const tags = ['btn']; export const relatedPages = [{'title': 'useButton', 'url': 'https://react-spectrum.adobe.com/react-aria/useButton.html'}]; @@ -47,9 +48,9 @@ export const description = 'Allows a user to perform an action, with mouse, touc ## Events -Use the `onPress` prop to handle interactions via mouse, keyboard, and touch. This is similar to `onClick`, but normalized for consistency across browsers, devices, and interaction methods. Read our [blog post](building-a-button-part-1.html) to learn more. +Use the `onPress` prop to handle interactions via mouse, keyboard, and touch. This is similar to `onClick`, but normalized for consistency across browsers, devices, and interaction methods. Read our [blog post](blog/building-a-button-part-1) to learn more. -The `onPressStart`, `onPressEnd`, and `onPressChange` events are also emitted as the user interacts with the button. Each of these handlers receives a , which provides information about the target and interaction method. See [usePress](https://react-spectrum.adobe.com/react-aria/usePress.html) for more details. +The `onPressStart`, `onPressEnd`, and `onPressChange` events are also emitted as the user interacts with the button. Each of these handlers receives a , which provides information about the target and interaction method. See usePress for more details. ```tsx render "use client"; @@ -111,7 +112,7 @@ function PendingButton() { ## Link buttons -The `Button` component always represents a button semantically. To create a link that visually looks like a button, use the [Link](Link.html) component instead. You can reuse the same styles you apply to the `Button` component on the `Link`. +The `Button` component always represents a button semantically. To create a link that visually looks like a button, use the [Link](Link) component instead. You can reuse the same styles you apply to the `Button` component on the `Link`. ```tsx render "use client"; diff --git a/packages/dev/s2-docs/pages/react-aria/Calendar.mdx b/packages/dev/s2-docs/pages/react-aria/Calendar.mdx index a11002e93fb..3090329a09f 100644 --- a/packages/dev/s2-docs/pages/react-aria/Calendar.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Calendar.mdx @@ -35,7 +35,7 @@ export const description = 'Displays one or more date grids and allows users to ## Value -Use the `value` or `defaultValue` prop to set the date value, using objects in the [@internationalized/date](../internationalized/date/index.html) package. This library supports parsing date strings in multiple formats, manipulation across international calendar systems, time zones, etc. +Use the `value` or `defaultValue` prop to set the date value, using objects in the [@internationalized/date](internationalized/date/) package. This library supports parsing date strings in multiple formats, manipulation across international calendar systems, time zones, etc. ```tsx render "use client"; @@ -79,7 +79,7 @@ import {Calendar} from 'vanilla-starter/Calendar'; ### Custom calendar systems -`Calendar` also supports custom calendar systems that implement custom business rules, for example a fiscal year calendar that follows a [4-5-4 format](https://nrf.com/resources/4-5-4-calendar), where month ranges don't follow the usual Gregorian calendar. See the [@internationalized/date docs](../internationalized/date/Calendar.html#custom-calendars) for an example implementation. +`Calendar` also supports custom calendar systems that implement custom business rules, for example a fiscal year calendar that follows a [4-5-4 format](https://nrf.com/resources/4-5-4-calendar), where month ranges don't follow the usual Gregorian calendar. See the [@internationalized/date docs](internationalized/date/Calendar#custom-calendars) for an example implementation. ```tsx render "use client"; @@ -308,7 +308,7 @@ import {ChevronLeft, ChevronRight} from 'lucide-react'; role="img" aria-label="Anatomy diagram of a calendar component, which consists of a heading, grid of cells, previous, and next buttons." /> -```tsx links={{Calendar: '#calendar', Button: 'Button.html', CalendarGrid: '#calendargrid', CalendarGridHeader: '#calendargridheader', CalendarHeaderCell: '#calendarheadercell', CalendarGridBody: '#calendargridbody', CalendarCell: '#calendarcell'}} +```tsx links={{Calendar: '#calendar', Button: 'Button', CalendarGrid: '#calendargrid', CalendarGridHeader: '#calendargridheader', CalendarHeaderCell: '#calendarheadercell', CalendarGridBody: '#calendargridbody', CalendarCell: '#calendarcell'}}
diff --git a/packages/dev/s2-docs/pages/react-aria/Table/testing.mdx b/packages/dev/s2-docs/pages/react-aria/Table/testing.mdx index ec5d5f1f201..8d59fe98520 100644 --- a/packages/dev/s2-docs/pages/react-aria/Table/testing.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Table/testing.mdx @@ -16,8 +16,8 @@ export const description = 'Testing Table with React Aria test utils'; Table supports long press interactions on its rows in certain configurations. See the following sections on how to handle these behaviors in your tests. -* [Timers](../testing.html#timers) -* [Long press](../testing.html#simulating-user-long-press) +* [Timers](../testing#timers) +* [Long press](../testing#simulating-user-long-press) ## Test utils diff --git a/packages/dev/s2-docs/pages/react-aria/Tabs.mdx b/packages/dev/s2-docs/pages/react-aria/Tabs.mdx index 689e6fddd4a..d6990c4bdc0 100644 --- a/packages/dev/s2-docs/pages/react-aria/Tabs.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Tabs.mdx @@ -11,7 +11,7 @@ import {InlineAlert, Heading, Content} from '@react-spectrum/s2' export const tags = ['navigation']; export const relatedPages = [ {title: 'useTabs', url: 'https://react-spectrum.adobe.com/react-aria/useTabs.html'}, - {title: 'Testing', url: './Tabs/testing.html'} + {title: 'Testing', url: './Tabs/testing'} ]; export const description = 'Organizes content into multiple sections and allows users to navigate between them.'; @@ -114,7 +114,7 @@ export const description = 'Organizes content into multiple sections and allows ## Content -`TabList` follows the [Collection Components API](collections.html?component=TabList), accepting both static and dynamic collections. This example shows a dynamic collection, passing a list of objects to the `items` prop, and a function to render the children. +`TabList` follows the [Collection Components API](collections?component=TabList), accepting both static and dynamic collections. This example shows a dynamic collection, passing a list of objects to the `items` prop, and a function to render the children. ```tsx render "use client"; @@ -181,7 +181,7 @@ function Example() { ### Links -Use the `href` prop on a `` to create a link. See the [framework setup guide](frameworks.html) to learn how to integrate with your framework. This example uses a simple hash-based router to sync the selected tab to the URL. +Use the `href` prop on a `` to create a link. See the [framework setup guide](frameworks) to learn how to integrate with your framework. This example uses a simple hash-based router to sync the selected tab to the URL. ```tsx render "use client"; @@ -225,7 +225,7 @@ function subscribe(fn) { ## Selection -Use the `defaultSelectedKey` or `selectedKey` prop to set the selected tab. The selected key corresponds to the `id` prop of a ``. Tabs can be disabled with the `isDisabled` prop. See the [selection guide](selection.html?component=Tabs#single-selection) for more details. +Use the `defaultSelectedKey` or `selectedKey` prop to set the selected tab. The selected key corresponds to the `id` prop of a ``. Tabs can be disabled with the `isDisabled` prop. See the [selection guide](selection?component=Tabs#single-selection) for more details. ```tsx render "use client"; @@ -283,7 +283,7 @@ function Example() { -```tsx links={{Tabs: '#tabs', TabList: '#tablist', Tab: '#tab', TabPanels: '#tabpanels', TabPanel: '#tabpanel', SelectionIndicator: 'selection.html#animated-selectionindicator'}} +```tsx links={{Tabs: '#tabs', TabList: '#tablist', Tab: '#tab', TabPanels: '#tabpanels', TabPanel: '#tabpanel', SelectionIndicator: 'selection#animated-selectionindicator'}} diff --git a/packages/dev/s2-docs/pages/react-aria/TagGroup.mdx b/packages/dev/s2-docs/pages/react-aria/TagGroup.mdx index af5f8c4b09b..ab6990235f4 100644 --- a/packages/dev/s2-docs/pages/react-aria/TagGroup.mdx +++ b/packages/dev/s2-docs/pages/react-aria/TagGroup.mdx @@ -44,7 +44,7 @@ export const description = 'A focusable list of labels, categories, keywords, fi ## Content -`TagGroup` follows the [Collection Components API](collections.html?component=TagGroup), accepting both static and dynamic collections. This example shows a dynamic collection, passing a list of objects to the `items` prop, and a function to render the children. Items can be removed via the `onRemove` event. +`TagGroup` follows the [Collection Components API](collections?component=TagGroup), accepting both static and dynamic collections. This example shows a dynamic collection, passing a list of objects to the `items` prop, and a function to render the children. Items can be removed via the `onRemove` event. ```tsx render "use client"; @@ -77,7 +77,7 @@ function Example() { ### Links -Use the `href` prop on a `` to create a link. See the [framework setup guide](frameworks.html) to learn how to integrate with your framework. +Use the `href` prop on a `` to create a link. See the [framework setup guide](frameworks) to learn how to integrate with your framework. ```tsx render "use client"; @@ -97,7 +97,7 @@ import {TagGroup, Tag} from 'vanilla-starter/TagGroup'; ## Selection -Use the `selectionMode` prop to enable single or multiple selection. The selected items can be controlled via the `selectedKeys` prop, matching the `id` prop of the items. Items can be disabled with the `isDisabled` prop. See the [selection guide](selection.html?component=TagGroup) for more details. +Use the `selectionMode` prop to enable single or multiple selection. The selected items can be controlled via the `selectedKeys` prop, matching the `id` prop of the items. Items can be disabled with the `isDisabled` prop. See the [selection guide](selection?component=TagGroup) for more details. ```tsx render docs={docs.exports.TagGroup} links={docs.links} props={['selectionMode', 'selectionBehavior', 'disallowEmptySelection']} initialProps={{selectionMode: 'multiple'}} wide "use client"; @@ -139,7 +139,7 @@ function Example(props) { -```tsx links={{TagGroup: '#taggroup', TagList: '#taglist', Tag: '#tag', Button: 'Button.html', SelectionIndicator: 'selection.html#animated-selectionindicator'}} +```tsx links={{TagGroup: '#taggroup', TagList: '#taglist', Tag: '#tag', Button: 'Button', SelectionIndicator: 'selection#animated-selectionindicator'}} -The [useDraggableCollection](https://react-spectrum.adobe.com/react-aria/useDraggableCollection.html) and [useDroppableCollection](../useDroppableCollection.html) hooks can be used to implement drag and drop within components built with existing React Aria hooks such as [useListBox](https://react-spectrum.adobe.com/react-aria/useListBox.html), [useTable](https://react-spectrum.adobe.com/react-aria/useTable.html), and [useGridList](https://react-spectrum.adobe.com/react-aria/useGridList.html). The drag and drop system integrates with our existing architecture for [collections](../collections.html) and [selection](../selection.html), which are used across all of these components. This enables multiple selected items to be dragged at once, allows keyboard navigation within a droppable collection to adapt based on the collection's layout, and facilitates automatic focus management when items are dropped. +The [useDraggableCollection](https://react-spectrum.adobe.com/react-aria/useDraggableCollection.html) and [useDroppableCollection](../useDroppableCollection) hooks can be used to implement drag and drop within components built with existing React Aria hooks such as [useListBox](https://react-spectrum.adobe.com/react-aria/useListBox.html), [useTable](https://react-spectrum.adobe.com/react-aria/useTable.html), and [useGridList](https://react-spectrum.adobe.com/react-aria/useGridList.html). The drag and drop system integrates with our existing architecture for [collections](../collections) and [selection](../selection), which are used across all of these components. This enables multiple selected items to be dragged at once, allows keyboard navigation within a droppable collection to adapt based on the collection's layout, and facilitates automatic focus management when items are dropped. Try out an example below, which allows reordering and dragging elements between lists. @@ -110,10 +110,10 @@ Defining an API that is both flexible and easy to use was also difficult. We ini ## Try it out! -We've been working on our drag and drop implementation for a while, and we're excited to share it with the community! Check out our documentation for [React Aria](../dnd.html) and [React Spectrum](../../s2/dnd.html) to get started. +We've been working on our drag and drop implementation for a while, and we're excited to share it with the community! Check out our documentation for [React Aria](../dnd) and [React Spectrum](../../s2/dnd) to get started. You can use our React Aria hooks standalone, or integrate with existing collection components for common use cases like list reordering, inserting items, or dropping into folders. You can also customize most of the behavior with lower level APIs as needed, allowing you to build more specialized experiences. -For React Spectrum, the [useDragAndDrop](../../s2/dnd.html) hook can be used to enable drag and drop in the components that support it. This returns an object containing implementations of the React Aria hooks used to implement drag and drop, keeping bundle size small when drag and drop is unused. Currently support is limited to [ListView](https://react-spectrum.adobe.com/react-spectrum/ListView.html), but we will be adding drag and drop to other components soon. +For React Spectrum, the [useDragAndDrop](../../s2/dnd) hook can be used to enable drag and drop in the components that support it. This returns an object containing implementations of the React Aria hooks used to implement drag and drop, keeping bundle size small when drag and drop is unused. Currently support is limited to [ListView](https://react-spectrum.adobe.com/react-spectrum/ListView.html), but we will be adding drag and drop to other components soon. We hope these new hooks help make accessible drag and drop interactions easier to build, and we can't wait to see what you create! diff --git a/packages/dev/s2-docs/pages/react-aria/blog/how-we-internationalized-our-numberfield.mdx b/packages/dev/s2-docs/pages/react-aria/blog/how-we-internationalized-our-numberfield.mdx index c6f7b191a37..08c3d113808 100644 --- a/packages/dev/s2-docs/pages/react-aria/blog/how-we-internationalized-our-numberfield.mdx +++ b/packages/dev/s2-docs/pages/react-aria/blog/how-we-internationalized-our-numberfield.mdx @@ -156,5 +156,5 @@ This approach of using a number formatter to generate a parser avoids needing to ## Conclusion -In this post, we covered how a number field can be internationalized and support advanced formatting, and how we improved the experience on mobile. If you need to implement localized number parsing in your own apps or components, check out the [@internationalized/number](http://npmjs.com/@internationalized/number) package on npm. And if you use the [useNumberField](https://react-spectrum.adobe.com/react-aria/useNumberField.html) hook in React Aria, or the [NumberField](../../s2/NumberField.html) component in React Spectrum, all of this is built in. +In this post, we covered how a number field can be internationalized and support advanced formatting, and how we improved the experience on mobile. If you need to implement localized number parsing in your own apps or components, check out the [@internationalized/number](http://npmjs.com/@internationalized/number) package on npm. And if you use the [useNumberField](https://react-spectrum.adobe.com/react-aria/useNumberField.html) hook in React Aria, or the [NumberField](../../s2/NumberField) component in React Spectrum, all of this is built in. diff --git a/packages/dev/s2-docs/pages/react-aria/blog/index.mdx b/packages/dev/s2-docs/pages/react-aria/blog/index.mdx index b1ef5236044..7bd7fab8b30 100644 --- a/packages/dev/s2-docs/pages/react-aria/blog/index.mdx +++ b/packages/dev/s2-docs/pages/react-aria/blog/index.mdx @@ -22,5 +22,5 @@ export const isPostList = true; # Blog - page.name.startsWith('react-aria/blog/') && !page.name.endsWith('index.html')) ?? []} /> + page.name.startsWith('react-aria/blog/') && !page.name.endsWith('index')) ?? []} /> diff --git a/packages/dev/s2-docs/pages/react-aria/blog/introducing-react-spectrum.mdx b/packages/dev/s2-docs/pages/react-aria/blog/introducing-react-spectrum.mdx index 3f5be8e9280..3faf6ea7bc4 100644 --- a/packages/dev/s2-docs/pages/react-aria/blog/introducing-react-spectrum.mdx +++ b/packages/dev/s2-docs/pages/react-aria/blog/introducing-react-spectrum.mdx @@ -31,7 +31,7 @@ export const isSubpage = true; # Introducing React Spectrum -We're excited to announce [React Spectrum](https://react-spectrum.adobe.com/index.html), a collection of libraries and tools that help you build adaptive, accessible, and robust user experiences. [Check it out on Github](https://github.com/adobe/react-spectrum)! React Spectrum includes three libraries: +We're excited to announce [React Spectrum](https://react-spectrum.adobe.com/), a collection of libraries and tools that help you build adaptive, accessible, and robust user experiences. [Check it out on Github](https://github.com/adobe/react-spectrum)! React Spectrum includes three libraries: - **React Spectrum** — A React implementation of Spectrum, Adobe's design system. - **React Aria** — A library of React Hooks that provides accessible UI primitives for your design system. @@ -49,10 +49,10 @@ We're excited to announce [React Spectrum](https://react-spectrum.adobe.com/inde ## Features -- ♿️ [**Accessible**](../quality.html#accessibility) – Accessibility and behavior is implemented according to [WAI-ARIA Authoring Practices](https://www.w3.org/TR/wai-aria-practices-1.2/), including full screen reader and keyboard navigation support. All components have been tested across a wide variety of screen readers and devices to ensure the best experience possible for all users. -- 📱 [**Adaptive**](../quality.html#interactions) – All components are designed to work with mouse, touch, and keyboard interactions. They're built with responsive design principles to deliver a great experience, no matter the device. -- 🌍 [**International**](../quality.html#internationalization) – Support for more than 30 languages is included out of the box, with support for right-to-left languages, date and number formatting, and more. -- 🎨 [**Customizable**](../../s2/styling.html) – React Spectrum automatically adapt for dark mode. For even more customizability, you can build your own components with your own DOM structure and styling using the [React Aria](../index.html) and [React Stately](https://react-spectrum.adobe.com/react-stately/index.html) hooks to provide behavior, accessibility, and interactions. +- ♿️ [**Accessible**](../quality#accessibility) – Accessibility and behavior is implemented according to [WAI-ARIA Authoring Practices](https://www.w3.org/TR/wai-aria-practices-1.2/), including full screen reader and keyboard navigation support. All components have been tested across a wide variety of screen readers and devices to ensure the best experience possible for all users. +- 📱 [**Adaptive**](../quality#interactions) – All components are designed to work with mouse, touch, and keyboard interactions. They're built with responsive design principles to deliver a great experience, no matter the device. +- 🌍 [**International**](../quality#internationalization) – Support for more than 30 languages is included out of the box, with support for right-to-left languages, date and number formatting, and more. +- 🎨 [**Customizable**](../../s2/styling) – React Spectrum automatically adapt for dark mode. For even more customizability, you can build your own components with your own DOM structure and styling using the [React Aria](../) and [React Stately](https://react-spectrum.adobe.com/react-stately/) hooks to provide behavior, accessibility, and interactions. Adobe is a large company with thousands of engineers working on hundreds of products, which must all meet high standards for UI consistency, accessibility, internationalization, and usability. Meeting these standards at our scale has been a challenge, and we're excited to share what we've learned with the community and raise the bar for web applications together. @@ -72,7 +72,7 @@ To enable reusing component behavior between design systems, React Spectrum spli ### React Stately -[React Stately](https://react-spectrum.adobe.com/react-stately/index.html) is a collection of hooks that provide state management and core logic for each component. They make no assumptions about the platform they are running on, and have no theme or design system-specific logic. +[React Stately](https://react-spectrum.adobe.com/react-stately/) is a collection of hooks that provide state management and core logic for each component. They make no assumptions about the platform they are running on, and have no theme or design system-specific logic. React Stately hooks accept common props from the component and provide state management. They implement the core logic for the component and return an interface for reading and updating the component state. @@ -80,7 +80,7 @@ React Stately can be used independently in your own components, or paired with R ### React Aria -[React Aria](../index.html) implements behavior and [accessibility](../quality.html#accessibility) for the web according to the [WAI-ARIA Authoring Practices](https://www.w3.org/TR/wai-aria-practices-1.2/). It includes full screen reader and keyboard navigation support, along with mouse and touch [interactions](../quality.html#interactions) that have been tested across a wide variety of devices and browsers. It also implements [internationalization](../quality.html#internationalization) for over 30 languages, with right-to-left specific behavior, localized date and number formatting, and more. +[React Aria](../) implements behavior and [accessibility](../quality#accessibility) for the web according to the [WAI-ARIA Authoring Practices](https://www.w3.org/TR/wai-aria-practices-1.2/). It includes full screen reader and keyboard navigation support, along with mouse and touch [interactions](../quality#interactions) that have been tested across a wide variety of devices and browsers. It also implements [internationalization](../quality#internationalization) for over 30 languages, with right-to-left specific behavior, localized date and number formatting, and more. React Aria does not contain any design system specific styling or logic. It implements event handling, accessibility, internationalization, etc. — all the parts of a component that could be shared across multiple design systems. It returns DOM props that can be spread onto the elements rendered by the component. These include semantic properties like [ARIA](https://www.w3.org/TR/wai-aria-1.2/), and event handlers. The event handlers in turn call methods on the state interface to implement the behavior for the component. @@ -119,11 +119,11 @@ function Switch(props) { Test ``` -[Read more](../quality.html) about React Aria and the problems it solves, and check out the docs to [get started](../getting-started.html) building your own design system. +[Read more](../quality) about React Aria and the problems it solves, and check out the docs to [get started](../getting-started) building your own design system. ### React Spectrum -[React Spectrum](../../s2/index.html) puts all of these pieces together and implements the Adobe-specific styling. It's designed to be adaptive, and works across mouse, touch, and keyboard interactions, on devices of any screen size. It includes automatic support for dark mode, and responsive scaling for large hit targets on touch devices. +[React Spectrum](../../s2/) puts all of these pieces together and implements the Adobe-specific styling. It's designed to be adaptive, and works across mouse, touch, and keyboard interactions, on devices of any screen size. It includes automatic support for dark mode, and responsive scaling for large hit targets on touch devices. If you're integrating with Adobe software or would like an end-to-end component library to use in your project, then React Spectrum is a great place to start. Save time by using [Adobe Developer App Builder](https://www.adobe.io/app-builder), our complete framework for building custom cloud-native Adobe apps. Enterprise customers and partners can extend the functionality of Adobe Experience Platform and Adobe Experience Cloud solutions in a custom app that solves specific business and workflow needs. @@ -158,7 +158,7 @@ import UserSettings from '@react-spectrum/s2/icons/UserSettings'; ``` -[Get started](../../s2/getting-started.html) building an application with React Spectrum, and check out the docs for each component to learn more. In addition, if you're building your own component library, React Spectrum is a good example of how to use React Aria and React Stately to build a full design system. +[Get started](../../s2/getting-started) building an application with React Spectrum, and check out the docs for each component to learn more. In addition, if you're building your own component library, React Spectrum is a good example of how to use React Aria and React Stately to build a full design system. ## Try it out! diff --git a/packages/dev/s2-docs/pages/react-aria/blog/rtl-date-time.mdx b/packages/dev/s2-docs/pages/react-aria/blog/rtl-date-time.mdx index 9f0f2912ed1..e6010db8975 100644 --- a/packages/dev/s2-docs/pages/react-aria/blog/rtl-date-time.mdx +++ b/packages/dev/s2-docs/pages/react-aria/blog/rtl-date-time.mdx @@ -34,7 +34,7 @@ Internationalization is a core feature of our Date and Time components. We suppo ## The Structure of Our Date and Time Components -In a [previous blog post](date-and-time-pickers-for-all.html#date-fields), we discussed the reasoning behind the component structure of our date and time components. In short, we designed these components to render individually focusable segments for each date and time unit, eliminating the challenges of parsing various date formats — an issue commonly encountered with free-form text fields. Since the date and time format is automatically determined based on the user's locale, the user only needs to fill in the values without worrying about the appropriate separators or the order. This made for a smoother, more intuitive experience for the user, removing the guesswork associated with formatting and parsing dates in various locales. +In a [previous blog post](date-and-time-pickers-for-all#date-fields), we discussed the reasoning behind the component structure of our date and time components. In short, we designed these components to render individually focusable segments for each date and time unit, eliminating the challenges of parsing various date formats — an issue commonly encountered with free-form text fields. Since the date and time format is automatically determined based on the user's locale, the user only needs to fill in the values without worrying about the appropriate separators or the order. This made for a smoother, more intuitive experience for the user, removing the guesswork associated with formatting and parsing dates in various locales.
The "root", "on", and "between" drop positions.