From 6df5cb8d657781a77d95a40a6fe98e372a1685fc Mon Sep 17 00:00:00 2001 From: Reid Barber Date: Tue, 2 Jun 2026 16:20:59 -0500 Subject: [PATCH 1/4] init new hooks docs: useButton, useListBox, useSelect --- .../pages/react-aria/Button/useButton.mdx | 76 ++++++++ .../pages/react-aria/ListBox/useListBox.mdx | 145 ++++++++++++++ .../pages/react-aria/Select/useSelect.mdx | 184 ++++++++++++++++++ 3 files changed, 405 insertions(+) create mode 100644 packages/dev/s2-docs/pages/react-aria/Button/useButton.mdx create mode 100644 packages/dev/s2-docs/pages/react-aria/ListBox/useListBox.mdx create mode 100644 packages/dev/s2-docs/pages/react-aria/Select/useSelect.mdx 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..afe3cd22c7e --- /dev/null +++ b/packages/dev/s2-docs/pages/react-aria/Button/useButton.mdx @@ -0,0 +1,76 @@ +{/* 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 +"use client"; +import React from 'react'; +import {useButton} from 'react-aria/useButton'; + +function Button(props) { + let ref = React.useRef(null); + let {buttonProps, isPressed} = useButton(props, ref); + + return ( + + ); +} + + +``` + +## Features + +On the surface, building a custom styled button seems simple. However, there are many cross browser inconsistencies in interactions and accessibility features to consider. `useButton` handles all of these interactions for you, so you can focus on the styling. It follows the [ARIA button pattern](https://www.w3.org/WAI/ARIA/apg/patterns/button/). + +* Native HTML ` + {state.isOpen && + + + + } + + ); +} + +///- begin collapse -/// +function Button(props) { + let ref = props.buttonRef; + let {buttonProps} = useButton(props, ref); + return ; +} + +function ListBox(props) { + let ref = React.useRef(null); + let {listBoxRef = ref, state} = props; + let {listBoxProps} = useListBox(props, state, listBoxRef); + + return ( + + ); +} + +function Option({item, state}) { + let ref = React.useRef(null); + let {optionProps, isSelected, isFocused, isDisabled} = useOption({key: item.key}, state, ref); + + return ( +
  • + {item.rendered} + {isSelected ? : null} +
  • + ); +} + +function Popover({children, state, ...props}) { + let popoverRef = React.useRef(null); + let {popoverProps, underlayProps} = usePopover({...props, popoverRef}, state); + + return ( + +
    +
    + + {children} + +
    + + ); +} +///- end collapse -/// + + +``` + +## Features + +A select can be built using the [<select>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select) and [<option>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option) HTML elements, but this is not possible to style consistently cross browser, especially the options. `useSelect` helps achieve accessible select components that can be styled as needed without compromising on high quality interactions. It follows the [ARIA listbox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/). + +* Exposed to assistive technology as a button with a `listbox` popup using ARIA (combined with [useListBox](../ListBox/useListBox.html)) +* Support for selecting a single option +* Support for disabled options +* Support for sections +* Labeling support for accessibility +* Support for native HTML constraint validation with customizable UI, custom validation functions, realtime validation, and server-side validation errors +* Support for mouse, touch, and keyboard interactions +* Tab stop focus management +* Keyboard support for opening the listbox using the arrow keys, including automatically focusing the first or last item accordingly +* Typeahead to allow selecting options by typing text, even without opening the listbox +* Browser autofill integration via a hidden native ``, see [useSelect](../Select/useSelect.html). +Note: `useListBox` only handles the list itself. For a dropdown similar to a `` to enable browser form autofill. The `Button`, `ListBox`, and `Popover` components shown collapsed below can be shared with other components such as a ComboBox or Menu. +This example combines `useSelect` with [useButton](../Button/useButton) for the trigger, [useListBox](../ListBox/useListBox) for the popup, and [usePopover](../Popover) for positioning. A <`HiddenSelect`> renders a hidden native `` to enable browser form autofill. The `Button`, `ListBox`, and `Popover` components shown collapsed below can be shared with other components such as a ComboBox or Menu. +This example uses `useSelect` to provide the behavior for a custom select, and reuses the [Button](../Button), [Popover](../Popover), and [ListBox](../ListBox) components from React Aria Components to render the trigger, popup, and list of options. The values returned by the hook are passed to these components via context, following the [Reusing children](../customization#reusing-children) pattern. A <`HiddenSelect`> renders a hidden native ` - Red - Orange - Yellow - Green - Blue - Purple - Black - White + + ```