@@ -636,7 +636,7 @@ function TreeExample (
{ children, ...props }
) {
return (
-
+
@@ -689,10 +689,10 @@ export function TreeItemContent({ children, ...props }) {
)}
{hasChildItems ? (
-
)}
diff --git a/examples/rsp-cra-18/src/AutocompleteExample.tsx b/examples/rsp-cra-18/src/AutocompleteExample.tsx
index 4e7a9a443fc..e92c4d8d763 100644
--- a/examples/rsp-cra-18/src/AutocompleteExample.tsx
+++ b/examples/rsp-cra-18/src/AutocompleteExample.tsx
@@ -1,4 +1,4 @@
-import {UNSTABLE_Autocomplete as Autocomplete, Input, Label, Menu, MenuItem, SearchField, Text, useFilter} from 'react-aria-components'
+import {Autocomplete, Input, Label, Menu, MenuItem, SearchField, Text, useFilter} from 'react-aria-components'
import {classNames} from '@react-spectrum/utils';
import styles from './autocomplete.css';
diff --git a/examples/rsp-next-ts/components/AutocompleteExample.tsx b/examples/rsp-next-ts/components/AutocompleteExample.tsx
index f333a2442f3..7228c5688f8 100644
--- a/examples/rsp-next-ts/components/AutocompleteExample.tsx
+++ b/examples/rsp-next-ts/components/AutocompleteExample.tsx
@@ -1,4 +1,4 @@
-import {UNSTABLE_Autocomplete as Autocomplete, Input, Label, Menu, MenuItem, SearchField, Text, useFilter} from 'react-aria-components'
+import {Autocomplete, Input, Label, Menu, MenuItem, SearchField, Text, useFilter} from 'react-aria-components'
import {classNames} from '@react-spectrum/utils';
import React from 'react';
import styles from './autocomplete.module.css';
diff --git a/packages/@react-aria/autocomplete/src/useAutocomplete.ts b/packages/@react-aria/autocomplete/src/useAutocomplete.ts
index 9467afbfca1..ad421e017f1 100644
--- a/packages/@react-aria/autocomplete/src/useAutocomplete.ts
+++ b/packages/@react-aria/autocomplete/src/useAutocomplete.ts
@@ -54,8 +54,8 @@ export interface AutocompleteAria {
}
/**
- * Provides the behavior and accessibility implementation for a autocomplete component.
- * A autocomplete combines a text input with a collection, allowing users to filter the collection's contents match a query.
+ * Provides the behavior and accessibility implementation for an autocomplete component.
+ * An autocomplete combines a text input with a collection, allowing users to filter the collection's contents match a query.
* @param props - Props for the autocomplete.
* @param state - State for the autocomplete, as returned by `useAutocompleteState`.
*/
diff --git a/packages/@react-spectrum/s2/stories/Popover.stories.tsx b/packages/@react-spectrum/s2/stories/Popover.stories.tsx
index b7d24e99463..1393ea2e35e 100644
--- a/packages/@react-spectrum/s2/stories/Popover.stories.tsx
+++ b/packages/@react-spectrum/s2/stories/Popover.stories.tsx
@@ -18,9 +18,9 @@ import Help from '../s2wf-icons/S2_Icon_HelpCircle_20_N.svg';
import Lightbulb from '../s2wf-icons/S2_Icon_Lightbulb_20_N.svg';
import type {Meta} from '@storybook/react';
import Org from '../s2wf-icons/S2_Icon_Buildings_20_N.svg';
+import {Autocomplete as RACAutocomplete, useFilter} from 'react-aria-components';
import Settings from '../s2wf-icons/S2_Icon_Settings_20_N.svg';
import {style} from '../style/spectrum-theme' with {type: 'macro'};
-import {UNSTABLE_Autocomplete, useFilter} from 'react-aria-components';
import User from '../s2wf-icons/S2_Icon_User_20_N.svg';
import Users from '../s2wf-icons/S2_Icon_UserGroup_20_N.svg';
@@ -171,7 +171,7 @@ AccountMenu.argTypes = {
function Autocomplete(props) {
let {contains} = useFilter({sensitivity: 'base'});
return (
-
+
);
}
diff --git a/packages/@react-spectrum/s2/test/SearchField.test.tsx b/packages/@react-spectrum/s2/test/SearchField.test.tsx
index be8b2ca04c9..a8ccddc2ae3 100644
--- a/packages/@react-spectrum/s2/test/SearchField.test.tsx
+++ b/packages/@react-spectrum/s2/test/SearchField.test.tsx
@@ -10,10 +10,10 @@
* governing permissions and limitations under the License.
*/
+import {Autocomplete} from 'react-aria-components';
import {Menu, MenuItem, SearchField} from '../src';
import {pointerMap, render} from '@react-spectrum/test-utils-internal';
import React from 'react';
-import {UNSTABLE_Autocomplete} from 'react-aria-components';
import userEvent from '@testing-library/user-event';
describe('SearchField', () => {
@@ -24,14 +24,14 @@ describe('SearchField', () => {
it('should not apply the focus visible styles on the group when typing in the Autocomplete wrapped SearchField', async () => {
let {getByRole} = render(
-
+
-
+
);
let input = getByRole('searchbox');
diff --git a/packages/@react-stately/autocomplete/src/useAutocompleteState.ts b/packages/@react-stately/autocomplete/src/useAutocompleteState.ts
index bb27d86db66..9c33a7c0d05 100644
--- a/packages/@react-stately/autocomplete/src/useAutocompleteState.ts
+++ b/packages/@react-stately/autocomplete/src/useAutocompleteState.ts
@@ -39,7 +39,7 @@ export interface AutocompleteProps {
export interface AutocompleteStateOptions extends Omit
{}
/**
- * Provides state management for a autocomplete component.
+ * Provides state management for an autocomplete component.
*/
export function UNSTABLE_useAutocompleteState(props: AutocompleteStateOptions): AutocompleteState {
let {
diff --git a/packages/react-aria-components/docs/Autocomplete.mdx b/packages/react-aria-components/docs/Autocomplete.mdx
index ec907dbbb50..3ef6c86eada 100644
--- a/packages/react-aria-components/docs/Autocomplete.mdx
+++ b/packages/react-aria-components/docs/Autocomplete.mdx
@@ -15,7 +15,16 @@ import {PropTable, HeaderInfo, TypeLink, PageDescription, StateTable, ContextTab
import styles from '@react-spectrum/docs/src/docs.css';
import packageData from 'react-aria-components/package.json';
import ChevronRight from '@spectrum-icons/workflow/ChevronRight';
-import {InlineAlert, Content, Heading} from '@adobe/react-spectrum';
+import statelyDocs from 'docs:@react-stately/autocomplete';
+import {ExampleCard} from '@react-spectrum/docs/src/ExampleCard';
+import {ExampleList} from '@react-spectrum/docs/src/ExampleList';
+import SearchField from '@react-spectrum/docs/pages/assets/component-illustrations/SearchField.svg';
+import TextField from '@react-spectrum/docs/pages/assets/component-illustrations/TextField.svg';
+import Menu from '@react-spectrum/docs/pages/assets/component-illustrations/Menu.svg';
+import ListBox from '@react-spectrum/docs/pages/assets/component-illustrations/ListBox.svg';
+import Collections from '@react-spectrum/docs/pages/assets/component-illustrations/Collections.svg';
+import Selection from '@react-spectrum/docs/pages/assets/component-illustrations/Selection.svg';
+import {StarterKits} from '@react-spectrum/docs/src/StarterKits';
---
category: Pickers
@@ -26,32 +35,30 @@ preRelease: alpha
# Autocomplete
-{docs.exports.UNSTABLE_Autocomplete.description}
+{docs.exports.Autocomplete.description}
-
- Under construction
- This component is in alpha. More documentation is coming soon!
-
-
## Example
```tsx example
-import {UNSTABLE_Autocomplete as Autocomplete, Menu, MenuItem, useFilter} from 'react-aria-components';
-import {MySearchField} from './SearchField';
+import {Autocomplete, Button, Input, Label, Menu, MenuItem, SearchField, useFilter} from 'react-aria-components';
function Example() {
let {contains} = useFilter({sensitivity: 'base'});
return (
-
+
+
+
+ ā
+
+
+
+
+
+
+
+
+
+## Examples
+
+
+
+## Starter kits
+
+To help kick-start your project, we offer starter kits that include example implementations of all React Aria components with various styling solutions. All components are fully styled, including support for dark mode, high contrast mode, and all UI states. Each starter comes with a pre-configured [Storybook](https://storybook.js.org/) that you can experiment with, or use as a starting point for your own component library.
+
+
+
+## Reusable wrappers
+
+If you will use an Autocomplete in multiple places in your app, you can wrap all of the pieces into a reusable component. This way, the DOM structure, styling code, and other logic are defined in a single place and reused everywhere to ensure consistency.
+
+This example wraps `Autocomplete` and all of its children together into a single component which accepts a `label` prop and `children`, which are passed through to the right places. The `Item` component is also wrapped to apply class names based on the current state, as described in the [styling](#styling) section.
+
+```tsx example export=true
+import type {AutocompleteProps, Key} from 'react-aria-components';
+import {Menu, MenuItem} from 'react-aria-components';
+import {MySearchField} from './SearchField';
+import {MyItem} from './Menu';
+
+interface MyAutocompleteProps
extends Omit {
+ label?: string,
+ placeholder?: string,
+ items?: Iterable;
+ children: React.ReactNode | ((item: T) => React.ReactNode)
+ onAction?: (id: Key) => void
+}
+
+function MyAutocomplete({label,placeholder, items, children, onAction, ...props}: MyAutocompleteProps) {
+ let {contains} = useFilter({sensitivity: 'base'});
+ return (
+
+ );
+}
+
+
+ Create new file...
+ Create new folder...
+ Assign to...
+ Assign to me
+ Change status...
+ Change priority...
+ Add label...
+ Remove label...
+
+```
+
+
+ Show CSS
+
+```css
+.my-autocomplete {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ max-width: 300px;
+ height: 180px;
+ border: 1px solid var(--border-color);
+ padding: 16px;
+ border-radius: 10px;
+ background: var(--overlay-background);
+}
+
+.react-aria-SearchField {
+ width: 100%;
+}
+
+.react-aria-Label {
+ margin-bottom: .5em;
+}
+```
+
+
+
+## Value
+
+An Autocomplete's `value` is empty by default, but an initial, uncontrolled, value can be provided using the `defaultInputValue` prop.
+Alternatively, a controlled value can be provided using the `inputValue` prop. Note that the input value of the Autocomplete does not affect
+the ComboBox's selected option.
+
+```tsx example
+function Example() {
+ let options = [
+ {id: 1, name: 'Adobe Photoshop'},
+ {id: 2, name: 'Adobe XD'},
+ {id: 3, name: 'Adobe InDesign'},
+ {id: 4, name: 'Adobe AfterEffects'},
+ {id: 5, name: 'Adobe Illustrator'},
+ {id: 6, name: 'Adobe Lightroom'},
+ {id: 7, name: 'Adobe Premiere Pro'},
+ {id: 8, name: 'Adobe Fresco'},
+ {id: 9, name: 'Adobe Dreamweaver'}
+ ];
+ let [value, setValue] = React.useState('Adobe XD');
+
+ return (
+
+
+ {/*- end highlight -*/}
+ {item => {item.name}}
+
+
+
+ {/*- end highlight -*/}
+ {item => {item.name}}
+
+
+ );
+}
```
## Props
-
+
+
+## Styling
+
+Since Autocomplete doesn't render any DOM elements itself, it doesn't offer any styling options. See the styling sections for [TextField](TextField.html#styling), [SearchField](SearchField.html#styling), [Menu](Menu.html#styling), and [ListBox](ListBox.html#styling) for more information on how to style components within the Autocomplete.
+
+## Advanced customization
+
+### Composition
+
+If you need to customize one of the components within an `Autocomplete`, such as `TextField`, `SearchField`, `Menu` or `ListBox`, you can create a wrapper
+component. This lets you customize the props passed to the component.
+
+```tsx
+function MyListBox(props) {
+ return
+}
+```
+
+### Contexts
+
+All React Aria Components export a corresponding context that can be used to send props to them from a parent element. This enables you to build your own compositional APIs similar to those found in React Aria Components itself. You can send any prop or ref via context that you could pass to the corresponding component. The local props and ref on the component are merged with the ones passed via context, with the local props taking precedence (following the rules documented in [mergeProps](mergeProps.html)).
+
+
+
+### State
+
+Autocomplete provides an object to its children via `AutocompleteStateContext`. This can be used to access and manipulate the autocomplete's state.
+
+This example shows an `AutocompleteClearButton` component that can be placed within an `Autocomplete` to allow the user to clear the input.
+
+```tsx example
+import {AutocompleteStateContext as AutocompleteStateContext, Button} from 'react-aria-components';
+
+function Example() {
+ let {contains} = useFilter({sensitivity: 'base'});
+ return (
+
+
+
+
+
+ Cat
+ Dog
+ Kangaroo
+
+
+
+ )
+}
+
+function AutocompleteClearButton() {
+ /*- begin highlight -*/
+ let state = React.useContext(AutocompleteStateContext);
+ /*- end highlight -*/
+ return (
+ state?.setInputValue('')}>
+ Clear
+
+ );
+}
+```
+
+
+ Show CSS
+
+```css
+
+.custom-autocomplete {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ max-width: 300px;
+ height: 220px;
+ border: 1px solid var(--border-color);
+ padding: 16px;
+ border-radius: 10px;
+ background: var(--overlay-background);
+}
+
+.clear-button {
+ margin-top: 8px;
+}
+```
+
+
+
+### Hooks
+
+If you need to customize things even further, such as accessing internal state, intercepting events, or customizing the DOM structure, you can drop down to the lower level Hook-based API. See [useAutocomplete](useAutocomplete.html) for more details.
diff --git a/packages/react-aria-components/docs/Menu.mdx b/packages/react-aria-components/docs/Menu.mdx
index 52dce6985da..b13035f189d 100644
--- a/packages/react-aria-components/docs/Menu.mdx
+++ b/packages/react-aria-components/docs/Menu.mdx
@@ -226,7 +226,7 @@ function MyMenuButton({label, children, ...props}: MyMenuButto
);
}
-function MyItem(props: MenuItemProps) {
+export function MyItem(props: MenuItemProps) {
let textValue = props.textValue || (typeof props.children === 'string' ? props.children : undefined);
return (
-
+
@@ -555,7 +555,7 @@ describe('Autocomplete', () => {
ā°
diff --git a/scripts/extractStarter.mjs b/scripts/extractStarter.mjs
index d13a016bf5b..b7899a1e264 100644
--- a/scripts/extractStarter.mjs
+++ b/scripts/extractStarter.mjs
@@ -29,7 +29,7 @@ fs.mkdirSync(`starters/docs/src`, {recursive: true});
fs.mkdirSync(`starters/docs/stories`, {recursive: true});
for (let file of glob.sync('packages/react-aria-components/docs/*.mdx')) {
- if (!/^[A-Z]/.test(basename(file)) || /^Autocomplete|^Virtualizer|^Toast/.test(basename(file))) {
+ if (!/^[A-Z]/.test(basename(file)) || /^Virtualizer|^Toast/.test(basename(file))) {
continue;
}
console.log('Processing ' + file);
diff --git a/starters/tailwind/src/Autocomplete.tsx b/starters/tailwind/src/Autocomplete.tsx
index 8826691e5c2..a4f476cfedb 100644
--- a/starters/tailwind/src/Autocomplete.tsx
+++ b/starters/tailwind/src/Autocomplete.tsx
@@ -1,6 +1,6 @@
import React from "react";
import {
- UNSTABLE_Autocomplete as AriaAutocomplete,
+ Autocomplete as AriaAutocomplete,
AutocompleteProps as AriaAutocompleteProps,
Menu as AriaMenu,
MenuSection as AriaMenuSection,