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/Switch.tsx CHANGED
@@ -10,10 +10,10 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import {AriaSwitchProps, HoverEvents, mergeProps, useFocusRing, useHover, usePress, useSwitch, VisuallyHidden} from 'react-aria';
13
+ import {AriaSwitchProps, HoverEvents, mergeProps, useFocusRing, useHover, useSwitch, VisuallyHidden} from 'react-aria';
14
14
  import {ContextValue, forwardRefType, removeDataAttributes, RenderProps, SlotProps, useContextProps, useRenderProps} from './utils';
15
15
  import {filterDOMProps} from '@react-aria/utils';
16
- import React, {createContext, ForwardedRef, forwardRef, useState} from 'react';
16
+ import React, {createContext, ForwardedRef, forwardRef, useRef} from 'react';
17
17
  import {ToggleState, useToggleState} from 'react-stately';
18
18
 
19
19
  export interface SwitchProps extends Omit<AriaSwitchProps, 'children'>, HoverEvents, RenderProps<SwitchRenderProps>, SlotProps {}
@@ -60,49 +60,31 @@ export interface SwitchRenderProps {
60
60
  state: ToggleState
61
61
  }
62
62
 
63
- export const SwitchContext = createContext<ContextValue<SwitchProps, HTMLInputElement>>(null);
63
+ export const SwitchContext = createContext<ContextValue<SwitchProps, HTMLLabelElement>>(null);
64
64
 
65
- function Switch(props: SwitchProps, ref: ForwardedRef<HTMLInputElement>) {
65
+ function Switch(props: SwitchProps, ref: ForwardedRef<HTMLLabelElement>) {
66
66
  [props, ref] = useContextProps(props, ref, SwitchContext);
67
+ let inputRef = useRef<HTMLInputElement>(null);
67
68
  let state = useToggleState(props);
68
- let {inputProps, isSelected, isDisabled, isReadOnly, isPressed: isPressedKeyboard} = useSwitch({
69
+ let {labelProps, inputProps, isSelected, isDisabled, isReadOnly, isPressed} = useSwitch({
69
70
  ...removeDataAttributes(props),
70
71
  // ReactNode type doesn't allow function children.
71
72
  children: typeof props.children === 'function' ? true : props.children
72
- }, state, ref);
73
+ }, state, inputRef);
73
74
  let {isFocused, isFocusVisible, focusProps} = useFocusRing();
74
75
  let isInteractionDisabled = props.isDisabled || props.isReadOnly;
75
76
 
76
- // Handle press state for full label. Keyboard press state is returned by useSwitch
77
- // since it is handled on the <input> element itself.
78
- let [isPressed, setPressed] = useState(false);
79
- let {pressProps} = usePress({
80
- isDisabled: isInteractionDisabled,
81
- onPressStart(e) {
82
- if (e.pointerType !== 'keyboard') {
83
- setPressed(true);
84
- }
85
- },
86
- onPressEnd(e) {
87
- if (e.pointerType !== 'keyboard') {
88
- setPressed(false);
89
- }
90
- }
91
- });
92
-
93
77
  let {hoverProps, isHovered} = useHover({
94
78
  ...props,
95
79
  isDisabled: isInteractionDisabled
96
80
  });
97
81
 
98
- let pressed = isInteractionDisabled ? false : (isPressed || isPressedKeyboard);
99
-
100
82
  let renderProps = useRenderProps({
101
83
  ...props,
102
84
  defaultClassName: 'react-aria-Switch',
103
85
  values: {
104
86
  isSelected,
105
- isPressed: pressed,
87
+ isPressed,
106
88
  isHovered,
107
89
  isFocused,
108
90
  isFocusVisible,
@@ -117,17 +99,18 @@ function Switch(props: SwitchProps, ref: ForwardedRef<HTMLInputElement>) {
117
99
 
118
100
  return (
119
101
  <label
120
- {...mergeProps(DOMProps, pressProps, hoverProps, renderProps)}
102
+ {...mergeProps(DOMProps, labelProps, hoverProps, renderProps)}
103
+ ref={ref}
121
104
  slot={props.slot || undefined}
122
105
  data-selected={isSelected || undefined}
123
- data-pressed={pressed || undefined}
106
+ data-pressed={isPressed || undefined}
124
107
  data-hovered={isHovered || undefined}
125
108
  data-focused={isFocused || undefined}
126
109
  data-focus-visible={isFocusVisible || undefined}
127
110
  data-disabled={isDisabled || undefined}
128
111
  data-readonly={isReadOnly || undefined}>
129
112
  <VisuallyHidden elementType="span">
130
- <input {...inputProps} {...focusProps} ref={ref} />
113
+ <input {...inputProps} {...focusProps} ref={inputRef} />
131
114
  </VisuallyHidden>
132
115
  {renderProps.children}
133
116
  </label>
package/src/Table.tsx CHANGED
@@ -4,7 +4,7 @@ import {buildHeaderRows, TableColumnResizeState} from '@react-stately/table';
4
4
  import {ButtonContext} from './Button';
5
5
  import {CheckboxContext} from './Checkbox';
6
6
  import {ColumnSize, ColumnStaticSize, TableCollection as ITableCollection, TableProps as SharedTableProps} from '@react-types/table';
7
- import {ContextValue, defaultSlot, DOMProps, forwardRefType, Provider, RenderProps, SlotProps, StyleProps, StyleRenderProps, useContextProps, useRenderProps} from './utils';
7
+ import {ContextValue, defaultSlot, DOMProps, forwardRefType, Provider, RenderProps, ScrollableProps, SlotProps, StyleProps, StyleRenderProps, useContextProps, useRenderProps} from './utils';
8
8
  import {DisabledBehavior, DraggableCollectionState, DroppableCollectionState, Node, SelectionBehavior, SelectionMode, SortDirection, TableState, useTableColumnResizeState, useTableState} from 'react-stately';
9
9
  import {DragAndDropContext, DragAndDropHooks, DropIndicator, DropIndicatorContext, DropIndicatorProps} from './useDragAndDrop';
10
10
  import {DraggableItemResult, DragPreviewRenderer, DropIndicatorAria, DroppableCollectionResult, FocusScope, ListKeyboardDelegate, mergeProps, useFocusRing, useHover, useLocale, useLocalizedStringFormatter, useTable, useTableCell, useTableColumnHeader, useTableColumnResize, useTableHeaderRow, useTableRow, useTableRowGroup, useTableSelectAllCheckbox, useTableSelectionCheckbox, useVisuallyHidden} from 'react-aria';
@@ -12,7 +12,7 @@ import {filterDOMProps, useLayoutEffect, useObjectRef, useResizeObserver} from '
12
12
  import {GridNode} from '@react-types/grid';
13
13
  // @ts-ignore
14
14
  import intlMessages from '../intl/*.json';
15
- import React, {createContext, ForwardedRef, forwardRef, ReactElement, ReactNode, RefObject, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
15
+ import React, {createContext, ForwardedRef, forwardRef, JSX, ReactElement, ReactNode, RefObject, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
16
16
  import ReactDOM from 'react-dom';
17
17
 
18
18
  class TableCollection<T> extends BaseCollection<T> implements ITableCollection<T> {
@@ -190,7 +190,7 @@ interface ResizableTableContainerContextValue {
190
190
 
191
191
  const ResizableTableContainerContext = createContext<ResizableTableContainerContextValue | null>(null);
192
192
 
193
- export interface ResizableTableContainerProps extends DOMProps {
193
+ export interface ResizableTableContainerProps extends DOMProps, ScrollableProps<HTMLDivElement> {
194
194
  /**
195
195
  * Handler that is called when a user starts a column resize.
196
196
  */
@@ -235,7 +235,8 @@ function ResizableTableContainer(props: ResizableTableContainerProps, ref: Forwa
235
235
  {...filterDOMProps(props as any)}
236
236
  ref={objectRef}
237
237
  className={props.className || 'react-aria-ResizableTableContainer'}
238
- style={props.style}>
238
+ style={props.style}
239
+ onScroll={props.onScroll}>
239
240
  <ResizableTableContainerContext.Provider value={ctx}>
240
241
  {props.children}
241
242
  </ResizableTableContainerContext.Provider>
@@ -272,7 +273,7 @@ export interface TableRenderProps {
272
273
  state: TableState<unknown>
273
274
  }
274
275
 
275
- export interface TableProps extends Omit<SharedTableProps<any>, 'children'>, StyleRenderProps<TableRenderProps>, SlotProps, AriaLabelingProps {
276
+ export interface TableProps extends Omit<SharedTableProps<any>, 'children'>, StyleRenderProps<TableRenderProps>, SlotProps, AriaLabelingProps, ScrollableProps<HTMLTableElement> {
276
277
  /** The elements that make up the table. Includes the TableHeader, TableBody, Columns, and Rows. */
277
278
  children?: ReactNode,
278
279
  /**
@@ -287,8 +288,6 @@ export interface TableProps extends Omit<SharedTableProps<any>, 'children'>, Sty
287
288
  disabledBehavior?: DisabledBehavior,
288
289
  /** Handler that is called when a user performs an action on the row. */
289
290
  onRowAction?: (key: Key) => void,
290
- /** Handler that is called when a user performs an action on the cell. */
291
- onCellAction?: (key: Key) => void,
292
291
  /** The drag and drop hooks returned by `useDragAndDrop` used to enable drag and drop behavior for the Table. */
293
292
  dragAndDropHooks?: DragAndDropHooks
294
293
  }
@@ -324,7 +323,7 @@ function Table(props: TableProps, ref: ForwardedRef<HTMLTableElement>) {
324
323
  let dropState: DroppableCollectionState | undefined = undefined;
325
324
  let droppableCollection: DroppableCollectionResult | undefined = undefined;
326
325
  let isRootDropTarget = false;
327
- let dragPreview: React.JSX.Element | null = null;
326
+ let dragPreview: JSX.Element | null = null;
328
327
  let preview = useRef<DragPreviewRenderer>(null);
329
328
 
330
329
  if (isListDraggable && dragAndDropHooks) {
@@ -416,6 +415,7 @@ function Table(props: TableProps, ref: ForwardedRef<HTMLTableElement>) {
416
415
  style={style}
417
416
  ref={ref}
418
417
  slot={props.slot || undefined}
418
+ onScroll={props.onScroll}
419
419
  data-allows-dragging={isListDraggable || undefined}
420
420
  data-drop-target={isRootDropTarget || undefined}
421
421
  data-focused={isFocused || undefined}
@@ -461,13 +461,16 @@ export interface TableHeaderProps<T> extends StyleProps {
461
461
  /** A list of table columns. */
462
462
  columns?: T[],
463
463
  /** A list of `Column(s)` or a function. If the latter, a list of columns must be provided using the `columns` prop. */
464
- children?: ReactNode | ((item: T) => ReactElement)
464
+ children?: ReactNode | ((item: T) => ReactElement),
465
+ /** Values that should invalidate the column cache when using dynamic collections. */
466
+ dependencies?: any[]
465
467
  }
466
468
 
467
469
  function TableHeader<T extends object>(props: TableHeaderProps<T>, ref: ForwardedRef<HTMLTableSectionElement>) {
468
470
  let children = useCollectionChildren({
469
471
  children: props.children,
470
- items: props.columns
472
+ items: props.columns,
473
+ dependencies: props.dependencies
471
474
  });
472
475
 
473
476
  let renderer = typeof props.children === 'function' ? props.children : null;
@@ -525,12 +528,9 @@ export interface ColumnRenderProps {
525
528
  startResize(): void
526
529
  }
527
530
 
528
- export interface ColumnProps<T = object> extends RenderProps<ColumnRenderProps> {
531
+ export interface ColumnProps extends RenderProps<ColumnRenderProps> {
532
+ /** The unique id of the column. */
529
533
  id?: Key,
530
- /** Rendered contents of the column if `children` contains child columns. */
531
- title?: ReactNode,
532
- /** A list of child columns used when dynamically rendering nested child columns. */
533
- childColumns?: Iterable<T>,
534
534
  /** Whether the column allows sorting. */
535
535
  allowsSorting?: boolean,
536
536
  /** Whether a column is a [row header](https://www.w3.org/TR/wai-aria-1.1/#rowheader) and should be announced by assistive technology during row navigation. */
@@ -547,21 +547,8 @@ export interface ColumnProps<T = object> extends RenderProps<ColumnRenderProps>
547
547
  maxWidth?: ColumnStaticSize | null
548
548
  }
549
549
 
550
- function Column<T extends object>(props: ColumnProps<T>, ref: ForwardedRef<HTMLTableCellElement>): React.JSX.Element | null {
551
- let render = useContext(CollectionRendererContext);
552
- let childColumns: ReactNode | ((item: T) => ReactNode);
553
- if (typeof render === 'function') {
554
- childColumns = render;
555
- } else if (typeof props.children !== 'function') {
556
- childColumns = props.children;
557
- }
558
-
559
- let children = useCollectionChildren({
560
- children: (props.title || props.childColumns) ? childColumns : null,
561
- items: props.childColumns
562
- });
563
-
564
- return useSSRCollectionNode('column', props, ref, props.title ?? props.children, children);
550
+ function Column(props: ColumnProps, ref: ForwardedRef<HTMLTableCellElement>): JSX.Element | null {
551
+ return useSSRCollectionNode('column', props, ref, props.children);
565
552
  }
566
553
 
567
554
  /**
@@ -588,7 +575,7 @@ export interface TableBodyProps<T> extends CollectionProps<T>, StyleRenderProps<
588
575
  renderEmptyState?: (props: TableBodyRenderProps) => ReactNode
589
576
  }
590
577
 
591
- function TableBody<T extends object>(props: TableBodyProps<T>, ref: ForwardedRef<HTMLTableSectionElement>): React.JSX.Element | null {
578
+ function TableBody<T extends object>(props: TableBodyProps<T>, ref: ForwardedRef<HTMLTableSectionElement>): JSX.Element | null {
592
579
  let children = useCollectionChildren(props);
593
580
  return useSSRCollectionNode('tablebody', props, ref, null, children);
594
581
  }
@@ -602,23 +589,30 @@ export {_TableBody as TableBody};
602
589
  export interface RowRenderProps extends ItemRenderProps {}
603
590
 
604
591
  export interface RowProps<T> extends StyleRenderProps<RowRenderProps>, LinkDOMProps {
592
+ /** The unique id of the row. */
605
593
  id?: Key,
606
594
  /** A list of columns used when dynamically rendering cells. */
607
595
  columns?: Iterable<T>,
608
596
  /** The cells within the row. Supports static items or a function for dynamic rendering. */
609
597
  children?: ReactNode | ((item: T) => ReactElement),
598
+ /** The object value that this row represents. When using dynamic collections, this is set automatically. */
599
+ value?: T,
600
+ /** Values that should invalidate the cell cache when using dynamic collections. */
601
+ dependencies?: any[],
610
602
  /** A string representation of the row's contents, used for features like typeahead. */
611
603
  textValue?: string
612
604
  }
613
605
 
614
- function Row<T extends object>(props: RowProps<T>, ref: ForwardedRef<HTMLTableRowElement>): React.JSX.Element | null {
606
+ function Row<T extends object>(props: RowProps<T>, ref: ForwardedRef<HTMLTableRowElement>): JSX.Element | null {
607
+ let dependencies = [props.value].concat(props.dependencies);
615
608
  let children = useCollectionChildren({
609
+ dependencies,
616
610
  children: props.children,
617
611
  items: props.columns,
618
612
  idScope: props.id
619
613
  });
620
614
 
621
- let ctx = useMemo(() => ({idScope: props.id}), [props.id]);
615
+ let ctx = useMemo(() => ({idScope: props.id, dependencies}), [props.id, ...dependencies]);
622
616
 
623
617
  return useSSRCollectionNode('item', props, ref, null, (
624
618
  <CollectionContext.Provider value={ctx}>
@@ -657,12 +651,13 @@ export interface CellRenderProps {
657
651
  }
658
652
 
659
653
  export interface CellProps extends RenderProps<CellRenderProps> {
654
+ /** The unique id of the cell. */
660
655
  id?: Key,
661
656
  /** A string representation of the cell's contents, used for features like typeahead. */
662
657
  textValue?: string
663
658
  }
664
659
 
665
- function Cell(props: CellProps, ref: ForwardedRef<HTMLTableCellElement>): React.JSX.Element | null {
660
+ function Cell(props: CellProps, ref: ForwardedRef<HTMLTableCellElement>): JSX.Element | null {
666
661
  return useSSRCollectionNode('cell', props, ref, props.children);
667
662
  }
668
663
 
@@ -804,7 +799,6 @@ function TableColumnHeader<T>({column}: {column: GridNode<T>}) {
804
799
  ref
805
800
  );
806
801
  let {isFocused, isFocusVisible, focusProps} = useFocusRing();
807
- let {hoverProps, isHovered} = useHover({});
808
802
 
809
803
  let layoutState = useContext(TableColumnResizeStateContext);
810
804
  let isResizing = false;
@@ -818,7 +812,8 @@ function TableColumnHeader<T>({column}: {column: GridNode<T>}) {
818
812
  }
819
813
  }
820
814
 
821
- let props: ColumnProps<unknown> = column.props;
815
+ let props: ColumnProps = column.props;
816
+ let {hoverProps, isHovered} = useHover({isDisabled: !props.allowsSorting});
822
817
  let renderProps = useRenderProps({
823
818
  ...props,
824
819
  id: undefined,
@@ -859,6 +854,7 @@ function TableColumnHeader<T>({column}: {column: GridNode<T>}) {
859
854
  style={style}
860
855
  colSpan={column.colspan}
861
856
  ref={ref}
857
+ data-hovered={isHovered || undefined}
862
858
  data-focused={isFocused || undefined}
863
859
  data-focus-visible={isFocusVisible || undefined}
864
860
  data-resizing={isResizing || undefined}
@@ -909,7 +905,7 @@ function ColumnResizer(props: ColumnResizerProps, ref: ForwardedRef<HTMLDivEleme
909
905
  if (!layoutState) {
910
906
  throw new Error('Wrap your <Table> in a <ResizableTableContainer> to enable column resizing');
911
907
  }
912
- let stringFormatter = useLocalizedStringFormatter(intlMessages);
908
+ let stringFormatter = useLocalizedStringFormatter(intlMessages, 'react-aria-components');
913
909
 
914
910
  let {onResizeStart, onResize, onResizeEnd} = useContext(ResizableTableContainerContext)!;
915
911
  let {column, triggerRef} = useContext(ColumnResizerContext)!;
@@ -1222,6 +1218,7 @@ function TableDropIndicator(props: TableDropIndicatorProps, ref: ForwardedRef<HT
1222
1218
  colSpan={state.collection.columnCount}
1223
1219
  style={{padding: 0}}>
1224
1220
  <div {...visuallyHiddenProps} role="button" {...dropIndicatorProps} ref={buttonRef} />
1221
+ {renderProps.children}
1225
1222
  </td>
1226
1223
  </tr>
1227
1224
  );
package/src/Tabs.tsx CHANGED
@@ -16,7 +16,7 @@ import {Collection, Node, TabListState, useTabListState} from 'react-stately';
16
16
  import {CollectionDocumentContext, CollectionPortal, CollectionProps, useCollectionDocument, useSSRCollectionNode} from './Collection';
17
17
  import {ContextValue, createHideableComponent, forwardRefType, Hidden, Provider, RenderProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps, useSlottedContext} from './utils';
18
18
  import {filterDOMProps, useObjectRef} from '@react-aria/utils';
19
- import React, {createContext, ForwardedRef, forwardRef, RefObject, useContext, useMemo} from 'react';
19
+ import React, {createContext, ForwardedRef, forwardRef, JSX, RefObject, useContext, useMemo} from 'react';
20
20
 
21
21
  export interface TabsProps extends Omit<AriaTabListProps<any>, 'items' | 'children'>, RenderProps<TabsRenderProps>, SlotProps {}
22
22
 
@@ -43,6 +43,7 @@ export interface TabListRenderProps {
43
43
  }
44
44
 
45
45
  export interface TabProps extends RenderProps<TabRenderProps>, AriaLabelingProps, LinkDOMProps {
46
+ /** The unique id of the tab. */
46
47
  id?: Key
47
48
  }
48
49
 
@@ -191,7 +192,7 @@ function TabsInner({props, tabsRef: ref, collection}: TabsInnerProps) {
191
192
  const _Tabs = /*#__PURE__*/ (forwardRef as forwardRefType)(Tabs);
192
193
  export {_Tabs as Tabs};
193
194
 
194
- function TabList<T extends object>(props: TabListProps<T>, ref: ForwardedRef<HTMLDivElement>): React.JSX.Element {
195
+ function TabList<T extends object>(props: TabListProps<T>, ref: ForwardedRef<HTMLDivElement>): JSX.Element {
195
196
  let document = useContext(CollectionDocumentContext);
196
197
  return document
197
198
  ? <CollectionPortal {...props} />
@@ -251,7 +252,7 @@ function TabListInner<T extends object>({props, forwardedRef: ref}: TabListInner
251
252
  const _TabList = /*#__PURE__*/ (forwardRef as forwardRefType)(TabList);
252
253
  export {_TabList as TabList};
253
254
 
254
- function Tab(props: TabProps, ref: ForwardedRef<HTMLDivElement>): React.JSX.Element | null {
255
+ function Tab(props: TabProps, ref: ForwardedRef<HTMLDivElement>): JSX.Element | null {
255
256
  return useSSRCollectionNode('item', props, ref, props.children);
256
257
  }
257
258
 
package/src/TagGroup.tsx CHANGED
@@ -19,7 +19,7 @@ import {Key, LinkDOMProps} from '@react-types/shared';
19
19
  import {LabelContext} from './Label';
20
20
  import {ListState, Node, useListState} from 'react-stately';
21
21
  import {ListStateContext} from './ListBox';
22
- import React, {createContext, ForwardedRef, forwardRef, ReactNode, useContext, useEffect, useRef} from 'react';
22
+ import React, {createContext, ForwardedRef, forwardRef, JSX, ReactNode, useContext, useEffect, useRef} from 'react';
23
23
  import {TextContext} from './Text';
24
24
 
25
25
  export interface TagGroupProps extends Omit<AriaTagGroupProps<unknown>, 'children' | 'items' | 'label' | 'description' | 'errorMessage' | 'keyboardDelegate'>, DOMProps, SlotProps {}
@@ -196,7 +196,7 @@ export interface TagProps extends RenderProps<TagRenderProps>, LinkDOMProps {
196
196
  textValue?: string
197
197
  }
198
198
 
199
- function Tag(props: TagProps, ref: ForwardedRef<HTMLDivElement>): React.JSX.Element | null {
199
+ function Tag(props: TagProps, ref: ForwardedRef<HTMLDivElement>): JSX.Element | null {
200
200
  return useSSRCollectionNode('item', props, ref, props.children);
201
201
  }
202
202
 
package/src/Tooltip.tsx CHANGED
@@ -36,7 +36,12 @@ export interface TooltipProps extends PositionProps, OverlayTriggerProps, AriaLa
36
36
  /**
37
37
  * Whether the tooltip is currently performing an exit animation.
38
38
  */
39
- isExiting?: boolean
39
+ isExiting?: boolean,
40
+ /**
41
+ * The container element in which the overlay portal will be placed. This may have unknown behavior depending on where it is portalled to.
42
+ * @default document.body
43
+ */
44
+ UNSTABLE_portalContainer?: Element
40
45
  }
41
46
 
42
47
  export interface TooltipRenderProps {
@@ -87,7 +92,7 @@ export function TooltipTrigger(props: TooltipTriggerComponentProps) {
87
92
  );
88
93
  }
89
94
 
90
- function Tooltip(props: TooltipProps, ref: ForwardedRef<HTMLDivElement>) {
95
+ function Tooltip({UNSTABLE_portalContainer, ...props}: TooltipProps, ref: ForwardedRef<HTMLDivElement>) {
91
96
  [props, ref] = useContextProps(props, ref, TooltipContext);
92
97
  let contextState = useContext(TooltipTriggerStateContext);
93
98
  let localState = useTooltipTriggerState(props);
@@ -98,7 +103,7 @@ function Tooltip(props: TooltipProps, ref: ForwardedRef<HTMLDivElement>) {
98
103
  }
99
104
 
100
105
  return (
101
- <OverlayContainer>
106
+ <OverlayContainer portalContainer={UNSTABLE_portalContainer}>
102
107
  <TooltipInner {...props} tooltipRef={ref} isExiting={isExiting} />
103
108
  </OverlayContainer>
104
109
  );
@@ -142,7 +147,7 @@ function TooltipInner(props: TooltipProps & {isExiting: boolean, tooltipRef: Ref
142
147
  {...tooltipProps}
143
148
  ref={props.tooltipRef}
144
149
  {...renderProps}
145
- style={{...renderProps.style, ...overlayProps.style}}
150
+ style={{...overlayProps.style, ...renderProps.style}}
146
151
  data-placement={placement}
147
152
  data-entering={isEntering || undefined}
148
153
  data-exiting={props.isExiting || undefined}>
package/src/index.ts CHANGED
@@ -15,6 +15,7 @@ export {Button, ButtonContext} from './Button';
15
15
  export {Calendar, CalendarGrid, CalendarGridHeader, CalendarGridBody, CalendarHeaderCell, CalendarCell, RangeCalendar, CalendarContext, RangeCalendarContext, CalendarStateContext, RangeCalendarStateContext} from './Calendar';
16
16
  export {Checkbox, CheckboxGroup, CheckboxGroupContext, CheckboxContext, CheckboxGroupStateContext} from './Checkbox';
17
17
  export {ComboBox, ComboBoxContext, ComboBoxStateContext} from './ComboBox';
18
+ export {composeRenderProps, Provider, useContextProps, useSlottedContext} from './utils';
18
19
  export {DateField, DateInput, DateSegment, TimeField, DateFieldContext, TimeFieldContext, DateFieldStateContext, TimeFieldStateContext} from './DateField';
19
20
  export {DatePicker, DateRangePicker, DatePickerContext, DateRangePickerContext, DatePickerStateContext, DateRangePickerStateContext} from './DatePicker';
20
21
  export {DialogTrigger, Dialog, DialogContext, OverlayTriggerStateContext} from './Dialog';
@@ -39,7 +40,6 @@ export {NumberField, NumberFieldContext, NumberFieldStateContext} from './Number
39
40
  export {OverlayArrow} from './OverlayArrow';
40
41
  export {Popover, PopoverContext} from './Popover';
41
42
  export {ProgressBar, ProgressBarContext} from './ProgressBar';
42
- export {Provider, useContextProps, useSlottedContext} from './utils';
43
43
  export {RadioGroup, Radio, RadioGroupContext, RadioContext, RadioGroupStateContext} from './RadioGroup';
44
44
  export {SearchField, SearchFieldContext} from './SearchField';
45
45
  export {Select, SelectValue, SelectContext, SelectValueContext, SelectStateContext} from './Select';
@@ -56,7 +56,7 @@ export {ToggleButton, ToggleButtonContext} from './ToggleButton';
56
56
  export {Toolbar, ToolbarContext} from './Toolbar';
57
57
  export {TooltipTrigger, Tooltip, TooltipTriggerStateContext, TooltipContext} from './Tooltip';
58
58
  export {useDragAndDrop, DropIndicator, DropIndicatorContext, DragAndDropContext} from './useDragAndDrop';
59
- export {DIRECTORY_DRAG_TYPE, isDirectoryDropItem, isFileDropItem, isTextDropItem, SSRProvider, RouterProvider, I18nProvider} from 'react-aria';
59
+ export {DIRECTORY_DRAG_TYPE, isDirectoryDropItem, isFileDropItem, isTextDropItem, SSRProvider, RouterProvider, I18nProvider, useLocale} from 'react-aria';
60
60
  export {FormValidationContext} from 'react-stately';
61
61
 
62
62
  export type {BreadcrumbsProps, BreadcrumbProps} from './Breadcrumbs';
@@ -40,7 +40,7 @@ import {
40
40
  useDraggableCollectionState,
41
41
  useDroppableCollectionState
42
42
  } from 'react-stately';
43
- import React, {createContext, ForwardedRef, forwardRef, ReactNode, RefObject, useContext, useMemo} from 'react';
43
+ import React, {createContext, ForwardedRef, forwardRef, JSX, ReactNode, RefObject, useContext, useMemo} from 'react';
44
44
  import {RenderProps} from './utils';
45
45
 
46
46
  interface DraggableCollectionStateOpts extends Omit<DraggableCollectionStateOptions, 'getItems'> {}
@@ -50,7 +50,7 @@ interface DragHooks {
50
50
  useDraggableCollection?: (props: DraggableCollectionOptions, state: DraggableCollectionState, ref: RefObject<HTMLElement>) => void,
51
51
  useDraggableItem?: (props: DraggableItemProps, state: DraggableCollectionState) => DraggableItemResult,
52
52
  DragPreview?: typeof DragPreview,
53
- renderDragPreview?: (items: DragItem[]) => React.JSX.Element
53
+ renderDragPreview?: (items: DragItem[]) => JSX.Element
54
54
  }
55
55
 
56
56
  interface DropHooks {
@@ -58,7 +58,7 @@ interface DropHooks {
58
58
  useDroppableCollection?: (props: DroppableCollectionOptions, state: DroppableCollectionState, ref: RefObject<HTMLElement>) => DroppableCollectionResult,
59
59
  useDroppableItem?: (options: DroppableItemOptions, state: DroppableCollectionState, ref: RefObject<HTMLElement>) => DroppableItemResult,
60
60
  useDropIndicator?: (props: AriaDropIndicatorProps, state: DroppableCollectionState, ref: RefObject<HTMLElement>) => DropIndicatorAria,
61
- renderDropIndicator?: (target: DropTarget) => React.JSX.Element,
61
+ renderDropIndicator?: (target: DropTarget) => JSX.Element,
62
62
  dropTargetDelegate?: DropTargetDelegate,
63
63
  ListDropTargetDelegate: typeof ListDropTargetDelegate
64
64
  }
@@ -80,13 +80,13 @@ export interface DragAndDropOptions extends Omit<DraggableCollectionProps, 'prev
80
80
  * A function that renders a drag preview, which is shown under the user's cursor while dragging.
81
81
  * By default, a copy of the dragged element is rendered.
82
82
  */
83
- renderDragPreview?: (items: DragItem[]) => React.JSX.Element,
83
+ renderDragPreview?: (items: DragItem[]) => JSX.Element,
84
84
  /**
85
85
  * A function that renders a drop indicator element between two items in a collection.
86
86
  * This should render a `<DropIndicator>` element. If this function is not provided, a
87
87
  * default DropIndicator is provided.
88
88
  */
89
- renderDropIndicator?: (target: DropTarget) => React.JSX.Element,
89
+ renderDropIndicator?: (target: DropTarget) => JSX.Element,
90
90
  /** A custom delegate object that provides drop targets for pointer coordinates within the collection. */
91
91
  dropTargetDelegate?: DropTargetDelegate
92
92
  }
@@ -160,7 +160,7 @@ interface DropIndicatorContextValue {
160
160
  render: (props: DropIndicatorProps, ref: ForwardedRef<HTMLElement>) => ReactNode
161
161
  }
162
162
 
163
- function DropIndicator(props: DropIndicatorProps, ref: ForwardedRef<HTMLElement>): React.JSX.Element {
163
+ function DropIndicator(props: DropIndicatorProps, ref: ForwardedRef<HTMLElement>): JSX.Element {
164
164
  let {render} = useContext(DropIndicatorContext)!;
165
165
  return <>{render(props, ref)}</>;
166
166
  }
package/src/utils.tsx CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  import {AriaLabelingProps, DOMProps as SharedDOMProps} from '@react-types/shared';
14
14
  import {mergeProps, mergeRefs, useLayoutEffect, useObjectRef} from '@react-aria/utils';
15
- import React, {Context, createContext, CSSProperties, ForwardedRef, ReactNode, RefCallback, RefObject, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
15
+ import React, {Context, createContext, CSSProperties, ForwardedRef, JSX, ReactNode, RefCallback, RefObject, UIEvent, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
16
16
  import ReactDOM from 'react-dom';
17
17
  import {useIsSSR} from 'react-aria';
18
18
 
@@ -53,13 +53,13 @@ interface ProviderProps<A, B, C, D, E, F, G, H, I, J, K> {
53
53
  children: ReactNode
54
54
  }
55
55
 
56
- export function Provider<A, B, C, D, E, F, G, H, I, J, K>({values, children}: ProviderProps<A, B, C, D, E, F, G, H, I, J, K>): React.JSX.Element {
56
+ export function Provider<A, B, C, D, E, F, G, H, I, J, K>({values, children}: ProviderProps<A, B, C, D, E, F, G, H, I, J, K>): JSX.Element {
57
57
  for (let [Context, value] of values) {
58
58
  // @ts-ignore
59
59
  children = <Context.Provider value={value}>{children}</Context.Provider>;
60
60
  }
61
61
 
62
- return children as React.JSX.Element;
62
+ return children as JSX.Element;
63
63
  }
64
64
 
65
65
  export interface StyleProps {
@@ -74,6 +74,11 @@ export interface DOMProps extends StyleProps {
74
74
  children?: ReactNode
75
75
  }
76
76
 
77
+ export interface ScrollableProps<T extends Element> {
78
+ /** Handler that is called when a user scrolls. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/scroll_event). */
79
+ onScroll?: (e: UIEvent<T>) => void
80
+ }
81
+
77
82
  export interface StyleRenderProps<T> {
78
83
  /** The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the element. A function may be provided to compute the class based on component state. */
79
84
  className?: string | ((values: T) => string),
@@ -136,6 +141,18 @@ export function useRenderProps<T>(props: RenderPropsHookOptions<T>) {
136
141
  }, [className, style, children, defaultClassName, defaultChildren, values]);
137
142
  }
138
143
 
144
+ /**
145
+ * A helper function that accepts a user-provided render prop value (either a static value or a function),
146
+ * and combines it with another value to create a final result.
147
+ */
148
+ export function composeRenderProps<T, U, V extends T>(
149
+ // https://stackoverflow.com/questions/60898079/typescript-type-t-or-function-t-usage
150
+ value: T extends any ? (T | ((renderProps: U) => V)) : never,
151
+ wrap: (prevValue: T, renderProps: U) => V
152
+ ): (renderProps: U) => V {
153
+ return (renderProps) => wrap(typeof value === 'function' ? value(renderProps) : value, renderProps);
154
+ }
155
+
139
156
  export type WithRef<T, E> = T & {ref?: ForwardedRef<E>};
140
157
  export interface SlotProps {
141
158
  /**