diff --git a/Makefile b/Makefile index cf9e3b12b1d..51aad416af4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: clean test lint build +.PHONY: clean test lint build sync-starter-css check-starter-css SHELL := /bin/bash PATH := ./node_modules/.bin:$(PATH) @@ -121,13 +121,22 @@ website-production: # $(MAKE) s2-docs-production $(MAKE) starter-zip $(MAKE) tailwind-starter + $(MAKE) hooks-starter $(MAKE) s2-storybook-docs mv starters/docs/storybook-static dist/production/docs/react-aria-starter mv starters/docs/react-aria-starter.zip dist/production/docs/react-aria-starter.$$(git rev-parse --short HEAD).zip mv starters/tailwind/storybook-static dist/production/docs/react-aria-tailwind-starter mv starters/tailwind/react-aria-tailwind-starter.zip dist/production/docs/react-aria-tailwind-starter.$$(git rev-parse --short HEAD).zip + mv starters/hooks/storybook-static dist/production/docs/react-aria-hooks-starter + mv starters/hooks/react-aria-hooks-starter.zip dist/production/docs/react-aria-hooks-starter.$$(git rev-parse --short HEAD).zip -check-examples: +sync-starter-css: + yarn sync:starter-css + +check-starter-css: + yarn check:starter-css + +check-examples: check-starter-css node scripts/extractExamplesS2.mjs yarn tsgo --project dist/docs-examples/tsconfig.json @@ -146,6 +155,12 @@ tailwind-starter: cd starters/tailwind && zip -r react-aria-tailwind-starter.zip . -x .gitignore .DS_Store "node_modules/*" "storybook-static/*" cd starters/tailwind && yarn build-storybook +hooks-starter: sync-starter-css + cp LICENSE starters/hooks/. + cd starters/hooks && yarn --no-immutable && yarn up react-aria react-stately @internationalized/date && yarn tsc + cd starters/hooks && zip -r react-aria-hooks-starter.zip . -x .gitignore .DS_Store "node_modules/*" "storybook-static/*" + cd starters/hooks && yarn build-storybook + s2-storybook-docs: yarn build:s2-storybook-docs -o dist/production/docs/s2 @@ -174,7 +189,7 @@ s2-docs-production: cd starters/tailwind && yarn install --no-immutable && yarn up react-aria-components tailwindcss-react-aria-components $(MAKE) build-starters -build-s2-docs: +build-s2-docs: check-starter-css yarn workspace @react-spectrum/s2-docs generate:md yarn workspace @react-spectrum/s2-docs generate:og LIBRARY=react-aria node scripts/buildRegistry.mjs diff --git a/package.json b/package.json index eb5805ba0e3..3aa0a953fa7 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,8 @@ "clean:all": "make clean_all", "format": "oxfmt", "format:check": "oxfmt --check", + "sync:starter-css": "node scripts/syncStarterCss.mjs", + "check:starter-css": "node scripts/syncStarterCss.mjs --check", "install-16": "node scripts/react-16-install-prep.mjs && yarn add react@^16.8.0 react-dom@^16.8.0 @testing-library/react@^12 @testing-library/react-hooks@^8 @testing-library/dom@^8 react-test-renderer@^16.9.0 && node scripts/oldReactSupport.mjs", "install-17": "node scripts/react-17-install-prep.mjs && yarn add react@^17 react-dom@^17 @testing-library/react@^12 @testing-library/react-hooks@^8 @testing-library/dom@^8 react-test-renderer@^16.9.0 && node scripts/oldReactSupport.mjs", "install-18": "node scripts/react-18-install-prep.mjs && yarn add react@^18 react-dom@^18 react-test-renderer@^18.3.1 && node scripts/oldReactSupport.mjs", diff --git a/packages/dev/s2-docs/package.json b/packages/dev/s2-docs/package.json index 5470e7669d1..608ce5bd1df 100644 --- a/packages/dev/s2-docs/package.json +++ b/packages/dev/s2-docs/package.json @@ -59,7 +59,8 @@ }, "alias": { "tailwind-starter": "../../../starters/tailwind/src", - "vanilla-starter": "../../../starters/docs/src" + "vanilla-starter": "../../../starters/docs/src", + "hooks-starter": "../../../starters/hooks/src" }, "targets": { "react-static": { diff --git a/packages/dev/s2-docs/pages/react-aria/Breadcrumbs.mdx b/packages/dev/s2-docs/pages/react-aria/Breadcrumbs.mdx index 9a270196acc..fa40a76d886 100644 --- a/packages/dev/s2-docs/pages/react-aria/Breadcrumbs.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Breadcrumbs.mdx @@ -7,7 +7,7 @@ import Anatomy from '/packages/react-aria/docs/breadcrumbs/anatomy.svg'; import {InlineAlert, Heading, Content} from '@react-spectrum/s2'; export const tags = ['navigation']; -export const relatedPages = [{'title': 'useBreadcrumbs', 'url': 'Breadcrumbs/useBreadcrumbs.html'}]; +export const relatedPages = [{'title': 'useBreadcrumbs', 'url': './Breadcrumbs/useBreadcrumbs'}]; export const description = 'Displays a hierarchy of links to the current page or resource in an application.'; # Breadcrumbs diff --git a/packages/dev/s2-docs/pages/react-aria/Breadcrumbs/useBreadcrumbs.mdx b/packages/dev/s2-docs/pages/react-aria/Breadcrumbs/useBreadcrumbs.mdx new file mode 100644 index 00000000000..5c8c8ea796d --- /dev/null +++ b/packages/dev/s2-docs/pages/react-aria/Breadcrumbs/useBreadcrumbs.mdx @@ -0,0 +1,69 @@ +{/* Copyright 2026 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. */} + +import {Layout} from '../../../src/Layout'; +export default Layout; +import {FunctionAPIGroup} from '../../../src/FunctionAPI'; +import {InterfaceType} from '../../../src/types'; +import docs from 'docs:@react-aria/breadcrumbs'; +import Anatomy from '/packages/react-aria/docs/breadcrumbs/anatomy.svg'; + +export const section = 'Hooks'; +export const description = 'Provides the behavior and accessibility implementation for a breadcrumbs component.'; +export const isSubpage = true; + +# useBreadcrumbs + +{docs.exports.useBreadcrumbs.description} + +```tsx render files={["starters/hooks/src/Breadcrumbs.tsx", "starters/hooks/src/Breadcrumbs.css", "starters/hooks/src/Link.css"]} +"use client"; +import {Breadcrumbs, Breadcrumb} from 'hooks-starter/Breadcrumbs'; + + + alert('Pressed Folder 1')}>Folder 1 + alert('Pressed Folder 2')}>Folder 2 + Folder 3 + +``` + +## API + + + +```tsx + + + + + +``` + + + +### AriaBreadcrumbsProps + + + +### BreadcrumbsAria + + + +### AriaBreadcrumbItemProps + + + +### BreadcrumbItemAria + + diff --git a/packages/dev/s2-docs/pages/react-aria/Button.mdx b/packages/dev/s2-docs/pages/react-aria/Button.mdx index 22065cb4fb5..33478c4307c 100644 --- a/packages/dev/s2-docs/pages/react-aria/Button.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Button.mdx @@ -12,7 +12,7 @@ import '../../tailwind/tailwind.css'; import typesDocs from 'docs:@react-types/shared/src/events.d.ts'; export const tags = ['btn']; -export const relatedPages = [{'title': 'useButton', 'url': 'Button/useButton.html'}]; +export const relatedPages = [{'title': 'useButton', 'url': './Button/useButton'}]; export const description = 'Allows a user to perform an action, with mouse, touch, and keyboard interactions.'; # Button diff --git a/packages/dev/s2-docs/pages/react-aria/Button/useButton.mdx b/packages/dev/s2-docs/pages/react-aria/Button/useButton.mdx new file mode 100644 index 00000000000..300ed80ada3 --- /dev/null +++ b/packages/dev/s2-docs/pages/react-aria/Button/useButton.mdx @@ -0,0 +1,41 @@ +{/* Copyright 2026 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. */} + +import {Layout} from '../../../src/Layout'; +export default Layout; +import {FunctionAPI} from '../../../src/FunctionAPI'; +import {InterfaceType} from '../../../src/types'; +import docs from 'docs:@react-aria/button'; + +export const section = 'Hooks'; +export const description = 'Provides the behavior and accessibility implementation for a button.'; +export const isSubpage = true; + +# useButton + +{docs.exports.useButton.description} + +```tsx render files={["starters/hooks/src/Button.tsx", "starters/hooks/src/Button.css"]} +"use client"; +import {Button} from 'hooks-starter/Button'; + + +``` + +## API + + + +### AriaButtonProps + + + +### ButtonAria + + diff --git a/packages/dev/s2-docs/pages/react-aria/Calendar.mdx b/packages/dev/s2-docs/pages/react-aria/Calendar.mdx index 7a3ec7657ce..95f0cad2472 100644 --- a/packages/dev/s2-docs/pages/react-aria/Calendar.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Calendar.mdx @@ -9,7 +9,7 @@ import '../../tailwind/tailwind.css'; import Anatomy from '/packages/react-aria/docs/calendar/calendar-anatomy.svg'; export const tags = ['date']; -export const relatedPages = [{'title': 'useCalendar', 'url': 'Calendar/useCalendar.html'}]; +export const relatedPages = [{'title': 'useCalendar', 'url': './Calendar/useCalendar'}]; export const description = 'Displays one or more date grids and allows users to select a single date.'; # Calendar diff --git a/packages/dev/s2-docs/pages/react-aria/Calendar/useCalendar.mdx b/packages/dev/s2-docs/pages/react-aria/Calendar/useCalendar.mdx new file mode 100644 index 00000000000..29c3aa9bde8 --- /dev/null +++ b/packages/dev/s2-docs/pages/react-aria/Calendar/useCalendar.mdx @@ -0,0 +1,91 @@ +{/* Copyright 2026 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. */} + +import {Layout} from '../../../src/Layout'; +export default Layout; +import {FunctionAPIGroup} from '../../../src/FunctionAPI'; +import {InterfaceType} from '../../../src/types'; +import docs from 'docs:@react-aria/calendar'; +import statelyDocs from 'docs:@react-stately/calendar'; +import Anatomy from '/packages/react-aria/docs/calendar/calendar-anatomy.svg'; + +export const section = 'Hooks'; +export const description = 'Provides the behavior and accessibility implementation for a calendar component.'; +export const isSubpage = true; + +# useCalendar + +{docs.exports.useCalendar.description} + +```tsx render files={["starters/hooks/src/Calendar.tsx", "starters/hooks/src/Calendar.css", "starters/docs/src/Button.tsx", "starters/docs/src/Button.css"]} +"use client"; +import {Calendar} from 'hooks-starter/Calendar'; + + +``` + +## API + + + +```tsx + + + + + + } + +``` + +## useDialog + +`useDialog` is the dialog primitive itself, so the `Dialog` component is built from scratch. To render it interactively, this example reuses the [Modal](../Modal), [Button](../Button), and `DialogTrigger` components from React Aria Components to provide the overlay container and trigger. A dialog may also be placed within a [popover](../Popover/usePopover). + +```tsx render files={["starters/hooks/src/Modal.tsx", "starters/hooks/src/Modal.css", "starters/hooks/src/Dialog.css", "starters/hooks/src/Button.css"]} +"use client"; +import {CloseButton, Dialog, ModalTrigger} from 'hooks-starter/Modal'; + + + {() => + +

This dialog is built with useDialog.

+ +
} +
+``` + +A dialog consists of a container element and an optional title. `useDialog` handles exposing this to assistive technology using ARIA. It can be combined with `useModalOverlay` or [usePopover](../Popover/usePopover) to create modal dialogs, popovers, and other types of overlays. + +If a dialog does not have a visible title element, an `aria-label` or `aria-labelledby` prop must be passed instead to identify the element to assistive technology. + +Focus containment must be enabled from a component rendered _inside_ the [<Overlay>](../Popover) — `useDialog` does this automatically, which is why focus is contained in the examples above. If you render content that does not use `useDialog` (or another hook that enables containment), make sure `useModalOverlay` is called from a component rendered inside `` so that focus is properly contained. + +## API + + + +```tsx links={{DialogTrigger: '#dialogtrigger', Button: 'Button', ModalOverlay: '#modaloverlay', Modal: '#modal', Dialog: '#dialog'}} + +