From f057a1f413bbf243d4b34d822f68372b836fcef4 Mon Sep 17 00:00:00 2001 From: Daniel Lu Date: Mon, 8 Dec 2025 12:14:44 -0800 Subject: [PATCH 1/2] docs: Restructure old docs in preparation of new docs site (#9154) * add temp banner to stately * add banner to all pages * move react spectrum pages to v3 * move releases under v3 * make sure intro and concept pages appear in sidebar for v3 * move stately hooks to aria and remove uneeded aria hooks * lint * test redirect * add redirect pages for v3 and releases * fix redirects for intro and concepts pages * add redirects for react aria * redirect release index page and rename script for consistency * add redirects for blog and internationalized * get rid of chevron * properly redirect examples and point to new concepts page * update more redirects * have both stately and aria hooks in sidenav for react stately too * rename sidebar headers * add redirects for the remaining Foundation section pages * Remove redirect pages. Will handle in CDN instead. * Remove old docs that we migrated * Update URL structure * Update URLs * Build old docs as part of s2 build * Add stage docs build * Remove RedirectLayout * Fix more URLs * Fix more URLs * Remove Dialog from DatePicker examples * More broken links * Fix broken links * More links * Open search menu on components link at bottom of homepage Also fix more links * update migration banner * make react spectrum links relative and bring back s2 gradient * create relative links for aria and stately hook banner * remove banner from releases and fix filetrigger link * Fix one more url * Move Support page to v3 * Remove unused useStepList docs * Fix links * Fix separator link * Fix useDialog links * Fix stately links from migration banner --------- Co-authored-by: Devon Govett --- .circleci/comment.js | 2 - .circleci/config.yml | 59 +-- Makefile | 28 +- README.md | 2 +- package.json | 4 +- .../autocomplete/src/useSearchAutocomplete.ts | 2 +- .../breadcrumbs/docs/useBreadcrumbs.mdx | 8 +- .../@react-aria/button/docs/useButton.mdx | 4 +- .../button/docs/useToggleButton.mdx | 2 +- .../button/docs/useToggleButtonGroup.mdx | 2 +- .../@react-aria/calendar/docs/useCalendar.mdx | 12 +- .../calendar/docs/useRangeCalendar.mdx | 12 +- .../checkbox/docs/useCheckboxGroup.mdx | 6 +- .../@react-aria/color/docs/useColorArea.mdx | 12 +- .../@react-aria/color/docs/useColorSlider.mdx | 4 +- .../@react-aria/color/docs/useColorWheel.mdx | 4 +- .../@react-aria/combobox/docs/useComboBox.mdx | 39 +- .../@react-aria/combobox/src/useComboBox.ts | 4 +- .../datepicker/docs/useDateField.mdx | 6 +- .../datepicker/docs/useDatePicker.mdx | 20 +- .../datepicker/docs/useDateRangePicker.mdx | 20 +- .../datepicker/docs/useTimeField.mdx | 4 +- .../@react-aria/dialog/docs/useDialog.mdx | 8 +- packages/@react-aria/dnd/docs/dnd.mdx | 87 ---- .../@react-aria/dnd/docs/useClipboard.mdx | 491 ------------------ packages/@react-aria/dnd/docs/useDrag.mdx | 406 --------------- .../dnd/docs/useDraggableCollection.mdx | 16 +- packages/@react-aria/dnd/docs/useDrop.mdx | 476 ----------------- .../dnd/docs/useDroppableCollection.mdx | 18 +- packages/@react-aria/focus/docs/FocusRing.mdx | 71 --- .../@react-aria/focus/docs/FocusScope.mdx | 134 ----- .../@react-aria/focus/docs/useFocusRing.mdx | 88 ---- .../@react-aria/gridlist/docs/useGridList.mdx | 19 +- .../@react-aria/i18n/docs/I18nProvider.mdx | 49 -- .../i18n/docs/internationalization.mdx | 268 ---------- .../@react-aria/i18n/docs/useCollator.mdx | 81 --- .../i18n/docs/useDateFormatter.mdx | 66 --- packages/@react-aria/i18n/docs/useFilter.mdx | 89 ---- packages/@react-aria/i18n/docs/useLocale.mdx | 63 --- .../i18n/docs/useNumberFormatter.mdx | 70 --- .../interactions/docs/interactions.mdx | 115 ---- .../interactions/docs/useFocus.mdx | 98 ---- .../interactions/docs/useFocusVisible.mdx | 76 --- .../interactions/docs/useFocusWithin.mdx | 114 ---- .../interactions/docs/useHover.mdx | 126 ----- .../interactions/docs/useKeyboard.mdx | 94 ---- .../interactions/docs/useLongPress.mdx | 127 ----- .../@react-aria/interactions/docs/useMove.mdx | 163 ------ .../interactions/docs/usePress.mdx | 126 ----- packages/@react-aria/label/docs/useField.mdx | 75 --- packages/@react-aria/label/docs/useLabel.mdx | 65 --- .../@react-aria/landmark/docs/useLandmark.mdx | 111 ---- .../@react-aria/listbox/docs/useListBox.mdx | 19 +- packages/@react-aria/menu/docs/useMenu.mdx | 16 +- packages/@react-aria/meter/docs/useMeter.mdx | 2 +- .../numberfield/docs/useNumberField.mdx | 10 +- .../numberfield/src/useNumberField.ts | 4 +- .../overlays/docs/PortalProvider.mdx | 138 ----- .../overlays/docs/useModalOverlay.mdx | 10 +- .../@react-aria/overlays/docs/usePopover.mdx | 12 +- .../@react-aria/radio/docs/useRadioGroup.mdx | 2 +- .../searchfield/docs/useSearchField.mdx | 6 +- .../@react-aria/select/docs/useSelect.mdx | 55 +- .../@react-aria/slider/docs/useSlider.mdx | 6 +- packages/@react-aria/ssr/docs/SSRProvider.mdx | 52 -- packages/@react-aria/ssr/docs/useIsSSR.mdx | 54 -- .../@react-aria/steplist/docs/useStepList.mdx | 40 -- packages/@react-aria/table/docs/useTable.mdx | 23 +- packages/@react-aria/tabs/docs/useTabList.mdx | 12 +- packages/@react-aria/tag/docs/useTagGroup.mdx | 8 +- .../textfield/docs/useTextField.mdx | 2 +- packages/@react-aria/toast/docs/useToast.mdx | 2 +- .../@react-aria/toolbar/docs/useToolbar.mdx | 2 +- .../@react-aria/utils/docs/mergeProps.mdx | 79 --- packages/@react-aria/utils/docs/useId.mdx | 46 -- .../@react-aria/utils/docs/useObjectRef.mdx | 64 --- .../visually-hidden/docs/VisuallyHidden.mdx | 75 --- .../actionbar/docs/ActionBar.mdx | 2 +- .../actiongroup/docs/ActionGroup.mdx | 4 +- .../autocomplete/docs/SearchAutocomplete.mdx | 6 +- .../breadcrumbs/docs/Breadcrumbs.mdx | 8 +- .../button/docs/ToggleButton.mdx | 2 +- .../calendar/docs/Calendar.mdx | 4 +- .../calendar/docs/RangeCalendar.mdx | 4 +- .../checkbox/docs/CheckboxGroup.mdx | 4 +- .../combobox/docs/ComboBox.mdx | 6 +- .../datepicker/docs/DateField.mdx | 6 +- .../datepicker/docs/DatePicker.mdx | 8 +- .../datepicker/docs/DateRangePicker.mdx | 8 +- .../datepicker/docs/TimeField.mdx | 6 +- packages/@react-spectrum/dnd/docs/dnd.mdx | 10 +- .../dropzone/docs/DropZone.mdx | 8 +- .../labeledvalue/docs/LabeledValue.mdx | 4 +- .../@react-spectrum/list/docs/ListView.mdx | 6 +- .../@react-spectrum/listbox/docs/ListBox.mdx | 6 +- .../@react-spectrum/menu/docs/ActionMenu.mdx | 2 +- packages/@react-spectrum/menu/docs/Menu.mdx | 4 +- .../@react-spectrum/menu/docs/MenuTrigger.mdx | 2 +- .../@react-spectrum/picker/docs/Picker.mdx | 20 +- .../provider/docs/Provider.mdx | 4 +- .../@react-spectrum/table/docs/TableView.mdx | 8 +- packages/@react-spectrum/tabs/docs/Tabs.mdx | 4 +- .../@react-spectrum/tag/docs/TagGroup.mdx | 4 +- .../@react-spectrum/tree/docs/TreeView.mdx | 4 +- .../calendar/docs/useCalendarState.mdx | 2 +- .../calendar/docs/useRangeCalendarState.mdx | 2 +- .../collections/docs/Collection.mdx | 67 --- .../color/docs/useColorAreaState.mdx | 2 +- .../color/docs/useColorFieldState.mdx | 2 +- .../color/docs/useColorSliderState.mdx | 2 +- .../color/docs/useColorWheelState.mdx | 2 +- .../combobox/docs/useComboBoxState.mdx | 2 +- .../datepicker/docs/useDateFieldState.mdx | 2 +- .../datepicker/docs/useDatePickerState.mdx | 2 +- .../docs/useDateRangePickerState.mdx | 2 +- .../datepicker/docs/useTimeFieldState.mdx | 2 +- .../docs/useDisclosureGroupState.mdx | 2 +- .../disclosure/docs/useDisclosureState.mdx | 2 +- .../dnd/docs/useDraggableCollectionState.mdx | 2 +- .../dnd/docs/useDroppableCollectionState.mdx | 2 +- .../@react-stately/list/docs/useListState.mdx | 2 +- .../menu/docs/useMenuTriggerState.mdx | 2 +- .../numberfield/docs/useNumberFieldState.mdx | 2 +- .../overlays/docs/useOverlayTriggerState.mdx | 2 +- .../radio/docs/useRadioGroupState.mdx | 2 +- .../searchfield/docs/useSearchFieldState.mdx | 2 +- .../select/docs/useSelectState.mdx | 2 +- .../selection/docs/SelectionManager.mdx | 57 -- .../docs/useMultipleSelectionState.mdx | 2 +- .../slider/docs/useSliderState.mdx | 2 +- .../steplist/docs/useStepListState.mdx | 41 -- .../table/docs/useTableState.mdx | 2 +- .../tabs/docs/useTabListState.mdx | 2 +- .../toast/docs/useToastState.mdx | 2 +- .../toggle/docs/useToggleState.mdx | 2 +- .../tooltip/docs/useTooltipTriggerState.mdx | 2 +- .../@react-stately/tree/docs/useTreeState.mdx | 2 +- .../wallpaper_collaborative_S2_desktop.webp | Bin 0 -> 50894 bytes .../dev/docs/pages/react-aria/collections.mdx | 2 +- packages/dev/docs/pages/react-aria/hooks.mdx | 4 +- .../pages/{ => react-spectrum}/Support.mdx | 8 +- .../pages/react-spectrum}/collections.mdx | 6 +- .../docs/pages/react-spectrum}/selection.mdx | 4 +- .../dev/docs/pages/react-spectrum/ssr.mdx | 6 +- .../dev/docs/pages/react-spectrum/testing.mdx | 2 +- .../docs/pages/react-spectrum/versioning.mdx | 2 +- .../dev/docs/pages/releases/2020-07-23.mdx | 8 +- .../dev/docs/pages/releases/2020-08-18.mdx | 4 +- .../dev/docs/pages/releases/2020-09-02.mdx | 12 +- .../dev/docs/pages/releases/2020-10-01.mdx | 14 +- .../dev/docs/pages/releases/2020-10-29.mdx | 2 +- .../dev/docs/pages/releases/2020-11-30.mdx | 2 +- .../dev/docs/pages/releases/2020-12-22.mdx | 2 +- .../dev/docs/pages/releases/2021-02-17.mdx | 14 +- .../dev/docs/pages/releases/2021-03-24.mdx | 26 +- .../dev/docs/pages/releases/2021-05-05.mdx | 26 +- .../dev/docs/pages/releases/2021-06-15.mdx | 30 +- .../dev/docs/pages/releases/2021-07-12.mdx | 10 +- .../dev/docs/pages/releases/2021-08-04.mdx | 6 +- .../dev/docs/pages/releases/2021-09-13.mdx | 22 +- .../dev/docs/pages/releases/2021-11-24.mdx | 16 +- .../dev/docs/pages/releases/2021-12-16.mdx | 12 +- .../dev/docs/pages/releases/2022-02-15.mdx | 18 +- .../dev/docs/pages/releases/2022-03-07.mdx | 12 +- .../dev/docs/pages/releases/2022-05-03.mdx | 10 +- .../dev/docs/pages/releases/2022-06-15.mdx | 28 +- .../dev/docs/pages/releases/2022-07-09.mdx | 2 +- .../dev/docs/pages/releases/2022-08-26.mdx | 4 +- .../dev/docs/pages/releases/2022-10-04.mdx | 8 +- .../dev/docs/pages/releases/2022-11-15.mdx | 28 +- .../dev/docs/pages/releases/2022-12-16.mdx | 2 +- .../dev/docs/pages/releases/2023-02-23.mdx | 2 +- .../dev/docs/pages/releases/2023-04-05.mdx | 4 +- .../dev/docs/pages/releases/2023-05-24.mdx | 16 +- .../dev/docs/pages/releases/2023-06-27.mdx | 8 +- .../dev/docs/pages/releases/2023-08-09.mdx | 4 +- .../dev/docs/pages/releases/2023-09-07.mdx | 6 +- .../dev/docs/pages/releases/2023-10-02.mdx | 8 +- .../dev/docs/pages/releases/2023-11-8.mdx | 4 +- .../dev/docs/pages/releases/2023-12-20.mdx | 2 +- .../dev/docs/pages/releases/2024-02-13.mdx | 2 +- .../dev/docs/pages/releases/2024-05-01.mdx | 8 +- .../dev/docs/pages/releases/2024-07-22.mdx | 2 +- .../dev/docs/pages/releases/2024-09-30.mdx | 6 +- .../dev/docs/pages/releases/2024-11-20.mdx | 6 +- .../dev/docs/pages/releases/2025-01-15.mdx | 10 +- .../dev/docs/pages/releases/2025-03-05.mdx | 8 +- .../dev/docs/pages/releases/2025-04-11.mdx | 2 +- .../dev/docs/pages/releases/2025-06-05.mdx | 2 +- .../dev/docs/pages/releases/2025-07-22.mdx | 2 +- .../dev/docs/pages/releases/2025-08-25.mdx | 2 +- .../dev/docs/pages/releases/2025-10-02.mdx | 4 +- packages/dev/docs/pages/releases/index.mdx | 2 +- packages/dev/docs/src/Layout.js | 121 ++--- packages/dev/docs/src/MigrationBanner.js | 200 +++++++ packages/dev/docs/src/PostListing.js | 15 +- packages/dev/docs/src/docs.css | 3 + packages/dev/docs/src/utils.js | 34 ++ packages/dev/parcel-namer-docs/DocsNamer.js | 69 ++- .../dev/parcel-packager-ssg/SSGPackager.js | 1 + .../s2-docs/pages/react-aria/Autocomplete.mdx | 2 +- .../s2-docs/pages/react-aria/Breadcrumbs.mdx | 10 +- .../dev/s2-docs/pages/react-aria/Button.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Calendar.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Checkbox.mdx | 2 +- .../pages/react-aria/CheckboxGroup.mdx | 2 +- .../s2-docs/pages/react-aria/ColorArea.mdx | 2 +- .../s2-docs/pages/react-aria/ColorField.mdx | 2 +- .../s2-docs/pages/react-aria/ColorSlider.mdx | 2 +- .../s2-docs/pages/react-aria/ColorSwatch.mdx | 2 +- .../s2-docs/pages/react-aria/ColorWheel.mdx | 2 +- .../dev/s2-docs/pages/react-aria/ComboBox.mdx | 2 +- .../s2-docs/pages/react-aria/DateField.mdx | 2 +- .../s2-docs/pages/react-aria/DatePicker.mdx | 8 +- .../pages/react-aria/DateRangePicker.mdx | 8 +- .../s2-docs/pages/react-aria/Disclosure.mdx | 2 +- .../dev/s2-docs/pages/react-aria/DropZone.mdx | 2 +- .../s2-docs/pages/react-aria/FocusScope.mdx | 2 +- .../dev/s2-docs/pages/react-aria/GridList.mdx | 2 +- .../pages/react-aria/GridList/testing.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Link.mdx | 2 +- .../dev/s2-docs/pages/react-aria/ListBox.mdx | 2 +- .../pages/react-aria/ListBox/testing.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Menu.mdx | 2 +- .../s2-docs/pages/react-aria/Menu/testing.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Meter.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Modal.mdx | 2 +- .../s2-docs/pages/react-aria/NumberField.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Popover.mdx | 2 +- .../pages/react-aria/PortalProvider.mdx | 2 +- .../s2-docs/pages/react-aria/ProgressBar.mdx | 2 +- .../s2-docs/pages/react-aria/RadioGroup.mdx | 2 +- .../pages/react-aria/RangeCalendar.mdx | 2 +- .../s2-docs/pages/react-aria/SearchField.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Select.mdx | 2 +- .../s2-docs/pages/react-aria/Separator.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Slider.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Switch.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Table.mdx | 2 +- .../pages/react-aria/Table/testing.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Tabs.mdx | 2 +- .../dev/s2-docs/pages/react-aria/TagGroup.mdx | 2 +- .../s2-docs/pages/react-aria/TextField.mdx | 2 +- .../s2-docs/pages/react-aria/TimeField.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Toast.mdx | 2 +- .../s2-docs/pages/react-aria/ToggleButton.mdx | 2 +- .../pages/react-aria/ToggleButtonGroup.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Toolbar.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Tooltip.mdx | 2 +- .../s2-docs/pages/react-aria/Tree/testing.mdx | 2 +- .../pages/react-aria/VisuallyHidden.mdx | 2 +- .../blog/building-a-button-part-1.mdx | 2 +- .../blog/building-a-button-part-2.mdx | 2 +- .../blog/building-a-button-part-3.mdx | 2 +- .../react-aria/blog/building-a-combobox.mdx | 8 +- .../blog/date-and-time-pickers-for-all.mdx | 12 +- .../pages/react-aria/blog/drag-and-drop.mdx | 10 +- ...w-we-internationalized-our-numberfield.mdx | 2 +- .../blog/introducing-react-spectrum.mdx | 6 +- .../pages/react-aria/blog/rtl-date-time.mdx | 4 +- .../s2-docs/pages/react-aria/collections.mdx | 4 +- .../pages/react-aria/customization.mdx | 4 +- .../dev/s2-docs/pages/react-aria/index.mdx | 16 +- .../internationalized/number/NumberParser.mdx | 2 +- .../pages/react-aria/releases/index.mdx | 2 +- .../pages/react-aria/releases/v1-0-0.mdx | 2 +- .../pages/react-aria/releases/v1-1-0.mdx | 2 +- .../pages/react-aria/releases/v1-13-0.mdx | 4 +- .../pages/react-aria/releases/v1-2-0.mdx | 6 +- .../pages/react-aria/releases/v1-6-0.mdx | 4 +- .../pages/react-aria/releases/v1-7-0.mdx | 4 +- .../dev/s2-docs/pages/react-aria/styling.mdx | 2 +- .../dev/s2-docs/pages/react-aria/useField.mdx | 2 +- .../dev/s2-docs/pages/react-aria/useIsSSR.mdx | 2 +- .../dev/s2-docs/pages/react-aria/useLabel.mdx | 2 +- .../s2-docs/pages/react-aria/useLandmark.mdx | 2 +- packages/dev/s2-docs/pages/s2/Breadcrumbs.mdx | 4 +- packages/dev/s2-docs/pages/s2/ButtonGroup.mdx | 2 + packages/dev/s2-docs/pages/s2/InlineAlert.mdx | 2 + packages/dev/s2-docs/pages/s2/Link.mdx | 2 +- packages/dev/s2-docs/pages/s2/Menu.mdx | 2 +- .../dev/s2-docs/pages/s2/Menu/testing.mdx | 2 +- .../s2-docs/pages/s2/TableView/testing.mdx | 2 +- .../dev/s2-docs/pages/s2/ToggleButton.mdx | 2 +- packages/dev/s2-docs/pages/s2/TreeView.mdx | 4 +- .../dev/s2-docs/pages/s2/TreeView/testing.mdx | 2 +- packages/dev/s2-docs/pages/s2/collections.mdx | 4 +- packages/dev/s2-docs/pages/s2/index.mdx | 2 +- packages/dev/s2-docs/pages/s2/migrating.mdx | 4 +- .../dev/s2-docs/pages/s2/releases/index.mdx | 2 +- .../dev/s2-docs/pages/s2/releases/v0-1-0.mdx | 2 +- .../dev/s2-docs/pages/s2/releases/v0-3-0.mdx | 4 +- .../dev/s2-docs/pages/s2/releases/v0-5-0.mdx | 4 +- .../dev/s2-docs/pages/s2/releases/v0-9-0.mdx | 2 +- packages/dev/s2-docs/pages/s2/styling.mdx | 4 +- .../dev/s2-docs/src/SearchMenuWrapper.tsx | 18 +- .../s2-docs/src/SearchMenuWrapperServer.tsx | 5 +- packages/dev/s2-docs/src/StarterKits.tsx | 8 +- packages/dev/s2-docs/src/client.tsx | 3 +- starters/tailwind/src/Calendar.tsx | 2 +- starters/tailwind/src/DatePicker.tsx | 7 +- starters/tailwind/src/DateRangePicker.tsx | 7 +- 302 files changed, 1098 insertions(+), 5303 deletions(-) delete mode 100644 packages/@react-aria/dnd/docs/dnd.mdx delete mode 100644 packages/@react-aria/dnd/docs/useClipboard.mdx delete mode 100644 packages/@react-aria/dnd/docs/useDrag.mdx delete mode 100644 packages/@react-aria/dnd/docs/useDrop.mdx delete mode 100644 packages/@react-aria/focus/docs/FocusRing.mdx delete mode 100644 packages/@react-aria/focus/docs/FocusScope.mdx delete mode 100644 packages/@react-aria/focus/docs/useFocusRing.mdx delete mode 100644 packages/@react-aria/i18n/docs/I18nProvider.mdx delete mode 100644 packages/@react-aria/i18n/docs/internationalization.mdx delete mode 100644 packages/@react-aria/i18n/docs/useCollator.mdx delete mode 100644 packages/@react-aria/i18n/docs/useDateFormatter.mdx delete mode 100644 packages/@react-aria/i18n/docs/useFilter.mdx delete mode 100644 packages/@react-aria/i18n/docs/useLocale.mdx delete mode 100644 packages/@react-aria/i18n/docs/useNumberFormatter.mdx delete mode 100644 packages/@react-aria/interactions/docs/interactions.mdx delete mode 100644 packages/@react-aria/interactions/docs/useFocus.mdx delete mode 100644 packages/@react-aria/interactions/docs/useFocusVisible.mdx delete mode 100644 packages/@react-aria/interactions/docs/useFocusWithin.mdx delete mode 100644 packages/@react-aria/interactions/docs/useHover.mdx delete mode 100644 packages/@react-aria/interactions/docs/useKeyboard.mdx delete mode 100644 packages/@react-aria/interactions/docs/useLongPress.mdx delete mode 100644 packages/@react-aria/interactions/docs/useMove.mdx delete mode 100644 packages/@react-aria/interactions/docs/usePress.mdx delete mode 100644 packages/@react-aria/label/docs/useField.mdx delete mode 100644 packages/@react-aria/label/docs/useLabel.mdx delete mode 100644 packages/@react-aria/landmark/docs/useLandmark.mdx delete mode 100644 packages/@react-aria/overlays/docs/PortalProvider.mdx delete mode 100644 packages/@react-aria/ssr/docs/SSRProvider.mdx delete mode 100644 packages/@react-aria/ssr/docs/useIsSSR.mdx delete mode 100644 packages/@react-aria/steplist/docs/useStepList.mdx delete mode 100644 packages/@react-aria/utils/docs/mergeProps.mdx delete mode 100644 packages/@react-aria/utils/docs/useId.mdx delete mode 100644 packages/@react-aria/utils/docs/useObjectRef.mdx delete mode 100644 packages/@react-aria/visually-hidden/docs/VisuallyHidden.mdx delete mode 100644 packages/@react-stately/collections/docs/Collection.mdx delete mode 100644 packages/@react-stately/selection/docs/SelectionManager.mdx delete mode 100644 packages/@react-stately/steplist/docs/useStepListState.mdx create mode 100644 packages/dev/docs/pages/assets/wallpaper_collaborative_S2_desktop.webp rename packages/dev/docs/pages/{ => react-spectrum}/Support.mdx (93%) rename packages/{@react-stately/collections/docs => dev/docs/pages/react-spectrum}/collections.mdx (98%) rename packages/{@react-stately/selection/docs => dev/docs/pages/react-spectrum}/selection.mdx (98%) create mode 100644 packages/dev/docs/src/MigrationBanner.js diff --git a/.circleci/comment.js b/.circleci/comment.js index 5af50c1c865..db53fa03ba1 100644 --- a/.circleci/comment.js +++ b/.circleci/comment.js @@ -59,7 +59,6 @@ async function run() { [NextJS App Size](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/verdaccio/publish-stats/next-build-stats.txt) [Publish stats](https://reactspectrum.blob.core.windows.net/reactspectrum/${process.env.CIRCLE_SHA1}/verdaccio/publish-stats/publish.json) [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 docs](https://d1pzu54gtk2aed.cloudfront.net/main/${process.env.CIRCLE_SHA1}/) @@ -83,7 +82,6 @@ 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 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}/)` }); diff --git a/.circleci/config.yml b/.circleci/config.yml index f89714246df..4ca3c8660de 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -485,7 +485,7 @@ jobs: paths: - '*/storybook-s2/' - docs: + docs-production: executor: rsp-xlarge steps: - restore_cache: @@ -493,29 +493,29 @@ jobs: - run: name: build docs - command: make website + command: make website-production - persist_to_workspace: root: dist paths: - '*/docs/' - docs-production: + s2-docs: executor: rsp-xlarge steps: - restore_cache: key: react-spectrum-{{ .Environment.CACHE_VERSION }}-{{ .Environment.CIRCLE_SHA1 }} - run: - name: build docs - command: make website-production + name: build s2 docs + command: make s2-docs - persist_to_workspace: root: dist paths: - - '*/docs/' + - 's2-docs/' - s2-docs: + s2-docs-stage: executor: rsp-xlarge steps: - restore_cache: @@ -523,7 +523,7 @@ jobs: - run: name: build s2 docs - command: make s2-docs + command: make s2-docs-stage - persist_to_workspace: root: dist @@ -567,37 +567,6 @@ jobs: paths: - storage - v-docs: - executor: rsp-2xlarge - steps: - - restore_cache: - key: react-spectrum-{{ .Environment.CACHE_VERSION }}-{{ .Environment.CIRCLE_SHA1 }} - - - attach_workspace: - at: /tmp/verdaccio-workspace - - - run: - name: build docs off verdaccio - command: | - ./scripts/verdaccio-ci.sh - ./scripts/verdaccio-build.sh - environment: - VERDACCIO_STORAGE_PATH: /tmp/verdaccio-workspace/storage - - - run: - name: build docs off verdaccio retry - command: | - ./scripts/verdaccio-ci.sh - ./scripts/verdaccio-build.sh - environment: - VERDACCIO_STORAGE_PATH: /tmp/verdaccio-workspace/storage - when: on_fail - - - persist_to_workspace: - root: verdaccio_dist - paths: - - '*/verdaccio/docs' - v-rsp-cra-18: executor: rsp-xlarge steps: @@ -973,13 +942,10 @@ workflows: - storybook-s2: requires: - install - - docs: - requires: - - install - s2-docs: requires: - install - - s2-docs-production: + - s2-docs-stage: requires: - install filters: @@ -991,9 +957,6 @@ workflows: only: main requires: - install - - v-docs: - requires: - - verdaccio - v-rsp-cra-18: requires: - verdaccio @@ -1038,7 +1001,6 @@ workflows: - test-esm - storybook - storybook-s2 - - docs - deploy-s3-stage: name: deploy-s3-commit requires: @@ -1050,13 +1012,12 @@ workflows: name: deploy-s3-main requires: - s2-docs - - s2-docs-production + - s2-docs-stage filters: branches: only: main - deploy-verdaccio: requires: - - v-docs - v-rsp-cra-18 - v-webpack-4 - v-nextjs diff --git a/Makefile b/Makefile index 8ee3b3a4bb3..a336fb06314 100644 --- a/Makefile +++ b/Makefile @@ -117,6 +117,10 @@ website-production: $(MAKE) starter-zip $(MAKE) tailwind-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 check-examples: node scripts/extractExamples.mjs @@ -128,18 +132,14 @@ starter: starter-zip: starter cp LICENSE starters/docs/. cd starters/docs && zip -r react-aria-starter.zip . -x .gitignore .DS_Store "node_modules/*" "storybook-static/*" - mv starters/docs/react-aria-starter.zip dist/production/docs/react-aria-starter.$$(git rev-parse --short HEAD).zip cd starters/docs && yarn build-storybook - mv starters/docs/storybook-static dist/production/docs/react-aria-starter tailwind-starter: cp LICENSE starters/tailwind/. cd starters/tailwind && yarn --no-immutable && yarn up react-aria-components && yarn up tailwindcss-react-aria-components && yarn tsc cd starters/tailwind && zip -r react-aria-tailwind-starter.zip . -x .gitignore .DS_Store "node_modules/*" "storybook-static/*" - mv starters/tailwind/react-aria-tailwind-starter.zip dist/production/docs/react-aria-tailwind-starter.$$(git rev-parse --short HEAD).zip cd starters/tailwind && yarn build-storybook - mv starters/tailwind/storybook-static dist/production/docs/react-aria-tailwind-starter s2-storybook-docs: yarn build:s2-storybook-docs -o dist/production/docs/s2 @@ -153,10 +153,17 @@ 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-stage: + DOCS_ENV=stage PUBLIC_URL=/ $(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 + $(MAKE) starters + s2-docs-production: 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 + $(MAKE) starters build-s2-docs: yarn workspace @react-spectrum/s2-docs generate:md @@ -171,3 +178,16 @@ build-s2-docs: 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 + + # Build old docs pages, which get inter-mixed with the new pages + # TODO: We probably don't need to build this on every PR + yarn parcel build 'packages/@react-spectrum/*/docs/*.mdx' 'packages/dev/docs/pages/{react-spectrum,releases}/**/*.mdx' --dist-dir dist/s2-docs/s2/$(PUBLIC_URL) --public-url $(PUBLIC_URL) + yarn parcel build 'packages/@react-{aria,stately}/*/docs/*.mdx' --dist-dir dist/s2-docs/react-aria/$(PUBLIC_URL) --public-url $(PUBLIC_URL) + +starters: + $(MAKE) starter-zip + $(MAKE) tailwind-starter + mv starters/docs/storybook-static dist/s2-docs/react-aria-starter + mv starters/docs/react-aria-starter.zip dist/s2-docs/react-aria-starter.$$(git rev-parse --short HEAD).zip + mv starters/tailwind/storybook-static dist/s2-docs/react-aria-tailwind-starter + mv starters/tailwind/react-aria-tailwind-starter.zip dist/s2-docs/react-aria-tailwind-starter.$$(git rev-parse --short HEAD).zip diff --git a/README.md b/README.md index d3f6b591f9c..dac69b059f3 100644 --- a/README.md +++ b/README.md @@ -47,4 +47,4 @@ React Spectrum includes several libraries, which you can choose depending on you One of the goals of the React Spectrum project is to make building design systems and component libraries as easy as possible, while maintaining high quality interactions and accessibility support. We aim to raise the bar for web applications. The best way to achieve that goal is **together**. We would love contributions from the community no matter how big or small. 😍 -Read our [contributing guide](https://react-spectrum.adobe.com/contribute.html) to learn about how to propose bugfixes and improvements, and how the development process works. For detailed information about our architecture, and how all of the pieces fit together, read our [architecture docs](https://react-spectrum.adobe.com/architecture.html). +Read our [contributing guide](https://github.com/adobe/react-spectrum/blob/main/CONTRIBUTING.md) to learn about how to propose bugfixes and improvements, and how the development process works. For detailed information about our architecture, and how all of the pieces fit together, read our [architecture docs](https://react-spectrum.adobe.com/architecture.html). diff --git a/package.json b/package.json index 7cead10d05a..f1b409e07b1 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,8 @@ "start:s2": "NODE_ENV=storybook storybook dev -p 6006 --ci -c '.storybook-s2'", "build:storybook-s2": "NODE_ENV=storybook storybook build -c .storybook-s2 -o dist/$(git rev-parse HEAD)/storybook-s2", "build:s2-storybook-docs": "NODE_ENV=storybook storybook build -c .storybook-s2 --docs", - "start:docs": "DOCS_ENV=dev parcel 'packages/@react-{spectrum,aria,stately}/*/docs/*.mdx' 'packages/react-aria-components/docs/**/*.mdx' 'packages/@internationalized/*/docs/*.mdx' 'packages/dev/docs/pages/**/*.mdx'", - "build:docs": "DOCS_ENV=staging parcel build 'packages/@react-{spectrum,aria,stately}/*/docs/*.mdx' 'packages/react-aria-components/docs/**/*.mdx' 'packages/@internationalized/*/docs/*.mdx' 'packages/dev/docs/pages/**/*.mdx'", + "start:docs": "DOCS_ENV=dev parcel 'packages/@react-{spectrum,aria,stately}/*/docs/*.mdx' 'packages/dev/docs/pages/{react-spectrum,releases}/**/*.mdx'", + "build:docs": "DOCS_ENV=staging parcel build 'packages/@react-{spectrum,aria,stately}/*/docs/*.mdx' 'packages/dev/docs/pages/{react-spectrum,releases}/**/*.mdx'", "start:s2-docs": "yarn workspace @react-spectrum/s2-docs start", "build:s2-docs": "yarn workspace @react-spectrum/s2-docs build", "build:mcp": "yarn workspace @react-spectrum/mcp build && yarn workspace @react-aria/mcp build", diff --git a/packages/@react-aria/autocomplete/src/useSearchAutocomplete.ts b/packages/@react-aria/autocomplete/src/useSearchAutocomplete.ts index 4eb891f3664..2c51aaf0a0a 100644 --- a/packages/@react-aria/autocomplete/src/useSearchAutocomplete.ts +++ b/packages/@react-aria/autocomplete/src/useSearchAutocomplete.ts @@ -25,7 +25,7 @@ export interface SearchAutocompleteAria extends ValidationResult { labelProps: DOMAttributes, /** Props for the search input element. */ inputProps: InputHTMLAttributes, - /** Props for the list box, to be passed to [useListBox](useListBox.html). */ + /** Props for the list box, to be passed to `useListBox`. */ listBoxProps: AriaListBoxOptions, /** Props for the search input's clear button. */ clearButtonProps: AriaButtonProps, diff --git a/packages/@react-aria/breadcrumbs/docs/useBreadcrumbs.mdx b/packages/@react-aria/breadcrumbs/docs/useBreadcrumbs.mdx index d5251d2ad77..e87dd5da3bb 100644 --- a/packages/@react-aria/breadcrumbs/docs/useBreadcrumbs.mdx +++ b/packages/@react-aria/breadcrumbs/docs/useBreadcrumbs.mdx @@ -180,8 +180,8 @@ function BreadcrumbItem(props) { } - Home - React Aria + Home + React Aria useBreadcrumbs ``` @@ -196,8 +196,8 @@ Breadcrumbs can be disabled using the `isDisabled` prop, passed to each disabled ```tsx example - Home - React Aria + Home + React Aria useBreadcrumbs ``` diff --git a/packages/@react-aria/button/docs/useButton.mdx b/packages/@react-aria/button/docs/useButton.mdx index d22f8dcb6c7..ec5de0790d5 100644 --- a/packages/@react-aria/button/docs/useButton.mdx +++ b/packages/@react-aria/button/docs/useButton.mdx @@ -48,7 +48,7 @@ cross browser inconsistencies in interactions and accessibility features to cons * Keyboard focus management and cross browser normalization * Keyboard event support for Space and Enter keys -Read our [blog post](/blog/building-a-button-part-1.html) about the complexities of building buttons that work well across devices and interaction methods. +Read our [blog post](../blog/building-a-button-part-1) about the complexities of building buttons that work well across devices and interaction methods. ## Anatomy @@ -131,7 +131,7 @@ The following examples show how to use the `Button` component created in the abo `useButton` supports user interactions via mouse, keyboard, and touch. You can handle all of these via the `onPress` prop. This is similar to the standard `onClick` event, but normalized to support all interaction methods equally. In addition, the `onPressStart`, `onPressEnd`, and `onPressChange` events are fired as the user interacts with the button. -Each of these handlers receives a , which exposes information about the target and the type of event that triggered the interaction. See [usePress](usePress.html) for more details. +Each of these handlers receives a , which exposes information about the target and the type of event that triggered the interaction. See [usePress](../usePress) for more details. ```tsx example function Example() { diff --git a/packages/@react-aria/button/docs/useToggleButton.mdx b/packages/@react-aria/button/docs/useToggleButton.mdx index 37e1481a7a7..ce8437d4420 100644 --- a/packages/@react-aria/button/docs/useToggleButton.mdx +++ b/packages/@react-aria/button/docs/useToggleButton.mdx @@ -70,7 +70,7 @@ If a visual label is not provided (e.g. an icon only button), then an `aria-labe ## Example By default, `useToggleButton` assumes that you are using it with a native ` - - ); -} - - - -``` - -## Disabling dragging - -If you need to temporarily disable dragging, you can pass the `isDisabled` option to `useDrag`. This will prevent dragging an element until it is re-enabled. - -```tsx example -import {useDrag} from '@react-aria/dnd'; - -function Draggable() { - let {dragProps, isDragging} = useDrag({ - getItems() { - return [{ - 'text/plain': 'hello world' - }]; - }, - /*- begin highlight -*/ - isDisabled: true - /*- end highlight -*/ - }); - - return ( -
- Drag me -
- ); -} - - -``` diff --git a/packages/@react-aria/dnd/docs/useDraggableCollection.mdx b/packages/@react-aria/dnd/docs/useDraggableCollection.mdx index 43cd93bfc09..450f0239b27 100644 --- a/packages/@react-aria/dnd/docs/useDraggableCollection.mdx +++ b/packages/@react-aria/dnd/docs/useDraggableCollection.mdx @@ -41,19 +41,19 @@ type: interaction ## Introduction -Collection components built with hooks such as [useListBox](useListBox.html), [useTable](useTable.html), and [useGridList](useGridList.html) can support drag and drop interactions. Users can drag multiple selected items at once, or drag individual non-selected items. +Collection components built with hooks such as [useListBox](ListBox/useListBox.html), [useTable](Table/useTable.html), and [useGridList](GridList/useGridList.html) can support drag and drop interactions. Users can drag multiple selected items at once, or drag individual non-selected items. React Aria supports traditional mouse and touch based drag and drop, but also implements keyboard and screen reader friendly interactions. Users can press Enter on a draggable element to enter drag and drop mode. Then, they can press Tab to navigate between drop targets, and Enter to drop or Escape to cancel. Touch screen reader users can also drag by double tapping to activate drag and drop mode, swiping between drop targets, and double tapping again to drop. -See the [drag and drop introduction](dnd.html) to learn more. +See the [drag and drop introduction](dnd) to learn more. ### Implementation -The hook implements drag interactions within any [collection component](../react-stately/collections.html), using state managed by . The hook should be added to each individual item within the collection to make it draggable, combining props from the relevant hook (e.g. `useOption`). These hooks integrate with React Aria's [selection](../react-stately/selection.html) system to enable dragging multiple selected items at once. +The hook implements drag interactions within any [collection component](v3:collections.html), using state managed by . The hook should be added to each individual item within the collection to make it draggable, combining props from the relevant hook (e.g. `useOption`). These hooks integrate with React Aria's [selection](v3:selection.html) system to enable dragging multiple selected items at once. ## Example -This example renders a ListBox using the [useListBox](useListBox.html) hook, and adds support for dragging items. The highlighted code sections below show the main additions for drag and drop compared with a normal listbox. +This example renders a ListBox using the [useListBox](ListBox/useListBox.html) hook, and adds support for dragging items. The highlighted code sections below show the main additions for drag and drop compared with a normal listbox. ```tsx example export=true import {useListBox, useOption} from '@react-aria/listbox'; @@ -189,7 +189,7 @@ function Option({ item, state, dragState }) { ### DropTarget -The `DropTarget` component used above is defined below. See [useDrop](useDrop.html) for more details and documentation. +The `DropTarget` component used above is defined below. See [useDrop](useDrop) for more details and documentation.
Show code @@ -413,7 +413,7 @@ Many operating systems display these in the form of a cursor change, e.g. a plus The `onDragEnd` event allows the drag source to respond when a drag that it initiated ends, either because it was dropped or because it was canceled by the user. The `dropOperation` property of the event object indicates the operation that was performed. For example, when data is moved, the UI could be updated to reflect this change by removing the original dragged items. -This example removes the dragged items from the UI when a move operation is completed. It uses the [useListData](../react-stately/useListData.html) hook to help manage and update the list of items. Try holding the Option or Alt keys to change the operation to copy, and see how the behavior changes. +This example removes the dragged items from the UI when a move operation is completed. It uses the [useListData](useListData.html) hook to help manage and update the list of items. Try holding the Option or Alt keys to change the operation to copy, and see how the behavior changes. ```tsx example import {useListData} from '@react-stately/data'; @@ -465,7 +465,7 @@ The drag source can also control which drop operations are allowed for the data. ## Reordering -Drag and drop can be combined in the same collection component to allow reordering items. See [useDroppableCollection](useDroppableCollection.html) for more details. +Drag and drop can be combined in the same collection component to allow reordering items. See [useDroppableCollection](./useDroppableCollection.html) for more details. ```tsx example export=true render=false import {useDroppableCollectionState} from '@react-stately/dnd'; @@ -598,7 +598,7 @@ function DropIndicator(props) { ///- end highlight -/// ``` -Now, we can render an example ListBox, which allows the user to reorder items. The `onReorder` event is triggered when the user drops dragged items which originated within the same collection. As above, [useListData](../react-stately/useListData.html) is used to manage the list items in this example, but it is not a requirement. +Now, we can render an example ListBox, which allows the user to reorder items. The `onReorder` event is triggered when the user drops dragged items which originated within the same collection. As above, [useListData](./useListData.html) is used to manage the list items in this example, but it is not a requirement. ```tsx example import {useListData} from '@react-stately/data'; diff --git a/packages/@react-aria/dnd/docs/useDrop.mdx b/packages/@react-aria/dnd/docs/useDrop.mdx deleted file mode 100644 index ecdd1c3fd2b..00000000000 --- a/packages/@react-aria/dnd/docs/useDrop.mdx +++ /dev/null @@ -1,476 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/dnd'; -import sharedDocs from 'docs:@react-types/shared/src/dnd.d.ts'; -import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/dnd/package.json'; -import ChevronRight from '@spectrum-icons/workflow/ChevronRight'; -import {Keyboard} from '@react-spectrum/text'; - ---- -category: Drag and Drop -keywords: [drag, drop, dnd, drag and drop, aria, accessibility] -type: interaction ---- - -# useDrop - -{docs.exports.useDrop.description} - - - -## API - - - -## Introduction - -Drag and drop is a common UI interaction that allows users to transfer data between two locations by directly moving a visual representation on screen. It is a flexible, efficient, and intuitive way for users to perform a variety of tasks, and is widely supported across both desktop and mobile operating systems. - -React Aria supports traditional mouse and touch based drag and drop, but also implements keyboard and screen reader friendly interactions. Users can press Enter on a draggable element to enter drag and drop mode. Then, they can press Tab to navigate between drop targets, and Enter to drop or Escape to cancel. Touch screen reader users can also drag by double tapping to activate drag and drop mode, swiping between drop targets, and double tapping again to drop. - -See the [drag and drop introduction](dnd.html) to learn more. - -## Example - -This example shows how to make a simple drop target that accepts plain text data. In order to support keyboard and screen reader drag interactions, the element must be focusable and have an ARIA role (in this case, `button`). While a drag is hovered over it, a blue outline is rendered by applying an additional CSS class. - -```tsx example -import type {TextDropItem} from '@react-aria/dnd'; -import {useDrop} from '@react-aria/dnd'; - -function DropTarget() { - let [dropped, setDropped] = React.useState(null); - let ref = React.useRef(null); - let {dropProps, isDropTarget} = useDrop({ - ref, - async onDrop(e) { - let items = await Promise.all( - e.items - .filter(item => item.kind === 'text' && item.types.has('text/plain')) - .map((item: TextDropItem) => item.getText('text/plain')) - ); - setDropped(items.join('\n')); - } - }); - - return ( -
- {dropped || 'Drop here'} -
- ); -} - - - -``` - -
- Show CSS - -```css -.draggable { - display: inline-block; - vertical-align: top; - border: 1px solid gray; - padding: 10px; - margin-right: 20px; -} - -.draggable.dragging { - opacity: 0.5; -} - -.droppable { - width: 100px; - height: 80px; - border-radius: 6px; - display: inline-block; - padding: 20px; - border: 2px dotted gray; - white-space: pre-wrap; - overflow: auto; -} - -.droppable.target { - border: 2px solid var(--blue); -} -``` - -
- -### Draggable - -The `Draggable` component used above is defined below. See [useDrag](useDrag.html) for more details and documentation. - -
- Show code - -```tsx example render=false export=true -import {useDrag} from '@react-aria/dnd'; - -function Draggable() { - let {dragProps, isDragging} = useDrag({ - getItems() { - return [{ - 'text/plain': 'hello world', - 'my-app-custom-type': JSON.stringify({message: 'hello world'}) - }]; - } - }); - - return ( -
- Drag me -
- ); -} -``` - -
- -## Drop data - -`useDrop` allows users to drop one or more **drag items**, each of which contains data to be transferred from the drag source to drop target. There are three kinds of drag items: - -* `text` – represents data inline as a string in one or more formats -* `file` – references a file on the user's device -* `directory` – references the contents of a directory - -### Text - -A represents textual data in one or more different formats. These may be either standard [mime types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) or custom app-specific formats. Representing data in multiple formats allows drop targets both within and outside an application to choose data in a format that they understand. For example, a complex object may be serialized in a custom format for use within an application, with fallbacks in plain text and/or rich HTML that can be used when a user drops data from an external application. - -The example below finds the first available item that includes a custom app-specific type. The same draggable component as used in the above example is used here, but rather than displaying the plain text representation, the custom format is used instead. - -```tsx example -function DropTarget() { - let [dropped, setDropped] = React.useState(null); - let ref = React.useRef(null); - let {dropProps, isDropTarget} = useDrop({ - ref, - /*- begin highlight -*/ - async onDrop(e) { - let item = e.items.find(item => item.kind === 'text' && item.types.has('my-app-custom-type')) as TextDropItem; - if (item) { - setDropped(await item.getText('my-app-custom-type')); - } - } - /*- end highlight -*/ - }); - - // ... - ///- begin collapse -/// - return ( -
- {dropped || 'Drop here'} -
- ); - ///- end collapse -/// -} -///- begin collapse -/// - - -///- end collapse -/// -``` - -### Files - -A references a file on the user's device. It includes the name and mime type of the file, and methods to read the contents as plain text, or retrieve a native [File](https://developer.mozilla.org/en-US/docs/Web/API/File) object which can be attached to form data for uploading. - -This example accepts JPEG and PNG image files, and renders them by creating a local [object URL](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL). - -```tsx example -import type {FileDropItem} from '@react-aria/dnd'; - -function DropTarget() { - let [file, setFile] = React.useState(null); - let ref = React.useRef(null); - let {dropProps, isDropTarget} = useDrop({ - ref, - /*- begin highlight -*/ - async onDrop(e) { - let item = e.items.find(item => item.kind === 'file' && (item.type === 'image/jpeg' || item.type === 'image/png')) as FileDropItem; - if (item) { - setFile(URL.createObjectURL(await item.getFile())); - } - } - /*- end highlight -*/ - }); - - return ( -
- {file ? : 'Drop image here'} -
- ); -} -``` - -### Directories - -A references the contents of a directory on the user's device. It includes the name of the directory, as well as a method to iterate through the files and folders within the directory. The contents of any folders within the directory can be accessed recursively. - -The `getEntries` method returns an [async iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) object, which can be used in a `for await...of` loop. This provides each item in the directory as either a or , and you can access the contents of each file as discussed above. - -This example renders the file names within a dropped directory in a grid. - -```tsx example -import type {DirectoryDropItem} from '@react-aria/dnd'; -import File from '@spectrum-icons/workflow/FileTxt'; -import Folder from '@spectrum-icons/workflow/Folder'; - -function DropTarget() { - let [files, setFiles] = React.useState(null); - let ref = React.useRef(null); - let {dropProps, isDropTarget} = useDrop({ - ref, - /*- begin highlight -*/ - async onDrop(e) { - // Find the first dropped item that is a directory. - let dir = e.items.find(item => item.kind === 'directory') as DirectoryDropItem; - if (dir) { - // Read entries in directory and update state with relevant info. - let files = []; - for await (let entry of dir.getEntries()) { - files.push({ - name: entry.name, - kind: entry.kind - }); - } - setFiles(files); - } - } - /*- end highlight -*/ - }); - - let contents = <>Drop directory here; - if (files) { - contents = ( -
    - {files.map(f => ( -
  • - {f.kind === 'directory' ? : } - {f.name} -
  • - ))} -
- ); - } - - return ( -
- {contents} -
- ); -} -``` - -
- Show CSS - -```css -.grid { - display: block; - width: auto; - height: auto; - min-height: 80px; -} - -.grid ul { - display: grid; - grid-template-columns: repeat(auto-fit, 100px); - list-style: none; - margin: 0; - padding: 0; - gap: 20px; -} - -.grid li { - display: flex; - align-items: center; - gap: 8px; -} - -.grid li svg { - flex: 0 0 auto; -} - -.grid li span { - flex: 1; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -``` - -
- -## Drop operations - -A is an indication of what will happen when dragged data is dropped on a particular drop target. These are: - -* `move` – indicates that the dragged data will be moved from its source location to the target location. -* `copy` – indicates that the dragged data will be copied to the target destination. -* `link` – indicates that there will be a relationship established between the source and target locations. -* `cancel` – indicates that the drag and drop operation will be canceled, resulting in no changes made to the source or target. - -Many operating systems display these in the form of a cursor change, e.g. a plus sign to indicate a copy operation. The user may also be able to use a modifier key to choose which drop operation to perform, such as Option or Alt to switch from move to copy. - -The drag source can specify which drop operations are allowed for the dragged data (see the [useDrag docs](useDrag.html) for how to customize this). By default, the first allowed operation is allowed by drop targets, meaning that the drop target accepts data of any type and operation. - -### getDropOperation - -The `getDropOperation` function passed to `useDrop` can be used to provide appropriate feedback to the user when a drag hovers over the drop target. If a drop target only supports data of specific types (e.g. images, videos, text, etc.), then it should implement `getDropOperation` and return `'cancel'` for types that aren't supported. This will prevent visual feedback indicating that the drop target accepts the dragged data when this is not true. - -When the data is supported, either return one of the drop operations in `allowedOperation` or a specific drop operation if only that drop operation is supported. If the returned operation is not in `allowedOperations`, then the drop target will act as if `'cancel'` was returned. - -In the below example, the drop target only supports dropping PNG images. If a PNG is dragged over the target, it will be highlighted and the operating system displays a copy cursor. If another type is dragged over the target, then there is no visual feedback, indicating that a drop is not accepted there. If the user holds a modifier key such as Control while dragging over the drop target in order to change the drop operation, then the drop target does not accept the drop. - -```tsx example -function DropTarget() { - let [file, setFile] = React.useState(null); - let ref = React.useRef(null); - let {dropProps, isDropTarget} = useDrop({ - ref, - /*- begin highlight -*/ - getDropOperation(types, allowedOperations) { - return types.has('image/png') ? 'copy' : 'cancel'; - }, - /*- end highlight -*/ - async onDrop(e) { - let item = e.items.find(item => item.kind === 'file' && item.type === 'image/png') as FileDropItem; - if (item) { - setFile(URL.createObjectURL(await item.getFile())); - } - } - }); - - // ... -///- begin collapse -/// - return ( -
- {file ? : 'Drop image here'} -
- ); -///- end collapse -/// -} -``` - -### onDrop - -The `onDrop` event also includes the `dropOperation`. This can be used to perform different actions accordingly, for example, when communicating with a backend API. - -```tsx -function DropTarget(props) { - let ref = React.useRef(null); - let {dropProps, isDropTarget} = useDrop({ - ref, - async onDrop(e) { - let item = e.items.find(item => item.kind === 'text' && item.types.has('my-app-file')) as TextDropItem; - if (!item) { - return; - } - - let data = JSON.parse(await item.getText('my-app-file')); - /*- begin highlight -*/ - switch (e.dropOperation) { - case 'move': - MyAppFileService.move(data.filePath, props.filePath); - break; - case 'copy': - MyAppFileService.copy(data.filePath, props.filePath); - break; - case 'link': - MyAppFileService.link(data.filePath, props.filePath); - break; - } - /*- end highlight -*/ - } - }); - - // ... -} -``` - -## Events - -Drop targets receive a number of events during a drag session. These are: - - - k.startsWith('on')))} /> - - -This example logs all events that occur within the drop target: - -```tsx example -function DropTarget() { - let [events, setEvents] = React.useState([]); - let onEvent = e => setEvents(events => [JSON.stringify(e), ...events]); - let ref = React.useRef(null); - let {dropProps, isDropTarget} = useDrop({ - ref, - onDropEnter: onEvent, - onDropMove: onEvent, - onDropExit: onEvent, - onDrop: onEvent - }); - - return ( -
    - {events.map((e, i) =>
  • {e}
  • )} -
- ); -} - - - -``` - -## Disabling dropping - -If you need to temporarily disable dropping, you can pass the `isDisabled` option to `useDrop`. This will prevent the drop target from accepting any drops until it is re-enabled. - -```tsx example -import type {TextDropItem} from '@react-aria/dnd'; -import {useDrop} from '@react-aria/dnd'; - -function DropTarget() { - let [dropped, setDropped] = React.useState(null); - let ref = React.useRef(null); - let {dropProps, isDropTarget} = useDrop({ - ref, - async onDrop(e) { - let items = await Promise.all( - e.items - .filter(item => item.kind === 'text' && item.types.has('text/plain')) - .map((item: TextDropItem) => item.getText('text/plain')) - ); - setDropped(items.join('\n')); - }, - /*- begin highlight -*/ - isDisabled: true - /*- end highlight -*/ - }); - - return ( -
- {dropped || 'Drop here'} -
- ); -} - - - -``` diff --git a/packages/@react-aria/dnd/docs/useDroppableCollection.mdx b/packages/@react-aria/dnd/docs/useDroppableCollection.mdx index c8a15b5a27e..d35297b6c6c 100644 --- a/packages/@react-aria/dnd/docs/useDroppableCollection.mdx +++ b/packages/@react-aria/dnd/docs/useDroppableCollection.mdx @@ -42,17 +42,17 @@ type: interaction ## Introduction -Collection components built with hooks such as [useListBox](useListBox.html), [useTable](useTable.html), and [useGridList](useGridList.html) can support drag and drop interactions. Users can drop data on the collection as a whole, on individual items, insert new items between existing ones, or reorder items. +Collection components built with hooks such as [useListBox](ListBox/useListBox.html), [useTable](Table/useTable.html), and [useGridList](GridList/useGridList.html) can support drag and drop interactions. Users can drop data on the collection as a whole, on individual items, insert new items between existing ones, or reorder items. React Aria supports traditional mouse and touch based drag and drop, but also implements keyboard and screen reader friendly interactions. Users can press Enter on a draggable element to enter drag and drop mode. Then, they can press Tab to navigate between drop targets. A droppable collection is treated as a single drop target, so that users can easily tab past it to get to the next drop target. Within a droppable collection, keys such as ArrowDown and ArrowUp can be used to select a _drop position_, such as on an item, or between items. These are represented using objects. The keyboard interactions used within a collection may differ depending on the type or layout. For example, in a grid the ArrowLeft and ArrowRight may also be used, whereas they may not within a list. In general, the keyboard interactions used during drag and drop match those used when navigating the collection normally. -See the [drag and drop introduction](dnd.html) to learn more. +See the [drag and drop introduction](dnd) to learn more. ### Implementation -The hook implements drop interactions within any [collection component](../react-stately/collections.html), using state managed by . The props it returns should be combined with those from the collection component you're using, such as `useListBox`. The hook should be added to each individual item within the collection, combining props from the relevant hook (e.g. `useOption`). +The hook implements drop interactions within any [collection component](v3:collections.html), using state managed by . The props it returns should be combined with those from the collection component you're using, such as `useListBox`. The hook should be added to each individual item within the collection, combining props from the relevant hook (e.g. `useOption`). To support dropping between items, the hook can be used to add additional elements between each item, for example, rendering a line when a user drags between two items. These elements must be implemented according to the relevant ARIA pattern. For example, within a listbox, drop indicators must be implemented using `role="option"`, and within a grid, they must use `role="row"` and `role="gridcell"` to ensure the accessibility tree is valid. @@ -60,7 +60,7 @@ Interactions like keyboard navigation, and drop target positioning may differ de ## Dropping on items -This example renders a ListBox using the [useListBox](useListBox.html) hook, and adds support for dropping data onto items. The highlighted code sections below show the main additions for drag and drop compared with a normal listbox. +This example renders a ListBox using the [useListBox](ListBox/useListBox.html) hook, and adds support for dropping data onto items. The highlighted code sections below show the main additions for drag and drop compared with a normal listbox. ```tsx example import {useListBox, useOption} from '@react-aria/listbox'; @@ -196,7 +196,7 @@ function Option({ item, state, dropState }) { ### Draggable -The `Draggable` component used above is defined below. See [useDrag](useDrag.html) for more details and documentation. +The `Draggable` component used above is defined below. See [useDrag](useDrag) for more details and documentation.
Show code @@ -307,7 +307,7 @@ function Option({ item, state, dropState }) { } ``` -Now, we can render an example ListBox, which inserts a new item on drop. This uses the [useListData](../react-stately/useListData.html) hook to manage the list of items, which is updated in the `onInsert` event. Note that `useListData` is a convenience hook, not a requirement. You can manage your state however you wish. +Now, we can render an example ListBox, which inserts a new item on drop. This uses the [useListData](./useListData.html) hook to manage the list of items, which is updated in the `onInsert` event. Note that `useListData` is a convenience hook, not a requirement. You can manage your state however you wish. ```tsx example import {useListData} from '@react-stately/data'; @@ -488,7 +488,7 @@ function Option({ item, state, dropState }) { ## Reordering -Drag and drop can be combined in the same collection component to allow reordering items. This example builds on the [dropping between items](#dropping-between-items) example above to add support for dragging items as well. This is done using the `useDraggableCollection` and `useDraggableItem` hooks. See the [docs](useDraggableCollection.html) for more details on these hooks. +Drag and drop can be combined in the same collection component to allow reordering items. This example builds on the [dropping between items](#dropping-between-items) example above to add support for dragging items as well. This is done using the `useDraggableCollection` and `useDraggableItem` hooks. See the [docs](./useDraggableCollection.html) for more details on these hooks. ```tsx example export=true render=false import {useDraggableCollectionState} from '@react-stately/dnd'; @@ -599,7 +599,7 @@ function ReorderableOption({ item, state, dragState, dropState }) { } ``` -Now, we can render an example ListBox, which allows the user to reorder items. The `onReorder` event is triggered when the user drops dragged items which originated within the same collection. As above, [useListData](../react-stately/useListData.html) is used to manage the list items in this example, but it is not a requirement. +Now, we can render an example ListBox, which allows the user to reorder items. The `onReorder` event is triggered when the user drops dragged items which originated within the same collection. As above, [useListData](./useListData.html) is used to manage the list items in this example, but it is not a requirement. ```tsx example import {useListData} from '@react-stately/data'; @@ -860,7 +860,7 @@ A Option or Alt to switch from move to copy. -The drag source can specify which drop operations are allowed for the dragged data (see the [useDrag docs](useDrag.html) for how to customize this). By default, the first allowed operation is allowed by drop targets, meaning that the drop target accepts data of any type and operation. +The drag source can specify which drop operations are allowed for the dragged data (see the [useDrag docs](useDrag) for how to customize this). By default, the first allowed operation is allowed by drop targets, meaning that the drop target accepts data of any type and operation. ### getDropOperation diff --git a/packages/@react-aria/focus/docs/FocusRing.mdx b/packages/@react-aria/focus/docs/FocusRing.mdx deleted file mode 100644 index 1b2acc0f922..00000000000 --- a/packages/@react-aria/focus/docs/FocusRing.mdx +++ /dev/null @@ -1,71 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/focus'; -import {HeaderInfo, PropTable, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/focus/package.json'; - ---- -category: Focus -keywords: [focus, keyboard focus, focus management, aria] ---- - -# FocusRing - -{docs.exports.FocusRing.description} - - - -## Introduction - -`FocusRing` is a utility component that can be used to apply a CSS class when an element has keyboard focus. -This helps keyboard users determine which element on a page or in an application has keyboard focus as they -navigate around. Focus rings are only visible when interacting with a keyboard so as not to distract mouse -and touch screen users. When we are unable to detect if the user is using a mouse or touch screen, such as -switching in from a different tab, we show the focus ring. - -If CSS classes are not being used for styling, see [useFocusRing](useFocusRing.html) for a hooks version. - -## Props - - - -## Example - -This example shows how to use `` to apply a CSS class when keyboard focus is on a button. - -```css -.button { - -webkit-appearance: none; - appearance: none; - background: green; - border: none; - color: white; - font-size: 14px; - padding: 4px 8px; -} - -.button.focus-ring { - outline: 2px solid dodgerblue; - outline-offset: 2px; -} -``` - -```tsx example -import {FocusRing} from '@react-aria/focus'; - - - - -``` diff --git a/packages/@react-aria/focus/docs/FocusScope.mdx b/packages/@react-aria/focus/docs/FocusScope.mdx deleted file mode 100644 index 94827c80d79..00000000000 --- a/packages/@react-aria/focus/docs/FocusScope.mdx +++ /dev/null @@ -1,134 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/focus'; -import {HeaderInfo, PropTable, FunctionAPI, TypeLink, ClassAPI, PageDescription} from '@react-spectrum/docs'; -import {Keyboard} from '@react-spectrum/text'; -import packageData from '@react-aria/focus/package.json'; - ---- -category: Focus -keywords: [focus scope, keyboard focus, focus management, aria] ---- - -# FocusScope - -{docs.exports.FocusScope.description} - - - -## Introduction - -`FocusScope` is a utility component that can be used to manage focus for its descendants. -When the `contain` prop is set, focus is contained within the scope. This is useful when -implementing overlays like modal dialogs, which should not allow focus to escape them while open. -In addition, the `restoreFocus` prop can be used to restore focus back to the previously focused -element when the focus scope unmounts, for example, back to a button which opened a dialog. -A FocusScope can also optionally auto focus the first focusable element within it on mount -when the `autoFocus` prop is set. - -The hook can also be used -in combination with a FocusScope to programmatically move focus within the scope. For example, -arrow key navigation could be implemented by handling keyboard events and using a focus manager -to move focus to the next and previous elements. - -## Props - - - -## FocusManager Interface - -To get a focus manager, call the hook -from a component within the FocusScope. A focus manager supports the following methods: - - - -## Example - -A basic example of a focus scope that contains focus within it is below. Clicking the "Open" -button mounts a FocusScope, which auto focuses the first input inside it. Once open, you can -press the Tab key to move within the scope, but focus is contained inside. Clicking the "Close" -button unmounts the focus scope, which restores focus back to the button. - -For a full example of building a modal dialog, see [useDialog](useDialog.html). - -```tsx example -import {FocusScope} from '@react-aria/focus'; - -function Example() { - let [isOpen, setOpen] = React.useState(false); - return ( - <> - - {isOpen && - - - - - - - - } - - ); -} -``` - -## useFocusManager example - -This example shows how to use `useFocusManager` to programmatically move focus within a -`FocusScope`. It implements a basic toolbar component, which allows using the left and -right arrow keys to move focus to the previous and next buttons. The `wrap` option is -used to make focus wrap around when it reaches the first or last button. - -```tsx example -import {useFocusManager} from '@react-aria/focus'; - -function Toolbar(props) { - return ( -
- - {props.children} - -
- ); -} - -function ToolbarButton(props) { - let focusManager = useFocusManager(); - let onKeyDown = (e) => { - switch (e.key) { - case 'ArrowRight': - focusManager.focusNext({wrap: true}); - break; - case 'ArrowLeft': - focusManager.focusPrevious({wrap: true}); - break; - } - }; - - return ( - - ); -} - - - Cut - Copy - Paste - -``` diff --git a/packages/@react-aria/focus/docs/useFocusRing.mdx b/packages/@react-aria/focus/docs/useFocusRing.mdx deleted file mode 100644 index 7aa14e0d4c5..00000000000 --- a/packages/@react-aria/focus/docs/useFocusRing.mdx +++ /dev/null @@ -1,88 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/focus'; -import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/focus/package.json'; - ---- -category: Focus -keywords: [focus ring, keyboard focus, focus management, aria] ---- - -# useFocusRing - -{docs.exports.useFocusRing.description} - - - -## API - - - -## Introduction - -The `useFocusRing` hook returns whether a focus ring should be displayed to indicate keyboard focus for a component. -This helps keyboard users determine which element on a page or in an application has keyboard focus as they -navigate around. Focus rings are only visible when interacting with a keyboard so as not to distract mouse -and touch screen users. - -If CSS classes are being used for styling, see the [FocusRing](FocusRing.html) component for a shortcut. - -## Options - - - - - -## Result - - - - - -## Example - -This example shows how to use `useFocusRing` to adjust styling when keyboard focus is on a button. -Specifically, the `outline` property is used to create the focus ring when `isFocusVisible` is true. - -See [useCheckbox](useCheckbox.html#styling), [useRadioGroup](useRadioGroup.html#styling), and -[useSwitch](useSwitch.html#example) for more advanced examples of focus rings with other styling -techniques. - -```tsx example -import {useFocusRing} from '@react-aria/focus'; - -function Example() { - let {isFocusVisible, focusProps} = useFocusRing(); - - return ( - - ); -} -``` diff --git a/packages/@react-aria/gridlist/docs/useGridList.mdx b/packages/@react-aria/gridlist/docs/useGridList.mdx index 92fe5bde2ad..4bdd7cfe819 100644 --- a/packages/@react-aria/gridlist/docs/useGridList.mdx +++ b/packages/@react-aria/gridlist/docs/useGridList.mdx @@ -59,9 +59,9 @@ HTML lists are meant for static content, rather than lists with rich interaction * **Async loading** – Support for loading items asynchronously, with infinite and virtualized scrolling. * **Keyboard navigation** – List items and focusable children can be navigated using the arrow keys, along with page up/down, home/end, etc. Typeahead, auto scrolling, and selection modifier keys are supported as well. * **Touch friendly** – Selection and actions adapt their behavior depending on the device. For example, selection is activated via long press on touch when item actions are present. -* **Accessible** – Follows the [ARIA grid pattern](https://www.w3.org/WAI/ARIA/apg/patterns/grid/), with additional selection announcements via an ARIA live region. Extensively tested across many devices and [assistive technologies](accessibility.html#testing) to ensure announcements and behaviors are consistent. +* **Accessible** – Follows the [ARIA grid pattern](https://www.w3.org/WAI/ARIA/apg/patterns/grid/), with additional selection announcements via an ARIA live region. Extensively tested across many devices and [assistive technologies](../quality#supported-screen-readers) to ensure announcements and behaviors are consistent. -**Note**: Use `useGridList` when your list items may contain interactive elements such as buttons, checkboxes, menus, etc. within them. If your list items contain only static content such as text and images, then consider using [useListBox](useListBox.html) instead for a slightly better screen reader experience (especially on mobile). +**Note**: Use `useGridList` when your list items may contain interactive elements such as buttons, checkboxes, menus, etc. within them. If your list items contain only static content such as text and images, then consider using [useListBox](../ListBox/useListBox.html) instead for a slightly better screen reader experience (especially on mobile). ## Anatomy @@ -100,18 +100,17 @@ interface, which is a generic interface to access sequential unique keyed data. implement this interface yourself, e.g. by using a prop to pass a list of item objects, but from `@react-stately/list` implements a JSX based interface for building collections instead. -See [Collection Components](/react-stately/collections.html) for more information, -and [Collection Interface](/react-stately/Collection.html) for internal details. +See [Collection Components](v3:collections.html) for more information. In addition, manages the state necessary for multiple selection and exposes a , which makes use of the collection to provide an interface to update the selection state. -For more information, see [Selection](/react-stately/selection.html). +For more information, see [Selection](v3:selection.html). ## Example -Lists are [collection components](../react-stately/collections.html) that include rows as child elements. +Lists are [collection components](v3:collections.html) that include rows as child elements. In this example, we'll use the standard HTML unordered list elements along with hooks from React Aria for each child. You may also use other elements like `
` to render these components as appropriate. We'll walk through creating the list container and list item, then add some additional behavior such as selection. @@ -314,7 +313,7 @@ examples of how to use the List component that we've built. ### Checkbox -The `Checkbox` component is used in the above example for row selection. It is built using the [useCheckbox](useCheckbox.html) hook, and can be shared with many other components. +The `Checkbox` component is used in the above example for row selection. It is built using the [useCheckbox](../Checkbox/useCheckbox.html) hook, and can be shared with many other components.
Show code @@ -338,7 +337,7 @@ function Checkbox(props) { ### Button -The `Button` component is used in the above example to show how rows can contain interactive elements. It is built using the [useButton](useButton.html) hook, and can be shared with many other components. +The `Button` component is used in the above example to show how rows can contain interactive elements. It is built using the [useButton](../Button/useButton.html) hook, and can be shared with many other components.
Show code @@ -506,11 +505,11 @@ Items in a GridList may also be links to another page or website. This can be ac #### Client side routing -The `` component works with frameworks and client side routers like [Next.js](https://nextjs.org/) and [React Router](https://reactrouter.com/en/main). As with other React Aria components that support links, this works via the component at the root of your app. See the [client side routing guide](routing.html) to learn how to set this up. +The `` component works with frameworks and client side routers like [Next.js](https://nextjs.org/) and [React Router](https://reactrouter.com/en/main). As with other React Aria components that support links, this works via the component at the root of your app. See the [framework setup guide](../frameworks) to learn how to set this up. ### Asynchronous loading -This example uses the [useAsyncList](../react-stately/useAsyncList.html) hook to handle asynchronous loading of data from a server. You may additionally want to display a spinner to indicate the loading state to the user, or support features like infinite scroll to load more data. +This example uses the [useAsyncList](../useAsyncList.html) hook to handle asynchronous loading of data from a server. You may additionally want to display a spinner to indicate the loading state to the user, or support features like infinite scroll to load more data. ```tsx example import {useAsyncList} from '@react-stately/data'; diff --git a/packages/@react-aria/i18n/docs/I18nProvider.mdx b/packages/@react-aria/i18n/docs/I18nProvider.mdx deleted file mode 100644 index 15572f2f390..00000000000 --- a/packages/@react-aria/i18n/docs/I18nProvider.mdx +++ /dev/null @@ -1,49 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/i18n'; -import {HeaderInfo, TypeContext, PropTable, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/i18n/package.json'; - ---- -category: Internationalization -keywords: [i18n, provider, aria, locale, localization] ---- - -# I18nProvider - -{docs.exports.I18nProvider.description} - - - -## Introduction - -`I18nProvider` allows you to override the default locale as determined by the browser/system setting -with a locale defined by your application (e.g. application setting). This should be done by wrapping -your entire application in the provider, which will be cause all child elements to receive the new locale -information via [useLocale](useLocale.html). - -## Props - - - -## Example - -```tsx -import {I18nProvider} from '@react-aria/i18n'; - - - - -``` diff --git a/packages/@react-aria/i18n/docs/internationalization.mdx b/packages/@react-aria/i18n/docs/internationalization.mdx deleted file mode 100644 index 7a8f0968077..00000000000 --- a/packages/@react-aria/i18n/docs/internationalization.mdx +++ /dev/null @@ -1,268 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import {HeaderInfo, PropTable, TypeLink} from '@react-spectrum/docs'; - ---- -category: Concepts -keywords: [i18n, aria, localization, locale] ---- - -# Internationalization - -Adapting components to respect languages and cultures of users around the world is an important way to help make your -application accessible to the widest number of people. React Aria supports over 30 languages, including -right-to-left mirroring and interactions. - -## Introduction - -Internationalization is the process of structuring your code and user interface to support localization. React Aria supports -many aspects of localization for many components out of the box, including translations for builtin strings, localized -date and number formatting, right-to-left interactions, and more. By using React Aria to build your components, -these aspects of internationalization are handled for you. You can also use our hooks in your own custom components. - -## Localization - -Localization is the process of adapting an application for a particular language or region. It includes translating text content, -as well as adapting date formatting, number formatting, collation and sorting, text search, and more. - -React Aria includes translations for all builtin strings in over 30 locales. However, because React Aria provides no rendering, -most of the builtin strings are for non-visible content to provide accessible labels. All application provided content must be localized -and passed in to components. This can be done with libraries such as [react-intl](https://formatjs.io/docs/react-intl). -Internally, React Aria uses the same [intl-messageformat](https://formatjs.io/docs/intl-messageformat) library used by react-intl. - -React Aria also formats, parses, and manipulates dates and numbers according to the user's preferred locale, and uses internationalized algorithms -for collation, sorting, and text search. This is built into all of the components that need to perform these tasks out of the box, but you can -also use our internationalization hooks in your own components. These are implemented with the builtin browser -[Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) APIs under the hood, so there's no -large libraries or locale data for users to download. - -See [useDateFormatter](useDateFormatter.html), [useNumberFormatter](useNumberFormatter.html), -and [useCollator](useCollator.html) for more information about using our internationalization hooks. The -[Internationalized](../../internationalized/index.html) collection of libraries provides framework-agnostic utilities for representing -and manipulating [dates and times](../../internationalized/date/index.html), and parsing and formatting -[numbers](../../internationalized/number/index.html) across many locales, calendar systems, numbering systems, and more. - -## Bi-directionality - -Many languages such as those written in the Latin script (e.g. English and French), Cyrillic script (e.g. Russian and Bulgarian), and -logographic scripts (e.g. Chinese and Japanese) are written left to right. Other languages such as Arabic and Hebrew are written -right to left. These languages are called β€œbi-directional,” or are also commonly referred to as β€œRTL” (β€œright-to-left”) languages. - -In right-to-left languages, user interfaces are expected to be **mirrored**. Layouts flip such that components are positioned on the -opposite side of the interface. For example, a button that would be displayed on the right side of a screen in a left-to-right language -would appear on the left side of the screen in a right-to-left language. In addition, elements within a component are also expected to -mirror. For example, in a checkbox component, the label would be placed on the left side of the checkmark rather than the right. - -Since React Aria provides no styling, it is up to you to implement RTL support in your design. CSS flex and grid layouts automatically flip depending -on the direction, and [logical properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties) are a great way to handle -margins, paddings, borders, and more. - -Even though it is not responsible for rendering or layout, React Aria is aware of the current directionality, and adjusts interactions -accordingly. For example, when navigating using the left and right arrow keys, React Aria automatically flips the direction so that -the left arrow always navigates to the item physically to the left, and the right arrow always navigates to the item physically to the right. - -## Example - -The root most element of your application should define the [lang](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang) -and [dir](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir) attributes so that the browser knows which language -and direction the user interface should be rendered in. This can be done with the [useLocale](useLocale.html) hook. - -```tsx -import {useLocale} from 'react-aria-components'; - -function YourApp() { - let {locale, direction} = useLocale(); - - return ( -
- {/* your app here */} -
- ); -} -``` - -React Aria automatically detects the user's current language by default, and even updates this if the browser or system language changes. -However, if you would like to override this with an application specific setting, you can do so using the [I18nProvider](I18nProvider.html) -component. - -```tsx -import {I18nProvider} from 'react-aria-components'; - - - - -``` - -**Note:** if you are using server side rendering, you should always specify a locale rather than relying on browser defaults -to ensure that the server and client match. See the [SSR docs](ssr.html#internationalization) for more information. - -## Supported locales - -React Aria currently includes translations for over 30 locales. They are listed below. - -
- -* Arabic (United Arab Emirates) -* Bulgarian (Bulgaria) -* Chinese (Simplified) -* Chinese (Traditional) -* Croatian (Croatia) -* Czech (Czech Republic) -* Danish (Denmark) -* Dutch (Netherlands) -* English (Great Britain) -* English (United States) -* Estonian (Estonia) -* Finnish (Finland) -* French (Canada) -* French (France) -* German (Germany) -* Greek (Greece) -* Hebrew (Israel) -* Hungarian (Hungary) -* Italian (Italy) -* Japanese (Japan) -* Korean (Korea) -* Latvian (Latvia) -* Lithuanian (Lithuania) -* Norwegian (Norway) -* Polish (Poland) -* Portuguese (Brazil) -* Romanian (Romania) -* Russian (Russia) -* Serbian (Serbia) -* Slovakian (Slovakia) -* Slovenian (Slovenia) -* Spanish (Spain) -* Swedish (Sweden) -* Turkish (Turkey) -* Ukrainian (Ukraine) - -
- -## Optimizing bundle size - -By default, React Aria includes translations for all of the languages listed above. This is inclusive to the most users out of the box, but comes at the cost of bundle size. If your application does not support all of these locales, you can use our build plugins to include only the languages that you do support in your JavaScript bundle. - -**Note**: If you are using server side rendering, you can also optimize this even further by sending only the strings for the current user's language. See the [SSR docs](ssr.html) for more details. - -### webpack - -First, install `@react-aria/optimize-locales-plugin` with your package manager. Then, add the following to your `webpack.config.js` and change the `locales` setting accordingly: - -```ts -// webpack.config.js -const optimizeLocales = require('@react-aria/optimize-locales-plugin'); - -module.exports = { - // ... - plugins: [ - optimizeLocales.webpack({ - locales: ['en-US', 'fr-FR'] - }) - ] -}; -``` - -### Next.js - -First, install `@react-aria/optimize-locales-plugin` with your package manager. Then, add the following to your `next.config.js` and change the `locales` setting accordingly: - -```ts -// next.config.js -const optimizeLocales = require('@react-aria/optimize-locales-plugin'); - -module.exports = { - webpack(config) { - config.plugins.push( - optimizeLocales.webpack({ - locales: ['en-US', 'fr-FR'] - }) - ); - return config; - } -}; -``` - -### Vite - -First, install `@react-aria/optimize-locales-plugin` with your package manager. Then, add the following to your `vite.config.js` and change the `locales` setting accordingly: - -```ts -// vite.config.js -import optimizeLocales from '@react-aria/optimize-locales-plugin'; - -export default { - plugins: [ - { - ...optimizeLocales.vite({ - locales: ['en-US', 'fr-FR'] - }), - enforce: 'pre' - } - ] -}; -``` - -### Rollup - -First, install `@react-aria/optimize-locales-plugin` with your package manager. Then, add the following to your `rollup.config.js` and change the `locales` setting accordingly: - -```ts -// rollup.config.js -import optimizeLocales from '@react-aria/optimize-locales-plugin'; - -export default { - plugins: [ - optimizeLocales.rollup({ - locales: ['en-US', 'fr-FR'] - }) - ] -}; -``` - -### Esbuild - -First, install `@react-aria/optimize-locales-plugin` with your package manager. Then, add the following to your esbuild script and change the `locales` setting accordingly: - -```ts -import {build} from 'esbuild'; -import optimizeLocales from '@react-aria/optimize-locales-plugin'; - -build({ - plugins: [ - optimizeLocales.esbuild({ - locales: ['en-US', 'fr-FR'] - }) - ] -}); -``` - -### Parcel - -First, install `@react-aria/parcel-resolver-optimize-locales` with your package manager. Then, add the following to your `.parcelrc`: - -```json -{ - "extends": "@parcel/config-default", - "resolvers": ["@react-aria/parcel-resolver-optimize-locales", "..."] -} -``` - -Then, in your project root `package.json`, add a `"locales"` field containing the languages you want to support: - -```json -{ - "locales": ["en-US", "fr-FR"] -} -``` diff --git a/packages/@react-aria/i18n/docs/useCollator.mdx b/packages/@react-aria/i18n/docs/useCollator.mdx deleted file mode 100644 index 84f452c3beb..00000000000 --- a/packages/@react-aria/i18n/docs/useCollator.mdx +++ /dev/null @@ -1,81 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/i18n'; -import {ClassAPI, HeaderInfo, TypeContext, FunctionAPI, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/i18n/package.json'; - ---- -category: Internationalization -keywords: [collator, i18n, aria, localization] ---- - -# useCollator - -{docs.exports.useCollator.description} - - - -## Introduction - -`useCollator` wraps a builtin browser [Intl.Collator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator) -object to provide a React Hook that integrates with the i18n system in React Aria. It handles string comparison according to the current locale, -updating when the locale changes, and caching of collators for performance. See the -[Intl.Collator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator) docs for -information. - -## API - - - -## Example - -This example includes two textfields and compares the values of the two fields using a collator according to the current locale. - -```tsx example -import {useCollator} from '@react-aria/i18n'; - -function Example() { - let [first, setFirst] = React.useState(''); - let [second, setSecond] = React.useState(''); - - let collator = useCollator(); - let result = collator.compare(first, second); - - return ( - <> -
- - setFirst(e.target.value)} /> - - setSecond(e.target.value)} /> -
-

- {result === 0 - ? 'The strings are the same' - : result < 0 - ? 'First comes before second' - : 'Second comes before first' - } -

- - ); -} -``` diff --git a/packages/@react-aria/i18n/docs/useDateFormatter.mdx b/packages/@react-aria/i18n/docs/useDateFormatter.mdx deleted file mode 100644 index 8e9162cac5a..00000000000 --- a/packages/@react-aria/i18n/docs/useDateFormatter.mdx +++ /dev/null @@ -1,66 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/i18n'; -import {ClassAPI, HeaderInfo, TypeContext, FunctionAPI, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/i18n/package.json'; - ---- -category: Internationalization -keywords: [date, time, i18n, aria, localization] ---- - -# useDateFormatter - -{docs.exports.useDateFormatter.description} - - - -## Introduction - -`useDateFormatter` wraps a builtin browser [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat) -object to provide a React Hook that integrates with the i18n system in React Aria. It handles formatting dates for the current locale, -updating when the locale changes, and caching of date formatters for performance. See the -[Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat) docs for -information on formatting options. - -## API - - - -## Example - -This example displays the current date for two locales: USA, and Russia. Two instances of the `CurrentDate` component are rendered, -using the [I18nProvider](I18nProvider.html) to specify the locale to display. - -```tsx example -import {I18nProvider, useDateFormatter} from '@react-aria/i18n'; - -function CurrentDate() { - let formatter = useDateFormatter(); - - return ( -

{formatter.format(new Date())}

- ); -} - -<> - - - - - - - -``` diff --git a/packages/@react-aria/i18n/docs/useFilter.mdx b/packages/@react-aria/i18n/docs/useFilter.mdx deleted file mode 100644 index 8e427d57df9..00000000000 --- a/packages/@react-aria/i18n/docs/useFilter.mdx +++ /dev/null @@ -1,89 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/i18n'; -import {ClassAPI, HeaderInfo, TypeContext, FunctionAPI, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/i18n/package.json'; - ---- -category: Internationalization -keywords: [filter, search, string match, i18n, aria, localization] ---- - -# useFilter - -{docs.exports.useFilter.description} - - - -## Introduction - -`useFilter` provides functions for filtering or searching based on substring matches. The builtin JavaScript -string methods `startsWith`, `endsWith`, and `includes` could be used for this, but do not implement locale -sensitive matching. `useFilter` provides options to allow ignoring case, diacritics, and Unicode normalization forms, -which are implemented according to locale-specific rules. It automatically uses the current locale set by the application, -either via the default browser language or via the [I18nProvider](I18nProvider.html). - -## API - - - -## Interface - - - -## Example - -The following example implements a filterable list using a `contains` matching strategy that ignores both case -and diacritics. - -```tsx example -import {useFilter} from '@react-aria/i18n'; - -function Example() { - const composers = [ - 'Wolfgang Amadeus Mozart', - 'Johann Sebastian Bach', - 'Ludwig van Beethoven', - 'Claude Debussy', - 'George Frideric Handel', - 'FrΓ©dΓ©ric Chopin', - 'Johannes Brahms', - 'Pyotr Ilyich Tchaikovsky', - 'AntonΓ­n DvoΕ™Γ‘k', - 'Felix Mendelssohn', - 'BΓ©la BartΓ³k', - 'NiccolΓ² Paganini' - ]; - - let {contains} = useFilter({ - sensitivity: 'base' - }); - - let [value, setValue] = React.useState(''); - let matchedComposers = composers.filter(composer => contains(composer, value)); - - return ( - <> - - setValue(e.target.value)} /> -
    - {matchedComposers.map((composer, i) => -
  • {composer}
  • ) - } -
- - ); -} -``` diff --git a/packages/@react-aria/i18n/docs/useLocale.mdx b/packages/@react-aria/i18n/docs/useLocale.mdx deleted file mode 100644 index 61e90c08e30..00000000000 --- a/packages/@react-aria/i18n/docs/useLocale.mdx +++ /dev/null @@ -1,63 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/i18n'; -import {ClassAPI, HeaderInfo, TypeContext, FunctionAPI, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/i18n/package.json'; - ---- -category: Internationalization -keywords: [locale, i18n, aria, localization] ---- - -# useLocale - -{docs.exports.useLocale.description} - - - -## Introduction - -`useLocale` allows components to access the current locale and interface layout direction. -By default, this is automatically detected based on the browser or system language, but it can -be overridden by using the [I18nProvider](I18nProvider.html) at the root of your app. - -`useLocale` should be used in the root of your app to define the -[lang](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang) -and [dir](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir) attributes -so that the browser knows which language and direction the user interface should be rendered in. - -## API - - - -## Interface - - - -## Example - -```tsx -import {useLocale} from '@react-aria/i18n'; - -function YourApp() { - let {locale, direction} = useLocale(); - - return ( -
- {/* your app here */} -
- ); -} -``` diff --git a/packages/@react-aria/i18n/docs/useNumberFormatter.mdx b/packages/@react-aria/i18n/docs/useNumberFormatter.mdx deleted file mode 100644 index 1a8dcb3c559..00000000000 --- a/packages/@react-aria/i18n/docs/useNumberFormatter.mdx +++ /dev/null @@ -1,70 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/i18n'; -import {ClassAPI, HeaderInfo, TypeContext, FunctionAPI, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/i18n/package.json'; - ---- -category: Internationalization -keywords: [number, i18n, aria, localization] ---- - -# useNumberFormatter - -{docs.exports.useNumberFormatter.description} - - - -## Introduction - -`useNumberFormatter` wraps a builtin browser [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) -object to provide a React Hook that integrates with the i18n system in React Aria. It handles formatting numbers for the current locale, -updating when the locale changes, and caching of number formatters for performance. See the -[Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) docs for -information on formatting options. - -## API - - - -## Example - -This example displays a currency value for two locales: USA, and Germany. Two instances of the `Currency` component are rendered, -using the [I18nProvider](I18nProvider.html) to specify the locale to display. - -```tsx example -import {I18nProvider, useNumberFormatter} from '@react-aria/i18n'; - -function Currency({value, currency}) { - let formatter = useNumberFormatter({ - style: 'currency', - currency, - minimumFractionDigits: 0 - }); - - return ( -

{formatter.format(value)}

- ); -} - -<> - - - - - - - -``` diff --git a/packages/@react-aria/interactions/docs/interactions.mdx b/packages/@react-aria/interactions/docs/interactions.mdx deleted file mode 100644 index b037d5dc41a..00000000000 --- a/packages/@react-aria/interactions/docs/interactions.mdx +++ /dev/null @@ -1,115 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import {HeaderInfo, PropTable, TypeLink} from '@react-spectrum/docs'; -import {Keyboard} from '@react-spectrum/text'; - ---- -category: Concepts -keywords: [aria, focus behavior, keyboard event, mouse event, pointer event, assistive technology] ---- - -# Interactions - -High quality interactions that work across a wide variety of devices are essential to a great user experience. -React Aria implements hooks for cross-device interactions that ensure consistent behavior across browsers and platforms. - -## Introduction - -Building high quality interactions that work across a wide variety of devices and platforms is very difficult today. -The web runs across an extremely wide variety of devices and platforms: desktop, mobile, TVs, cars, even refrigerators. -This extends to interaction models too: the web supports mouse, touch, keyboard, gamepads, screen readers, and more. - -Unfortunately, the web platform doesn't have any high level abstractions across these interaction models. There's no -high level gesture events, or even the concept of a β€œpress” event that works across all of these interaction models. -We just have low level events like mouse, touch, keyboard, and focus events, and it's up to developers to put them -together properly. This leads to many web apps not working consistently across various types of devices and interaction models. - -React Aria includes a collection of [Hooks](https://react.dev/reference/react/hooks) that provide higher level abstractions -over the low level events exposed by the web platform, and helps normalize the behavior across browsers and devices. This includes -support for high level events like β€œpress”, β€œhover”, and β€œfocus”. Some of these seem simple at first, but you’d be surprised how -complicated it is to handle these events in a cross-browser, cross-device way. There are many tiny behavioral -differences that have a big impact on how well components work across all of these platforms. - -## Pointer events - -The web was originally designed for mouse events. Later, when touch devices were introduced, browsers added support for -touch events. However, since existing web apps had not been designed with touch in mind, browsers needed to emulate -mouse events on touch devices to ensure some compatibility with them. - -Touch input is quite different than mouse input though. For example, it is possible to hover over an element with a mouse, -but not with touch. But since existing apps designed for mouse input have hover only effects, browsers emulate hover events -on touch devices. Touching an element once fires `onMouseEnter` and touching it again fires `onMouseLeave`. On one hand this is -good because it means the functionality is accessible to users on touch devices, but on the other hand, it's not a great experience. - -Mobile browsers also support many types of gestures by default, e.g. double tap to zoom, scrolling, and long press to select text. -Because of this, touch devices often delay firing events like `onClick` in order to first determine if the user intends to zoom or -scroll the page. In the context of a highly interactive web application, this leads to a sub-optimal user experience. - -The new [pointer events](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events) spec helps simplify handling events -across mouse, touch, and stylus/pen interaction models. React Aria uses pointer events where available with fallbacks on older -devices to mouse and touch events. It normalizes many cross-browser behavioral differences, and ensures that all browsers and -platforms behave consistently. In addition, React Aria supports additional interaction models like keyboard and focus events -to ensure that all users can interact with your app, not just mouse and touchscreen users. - -CSS pseudo classes like `:hover` and `:active` are also problematic in many cases, especially on hybrid devices that support -both mouse and touch. They also emulate mouse behavior on touch devices, e.g. showing hover effects when you touch elements. -It's best to use JavaScript events that apply CSS styles rather than these pseudo classes for the best cross-device experience. - -See [usePress](usePress.html) and [useHover](useHover.html) for more details about React Aria's hooks for cross device -interactions. - -## Keyboard and focus behavior - -Keyboard and focus support is important to allow users to navigate your app with a keyboard. This is imperative for users -who are unable to physically use a mouse or touch screen, but also nice for power users who may find it faster to navigate -parts of your app without lifting their hands from the keyboard. - -At a high level, keyboard navigation is broken up into **tab stops**, which may be navigated by pressing the Tab key to -move to the next tab stop, and Shift + Tab to move to the previous tab stop. A tab stop may be an atomic -component like a text field or button, or a composite component like a listbox, radio group, grid, or toolbar. Composite components -behave as a single tab stop. Elements within a composite component are typically navigated with the arrow keys, while the Tab -key continues to navigate to the next/previous tab stop. React Aria implements many of these composite components and handles -all of the keyboard navigation behavior for elements inside them. - -Overlay elements like dialogs, popovers, and menus have additional focus behavior to ensure that focus stays within them while they -are open, and focus is restored back to the element that opened them when they are closed. In React Aria this is implemented by -the [FocusScope](FocusScope.html) component. - -Another important feature for keyboard users is a **focus ring**. This is a visual affordance for the currently focused element, which -allows a keyboard user to know which element they are currently on. It should only be visible when navigating with a keyboard, so as -not to distract mouse and touchscreen users. This can be implemented using the [useFocusRing](useFocusRing.html) hook or the -[FocusRing](FocusRing.html) component. The [useFocusVisible](useFocusVisible.html) hook can also be used to determine whether -the user is currently navigating with a keyboard or not. - -## Assistive technology - -An assistive technology, such as a screen reader, relies on semantic information exposed to the browser through ARIA or native HTML element -semantics. This allows it to know what an element represents and relay this information to the user. As a screen reader or other -assistive technology navigates around an application, it may fire various JavaScript events. Since screen readers are navigating -the app in a completely different way than traditional mouse, touch, or keyboard behavior, these events are emulated by a -screen reader. It may focus elements, fire click events to activate them, or otherwise emulate mouse and keyboard events. - -React Aria is careful to handle events fired by assistive technology, and normalizes this behavior as needed so it is consistent -with other interactions. For example, while we use pointer events for mouse and touch interactions, many screen readers do not -fire these events at all, instead only firing `onClick`. React Aria handles this and simulates press start and press end events -so that components receive a consistent stream of events regardless of the interaction model. - -## Supported browsers and platforms - -All React Aria components are tested across a wide variety of browsers and devices. We test across devices with -mouse input, touchscreens, and also hybrid devices. - -* Chrome on macOS, Windows, and Android -* Firefox on macOS and Windows -* Safari on macOS, iOS, and iPadOS -* Edge on Windows diff --git a/packages/@react-aria/interactions/docs/useFocus.mdx b/packages/@react-aria/interactions/docs/useFocus.mdx deleted file mode 100644 index 6894325dd76..00000000000 --- a/packages/@react-aria/interactions/docs/useFocus.mdx +++ /dev/null @@ -1,98 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/interactions'; -import typesDocs from 'docs:@react-types/shared/src/events.d.ts'; -import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/interactions/package.json'; - ---- -category: Interactions -keywords: [keyboard focus, focus management, focus pseudo class, aria] ---- - -# useFocus - -{docs.exports.useFocus.description} - - - -## API - - - -## Features - -`useFocus` handles focus interactions for an element. Unlike React's built-in focus events, -`useFocus` does not fire focus events for child elements of the target. This matches DOM -behavior where focus events do not bubble. This is similar to -the [:focus](https://developer.mozilla.org/en-US/docs/Web/CSS/:focus) pseudo class -in CSS. - -To handle focus events on descendants of an element, see [useFocusWithin](useFocusWithin.html). - -## Usage - -`useFocus` returns props that you should spread onto the target element: - - - - - -`useFocus` supports the following event handlers: - - - - - -## Example - -This example shows a simple input element that handles focus events with `useFocus` and logs them to a list below. - -**NOTE: for more advanced text field functionality, see [useTextField](useTextField.html).** - -```tsx example -import {useFocus} from '@react-aria/interactions'; - -function Example() { - let [events, setEvents] = React.useState([]); - let {focusProps} = useFocus({ - onFocus: e => setEvents( - events => [...events, 'focus'] - ), - onBlur: e => setEvents( - events => [...events, 'blur'] - ), - onFocusChange: isFocused => setEvents( - events => [...events, `focus change: ${isFocused}`] - ) - }); - - return ( - <> - - -
    - {events.map((e, i) =>
  • {e}
  • )} -
- - ); -} -``` diff --git a/packages/@react-aria/interactions/docs/useFocusVisible.mdx b/packages/@react-aria/interactions/docs/useFocusVisible.mdx deleted file mode 100644 index 3973ea4dda2..00000000000 --- a/packages/@react-aria/interactions/docs/useFocusVisible.mdx +++ /dev/null @@ -1,76 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/interactions'; -import typesDocs from 'docs:@react-types/shared/src/events.d.ts'; -import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/interactions/package.json'; - ---- -category: Interactions -keywords: [keyboard focus, focus management, focus ring, focus visibility, aria] ---- - -# useFocusVisible - -{docs.exports.useFocusVisible.description} - - - -## API - - - -## Features - -`useFocusVisible` handles focus interactions for the page and determines whether keyboard focus -should be visible (e.g. with a focus ring). Focus visibility is computed based on the current -interaction mode of the user. When the user interacts via a mouse or touch, then focus is not -visible. When the user interacts via a keyboard or screen reader, then focus is visible. This is similar to -the [:focus-visible](https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible) pseudo class -in CSS. - -To determine whether a focus ring should be visible for an individual component rather than -globally, see [useFocusRing](useFocusRing.html). - -## Example - -This example shows focus visible state and updates as you interact with the page. By default, -when the page loads, it is true. If you press anywhere on the page with a mouse or touch, -then focus visible state is set to false. If you keyboard navigate around the page then -it is set to true again. - -Note that this example uses the `isTextInput` option so that only certain navigation keys -cause focus visible state to appear. This prevents focus visible state from appearing when -typing text in a text field. - -```tsx example -import {useFocusVisible} from '@react-aria/interactions'; - -function Example() { - let {isFocusVisible} = useFocusVisible({isTextInput: true}); - - return ( - <> -
Focus visible: {String(isFocusVisible)}
- - - - ); -} -``` diff --git a/packages/@react-aria/interactions/docs/useFocusWithin.mdx b/packages/@react-aria/interactions/docs/useFocusWithin.mdx deleted file mode 100644 index c56f248404c..00000000000 --- a/packages/@react-aria/interactions/docs/useFocusWithin.mdx +++ /dev/null @@ -1,114 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/interactions'; -import typesDocs from 'docs:@react-types/shared/src/events.d.ts'; -import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/interactions/package.json'; - ---- -category: Interactions -keywords: [keyboard focus, focus management, focus ring, focus descendant, aria] ---- - -# useFocusWithin - -{docs.exports.useFocusWithin.description} - - - -## API - - - -## Features - -`useFocusWithin` handles focus interactions for an element and its descendants. Focus is "within" -an element when either the element itself or a descendant element has focus. This is similar to -the [:focus-within](https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-within) pseudo class -in CSS. - -To handle focus events on only the target element, and not descendants, see [useFocus](useFocus.html). - -## Usage - -`useFocusWithin` returns props that you should spread onto the target element: - - - - - -`useFocusWithin` supports the following event handlers: - -{/* filter props to only include events... */} - - prop.value.type === 'function'))} /> - - -## Example - -This example shows two text fields inside a div, which handles focus within events. It stores focus -within state in local component state, which is updated by an `onFocusWithinChange` handler. This is used -to update the background color and text color of the group while one of the text fields has focus. - -Focus within and blur within events are also logged to the list below. Notice that the events are only -fired when the wrapper gains and loses focus, not when focus moves within the group. - -**NOTE: for more advanced text field functionality, see [useTextField](useTextField.html).** - -```tsx example -import {useFocusWithin} from '@react-aria/interactions'; - -function Example() { - let [events, setEvents] = React.useState([]); - let [isFocusWithin, setFocusWithin] = React.useState(false); - let {focusWithinProps} = useFocusWithin({ - onFocusWithin: e => setEvents( - events => [...events, 'focus within'] - ), - onBlurWithin: e => setEvents( - events => [...events, 'blur within'] - ), - onFocusWithinChange: isFocusWithin => setFocusWithin(isFocusWithin) - }); - - return ( - <> -
- - -
-
    - {events.map((e, i) =>
  • {e}
  • )} -
- - ); -} -``` diff --git a/packages/@react-aria/interactions/docs/useHover.mdx b/packages/@react-aria/interactions/docs/useHover.mdx deleted file mode 100644 index 94d78dc120a..00000000000 --- a/packages/@react-aria/interactions/docs/useHover.mdx +++ /dev/null @@ -1,126 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/interactions'; -import typesDocs from 'docs:@react-types/shared/src/events.d.ts'; -import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/interactions/package.json'; - ---- -category: Interactions -keywords: [pointer hover, point events, hover events, aria] ---- - -# useHover - -{docs.exports.useHover.description} - - - -## API - - - -## Features - -`useHover` handles hover interactions for an element. A hover interaction begins when a user moves their pointer -over an element, and ends when they move their pointer off of the element. - -* Uses pointer events where available, with fallbacks to mouse and touch events -* Ignores emulated mouse events in mobile browsers - -`useHover` is similar to the [:hover](https://developer.mozilla.org/en-US/docs/Web/CSS/:hover) pseudo class in CSS, -but `:hover` is problematic on touch devices due to mouse emulation in mobile browsers. Depending on the browser -and device, `:hover` may never apply, or may apply continuously until the user touches another element. -`useHover` only applies when the pointer is truly capable of hovering, and emulated mouse events are ignored. - -Read our [blog post](/blog/building-a-button-part-2.html) about the complexities of hover event handling to learn more. - -## Usage - -`useHover` returns props that you should spread onto the target element: - - - - - -`useHover` supports the following event handlers: - - - - - -Each of these handlers is fired with a `HoverEvent`, which exposes information about the target and the -type of event that triggered the interaction. - - - - - -## Accessibility - -Hover interactions should never be the only way to interact with an element because they are not -supported across all devices. Alternative interactions should be provided on touch devices, for -example a long press or an explicit button to tap. - -In addition, even on devices with hover support, users may be using a keyboard or screen reader -to navigate your app, which also do not trigger hover events. Hover interactions should be paired -with focus events in order to expose the content to keyboard users. - -## Example - -This example shows a simple target that handles hover events with `useHover` and logs them to a -list below. It also uses the `isHovered` state to adjust the background -color when the target is hovered. - -```tsx example -import {useHover} from '@react-aria/interactions'; - -function Example() { - let [events, setEvents] = React.useState([]); - let {hoverProps, isHovered} = useHover({ - onHoverStart: e => setEvents( - events => [...events, `hover start with ${e.pointerType}`] - ), - onHoverEnd: e => setEvents( - events => [...events, `hover end with ${e.pointerType}`] - ) - }); - - return ( - <> -
- Hover me! -
-
    - {events.map((e, i) =>
  • {e}
  • )} -
- - ); -} -``` diff --git a/packages/@react-aria/interactions/docs/useKeyboard.mdx b/packages/@react-aria/interactions/docs/useKeyboard.mdx deleted file mode 100644 index 364d36b311c..00000000000 --- a/packages/@react-aria/interactions/docs/useKeyboard.mdx +++ /dev/null @@ -1,94 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/interactions'; -import typesDocs from 'docs:@react-types/shared/src/events.d.ts'; -import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/interactions/package.json'; - ---- -category: Interactions -keywords: [keyboard interactions, keyboard events, aria] ---- - -# useKeyboard - -{docs.exports.useKeyboard.description} - - - -## API - - - -## Features - -`useKeyboard` handles keyboard interactions. The only difference from DOM events is that propagation -is stopped by default if there is an event handler, unless `event.continuePropagation()` is called. -This provides better modularity by default, so that a parent component doesn't respond to an event -that a child already handled. If the child doesn't handle the event (e.g. it was for an unknown key), -it can call `event.continuePropagation()` to allow parents to handle the event. - -## Usage - -`useKeyboard` returns props that you should spread onto the target element: - - - - - -`useKeyboard` supports the following event handlers: - - - - - -## Example - -This example shows a simple input element that handles keyboard events with `useKeyboard` and logs them to a list below. - -**NOTE: for more advanced text field functionality, see [useTextField](useTextField.html).** - -```tsx example -import {useKeyboard} from '@react-aria/interactions'; - -function Example() { - let [events, setEvents] = React.useState([]); - let {keyboardProps} = useKeyboard({ - onKeyDown: e => setEvents( - events => [`key down: ${e.key}`, ...events] - ), - onKeyUp: e => setEvents( - events => [`key up: ${e.key}`, ...events] - ) - }); - - return ( - <> - - -
    - {events.map((e, i) =>
  • {e}
  • )} -
- - ); -} -``` diff --git a/packages/@react-aria/interactions/docs/useLongPress.mdx b/packages/@react-aria/interactions/docs/useLongPress.mdx deleted file mode 100644 index d1e3fa45a4c..00000000000 --- a/packages/@react-aria/interactions/docs/useLongPress.mdx +++ /dev/null @@ -1,127 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/interactions'; -import typesDocs from 'docs:@react-types/shared/src/events.d.ts'; -import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/interactions/package.json'; - ---- -category: Interactions -keywords: [long press interactions, long press events, long press gesture, aria] ---- - -# useLongPress - -{docs.exports.useLongPress.description} - - - -## API - - - -## Features - -`useLongPress` handles long press interactions across both mouse and touch devices. A long press is triggered when a user presses -and holds their pointer over a target for a minimum period of time. If the user moves their pointer off of the target before the -time threshold, the interaction is canceled. Once a long press event is triggered, other pointer interactions that may be active -such as `usePress` and `useMove` will be canceled so that only the long press is activated. - -* Handles mouse and touch events -* Uses pointer events where available, with fallbacks to mouse and touch events -* Ignores emulated mouse events in mobile browsers -* Prevents text selection on touch devices while long pressing -* Prevents browser and OS context menus from appearing while long pressing -* Customizable time threshold for long press -* Supports an accessibility description to indicate to assistive technology users that a long press action is available - -## Usage - -`useLongPress` returns props that you should spread onto the target element: - - - - - -`useLongPress` supports the following event handlers and options: - - - - - -Each of these handlers is fired with a `LongPressEvent`, which exposes information about the target and the -type of event that triggered the interaction. - - - - - -## Example - -This example shows a button that has both a normal press action using [usePress](usePress.html), as well as a long -press action using `useLongPress`. Pressing the button will set the mode to "Normal speed", and long pressing it will -set the mode to "Hyper speed". All of the emitted events are also logged below. Note that when long pressing the button, -only a long press is emitted, and no normal press is emitted on pointer up. - -**Note**: this example does not have a keyboard accessible way to trigger the long press action. Because the method of triggering -this action will differ depending on the component, it is outside the scope of `useLongPress`. Make sure to implement a keyboard -friendly alternative to all long press interactions if you are using this hook directly. - -```tsx example -import {mergeProps} from '@react-aria/utils'; -import {useLongPress, usePress} from '@react-aria/interactions'; - -function Example() { - let [events, setEvents] = React.useState([]); - let [mode, setMode] = React.useState('Activate'); - let {longPressProps} = useLongPress({ - accessibilityDescription: 'Long press to activate hyper speed', - onLongPressStart: e => setEvents( - events => [`long press start with ${e.pointerType}`, ...events] - ), - onLongPressEnd: e => setEvents( - events => [`long press end with ${e.pointerType}`, ...events] - ), - onLongPress: e => { - setMode('Hyper speed'); - setEvents( - events => [`long press with ${e.pointerType}`, ...events] - ); - } - }); - - let {pressProps} = usePress({ - onPress: e => { - setMode('Normal speed'); - setEvents( - events => [`press with ${e.pointerType}`, ...events] - ); - } - }); - - return ( - <> - -
    - {events.map((e, i) =>
  • {e}
  • )} -
- - ); -} -``` diff --git a/packages/@react-aria/interactions/docs/useMove.mdx b/packages/@react-aria/interactions/docs/useMove.mdx deleted file mode 100644 index 1e9a0ac1150..00000000000 --- a/packages/@react-aria/interactions/docs/useMove.mdx +++ /dev/null @@ -1,163 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/interactions'; -import typesDocs from 'docs:@react-types/shared/src/events.d.ts'; -import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, TypeLink, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/interactions/package.json'; - ---- -category: Interactions -keywords: [move interactions, move events, drag, touch, mouse, keyboard, aria] ---- - -# useMove - -{docs.exports.useMove.description} - - - -## API - - - -## Features - -`useMove` handles move interactions across mouse, touch, and keyboard. A move interaction starts when a -user moves after pressing down with a mouse or their finger on the target, and ends when they lift their pointer. Move -events are fired as the pointer moves around, and specify the distance that the pointer traveled since the last -event. In addition, after a user focuses the target element, move events are fired when the user presses the arrow keys. - -* Handles mouse and touch events -* Handles arrow key presses -* Uses pointer events where available, with fallbacks to mouse and touch events -* Ignores emulated mouse events in mobile browsers -* Handles disabling text selection on mobile while the press interaction is active -* Normalizes many cross browser inconsistencies - -## Usage - -`useMove` returns props that you should spread onto the target element: - - - - - -`useMove` supports the following event handlers: - - - - - -Each of these handlers is fired with a `MoveEvent`, which exposes information about the target and the -type of event that triggered the interaction. - - - - - -## Example - -This example shows a ball that can be moved by dragging with a mouse or touch, or by tabbing to it and using -the arrow keys on your keyboard. The movement is clamped so that the ball cannot be dragged outside a box. -In addition, all of the move events are logged below so that you can inspect what is going on. - -```tsx example -import {useMove} from '@react-aria/interactions'; - -function Example() { - const CONTAINER_SIZE = 200; - const BALL_SIZE = 30; - - let [events, setEvents] = React.useState([]); - let [color, setColor] = React.useState('black'); - let [position, setPosition] = React.useState({ - x: 0, - y: 0 - }); - - let clamp = pos => Math.min(Math.max(pos, 0), CONTAINER_SIZE - BALL_SIZE); - let {moveProps} = useMove({ - onMoveStart(e) { - setColor('red'); - setEvents(events => [`move start with pointerType = ${e.pointerType}`, ...events]); - }, - onMove(e) { - setPosition(({x, y}) => { - // Normally, we want to allow the user to continue - // dragging outside the box such that they need to - // drag back over the ball again before it moves. - // This is handled below by clamping during render. - // If using the keyboard, however, we need to clamp - // here so that dragging outside the container and - // then using the arrow keys works as expected. - if (e.pointerType === 'keyboard') { - x = clamp(x); - y = clamp(y); - } - - x += e.deltaX; - y += e.deltaY; - return {x, y}; - }); - - setEvents(events => [`move with pointerType = ${e.pointerType}, deltaX = ${e.deltaX}, deltaY = ${e.deltaY}`, ...events]); - }, - onMoveEnd(e) { - setPosition(({x, y}) => { - // Clamp position on mouse up - x = clamp(x); - y = clamp(y); - return {x, y}; - }); - setColor('black'); - setEvents(events => [`move end with pointerType = ${e.pointerType}`, ...events]); - } - }); - - return ( - <> -
-
-
-
    - {events.map((e, i) =>
  • {e}
  • )} -
- - ); -} -``` diff --git a/packages/@react-aria/interactions/docs/usePress.mdx b/packages/@react-aria/interactions/docs/usePress.mdx deleted file mode 100644 index 548df8e6ecb..00000000000 --- a/packages/@react-aria/interactions/docs/usePress.mdx +++ /dev/null @@ -1,126 +0,0 @@ -{/* Copyright 2020 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/interactions'; -import typesDocs from 'docs:@react-types/shared/src/events.d.ts'; -import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, TypeLink, PageDescription} from '@react-spectrum/docs'; -import {Keyboard} from '@react-spectrum/text'; -import packageData from '@react-aria/interactions/package.json'; - ---- -category: Interactions -keywords: [press interactions, press events, aria] ---- - -# usePress - -{docs.exports.usePress.description} - - - -## API - - - -## Features - -`usePress` handles press interactions across mouse, touch, keyboard, and screen readers. A press interaction starts when a -user presses down with a mouse or their finger on the target, and ends when they move the pointer off the target. It may -start again if the pointer re-enters the target. `usePress` returns the current press state, which can be used to adjust -the visual appearance of the target. If the pointer is released over the target, then an `onPress` event is fired. - -* Handles mouse and touch events -* Handles Enter or Space key presses -* Handles screen reader virtual clicks -* Uses pointer events where available, with fallbacks to mouse and touch events -* Normalizes focus behavior on mouse and touch interactions across browsers -* Handles disabling text selection on mobile while the press interaction is active -* Handles canceling press interactions on scroll -* Normalizes many cross browser inconsistencies - -Read our [blog post](/blog/building-a-button-part-1.html) about the complexities of press event handling to learn more. - -## Usage - -`usePress` returns props that you should spread onto the target element, along with the current press state: - - - - - -`usePress` supports the following event handlers: - - - - - -Each of these handlers is fired with a `PressEvent`, which exposes information about the target and the -type of event that triggered the interaction. - - - - - -## Example - -This example shows a simple target that handles press events with `usePress` and logs them to a list below. -It also uses the `isPressed` state to adjust the background color when the target is pressed. -Press down on the target and drag your pointer off and over to see when the events are fired, and try focusing -the target with a keyboard and pressing the Enter or Space keys to trigger events as well. - -**NOTE: for more advanced button functionality, see [useButton](useButton.html).** - -```tsx example -import {usePress} from '@react-aria/interactions'; - -function Example() { - let [events, setEvents] = React.useState([]); - let {pressProps, isPressed} = usePress({ - onPressStart: e => setEvents( - events => [...events, `press start with ${e.pointerType}`] - ), - onPressEnd: e => setEvents( - events => [...events, `press end with ${e.pointerType}`] - ), - onPress: e => setEvents( - events => [...events, `press with ${e.pointerType}`] - ) - }); - - return ( - <> -
- Press me! -
-
    - {events.map((e, i) =>
  • {e}
  • )} -
- - ); -} -``` diff --git a/packages/@react-aria/label/docs/useField.mdx b/packages/@react-aria/label/docs/useField.mdx deleted file mode 100644 index 5e65fc4eb81..00000000000 --- a/packages/@react-aria/label/docs/useField.mdx +++ /dev/null @@ -1,75 +0,0 @@ -{/* Copyright 2021 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 '@react-spectrum/docs'; -export default Layout; - -import docs from 'docs:@react-aria/label'; -import {FunctionAPI, HeaderInfo, PageDescription} from '@react-spectrum/docs'; -import packageData from '@react-aria/label/package.json'; - ---- -category: Utilities -keywords: [label, form, description, error, field, aria] -after_version: 3.1.3 ---- - -# useField - -{docs.exports.useField.description} - - - -## API - - - -## Example - -The `useField` hook associates a form control with a label, and an optional description and/or error message. This is useful for providing context about how users should fill in a field, or a validation message. `useField` takes care of creating ids for each element and associating them with the correct ARIA attributes (`aria-labelledby` and `aria-describedby`). - -By default, `useField` assumes that the label is a native HTML `