react-aria-components 1.0.0-rc.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/README.md +8 -13
  2. package/dist/ar-AE.main.js +8 -0
  3. package/dist/ar-AE.main.js.map +1 -0
  4. package/dist/ar-AE.mjs +10 -0
  5. package/dist/ar-AE.module.js +10 -0
  6. package/dist/ar-AE.module.js.map +1 -0
  7. package/dist/bg-BG.main.js +8 -0
  8. package/dist/bg-BG.main.js.map +1 -0
  9. package/dist/bg-BG.mjs +10 -0
  10. package/dist/bg-BG.module.js +10 -0
  11. package/dist/bg-BG.module.js.map +1 -0
  12. package/dist/cs-CZ.main.js +8 -0
  13. package/dist/cs-CZ.main.js.map +1 -0
  14. package/dist/cs-CZ.mjs +10 -0
  15. package/dist/cs-CZ.module.js +10 -0
  16. package/dist/cs-CZ.module.js.map +1 -0
  17. package/dist/da-DK.main.js +8 -0
  18. package/dist/da-DK.main.js.map +1 -0
  19. package/dist/da-DK.mjs +10 -0
  20. package/dist/da-DK.module.js +10 -0
  21. package/dist/da-DK.module.js.map +1 -0
  22. package/dist/de-DE.main.js +8 -0
  23. package/dist/de-DE.main.js.map +1 -0
  24. package/dist/de-DE.mjs +10 -0
  25. package/dist/de-DE.module.js +10 -0
  26. package/dist/de-DE.module.js.map +1 -0
  27. package/dist/el-GR.main.js +8 -0
  28. package/dist/el-GR.main.js.map +1 -0
  29. package/dist/el-GR.mjs +10 -0
  30. package/dist/el-GR.module.js +10 -0
  31. package/dist/el-GR.module.js.map +1 -0
  32. package/dist/en-US.main.js +8 -0
  33. package/dist/en-US.main.js.map +1 -0
  34. package/dist/en-US.mjs +10 -0
  35. package/dist/en-US.module.js +10 -0
  36. package/dist/en-US.module.js.map +1 -0
  37. package/dist/es-ES.main.js +8 -0
  38. package/dist/es-ES.main.js.map +1 -0
  39. package/dist/es-ES.mjs +10 -0
  40. package/dist/es-ES.module.js +10 -0
  41. package/dist/es-ES.module.js.map +1 -0
  42. package/dist/et-EE.main.js +8 -0
  43. package/dist/et-EE.main.js.map +1 -0
  44. package/dist/et-EE.mjs +10 -0
  45. package/dist/et-EE.module.js +10 -0
  46. package/dist/et-EE.module.js.map +1 -0
  47. package/dist/fi-FI.main.js +8 -0
  48. package/dist/fi-FI.main.js.map +1 -0
  49. package/dist/fi-FI.mjs +10 -0
  50. package/dist/fi-FI.module.js +10 -0
  51. package/dist/fi-FI.module.js.map +1 -0
  52. package/dist/fr-FR.main.js +8 -0
  53. package/dist/fr-FR.main.js.map +1 -0
  54. package/dist/fr-FR.mjs +10 -0
  55. package/dist/fr-FR.module.js +10 -0
  56. package/dist/fr-FR.module.js.map +1 -0
  57. package/dist/he-IL.main.js +8 -0
  58. package/dist/he-IL.main.js.map +1 -0
  59. package/dist/he-IL.mjs +10 -0
  60. package/dist/he-IL.module.js +10 -0
  61. package/dist/he-IL.module.js.map +1 -0
  62. package/dist/hr-HR.main.js +8 -0
  63. package/dist/hr-HR.main.js.map +1 -0
  64. package/dist/hr-HR.mjs +10 -0
  65. package/dist/hr-HR.module.js +10 -0
  66. package/dist/hr-HR.module.js.map +1 -0
  67. package/dist/hu-HU.main.js +8 -0
  68. package/dist/hu-HU.main.js.map +1 -0
  69. package/dist/hu-HU.mjs +10 -0
  70. package/dist/hu-HU.module.js +10 -0
  71. package/dist/hu-HU.module.js.map +1 -0
  72. package/dist/import.mjs +277 -309
  73. package/dist/it-IT.main.js +8 -0
  74. package/dist/it-IT.main.js.map +1 -0
  75. package/dist/it-IT.mjs +10 -0
  76. package/dist/it-IT.module.js +10 -0
  77. package/dist/it-IT.module.js.map +1 -0
  78. package/dist/ja-JP.main.js +8 -0
  79. package/dist/ja-JP.main.js.map +1 -0
  80. package/dist/ja-JP.mjs +10 -0
  81. package/dist/ja-JP.module.js +10 -0
  82. package/dist/ja-JP.module.js.map +1 -0
  83. package/dist/ko-KR.main.js +8 -0
  84. package/dist/ko-KR.main.js.map +1 -0
  85. package/dist/ko-KR.mjs +10 -0
  86. package/dist/ko-KR.module.js +10 -0
  87. package/dist/ko-KR.module.js.map +1 -0
  88. package/dist/lt-LT.main.js +8 -0
  89. package/dist/lt-LT.main.js.map +1 -0
  90. package/dist/lt-LT.mjs +10 -0
  91. package/dist/lt-LT.module.js +10 -0
  92. package/dist/lt-LT.module.js.map +1 -0
  93. package/dist/lv-LV.main.js +8 -0
  94. package/dist/lv-LV.main.js.map +1 -0
  95. package/dist/lv-LV.mjs +10 -0
  96. package/dist/lv-LV.module.js +10 -0
  97. package/dist/lv-LV.module.js.map +1 -0
  98. package/dist/main.js +271 -301
  99. package/dist/main.js.map +1 -1
  100. package/dist/module.js +277 -309
  101. package/dist/module.js.map +1 -1
  102. package/dist/nb-NO.main.js +8 -0
  103. package/dist/nb-NO.main.js.map +1 -0
  104. package/dist/nb-NO.mjs +10 -0
  105. package/dist/nb-NO.module.js +10 -0
  106. package/dist/nb-NO.module.js.map +1 -0
  107. package/dist/nl-NL.main.js +8 -0
  108. package/dist/nl-NL.main.js.map +1 -0
  109. package/dist/nl-NL.mjs +10 -0
  110. package/dist/nl-NL.module.js +10 -0
  111. package/dist/nl-NL.module.js.map +1 -0
  112. package/dist/pl-PL.main.js +8 -0
  113. package/dist/pl-PL.main.js.map +1 -0
  114. package/dist/pl-PL.mjs +10 -0
  115. package/dist/pl-PL.module.js +10 -0
  116. package/dist/pl-PL.module.js.map +1 -0
  117. package/dist/pt-BR.main.js +8 -0
  118. package/dist/pt-BR.main.js.map +1 -0
  119. package/dist/pt-BR.mjs +10 -0
  120. package/dist/pt-BR.module.js +10 -0
  121. package/dist/pt-BR.module.js.map +1 -0
  122. package/dist/pt-PT.main.js +8 -0
  123. package/dist/pt-PT.main.js.map +1 -0
  124. package/dist/pt-PT.mjs +10 -0
  125. package/dist/pt-PT.module.js +10 -0
  126. package/dist/pt-PT.module.js.map +1 -0
  127. package/dist/ro-RO.main.js +8 -0
  128. package/dist/ro-RO.main.js.map +1 -0
  129. package/dist/ro-RO.mjs +10 -0
  130. package/dist/ro-RO.module.js +10 -0
  131. package/dist/ro-RO.module.js.map +1 -0
  132. package/dist/ru-RU.main.js +8 -0
  133. package/dist/ru-RU.main.js.map +1 -0
  134. package/dist/ru-RU.mjs +10 -0
  135. package/dist/ru-RU.module.js +10 -0
  136. package/dist/ru-RU.module.js.map +1 -0
  137. package/dist/sk-SK.main.js +8 -0
  138. package/dist/sk-SK.main.js.map +1 -0
  139. package/dist/sk-SK.mjs +10 -0
  140. package/dist/sk-SK.module.js +10 -0
  141. package/dist/sk-SK.module.js.map +1 -0
  142. package/dist/sl-SI.main.js +8 -0
  143. package/dist/sl-SI.main.js.map +1 -0
  144. package/dist/sl-SI.mjs +10 -0
  145. package/dist/sl-SI.module.js +10 -0
  146. package/dist/sl-SI.module.js.map +1 -0
  147. package/dist/sr-SP.main.js +8 -0
  148. package/dist/sr-SP.main.js.map +1 -0
  149. package/dist/sr-SP.mjs +10 -0
  150. package/dist/sr-SP.module.js +10 -0
  151. package/dist/sr-SP.module.js.map +1 -0
  152. package/dist/sv-SE.main.js +8 -0
  153. package/dist/sv-SE.main.js.map +1 -0
  154. package/dist/sv-SE.mjs +10 -0
  155. package/dist/sv-SE.module.js +10 -0
  156. package/dist/sv-SE.module.js.map +1 -0
  157. package/dist/tr-TR.main.js +8 -0
  158. package/dist/tr-TR.main.js.map +1 -0
  159. package/dist/tr-TR.mjs +10 -0
  160. package/dist/tr-TR.module.js +10 -0
  161. package/dist/tr-TR.module.js.map +1 -0
  162. package/dist/types.d.ts +126 -79
  163. package/dist/types.d.ts.map +1 -1
  164. package/dist/uk-UA.main.js +8 -0
  165. package/dist/uk-UA.main.js.map +1 -0
  166. package/dist/uk-UA.mjs +10 -0
  167. package/dist/uk-UA.module.js +10 -0
  168. package/dist/uk-UA.module.js.map +1 -0
  169. package/dist/zh-CN.main.js +8 -0
  170. package/dist/zh-CN.main.js.map +1 -0
  171. package/dist/zh-CN.mjs +10 -0
  172. package/dist/zh-CN.module.js +10 -0
  173. package/dist/zh-CN.module.js.map +1 -0
  174. package/dist/zh-TW.main.js +8 -0
  175. package/dist/zh-TW.main.js.map +1 -0
  176. package/dist/zh-TW.mjs +10 -0
  177. package/dist/zh-TW.module.js +10 -0
  178. package/dist/zh-TW.module.js.map +1 -0
  179. package/i18n/ar-AE.js +1 -0
  180. package/i18n/ar-AE.mjs +1 -0
  181. package/i18n/bg-BG.js +1 -0
  182. package/i18n/bg-BG.mjs +1 -0
  183. package/i18n/cs-CZ.js +1 -0
  184. package/i18n/cs-CZ.mjs +1 -0
  185. package/i18n/da-DK.js +1 -0
  186. package/i18n/da-DK.mjs +1 -0
  187. package/i18n/de-DE.js +1 -0
  188. package/i18n/de-DE.mjs +1 -0
  189. package/i18n/el-GR.js +1 -0
  190. package/i18n/el-GR.mjs +1 -0
  191. package/i18n/en-US.js +1 -0
  192. package/i18n/en-US.mjs +1 -0
  193. package/i18n/es-ES.js +1 -0
  194. package/i18n/es-ES.mjs +1 -0
  195. package/i18n/et-EE.js +1 -0
  196. package/i18n/et-EE.mjs +1 -0
  197. package/i18n/fi-FI.js +1 -0
  198. package/i18n/fi-FI.mjs +1 -0
  199. package/i18n/fr-FR.js +1 -0
  200. package/i18n/fr-FR.mjs +1 -0
  201. package/i18n/he-IL.js +1 -0
  202. package/i18n/he-IL.mjs +1 -0
  203. package/i18n/hr-HR.js +1 -0
  204. package/i18n/hr-HR.mjs +1 -0
  205. package/i18n/hu-HU.js +1 -0
  206. package/i18n/hu-HU.mjs +1 -0
  207. package/i18n/index.d.ts +12 -0
  208. package/i18n/index.js +118 -0
  209. package/i18n/index.mjs +115 -0
  210. package/i18n/it-IT.js +1 -0
  211. package/i18n/it-IT.mjs +1 -0
  212. package/i18n/ja-JP.js +1 -0
  213. package/i18n/ja-JP.mjs +1 -0
  214. package/i18n/ko-KR.js +1 -0
  215. package/i18n/ko-KR.mjs +1 -0
  216. package/i18n/lang.d.ts +7 -0
  217. package/i18n/lt-LT.js +1 -0
  218. package/i18n/lt-LT.mjs +1 -0
  219. package/i18n/lv-LV.js +1 -0
  220. package/i18n/lv-LV.mjs +1 -0
  221. package/i18n/nb-NO.js +1 -0
  222. package/i18n/nb-NO.mjs +1 -0
  223. package/i18n/nl-NL.js +1 -0
  224. package/i18n/nl-NL.mjs +1 -0
  225. package/i18n/pl-PL.js +1 -0
  226. package/i18n/pl-PL.mjs +1 -0
  227. package/i18n/pt-BR.js +1 -0
  228. package/i18n/pt-BR.mjs +1 -0
  229. package/i18n/pt-PT.js +1 -0
  230. package/i18n/pt-PT.mjs +1 -0
  231. package/i18n/ro-RO.js +1 -0
  232. package/i18n/ro-RO.mjs +1 -0
  233. package/i18n/ru-RU.js +1 -0
  234. package/i18n/ru-RU.mjs +1 -0
  235. package/i18n/sk-SK.js +1 -0
  236. package/i18n/sk-SK.mjs +1 -0
  237. package/i18n/sl-SI.js +1 -0
  238. package/i18n/sl-SI.mjs +1 -0
  239. package/i18n/sr-SP.js +1 -0
  240. package/i18n/sr-SP.mjs +1 -0
  241. package/i18n/sv-SE.js +1 -0
  242. package/i18n/sv-SE.mjs +1 -0
  243. package/i18n/tr-TR.js +1 -0
  244. package/i18n/tr-TR.mjs +1 -0
  245. package/i18n/uk-UA.js +1 -0
  246. package/i18n/uk-UA.mjs +1 -0
  247. package/i18n/zh-CN.js +1 -0
  248. package/i18n/zh-CN.mjs +1 -0
  249. package/i18n/zh-TW.js +1 -0
  250. package/i18n/zh-TW.mjs +1 -0
  251. package/package.json +30 -16
  252. package/src/Breadcrumbs.tsx +3 -2
  253. package/src/Calendar.tsx +7 -7
  254. package/src/Checkbox.tsx +14 -31
  255. package/src/Collection.tsx +40 -27
  256. package/src/ComboBox.tsx +3 -0
  257. package/src/DateField.tsx +5 -5
  258. package/src/DatePicker.tsx +5 -5
  259. package/src/Dialog.tsx +1 -1
  260. package/src/DropZone.tsx +1 -1
  261. package/src/FileTrigger.tsx +10 -4
  262. package/src/GridList.tsx +6 -4
  263. package/src/Heading.tsx +1 -1
  264. package/src/ListBox.tsx +8 -13
  265. package/src/Menu.tsx +23 -5
  266. package/src/Modal.tsx +11 -4
  267. package/src/OverlayArrow.tsx +7 -2
  268. package/src/Popover.tsx +26 -5
  269. package/src/RadioGroup.tsx +13 -31
  270. package/src/SearchField.tsx +2 -0
  271. package/src/Select.tsx +2 -1
  272. package/src/Slider.tsx +1 -1
  273. package/src/Switch.tsx +12 -29
  274. package/src/Table.tsx +34 -37
  275. package/src/Tabs.tsx +4 -3
  276. package/src/TagGroup.tsx +2 -2
  277. package/src/Tooltip.tsx +9 -4
  278. package/src/index.ts +2 -2
  279. package/src/useDragAndDrop.tsx +6 -6
  280. package/src/utils.tsx +20 -3
package/src/DateField.tsx CHANGED
@@ -18,7 +18,7 @@ import {filterDOMProps, useObjectRef} from '@react-aria/utils';
18
18
  import {Group, GroupContext} from './Group';
19
19
  import {Input, InputContext} from './Input';
20
20
  import {LabelContext} from './Label';
21
- import React, {cloneElement, createContext, ForwardedRef, forwardRef, ReactElement, useContext, useRef} from 'react';
21
+ import React, {cloneElement, createContext, ForwardedRef, forwardRef, JSX, ReactElement, useContext, useRef} from 'react';
22
22
  import {TextContext} from './Text';
23
23
 
24
24
  export interface DateFieldRenderProps {
@@ -82,7 +82,7 @@ function DateField<T extends DateValue>(props: DateFieldProps<T>, ref: Forwarded
82
82
  <Provider
83
83
  values={[
84
84
  [DateFieldStateContext, state],
85
- [GroupContext, {...fieldProps, ref: fieldRef}],
85
+ [GroupContext, {...fieldProps, ref: fieldRef, isInvalid: state.isInvalid}],
86
86
  [InputContext, {...inputProps, ref: inputRef}],
87
87
  [LabelContext, {...labelProps, ref: labelRef, elementType: 'span'}],
88
88
  [TextContext, {
@@ -146,7 +146,7 @@ function TimeField<T extends TimeValue>(props: TimeFieldProps<T>, ref: Forwarded
146
146
  <Provider
147
147
  values={[
148
148
  [TimeFieldStateContext, state],
149
- [GroupContext, {...fieldProps, ref: fieldRef}],
149
+ [GroupContext, {...fieldProps, ref: fieldRef, isInvalid: state.isInvalid}],
150
150
  [InputContext, {...inputProps, ref: inputRef}],
151
151
  [LabelContext, {...labelProps, ref: labelRef, elementType: 'span'}],
152
152
  [TextContext, {
@@ -201,7 +201,7 @@ export interface DateInputProps extends SlotProps, StyleRenderProps<DateInputRen
201
201
  children: (segment: IDateSegment) => ReactElement
202
202
  }
203
203
 
204
- function DateInput(props: DateInputProps, ref: ForwardedRef<HTMLDivElement>): React.JSX.Element {
204
+ function DateInput(props: DateInputProps, ref: ForwardedRef<HTMLDivElement>): JSX.Element {
205
205
  // If state is provided by DateField/TimeField, just render.
206
206
  // Otherwise (e.g. in DatePicker), we need to call hooks and create state ourselves.
207
207
  let dateFieldState = useContext(DateFieldStateContext);
@@ -228,7 +228,7 @@ const DateInputStandalone = forwardRef((props: DateInputProps, ref: ForwardedRef
228
228
  values={[
229
229
  [DateFieldStateContext, state],
230
230
  [InputContext, {...inputProps, ref: inputRef}],
231
- [GroupContext, {...fieldProps, ref: fieldRef}]
231
+ [GroupContext, {...fieldProps, ref: fieldRef, isInvalid: state.isInvalid}]
232
232
  ]}>
233
233
  <DateInputInner {...props} />
234
234
  </Provider>
@@ -62,7 +62,7 @@ export interface DateRangePickerRenderProps extends Omit<DatePickerRenderProps,
62
62
  state: DateRangePickerState
63
63
  }
64
64
 
65
- export interface DatePickerProps<T extends DateValue> extends Omit<AriaDatePickerProps<T>, 'label' | 'description' | 'errorMessage' | 'validationState'>, Pick<DatePickerStateOptions<T>, 'shouldCloseOnSelect'>, RACValidation, RenderProps<DatePickerRenderProps>, SlotProps {}
65
+ export interface DatePickerProps<T extends DateValue> extends Omit<AriaDatePickerProps<T>, 'label' | 'description' | 'errorMessage' | 'validationState' | 'validationBehavior'>, Pick<DatePickerStateOptions<T>, 'shouldCloseOnSelect'>, RACValidation, RenderProps<DatePickerRenderProps>, SlotProps {}
66
66
  export interface DateRangePickerProps<T extends DateValue> extends Omit<AriaDateRangePickerProps<T>, 'label' | 'description' | 'errorMessage' | 'validationState' | 'validationBehavior'>, Pick<DateRangePickerStateOptions<T>, 'shouldCloseOnSelect'>, RACValidation, RenderProps<DateRangePickerRenderProps>, SlotProps {}
67
67
 
68
68
  export const DatePickerContext = createContext<ContextValue<DatePickerProps<any>, HTMLDivElement>>(null);
@@ -116,13 +116,13 @@ function DatePicker<T extends DateValue>(props: DatePickerProps<T>, ref: Forward
116
116
  <Provider
117
117
  values={[
118
118
  [DatePickerStateContext, state],
119
- [GroupContext, {...groupProps, ref: groupRef}],
119
+ [GroupContext, {...groupProps, ref: groupRef, isInvalid: state.isInvalid}],
120
120
  [DateFieldContext, fieldProps],
121
121
  [ButtonContext, {...buttonProps, isPressed: state.isOpen}],
122
122
  [LabelContext, {...labelProps, ref: labelRef, elementType: 'span'}],
123
123
  [CalendarContext, calendarProps],
124
124
  [OverlayTriggerStateContext, state],
125
- [PopoverContext, {triggerRef: groupRef, placement: 'bottom start'}],
125
+ [PopoverContext, {trigger: 'DatePicker', triggerRef: groupRef, placement: 'bottom start'}],
126
126
  [DialogContext, dialogProps],
127
127
  [TextContext, {
128
128
  slots: {
@@ -200,12 +200,12 @@ function DateRangePicker<T extends DateValue>(props: DateRangePickerProps<T>, re
200
200
  <Provider
201
201
  values={[
202
202
  [DateRangePickerStateContext, state],
203
- [GroupContext, {...groupProps, ref: groupRef}],
203
+ [GroupContext, {...groupProps, ref: groupRef, isInvalid: state.isInvalid}],
204
204
  [ButtonContext, {...buttonProps, isPressed: state.isOpen}],
205
205
  [LabelContext, {...labelProps, ref: labelRef, elementType: 'span'}],
206
206
  [RangeCalendarContext, calendarProps],
207
207
  [OverlayTriggerStateContext, state],
208
- [PopoverContext, {triggerRef: groupRef, placement: 'bottom start'}],
208
+ [PopoverContext, {trigger: 'DateRangePicker', triggerRef: groupRef, placement: 'bottom start'}],
209
209
  [DialogContext, dialogProps],
210
210
  [DateFieldContext, {
211
211
  slots: {
package/src/Dialog.tsx CHANGED
@@ -55,7 +55,7 @@ export function DialogTrigger(props: DialogTriggerProps) {
55
55
  values={[
56
56
  [OverlayTriggerStateContext, state],
57
57
  [DialogContext, overlayProps],
58
- [PopoverContext, {triggerRef: buttonRef}]
58
+ [PopoverContext, {trigger: 'DialogTrigger', triggerRef: buttonRef}]
59
59
  ]}>
60
60
  <PressResponder {...triggerProps} ref={buttonRef} isPressed={state.isOpen}>
61
61
  {props.children}
package/src/DropZone.tsx CHANGED
@@ -52,7 +52,7 @@ function DropZone(props: DropZoneProps, ref: ForwardedRef<HTMLDivElement>) {
52
52
  let {dropProps, dropButtonProps, isDropTarget} = useDrop({...props, ref: buttonRef, hasDropButton: true});
53
53
  let {hoverProps, isHovered} = useHover(props);
54
54
  let {focusProps, isFocused, isFocusVisible} = useFocusRing();
55
- let stringFormatter = useLocalizedStringFormatter(intlMessages);
55
+ let stringFormatter = useLocalizedStringFormatter(intlMessages, 'react-aria-components');
56
56
 
57
57
  let textId = useSlotId();
58
58
  let dropzoneId = useSlotId();
@@ -35,17 +35,21 @@ export interface FileTriggerProps {
35
35
  /**
36
36
  * The children of the component.
37
37
  */
38
- children?: ReactNode
38
+ children?: ReactNode,
39
+ /**
40
+ * Enables the selection of directories instead of individual files.
41
+ */
42
+ acceptDirectory?: boolean
39
43
  }
40
44
 
41
45
  function FileTrigger(props: FileTriggerProps, ref: ForwardedRef<HTMLInputElement>) {
42
- let {onSelect, acceptedFileTypes, allowsMultiple, defaultCamera, children, ...rest} = props;
46
+ let {onSelect, acceptedFileTypes, allowsMultiple, defaultCamera, children, acceptDirectory, ...rest} = props;
43
47
  let inputRef = useObjectRef(ref);
44
48
  let domProps = filterDOMProps(rest);
45
49
 
46
50
  return (
47
51
  <>
48
- <PressResponder
52
+ <PressResponder
49
53
  onPress={() => {
50
54
  if (inputRef.current.value) {
51
55
  inputRef.current.value = '';
@@ -62,7 +66,9 @@ function FileTrigger(props: FileTriggerProps, ref: ForwardedRef<HTMLInputElement
62
66
  accept={acceptedFileTypes?.toString()}
63
67
  onChange={(e) => onSelect?.(e.target.files)}
64
68
  capture={defaultCamera}
65
- multiple={allowsMultiple} />
69
+ multiple={allowsMultiple}
70
+ // @ts-expect-error
71
+ webkitdirectory={acceptDirectory ? '' : undefined} />
66
72
  </>
67
73
  );
68
74
  }
package/src/GridList.tsx CHANGED
@@ -14,12 +14,12 @@ import {ButtonContext} from './Button';
14
14
  import {CheckboxContext} from './Checkbox';
15
15
  import {Collection, DraggableCollectionState, DroppableCollectionState, ListState, Node, SelectionBehavior, useListState} from 'react-stately';
16
16
  import {CollectionProps, ItemRenderProps, useCachedChildren, useCollection, useSSRCollectionNode} from './Collection';
17
- import {ContextValue, defaultSlot, forwardRefType, Provider, RenderProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps} from './utils';
17
+ import {ContextValue, defaultSlot, forwardRefType, Provider, RenderProps, ScrollableProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps} from './utils';
18
18
  import {DragAndDropContext, DragAndDropHooks, DropIndicator, DropIndicatorContext, DropIndicatorProps} from './useDragAndDrop';
19
19
  import {filterDOMProps, useObjectRef} from '@react-aria/utils';
20
20
  import {Key, LinkDOMProps} from '@react-types/shared';
21
21
  import {ListStateContext} from './ListBox';
22
- import React, {createContext, ForwardedRef, forwardRef, HTMLAttributes, ReactNode, RefObject, useContext, useEffect, useRef} from 'react';
22
+ import React, {createContext, ForwardedRef, forwardRef, HTMLAttributes, JSX, ReactNode, RefObject, useContext, useEffect, useRef} from 'react';
23
23
  import {TextContext} from './Text';
24
24
 
25
25
  export interface GridListRenderProps {
@@ -49,7 +49,7 @@ export interface GridListRenderProps {
49
49
  state: ListState<unknown>
50
50
  }
51
51
 
52
- export interface GridListProps<T> extends Omit<AriaGridListProps<T>, 'children'>, CollectionProps<T>, StyleRenderProps<GridListRenderProps>, SlotProps {
52
+ export interface GridListProps<T> extends Omit<AriaGridListProps<T>, 'children'>, CollectionProps<T>, StyleRenderProps<GridListRenderProps>, SlotProps, ScrollableProps<HTMLDivElement> {
53
53
  /** How multiple selection should behave in the collection. */
54
54
  selectionBehavior?: SelectionBehavior,
55
55
  /** The drag and drop hooks returned by `useDragAndDrop` used to enable drag and drop behavior for the GridList. */
@@ -119,7 +119,7 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
119
119
  let dropState: DroppableCollectionState | undefined = undefined;
120
120
  let droppableCollection: DroppableCollectionResult | undefined = undefined;
121
121
  let isRootDropTarget = false;
122
- let dragPreview: React.JSX.Element | null = null;
122
+ let dragPreview: JSX.Element | null = null;
123
123
  let preview = useRef<DragPreviewRenderer>(null);
124
124
 
125
125
  if (isListDraggable && dragAndDropHooks) {
@@ -192,6 +192,7 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
192
192
  {...mergeProps(gridProps, focusProps, droppableCollection?.collectionProps, emptyStatePropOverrides)}
193
193
  ref={ref}
194
194
  slot={props.slot || undefined}
195
+ onScroll={props.onScroll}
195
196
  data-drop-target={isRootDropTarget || undefined}
196
197
  data-empty={state.collection.size === 0 || undefined}
197
198
  data-focused={isFocused || undefined}
@@ -426,6 +427,7 @@ function GridListDropIndicator(props: GridListDropIndicatorProps, ref: Forwarded
426
427
  data-drop-target={isDropTarget || undefined}>
427
428
  <div role="gridcell">
428
429
  <div {...visuallyHiddenProps} role="button" {...dropIndicatorProps} ref={buttonRef} />
430
+ {renderProps.children}
429
431
  </div>
430
432
  </div>
431
433
  );
package/src/Heading.tsx CHANGED
@@ -25,7 +25,7 @@ function Heading(props: HeadingProps, ref: ForwardedRef<HTMLHeadingElement>) {
25
25
  let Element = `h${level}` as ElementType;
26
26
 
27
27
  return (
28
- <Element {...domProps} className={className ?? 'react-aria-Heading'}>
28
+ <Element {...domProps} ref={ref} className={className ?? 'react-aria-Heading'}>
29
29
  {children}
30
30
  </Element>
31
31
  );
package/src/ListBox.tsx CHANGED
@@ -12,13 +12,13 @@
12
12
 
13
13
  import {AriaListBoxOptions, AriaListBoxProps, DraggableItemResult, DragPreviewRenderer, DroppableCollectionResult, DroppableItemResult, FocusScope, ListKeyboardDelegate, mergeProps, useCollator, useFocusRing, useHover, useListBox, useListBoxSection, useLocale, useOption} from 'react-aria';
14
14
  import {CollectionDocumentContext, CollectionPortal, CollectionProps, ItemRenderProps, useCachedChildren, useCollection, useSSRCollectionNode} from './Collection';
15
- import {ContextValue, forwardRefType, HiddenContext, Provider, RenderProps, SlotProps, StyleProps, StyleRenderProps, useContextProps, useRenderProps, useSlot, useSlottedContext} from './utils';
15
+ import {ContextValue, forwardRefType, HiddenContext, Provider, RenderProps, ScrollableProps, SlotProps, StyleProps, StyleRenderProps, useContextProps, useRenderProps, useSlot} from './utils';
16
16
  import {DragAndDropContext, DragAndDropHooks, DropIndicator, DropIndicatorContext, DropIndicatorProps} from './useDragAndDrop';
17
17
  import {DraggableCollectionState, DroppableCollectionState, ListState, Node, Orientation, SelectionBehavior, useListState} from 'react-stately';
18
18
  import {filterDOMProps, mergeRefs, useObjectRef} from '@react-aria/utils';
19
19
  import {Header} from './Header';
20
20
  import {Key, LinkDOMProps} from '@react-types/shared';
21
- import React, {createContext, ForwardedRef, forwardRef, ReactNode, RefObject, useContext, useEffect, useMemo, useRef} from 'react';
21
+ import React, {createContext, ForwardedRef, forwardRef, JSX, ReactNode, RefObject, useContext, useEffect, useMemo, useRef} from 'react';
22
22
  import {Separator, SeparatorContext} from './Separator';
23
23
  import {TextContext} from './Text';
24
24
 
@@ -54,7 +54,7 @@ export interface ListBoxRenderProps {
54
54
  state: ListState<unknown>
55
55
  }
56
56
 
57
- export interface ListBoxProps<T> extends Omit<AriaListBoxProps<T>, 'children' | 'label'>, CollectionProps<T>, StyleRenderProps<ListBoxRenderProps>, SlotProps {
57
+ export interface ListBoxProps<T> extends Omit<AriaListBoxProps<T>, 'children' | 'label'>, CollectionProps<T>, StyleRenderProps<ListBoxRenderProps>, SlotProps, ScrollableProps<HTMLDivElement> {
58
58
  /** How multiple selection should behave in the collection. */
59
59
  selectionBehavior?: SelectionBehavior,
60
60
  /** The drag and drop hooks returned by `useDragAndDrop` used to enable drag and drop behavior for the ListBox. */
@@ -181,7 +181,7 @@ function ListBoxInner<T>({state, props, listBoxRef}: ListBoxInnerProps<T>) {
181
181
  let dropState: DroppableCollectionState | undefined = undefined;
182
182
  let droppableCollection: DroppableCollectionResult | undefined = undefined;
183
183
  let isRootDropTarget = false;
184
- let dragPreview: React.JSX.Element | null = null;
184
+ let dragPreview: JSX.Element | null = null;
185
185
  let preview = useRef<DragPreviewRenderer>(null);
186
186
 
187
187
  if (isListDraggable && dragAndDropHooks) {
@@ -229,7 +229,7 @@ function ListBoxInner<T>({state, props, listBoxRef}: ListBoxInnerProps<T>) {
229
229
  values: renderValues
230
230
  });
231
231
 
232
- let emptyState: React.JSX.Element | null = null;
232
+ let emptyState: JSX.Element | null = null;
233
233
  if (state.collection.size === 0 && props.renderEmptyState) {
234
234
  emptyState = (
235
235
  <div
@@ -249,6 +249,7 @@ function ListBoxInner<T>({state, props, listBoxRef}: ListBoxInnerProps<T>) {
249
249
  {...renderProps}
250
250
  ref={listBoxRef}
251
251
  slot={props.slot || undefined}
252
+ onScroll={props.onScroll}
252
253
  data-drop-target={isRootDropTarget || undefined}
253
254
  data-empty={state.collection.size === 0 || undefined}
254
255
  data-focused={isFocused || undefined}
@@ -281,7 +282,7 @@ function ListBoxSection<T>({section, className, style}: ListBoxSectionProps<T>)
281
282
  let [headingRef, heading] = useSlot();
282
283
  let {headingProps, groupProps} = useListBoxSection({
283
284
  heading,
284
- 'aria-label': section['aria-label'] ?? undefined
285
+ 'aria-label': section.props['aria-label'] ?? undefined
285
286
  });
286
287
 
287
288
  let children = useCachedChildren({
@@ -359,7 +360,6 @@ interface OptionProps<T> {
359
360
  function Option<T>({item}: OptionProps<T>) {
360
361
  let ref = useObjectRef<any>(item.props.ref);
361
362
  let state = useContext(ListStateContext)!;
362
- let {shouldFocusOnHover} = useSlottedContext(ListBoxContext)! as AriaListBoxOptions<T>;
363
363
  let {dragAndDropHooks, dragState, dropState} = useContext(DragAndDropContext)!;
364
364
  let {optionProps, labelProps, descriptionProps, ...states} = useOption(
365
365
  {key: item.key},
@@ -368,14 +368,9 @@ function Option<T>({item}: OptionProps<T>) {
368
368
  );
369
369
 
370
370
  let {hoverProps, isHovered} = useHover({
371
- isDisabled: shouldFocusOnHover || (!states.allowsSelection && !states.hasAction)
371
+ isDisabled: !states.allowsSelection && !states.hasAction
372
372
  });
373
373
 
374
- if (shouldFocusOnHover) {
375
- hoverProps = {};
376
- isHovered = states.isFocused;
377
- }
378
-
379
374
  let draggableItem: DraggableItemResult | null = null;
380
375
  if (dragState && dragAndDropHooks) {
381
376
  draggableItem = dragAndDropHooks.useDraggableItem!({key: item.key}, dragState);
package/src/Menu.tsx CHANGED
@@ -14,15 +14,15 @@
14
14
  import {AriaMenuProps, mergeProps, useFocusRing, useMenu, useMenuItem, useMenuSection, useMenuTrigger} from 'react-aria';
15
15
  import {BaseCollection, CollectionProps, ItemRenderProps, useCachedChildren, useCollection, useSSRCollectionNode} from './Collection';
16
16
  import {MenuTriggerProps as BaseMenuTriggerProps, Node, TreeState, useMenuTriggerState, useTreeState} from 'react-stately';
17
- import {ContextValue, forwardRefType, Provider, RenderProps, SlotProps, StyleProps, useContextProps, useRenderProps, useSlot} from './utils';
18
- import {filterDOMProps, mergeRefs, useObjectRef} from '@react-aria/utils';
17
+ import {ContextValue, forwardRefType, Provider, RenderProps, ScrollableProps, SlotProps, StyleProps, useContextProps, useRenderProps, useSlot} from './utils';
18
+ import {filterDOMProps, mergeRefs, useObjectRef, useResizeObserver} from '@react-aria/utils';
19
19
  import {Header} from './Header';
20
20
  import {Key, LinkDOMProps} from '@react-types/shared';
21
21
  import {KeyboardContext} from './Keyboard';
22
22
  import {OverlayTriggerStateContext} from './Dialog';
23
23
  import {PopoverContext} from './Popover';
24
24
  import {PressResponder} from '@react-aria/interactions';
25
- import React, {createContext, ForwardedRef, forwardRef, ReactNode, RefObject, useContext, useRef} from 'react';
25
+ import React, {createContext, ForwardedRef, forwardRef, ReactNode, RefObject, useCallback, useContext, useRef, useState} from 'react';
26
26
  import {Separator, SeparatorContext} from './Separator';
27
27
  import {TextContext} from './Text';
28
28
 
@@ -41,13 +41,30 @@ export function MenuTrigger(props: MenuTriggerProps) {
41
41
  ...props,
42
42
  type: 'menu'
43
43
  }, state, ref);
44
+ // Allows menu width to match button
45
+ let [buttonWidth, setButtonWidth] = useState<string | null>(null);
46
+ let onResize = useCallback(() => {
47
+ if (ref.current) {
48
+ setButtonWidth(ref.current.offsetWidth + 'px');
49
+ }
50
+ }, [ref]);
51
+
52
+ useResizeObserver({
53
+ ref: ref,
54
+ onResize: onResize
55
+ });
44
56
 
45
57
  return (
46
58
  <Provider
47
59
  values={[
48
60
  [MenuContext, menuProps],
49
61
  [OverlayTriggerStateContext, state],
50
- [PopoverContext, {triggerRef: ref, placement: 'bottom start'}]
62
+ [PopoverContext, {
63
+ trigger: 'MenuTrigger',
64
+ triggerRef: ref,
65
+ placement: 'bottom start',
66
+ style: {'--trigger-width': buttonWidth} as React.CSSProperties
67
+ }]
51
68
  ]}>
52
69
  <PressResponder {...menuTriggerProps} ref={ref} isPressed={state.isOpen}>
53
70
  {props.children}
@@ -56,7 +73,7 @@ export function MenuTrigger(props: MenuTriggerProps) {
56
73
  );
57
74
  }
58
75
 
59
- export interface MenuProps<T> extends Omit<AriaMenuProps<T>, 'children'>, CollectionProps<T>, StyleProps, SlotProps {}
76
+ export interface MenuProps<T> extends Omit<AriaMenuProps<T>, 'children'>, CollectionProps<T>, StyleProps, SlotProps, ScrollableProps<HTMLDivElement> {}
60
77
 
61
78
  function Menu<T extends object>(props: MenuProps<T>, ref: ForwardedRef<HTMLDivElement>) {
62
79
  [props, ref] = useContextProps(props, ref, MenuContext);
@@ -107,6 +124,7 @@ function MenuInner<T extends object>({props, collection, menuRef: ref}: MenuInne
107
124
  {...menuProps}
108
125
  ref={ref}
109
126
  slot={props.slot || undefined}
127
+ onScroll={props.onScroll}
110
128
  style={props.style}
111
129
  className={props.className ?? 'react-aria-Menu'}>
112
130
  <Provider
package/src/Modal.tsx CHANGED
@@ -26,7 +26,12 @@ export interface ModalOverlayProps extends AriaModalOverlayProps, OverlayTrigger
26
26
  /**
27
27
  * Whether the modal is currently performing an exit animation.
28
28
  */
29
- isExiting?: boolean
29
+ isExiting?: boolean,
30
+ /**
31
+ * The container element in which the overlay portal will be placed. This may have unknown behavior depending on where it is portalled to.
32
+ * @default document.body
33
+ */
34
+ UNSTABLE_portalContainer?: Element
30
35
  }
31
36
 
32
37
  interface InternalModalContextValue {
@@ -72,6 +77,7 @@ function Modal(props: ModalOverlayProps, ref: ForwardedRef<HTMLDivElement>) {
72
77
  children,
73
78
  isEntering,
74
79
  isExiting,
80
+ UNSTABLE_portalContainer,
75
81
  ...otherProps
76
82
  } = props;
77
83
 
@@ -83,7 +89,8 @@ function Modal(props: ModalOverlayProps, ref: ForwardedRef<HTMLDivElement>) {
83
89
  defaultOpen={defaultOpen}
84
90
  onOpenChange={onOpenChange}
85
91
  isEntering={isEntering}
86
- isExiting={isExiting}>
92
+ isExiting={isExiting}
93
+ UNSTABLE_portalContainer={UNSTABLE_portalContainer}>
87
94
  <ModalContent {...otherProps} modalRef={ref}>
88
95
  {children}
89
96
  </ModalContent>
@@ -136,7 +143,7 @@ function ModalOverlayWithForwardRef(props: ModalOverlayProps, ref: ForwardedRef<
136
143
  */
137
144
  export const ModalOverlay = /*#__PURE__*/ (forwardRef as forwardRefType)(ModalOverlayWithForwardRef);
138
145
 
139
- function ModalOverlayInner(props: ModalOverlayInnerProps) {
146
+ function ModalOverlayInner({UNSTABLE_portalContainer, ...props}: ModalOverlayInnerProps) {
140
147
  let modalRef = props.modalRef;
141
148
  let {state} = props;
142
149
  let {modalProps, underlayProps} = useModalOverlay(props, state, modalRef);
@@ -159,7 +166,7 @@ function ModalOverlayInner(props: ModalOverlayInnerProps) {
159
166
  };
160
167
 
161
168
  return (
162
- <Overlay isExiting={props.isExiting}>
169
+ <Overlay isExiting={props.isExiting} portalContainer={UNSTABLE_portalContainer}>
163
170
  <div
164
171
  {...mergeProps(filterDOMProps(props as any), underlayProps)}
165
172
  {...renderProps}
@@ -48,14 +48,19 @@ function OverlayArrow(props: OverlayArrowProps, ref: ForwardedRef<HTMLDivElement
48
48
  placement
49
49
  }
50
50
  });
51
+ // remove undefined values from renderProps.style object so that it can be
52
+ // spread merged with the other style object
53
+ if (renderProps.style) {
54
+ Object.keys(renderProps.style).forEach(key => renderProps.style![key] === undefined && delete renderProps.style![key]);
55
+ }
51
56
 
52
57
  return (
53
58
  <div
54
59
  {...props}
55
60
  {...renderProps}
56
61
  style={{
57
- ...renderProps.style,
58
- ...style
62
+ ...style,
63
+ ...renderProps.style
59
64
  }}
60
65
  ref={ref}
61
66
  data-placement={placement} />
package/src/Popover.tsx CHANGED
@@ -19,6 +19,12 @@ import {OverlayTriggerStateContext} from './Dialog';
19
19
  import React, {createContext, ForwardedRef, forwardRef, RefObject, useContext} from 'react';
20
20
 
21
21
  export interface PopoverProps extends Omit<PositionProps, 'isOpen'>, Omit<AriaPopoverProps, 'popoverRef' | 'triggerRef'>, OverlayTriggerProps, RenderProps<PopoverRenderProps>, SlotProps {
22
+ /**
23
+ * The name of the component that triggered the popover. This is reflected on the element
24
+ * as the `data-trigger` attribute, and can be used to provide specific
25
+ * styles for the popover depending on which element triggered it.
26
+ */
27
+ trigger?: string,
22
28
  /**
23
29
  * The ref for the element which the popover positions itself with respect to.
24
30
  *
@@ -33,10 +39,20 @@ export interface PopoverProps extends Omit<PositionProps, 'isOpen'>, Omit<AriaPo
33
39
  /**
34
40
  * Whether the popover is currently performing an exit animation.
35
41
  */
36
- isExiting?: boolean
42
+ isExiting?: boolean,
43
+ /**
44
+ * The container element in which the overlay portal will be placed. This may have unknown behavior depending on where it is portalled to.
45
+ * @default document.body
46
+ */
47
+ UNSTABLE_portalContainer?: Element
37
48
  }
38
49
 
39
50
  export interface PopoverRenderProps {
51
+ /**
52
+ * The name of the component that triggered the popover, e.g. "DialogTrigger" or "ComboBox".
53
+ * @selector [data-trigger="..."]
54
+ */
55
+ trigger: string | null,
40
56
  /**
41
57
  * The placement of the popover relative to the trigger.
42
58
  * @selector [data-placement="left | right | top | bottom"]
@@ -69,6 +85,7 @@ function Popover(props: PopoverProps, ref: ForwardedRef<HTMLElement>) {
69
85
  let children = props.children;
70
86
  if (typeof children === 'function') {
71
87
  children = children({
88
+ trigger: props.trigger || null,
72
89
  placement: 'bottom',
73
90
  isEntering: false,
74
91
  isExiting: false
@@ -101,10 +118,12 @@ export {_Popover as Popover};
101
118
  interface PopoverInnerProps extends AriaPopoverProps, RenderProps<PopoverRenderProps>, SlotProps {
102
119
  state: OverlayTriggerState,
103
120
  isEntering?: boolean,
104
- isExiting: boolean
121
+ isExiting: boolean,
122
+ UNSTABLE_portalContainer?: Element,
123
+ trigger?: string
105
124
  }
106
125
 
107
- function PopoverInner({state, isExiting, ...props}: PopoverInnerProps) {
126
+ function PopoverInner({state, isExiting, UNSTABLE_portalContainer, ...props}: PopoverInnerProps) {
108
127
  let {popoverProps, underlayProps, arrowProps, placement} = usePopover({
109
128
  ...props,
110
129
  offset: props.offset ?? 8
@@ -116,16 +135,17 @@ function PopoverInner({state, isExiting, ...props}: PopoverInnerProps) {
116
135
  ...props,
117
136
  defaultClassName: 'react-aria-Popover',
118
137
  values: {
138
+ trigger: props.trigger || null,
119
139
  placement,
120
140
  isEntering,
121
141
  isExiting
122
142
  }
123
143
  });
124
144
 
125
- let style = {...renderProps.style, ...popoverProps.style};
145
+ let style = {...popoverProps.style, ...renderProps.style};
126
146
 
127
147
  return (
128
- <Overlay isExiting={isExiting}>
148
+ <Overlay isExiting={isExiting} portalContainer={UNSTABLE_portalContainer}>
129
149
  {!props.isNonModal && state.isOpen && <div {...underlayProps} style={{position: 'fixed', inset: 0}} />}
130
150
  <div
131
151
  {...mergeProps(filterDOMProps(props as any), popoverProps)}
@@ -133,6 +153,7 @@ function PopoverInner({state, isExiting, ...props}: PopoverInnerProps) {
133
153
  ref={ref}
134
154
  slot={props.slot || undefined}
135
155
  style={style}
156
+ data-trigger={props.trigger}
136
157
  data-placement={placement}
137
158
  data-entering={isEntering || undefined}
138
159
  data-exiting={isExiting || undefined}>
@@ -10,13 +10,13 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import {AriaRadioGroupProps, AriaRadioProps, HoverEvents, Orientation, useFocusRing, useHover, usePress, useRadio, useRadioGroup, VisuallyHidden} from 'react-aria';
13
+ import {AriaRadioGroupProps, AriaRadioProps, HoverEvents, Orientation, useFocusRing, useHover, useRadio, useRadioGroup, VisuallyHidden} from 'react-aria';
14
14
  import {ContextValue, forwardRefType, Provider, RACValidation, removeDataAttributes, RenderProps, SlotProps, useContextProps, useRenderProps, useSlot} from './utils';
15
15
  import {FieldErrorContext} from './FieldError';
16
- import {filterDOMProps, mergeProps, useObjectRef} from '@react-aria/utils';
16
+ import {filterDOMProps, mergeProps} from '@react-aria/utils';
17
17
  import {LabelContext} from './Label';
18
18
  import {RadioGroupState, useRadioGroupState} from 'react-stately';
19
- import React, {createContext, ForwardedRef, forwardRef, useState} from 'react';
19
+ import React, {createContext, ForwardedRef, forwardRef, useRef} from 'react';
20
20
  import {TextContext} from './Text';
21
21
 
22
22
  export interface RadioGroupProps extends Omit<AriaRadioGroupProps, 'children' | 'label' | 'description' | 'errorMessage' | 'validationState' | 'validationBehavior'>, RACValidation, RenderProps<RadioGroupRenderProps>, SlotProps {}
@@ -103,7 +103,7 @@ export interface RadioRenderProps {
103
103
  }
104
104
 
105
105
  export const RadioGroupContext = createContext<ContextValue<RadioGroupProps, HTMLDivElement>>(null);
106
- export const RadioContext = createContext<ContextValue<Partial<RadioProps>, HTMLInputElement>>(null);
106
+ export const RadioContext = createContext<ContextValue<Partial<RadioProps>, HTMLLabelElement>>(null);
107
107
  export const RadioGroupStateContext = createContext<RadioGroupState | null>(null);
108
108
 
109
109
  function RadioGroup(props: RadioGroupProps, ref: ForwardedRef<HTMLDivElement>) {
@@ -162,48 +162,29 @@ function RadioGroup(props: RadioGroupProps, ref: ForwardedRef<HTMLDivElement>) {
162
162
  );
163
163
  }
164
164
 
165
- function Radio(props: RadioProps, ref: ForwardedRef<HTMLInputElement>) {
165
+ function Radio(props: RadioProps, ref: ForwardedRef<HTMLLabelElement>) {
166
166
  [props, ref] = useContextProps(props, ref, RadioContext);
167
167
  let state = React.useContext(RadioGroupStateContext)!;
168
- let domRef = useObjectRef(ref);
169
- let {inputProps, isSelected, isDisabled, isPressed: isPressedKeyboard} = useRadio({
168
+ let inputRef = useRef<HTMLInputElement>(null);
169
+ let {labelProps, inputProps, isSelected, isDisabled, isPressed} = useRadio({
170
170
  ...removeDataAttributes<RadioProps>(props),
171
171
  // ReactNode type doesn't allow function children.
172
172
  children: typeof props.children === 'function' ? true : props.children
173
- }, state, domRef);
173
+ }, state, inputRef);
174
174
  let {isFocused, isFocusVisible, focusProps} = useFocusRing();
175
175
  let interactionDisabled = isDisabled || state.isReadOnly;
176
176
 
177
- // Handle press state for full label. Keyboard press state is returned by useRadio
178
- // since it is handled on the <input> element itself.
179
- let [isPressed, setPressed] = useState(false);
180
- let {pressProps} = usePress({
181
- isDisabled: interactionDisabled,
182
- onPressStart(e) {
183
- if (e.pointerType !== 'keyboard') {
184
- setPressed(true);
185
- }
186
- },
187
- onPressEnd(e) {
188
- if (e.pointerType !== 'keyboard') {
189
- setPressed(false);
190
- }
191
- }
192
- });
193
-
194
177
  let {hoverProps, isHovered} = useHover({
195
178
  ...props,
196
179
  isDisabled: interactionDisabled
197
180
  });
198
181
 
199
- let pressed = interactionDisabled ? false : (isPressed || isPressedKeyboard);
200
-
201
182
  let renderProps = useRenderProps({
202
183
  ...props,
203
184
  defaultClassName: 'react-aria-Radio',
204
185
  values: {
205
186
  isSelected,
206
- isPressed: pressed,
187
+ isPressed,
207
188
  isHovered,
208
189
  isFocused,
209
190
  isFocusVisible,
@@ -219,9 +200,10 @@ function Radio(props: RadioProps, ref: ForwardedRef<HTMLInputElement>) {
219
200
 
220
201
  return (
221
202
  <label
222
- {...mergeProps(DOMProps, pressProps, hoverProps, renderProps)}
203
+ {...mergeProps(DOMProps, labelProps, hoverProps, renderProps)}
204
+ ref={ref}
223
205
  data-selected={isSelected || undefined}
224
- data-pressed={pressed || undefined}
206
+ data-pressed={isPressed || undefined}
225
207
  data-hovered={isHovered || undefined}
226
208
  data-focused={isFocused || undefined}
227
209
  data-focus-visible={isFocusVisible || undefined}
@@ -230,7 +212,7 @@ function Radio(props: RadioProps, ref: ForwardedRef<HTMLInputElement>) {
230
212
  data-invalid={state.isInvalid || undefined}
231
213
  data-required={state.isRequired || undefined}>
232
214
  <VisuallyHidden elementType="span">
233
- <input {...mergeProps(inputProps, focusProps)} ref={domRef} />
215
+ <input {...mergeProps(inputProps, focusProps)} ref={inputRef} />
234
216
  </VisuallyHidden>
235
217
  {renderProps.children}
236
218
  </label>
@@ -15,6 +15,7 @@ import {ButtonContext} from './Button';
15
15
  import {ContextValue, forwardRefType, Provider, RACValidation, removeDataAttributes, RenderProps, SlotProps, useContextProps, useRenderProps, useSlot} from './utils';
16
16
  import {FieldErrorContext} from './FieldError';
17
17
  import {filterDOMProps} from '@react-aria/utils';
18
+ import {GroupContext} from './Group';
18
19
  import {InputContext} from './Input';
19
20
  import {LabelContext} from './Label';
20
21
  import React, {createContext, ForwardedRef, forwardRef, useRef} from 'react';
@@ -96,6 +97,7 @@ function SearchField(props: SearchFieldProps, ref: ForwardedRef<HTMLDivElement>)
96
97
  errorMessage: errorMessageProps
97
98
  }
98
99
  }],
100
+ [GroupContext, {isInvalid: validation.isInvalid, isDisabled: props.isDisabled || false}],
99
101
  [FieldErrorContext, validation]
100
102
  ]}>
101
103
  {renderProps.children}
package/src/Select.tsx CHANGED
@@ -148,6 +148,7 @@ function Select<T extends object>(props: SelectProps<T>, ref: ForwardedRef<HTMLD
148
148
  [ButtonContext, {...triggerProps, ref: buttonRef, isPressed: state.isOpen}],
149
149
  [OverlayTriggerStateContext, state],
150
150
  [PopoverContext, {
151
+ trigger: 'Select',
151
152
  triggerRef: buttonRef,
152
153
  placement: 'bottom start',
153
154
  style: {'--trigger-width': buttonWidth} as React.CSSProperties
@@ -230,7 +231,7 @@ function SelectValue<T extends object>(props: SelectValueProps<T>, ref: Forwarde
230
231
  });
231
232
  }
232
233
 
233
- let stringFormatter = useLocalizedStringFormatter(intlMessages);
234
+ let stringFormatter = useLocalizedStringFormatter(intlMessages, 'react-aria-components');
234
235
 
235
236
  let renderProps = useRenderProps({
236
237
  ...props,
package/src/Slider.tsx CHANGED
@@ -210,7 +210,7 @@ export interface SliderThumbRenderProps {
210
210
  isDisabled: boolean
211
211
  }
212
212
 
213
- export interface SliderThumbProps extends Omit<AriaSliderThumbProps, 'validationState'>, HoverEvents, RenderProps<SliderThumbRenderProps> {}
213
+ export interface SliderThumbProps extends Omit<AriaSliderThumbProps, 'label' | 'validationState'>, HoverEvents, RenderProps<SliderThumbRenderProps> {}
214
214
 
215
215
  function SliderThumb(props: SliderThumbProps, ref: ForwardedRef<HTMLDivElement>) {
216
216
  let state = useContext(SliderStateContext)!;