@react-spectrum/s2 1.1.0 → 1.2.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 (427) hide show
  1. package/dist/Accordion.cjs +2 -2
  2. package/dist/Accordion.css +2 -2
  3. package/dist/Accordion.mjs +2 -2
  4. package/dist/ActionBar.cjs +59 -59
  5. package/dist/ActionBar.css +58 -58
  6. package/dist/ActionBar.mjs +59 -59
  7. package/dist/ActionButton.cjs +233 -233
  8. package/dist/ActionButton.css +160 -160
  9. package/dist/ActionButton.mjs +233 -233
  10. package/dist/ActionButtonGroup.cjs +15 -15
  11. package/dist/ActionButtonGroup.css +9 -9
  12. package/dist/ActionButtonGroup.mjs +15 -15
  13. package/dist/Add.cjs +10 -10
  14. package/dist/Add.css +6 -6
  15. package/dist/Add.mjs +10 -10
  16. package/dist/AlertDialog.cjs +3 -3
  17. package/dist/AlertDialog.css +3 -3
  18. package/dist/AlertDialog.mjs +3 -3
  19. package/dist/Asterisk.cjs +6 -6
  20. package/dist/Asterisk.css +4 -4
  21. package/dist/Asterisk.mjs +6 -6
  22. package/dist/Avatar.cjs +16 -16
  23. package/dist/Avatar.css +16 -16
  24. package/dist/Avatar.mjs +16 -16
  25. package/dist/AvatarGroup.cjs +120 -120
  26. package/dist/AvatarGroup.css +31 -31
  27. package/dist/AvatarGroup.mjs +120 -120
  28. package/dist/Badge.cjs +196 -196
  29. package/dist/Badge.css +125 -125
  30. package/dist/Badge.mjs +196 -196
  31. package/dist/Breadcrumbs.cjs +234 -234
  32. package/dist/Breadcrumbs.css +100 -100
  33. package/dist/Breadcrumbs.mjs +234 -234
  34. package/dist/Button.cjs +332 -332
  35. package/dist/Button.css +174 -174
  36. package/dist/Button.mjs +332 -332
  37. package/dist/ButtonGroup.cjs +20 -20
  38. package/dist/ButtonGroup.css +15 -15
  39. package/dist/ButtonGroup.mjs +20 -20
  40. package/dist/Calendar.cjs +168 -168
  41. package/dist/Calendar.css +134 -134
  42. package/dist/Calendar.mjs +168 -168
  43. package/dist/Card.cjs +309 -309
  44. package/dist/Card.css +206 -206
  45. package/dist/Card.mjs +309 -309
  46. package/dist/CardView.cjs +17 -17
  47. package/dist/CardView.css +17 -17
  48. package/dist/CardView.mjs +17 -17
  49. package/dist/CenterBaseline.cjs +1 -1
  50. package/dist/CenterBaseline.css +2 -2
  51. package/dist/CenterBaseline.mjs +1 -1
  52. package/dist/Checkbox.cjs +161 -161
  53. package/dist/Checkbox.css +92 -92
  54. package/dist/Checkbox.mjs +161 -161
  55. package/dist/CheckboxGroup.cjs +43 -43
  56. package/dist/CheckboxGroup.css +37 -37
  57. package/dist/CheckboxGroup.mjs +43 -43
  58. package/dist/Checkmark.cjs +12 -12
  59. package/dist/Checkmark.css +8 -8
  60. package/dist/Checkmark.mjs +12 -12
  61. package/dist/Chevron.cjs +12 -12
  62. package/dist/Chevron.css +10 -10
  63. package/dist/Chevron.mjs +12 -12
  64. package/dist/ClearButton.cjs +30 -30
  65. package/dist/ClearButton.css +30 -30
  66. package/dist/ClearButton.mjs +30 -30
  67. package/dist/CloseButton.cjs +55 -55
  68. package/dist/CloseButton.css +47 -47
  69. package/dist/CloseButton.mjs +55 -55
  70. package/dist/ColorArea.cjs +16 -16
  71. package/dist/ColorArea.css +16 -16
  72. package/dist/ColorArea.mjs +16 -16
  73. package/dist/ColorField.cjs +31 -31
  74. package/dist/ColorField.css +27 -27
  75. package/dist/ColorField.mjs +31 -31
  76. package/dist/ColorHandle.cjs +27 -27
  77. package/dist/ColorHandle.css +42 -42
  78. package/dist/ColorHandle.mjs +27 -27
  79. package/dist/ColorSlider.cjs +108 -108
  80. package/dist/ColorSlider.css +52 -52
  81. package/dist/ColorSlider.mjs +108 -108
  82. package/dist/ColorSwatch.cjs +29 -29
  83. package/dist/ColorSwatch.css +29 -29
  84. package/dist/ColorSwatch.mjs +29 -29
  85. package/dist/ColorSwatchPicker.cjs +29 -29
  86. package/dist/ColorSwatchPicker.css +48 -48
  87. package/dist/ColorSwatchPicker.mjs +29 -29
  88. package/dist/ColorWheel.cjs +26 -26
  89. package/dist/ColorWheel.css +17 -17
  90. package/dist/ColorWheel.mjs +26 -26
  91. package/dist/ComboBox.cjs +381 -381
  92. package/dist/ComboBox.cjs.map +1 -1
  93. package/dist/ComboBox.css +187 -187
  94. package/dist/ComboBox.css.map +1 -1
  95. package/dist/ComboBox.mjs +381 -381
  96. package/dist/ComboBox.mjs.map +1 -1
  97. package/dist/ContextualHelp.cjs +70 -41
  98. package/dist/ContextualHelp.cjs.map +1 -1
  99. package/dist/ContextualHelp.css +71 -71
  100. package/dist/ContextualHelp.css.map +1 -1
  101. package/dist/ContextualHelp.mjs +74 -46
  102. package/dist/ContextualHelp.mjs.map +1 -1
  103. package/dist/Cross.cjs +14 -14
  104. package/dist/Cross.css +10 -10
  105. package/dist/Cross.mjs +14 -14
  106. package/dist/CustomDialog.cjs +25 -25
  107. package/dist/CustomDialog.css +25 -25
  108. package/dist/CustomDialog.mjs +25 -25
  109. package/dist/Dash.cjs +10 -10
  110. package/dist/Dash.css +6 -6
  111. package/dist/Dash.mjs +10 -10
  112. package/dist/DateField.cjs +73 -73
  113. package/dist/DateField.css +77 -77
  114. package/dist/DateField.mjs +73 -73
  115. package/dist/DatePicker.cjs +172 -172
  116. package/dist/DatePicker.css +128 -128
  117. package/dist/DatePicker.mjs +172 -172
  118. package/dist/DateRangePicker.cjs +55 -55
  119. package/dist/DateRangePicker.css +59 -59
  120. package/dist/DateRangePicker.mjs +55 -55
  121. package/dist/Dialog.cjs +17 -17
  122. package/dist/Dialog.css +70 -70
  123. package/dist/Dialog.mjs +17 -17
  124. package/dist/Disclosure.cjs +119 -119
  125. package/dist/Disclosure.css +112 -112
  126. package/dist/Disclosure.mjs +119 -119
  127. package/dist/Divider.cjs +25 -25
  128. package/dist/Divider.css +25 -25
  129. package/dist/Divider.mjs +25 -25
  130. package/dist/DropZone.cjs +61 -61
  131. package/dist/DropZone.css +57 -57
  132. package/dist/DropZone.mjs +61 -61
  133. package/dist/Field.cjs +351 -351
  134. package/dist/Field.cjs.map +1 -1
  135. package/dist/Field.css +147 -147
  136. package/dist/Field.css.map +1 -1
  137. package/dist/Field.mjs +351 -351
  138. package/dist/Field.mjs.map +1 -1
  139. package/dist/Form.cjs +9 -9
  140. package/dist/Form.css +9 -9
  141. package/dist/Form.mjs +9 -9
  142. package/dist/FullscreenDialog.cjs +5 -5
  143. package/dist/FullscreenDialog.css +78 -78
  144. package/dist/FullscreenDialog.mjs +5 -5
  145. package/dist/IllustratedMessage.cjs +228 -228
  146. package/dist/IllustratedMessage.css +72 -72
  147. package/dist/IllustratedMessage.mjs +228 -228
  148. package/dist/Image.cjs +14 -14
  149. package/dist/Image.css +14 -14
  150. package/dist/Image.mjs +14 -14
  151. package/dist/InlineAlert.cjs +100 -100
  152. package/dist/InlineAlert.css +76 -76
  153. package/dist/InlineAlert.mjs +100 -100
  154. package/dist/Link.cjs +49 -49
  155. package/dist/Link.css +41 -41
  156. package/dist/Link.mjs +49 -49
  157. package/dist/LinkOut.cjs +8 -8
  158. package/dist/LinkOut.css +8 -8
  159. package/dist/LinkOut.mjs +8 -8
  160. package/dist/ListView.cjs +777 -0
  161. package/dist/ListView.cjs.map +1 -0
  162. package/dist/ListView.css +740 -0
  163. package/dist/ListView.css.map +1 -0
  164. package/dist/ListView.mjs +770 -0
  165. package/dist/ListView.mjs.map +1 -0
  166. package/dist/Menu.cjs +529 -437
  167. package/dist/Menu.cjs.map +1 -1
  168. package/dist/Menu.css +234 -190
  169. package/dist/Menu.css.map +1 -1
  170. package/dist/Menu.mjs +530 -439
  171. package/dist/Menu.mjs.map +1 -1
  172. package/dist/Meter.cjs +153 -153
  173. package/dist/Meter.css +91 -91
  174. package/dist/Meter.mjs +153 -153
  175. package/dist/Modal.cjs +66 -66
  176. package/dist/Modal.css +54 -54
  177. package/dist/Modal.mjs +66 -66
  178. package/dist/NotificationBadge.cjs +56 -56
  179. package/dist/NotificationBadge.css +49 -49
  180. package/dist/NotificationBadge.mjs +56 -56
  181. package/dist/NumberField.cjs +114 -114
  182. package/dist/NumberField.css +99 -99
  183. package/dist/NumberField.mjs +114 -114
  184. package/dist/Picker.cjs +336 -284
  185. package/dist/Picker.cjs.map +1 -1
  186. package/dist/Picker.css +173 -173
  187. package/dist/Picker.css.map +1 -1
  188. package/dist/Picker.mjs +338 -286
  189. package/dist/Picker.mjs.map +1 -1
  190. package/dist/Popover.cjs +87 -87
  191. package/dist/Popover.css +70 -70
  192. package/dist/Popover.mjs +87 -87
  193. package/dist/ProgressBar.cjs +163 -163
  194. package/dist/ProgressBar.css +99 -99
  195. package/dist/ProgressBar.mjs +163 -163
  196. package/dist/ProgressCircle.cjs +31 -31
  197. package/dist/ProgressCircle.css +24 -24
  198. package/dist/ProgressCircle.mjs +31 -31
  199. package/dist/Provider.cjs +11 -11
  200. package/dist/Provider.css +10 -10
  201. package/dist/Provider.mjs +11 -11
  202. package/dist/Radio.cjs +145 -145
  203. package/dist/Radio.css +78 -78
  204. package/dist/Radio.mjs +145 -145
  205. package/dist/RadioGroup.cjs +41 -41
  206. package/dist/RadioGroup.css +37 -37
  207. package/dist/RadioGroup.mjs +41 -41
  208. package/dist/RangeCalendar.cjs +7 -7
  209. package/dist/RangeCalendar.css +10 -10
  210. package/dist/RangeCalendar.mjs +7 -7
  211. package/dist/SearchField.cjs +41 -41
  212. package/dist/SearchField.css +45 -45
  213. package/dist/SearchField.mjs +41 -41
  214. package/dist/SegmentedControl.cjs +178 -178
  215. package/dist/SegmentedControl.css +123 -123
  216. package/dist/SegmentedControl.mjs +178 -178
  217. package/dist/SelectBoxGroup.cjs +142 -142
  218. package/dist/SelectBoxGroup.css +120 -120
  219. package/dist/SelectBoxGroup.mjs +142 -142
  220. package/dist/Slider.cjs +294 -294
  221. package/dist/Slider.css +154 -154
  222. package/dist/Slider.mjs +294 -294
  223. package/dist/StatusLight.cjs +115 -115
  224. package/dist/StatusLight.css +59 -59
  225. package/dist/StatusLight.mjs +115 -115
  226. package/dist/Switch.cjs +154 -154
  227. package/dist/Switch.css +74 -74
  228. package/dist/Switch.mjs +154 -154
  229. package/dist/TableView.cjs +444 -420
  230. package/dist/TableView.cjs.map +1 -1
  231. package/dist/TableView.css +232 -204
  232. package/dist/TableView.css.map +1 -1
  233. package/dist/TableView.mjs +446 -422
  234. package/dist/TableView.mjs.map +1 -1
  235. package/dist/Tabs.cjs +123 -123
  236. package/dist/Tabs.css +105 -105
  237. package/dist/Tabs.mjs +123 -123
  238. package/dist/TabsPicker.cjs +127 -127
  239. package/dist/TabsPicker.css +108 -108
  240. package/dist/TabsPicker.mjs +127 -127
  241. package/dist/TagGroup.cjs +203 -203
  242. package/dist/TagGroup.css +146 -146
  243. package/dist/TagGroup.mjs +203 -203
  244. package/dist/TextField.cjs +58 -58
  245. package/dist/TextField.css +54 -54
  246. package/dist/TextField.mjs +58 -58
  247. package/dist/TimeField.cjs +51 -51
  248. package/dist/TimeField.css +47 -47
  249. package/dist/TimeField.mjs +51 -51
  250. package/dist/Toast.cjs +121 -121
  251. package/dist/Toast.cjs.map +1 -1
  252. package/dist/Toast.css +110 -110
  253. package/dist/Toast.css.map +1 -1
  254. package/dist/Toast.mjs +122 -122
  255. package/dist/Toast.mjs.map +1 -1
  256. package/dist/ToggleButton.cjs +3 -3
  257. package/dist/ToggleButton.css +12 -12
  258. package/dist/ToggleButton.mjs +3 -3
  259. package/dist/Tooltip.cjs +78 -78
  260. package/dist/Tooltip.css +65 -65
  261. package/dist/Tooltip.mjs +78 -78
  262. package/dist/TreeView.cjs +179 -145
  263. package/dist/TreeView.cjs.map +1 -1
  264. package/dist/TreeView.css +140 -128
  265. package/dist/TreeView.css.map +1 -1
  266. package/dist/TreeView.mjs +179 -145
  267. package/dist/TreeView.mjs.map +1 -1
  268. package/dist/ar-AE.cjs +1 -0
  269. package/dist/ar-AE.cjs.map +1 -1
  270. package/dist/ar-AE.mjs +1 -0
  271. package/dist/ar-AE.mjs.map +1 -1
  272. package/dist/bg-BG.cjs +1 -0
  273. package/dist/bg-BG.cjs.map +1 -1
  274. package/dist/bg-BG.mjs +1 -0
  275. package/dist/bg-BG.mjs.map +1 -1
  276. package/dist/cs-CZ.cjs +1 -0
  277. package/dist/cs-CZ.cjs.map +1 -1
  278. package/dist/cs-CZ.mjs +1 -0
  279. package/dist/cs-CZ.mjs.map +1 -1
  280. package/dist/da-DK.cjs +1 -0
  281. package/dist/da-DK.cjs.map +1 -1
  282. package/dist/da-DK.mjs +1 -0
  283. package/dist/da-DK.mjs.map +1 -1
  284. package/dist/de-DE.cjs +1 -0
  285. package/dist/de-DE.cjs.map +1 -1
  286. package/dist/de-DE.mjs +1 -0
  287. package/dist/de-DE.mjs.map +1 -1
  288. package/dist/el-GR.cjs +1 -0
  289. package/dist/el-GR.cjs.map +1 -1
  290. package/dist/el-GR.mjs +1 -0
  291. package/dist/el-GR.mjs.map +1 -1
  292. package/dist/en-US.cjs +1 -0
  293. package/dist/en-US.cjs.map +1 -1
  294. package/dist/en-US.mjs +1 -0
  295. package/dist/en-US.mjs.map +1 -1
  296. package/dist/es-ES.cjs +1 -0
  297. package/dist/es-ES.cjs.map +1 -1
  298. package/dist/es-ES.mjs +1 -0
  299. package/dist/es-ES.mjs.map +1 -1
  300. package/dist/et-EE.cjs +1 -0
  301. package/dist/et-EE.cjs.map +1 -1
  302. package/dist/et-EE.mjs +1 -0
  303. package/dist/et-EE.mjs.map +1 -1
  304. package/dist/fi-FI.cjs +1 -0
  305. package/dist/fi-FI.cjs.map +1 -1
  306. package/dist/fi-FI.mjs +1 -0
  307. package/dist/fi-FI.mjs.map +1 -1
  308. package/dist/fr-FR.cjs +1 -0
  309. package/dist/fr-FR.cjs.map +1 -1
  310. package/dist/fr-FR.mjs +1 -0
  311. package/dist/fr-FR.mjs.map +1 -1
  312. package/dist/he-IL.cjs +1 -0
  313. package/dist/he-IL.cjs.map +1 -1
  314. package/dist/he-IL.mjs +1 -0
  315. package/dist/he-IL.mjs.map +1 -1
  316. package/dist/hr-HR.cjs +1 -0
  317. package/dist/hr-HR.cjs.map +1 -1
  318. package/dist/hr-HR.mjs +1 -0
  319. package/dist/hr-HR.mjs.map +1 -1
  320. package/dist/hu-HU.cjs +1 -0
  321. package/dist/hu-HU.cjs.map +1 -1
  322. package/dist/hu-HU.mjs +1 -0
  323. package/dist/hu-HU.mjs.map +1 -1
  324. package/dist/it-IT.cjs +1 -0
  325. package/dist/it-IT.cjs.map +1 -1
  326. package/dist/it-IT.mjs +1 -0
  327. package/dist/it-IT.mjs.map +1 -1
  328. package/dist/ja-JP.cjs +1 -0
  329. package/dist/ja-JP.cjs.map +1 -1
  330. package/dist/ja-JP.mjs +1 -0
  331. package/dist/ja-JP.mjs.map +1 -1
  332. package/dist/ko-KR.cjs +1 -0
  333. package/dist/ko-KR.cjs.map +1 -1
  334. package/dist/ko-KR.mjs +1 -0
  335. package/dist/ko-KR.mjs.map +1 -1
  336. package/dist/lt-LT.cjs +1 -0
  337. package/dist/lt-LT.cjs.map +1 -1
  338. package/dist/lt-LT.mjs +1 -0
  339. package/dist/lt-LT.mjs.map +1 -1
  340. package/dist/lv-LV.cjs +1 -0
  341. package/dist/lv-LV.cjs.map +1 -1
  342. package/dist/lv-LV.mjs +1 -0
  343. package/dist/lv-LV.mjs.map +1 -1
  344. package/dist/main.cjs +7 -0
  345. package/dist/main.cjs.map +1 -1
  346. package/dist/module.mjs +5 -3
  347. package/dist/module.mjs.map +1 -1
  348. package/dist/nb-NO.cjs +1 -0
  349. package/dist/nb-NO.cjs.map +1 -1
  350. package/dist/nb-NO.mjs +1 -0
  351. package/dist/nb-NO.mjs.map +1 -1
  352. package/dist/nl-NL.cjs +1 -0
  353. package/dist/nl-NL.cjs.map +1 -1
  354. package/dist/nl-NL.mjs +1 -0
  355. package/dist/nl-NL.mjs.map +1 -1
  356. package/dist/pl-PL.cjs +1 -0
  357. package/dist/pl-PL.cjs.map +1 -1
  358. package/dist/pl-PL.mjs +1 -0
  359. package/dist/pl-PL.mjs.map +1 -1
  360. package/dist/pt-BR.cjs +1 -0
  361. package/dist/pt-BR.cjs.map +1 -1
  362. package/dist/pt-BR.mjs +1 -0
  363. package/dist/pt-BR.mjs.map +1 -1
  364. package/dist/pt-PT.cjs +1 -0
  365. package/dist/pt-PT.cjs.map +1 -1
  366. package/dist/pt-PT.mjs +1 -0
  367. package/dist/pt-PT.mjs.map +1 -1
  368. package/dist/ro-RO.cjs +1 -0
  369. package/dist/ro-RO.cjs.map +1 -1
  370. package/dist/ro-RO.mjs +1 -0
  371. package/dist/ro-RO.mjs.map +1 -1
  372. package/dist/ru-RU.cjs +1 -0
  373. package/dist/ru-RU.cjs.map +1 -1
  374. package/dist/ru-RU.mjs +1 -0
  375. package/dist/ru-RU.mjs.map +1 -1
  376. package/dist/sk-SK.cjs +1 -0
  377. package/dist/sk-SK.cjs.map +1 -1
  378. package/dist/sk-SK.mjs +1 -0
  379. package/dist/sk-SK.mjs.map +1 -1
  380. package/dist/sl-SI.cjs +1 -0
  381. package/dist/sl-SI.cjs.map +1 -1
  382. package/dist/sl-SI.mjs +1 -0
  383. package/dist/sl-SI.mjs.map +1 -1
  384. package/dist/sr-SP.cjs +1 -0
  385. package/dist/sr-SP.cjs.map +1 -1
  386. package/dist/sr-SP.mjs +1 -0
  387. package/dist/sr-SP.mjs.map +1 -1
  388. package/dist/sv-SE.cjs +1 -0
  389. package/dist/sv-SE.cjs.map +1 -1
  390. package/dist/sv-SE.mjs +1 -0
  391. package/dist/sv-SE.mjs.map +1 -1
  392. package/dist/tr-TR.cjs +1 -0
  393. package/dist/tr-TR.cjs.map +1 -1
  394. package/dist/tr-TR.mjs +1 -0
  395. package/dist/tr-TR.mjs.map +1 -1
  396. package/dist/types.d.ts +77 -6
  397. package/dist/types.d.ts.map +1 -1
  398. package/dist/uk-UA.cjs +1 -0
  399. package/dist/uk-UA.cjs.map +1 -1
  400. package/dist/uk-UA.mjs +1 -0
  401. package/dist/uk-UA.mjs.map +1 -1
  402. package/dist/zh-CN.cjs +1 -0
  403. package/dist/zh-CN.cjs.map +1 -1
  404. package/dist/zh-CN.mjs +1 -0
  405. package/dist/zh-CN.mjs.map +1 -1
  406. package/dist/zh-TW.cjs +1 -0
  407. package/dist/zh-TW.cjs.map +1 -1
  408. package/dist/zh-TW.mjs +1 -0
  409. package/dist/zh-TW.mjs.map +1 -1
  410. package/icons/Icon.cjs +10 -10
  411. package/icons/Icon.css +9 -9
  412. package/icons/Icon.mjs +10 -10
  413. package/icons/Skeleton.cjs +2 -2
  414. package/icons/Skeleton.css +6 -6
  415. package/icons/Skeleton.mjs +2 -2
  416. package/package.json +21 -21
  417. package/src/ComboBox.tsx +4 -3
  418. package/src/ContextualHelp.tsx +81 -43
  419. package/src/Field.tsx +3 -3
  420. package/src/ListView.tsx +782 -0
  421. package/src/Menu.tsx +100 -16
  422. package/src/Picker.tsx +72 -11
  423. package/src/TableView.tsx +30 -12
  424. package/src/Toast.tsx +2 -2
  425. package/src/TreeView.tsx +43 -6
  426. package/src/index.ts +6 -3
  427. package/style/__tests__/style-macro.test.js +69 -69
package/src/Menu.tsx CHANGED
@@ -34,21 +34,25 @@ import {centerBaseline} from './CenterBaseline';
34
34
  import {centerPadding, control, controlFont, controlSize, getAllowedOverrides, StyleProps} from './style-utils' with {type: 'macro'};
35
35
  import CheckmarkIcon from '../ui-icons/Checkmark';
36
36
  import ChevronRightIcon from '../ui-icons/Chevron';
37
- import {createContext, forwardRef, JSX, ReactNode, useContext, useRef, useState} from 'react';
37
+ import {createContext, forwardRef, JSX, ReactElement, ReactNode, useContext, useRef, useState} from 'react';
38
38
  import {divider} from './Divider';
39
39
  import {DOMRef, DOMRefValue, GlobalDOMAttributes, PressEvent} from '@react-types/shared';
40
40
  import {edgeToText} from '../style/spectrum-theme' with {type: 'macro'};
41
41
  import {forwardRefType} from './types';
42
42
  import {HeaderContext, HeadingContext, KeyboardContext, Text, TextContext} from './Content';
43
- import {IconContext} from './Icon'; // chevron right removed??
44
- import {ImageContext} from './Image';
43
+ import {IconContext} from './Icon';
44
+ import {ImageContext} from './Image'; // chevron right removed??
45
+ import InfoCircleIcon from '../s2wf-icons/S2_Icon_InfoCircle_20_N.svg';
45
46
  import {InPopoverContext, Popover, PopoverContext} from './Popover';
47
+ // @ts-ignore
48
+ import intlMessages from '../intl/*.json';
46
49
  import LinkOutIcon from '../ui-icons/LinkOut';
47
50
  import {mergeStyles} from '../style/runtime';
48
51
  import {Placement, useLocale} from 'react-aria';
49
52
  import {PressResponder} from '@react-aria/interactions';
50
53
  import {pressScale} from './pressScale';
51
- import {useGlobalListeners} from '@react-aria/utils';
54
+ import {useGlobalListeners, useId} from '@react-aria/utils';
55
+ import {useLocalizedStringFormatter} from '@react-aria/i18n';
52
56
  import {useSpectrumContextProps} from './useSpectrumContextProps';
53
57
  // viewbox on LinkOut is super weird just because i copied the icon from designs...
54
58
  // need to strip id's from icons
@@ -317,6 +321,7 @@ let keyboard = style<{size: 'S' | 'M' | 'L' | 'XL', isDisabled: boolean}>({
317
321
 
318
322
  let descriptor = style({
319
323
  gridArea: 'descriptor',
324
+ placeSelf: 'end',
320
325
  marginStart: 8,
321
326
  '--iconPrimary': {
322
327
  type: 'fill',
@@ -324,6 +329,19 @@ let descriptor = style({
324
329
  }
325
330
  });
326
331
 
332
+ let descriptorIcon = style<{size: 'S' | 'M' | 'L' | 'XL'}>({
333
+ marginEnd: 0,
334
+ display: 'block',
335
+ size: {
336
+ size: {
337
+ S: 16,
338
+ M: 20,
339
+ L: 24,
340
+ XL: 26
341
+ }
342
+ }
343
+ });
344
+
327
345
  let InternalMenuContext = createContext<{size: 'S' | 'M' | 'L' | 'XL', isSubmenu: boolean, hideLinkOutIcon: boolean}>({
328
346
  size: 'M',
329
347
  isSubmenu: false,
@@ -331,6 +349,7 @@ let InternalMenuContext = createContext<{size: 'S' | 'M' | 'L' | 'XL', isSubmenu
331
349
  });
332
350
 
333
351
  let InternalMenuTriggerContext = createContext<Omit<MenuTriggerProps, 'children'> | null>(null);
352
+ let UnavailableContext = createContext(false);
334
353
 
335
354
  let wrappingDiv = style({
336
355
  display: 'flex',
@@ -459,6 +478,33 @@ const linkIconSize = {
459
478
  XL: 'XL'
460
479
  } as const;
461
480
 
481
+ interface UnavailableIconWrapperProps {
482
+ direction: 'ltr' | 'rtl',
483
+ size: 'S' | 'M' | 'L' | 'XL',
484
+ id?: string
485
+ }
486
+
487
+ function UnavailableIconWrapper(props: UnavailableIconWrapperProps) {
488
+ let {direction, size, id} = props;
489
+ let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/s2');
490
+
491
+ return (
492
+ <div slot="descriptor" className={mergeStyles(descriptor, style({marginBottom: fontRelative(-1)}))} id={id}>
493
+ <Provider values={[[IconContext, {slots: {icon: {styles: descriptorIcon({size})}}}]]}>
494
+ <InfoCircleIcon
495
+ aria-label={stringFormatter.format('menu.unavailable')}
496
+ className={style({
497
+ scaleX: {
498
+ direction: {
499
+ rtl: -1
500
+ }
501
+ }
502
+ })({direction})} />
503
+ </Provider>
504
+ </div>
505
+ );
506
+ }
507
+
462
508
  export function MenuItem(props: MenuItemProps): ReactNode {
463
509
  let ref = useRef(null);
464
510
  let isLink = props.href != null;
@@ -466,9 +512,13 @@ export function MenuItem(props: MenuItemProps): ReactNode {
466
512
  let {size, hideLinkOutIcon} = useContext(InternalMenuContext);
467
513
  let textValue = props.textValue || (typeof props.children === 'string' ? props.children : undefined);
468
514
  let {direction} = useLocale();
515
+ let isUnavailable = useContext(UnavailableContext);
516
+ let infoIconId = useId();
517
+
469
518
  return (
470
519
  <AriaMenuItem
471
520
  {...props}
521
+ aria-describedby={isUnavailable ? infoIconId : undefined}
472
522
  textValue={textValue}
473
523
  ref={ref}
474
524
  style={pressScale(ref, props.UNSAFE_style)}
@@ -518,17 +568,21 @@ export function MenuItem(props: MenuItemProps): ReactNode {
518
568
  </div>
519
569
  )}
520
570
  {renderProps.hasSubmenu && (
521
- <div slot="descriptor" className={descriptor}>
522
- <ChevronRightIcon
523
- size={size}
524
- className={style({
525
- scaleX: {
526
- direction: {
527
- rtl: -1
528
- }
529
- }
530
- })({direction})} />
531
- </div>
571
+ isUnavailable
572
+ ? <UnavailableIconWrapper direction={direction} size={size} id={infoIconId} />
573
+ : (
574
+ <div slot="descriptor" className={descriptor}>
575
+ <ChevronRightIcon
576
+ size={size}
577
+ className={style({
578
+ scaleX: {
579
+ direction: {
580
+ rtl: -1
581
+ }
582
+ }
583
+ })({direction})} />
584
+ </div>
585
+ )
532
586
  )}
533
587
  </Provider>
534
588
  </>
@@ -611,7 +665,37 @@ function SubmenuTrigger(props: SubmenuTriggerProps): JSX.Element {
611
665
  );
612
666
  }
613
667
 
614
- export {MenuTrigger, SubmenuTrigger};
668
+ export interface UnavailableMenuItemTriggerProps {
669
+ /**
670
+ * The contents of the UnavailableMenuItemTrigger. The first child should be a MenuItem and the second child be a ContextualHelpPopover.
671
+ */
672
+ children: ReactElement[],
673
+ /**
674
+ * Whether the menu item is currently unavailable.
675
+ * @default false
676
+ */
677
+ isUnavailable?: boolean
678
+ }
679
+
680
+ function UnavailableMenuItemTrigger(props: UnavailableMenuItemTriggerProps): JSX.Element {
681
+ let {isUnavailable = false, children} = props;
682
+ if (isUnavailable) {
683
+ return (
684
+ <UnavailableContext.Provider value={isUnavailable}>
685
+ <AriaSubmenuTrigger>
686
+ {children[0]}
687
+ <PopoverContext.Provider value={{hideArrow: true, offset: -2, crossOffset: -8, placement: 'end top'}}>
688
+ {children[1]}
689
+ </PopoverContext.Provider>
690
+ </AriaSubmenuTrigger>
691
+ </UnavailableContext.Provider>
692
+ );
693
+ }
694
+
695
+ return children[0] as JSX.Element;
696
+ }
697
+
698
+ export {MenuTrigger, SubmenuTrigger, UnavailableMenuItemTrigger};
615
699
 
616
700
  // This is purely so that storybook generates the types for both Menu and MenuTrigger
617
701
  interface ICombined<T extends object> extends MenuProps<T>, Omit<MenuTriggerProps, 'children'> {}
package/src/Picker.tsx CHANGED
@@ -29,6 +29,7 @@ import {
29
29
  ListLayout,
30
30
  Provider,
31
31
  SectionProps,
32
+ SelectStateContext,
32
33
  SelectValue,
33
34
  Virtualizer
34
35
  } from 'react-aria-components';
@@ -50,6 +51,7 @@ import CheckmarkIcon from '../ui-icons/Checkmark';
50
51
  import ChevronIcon from '../ui-icons/Chevron';
51
52
  import {control, controlBorderRadius, controlFont, field, fieldInput, getAllowedOverrides, StyleProps} from './style-utils' with {type: 'macro'};
52
53
  import {createHideableComponent} from '@react-aria/collections';
54
+ import {createShadowTreeWalker, getOwnerDocument, isFocusable, useGlobalListeners, useSlotId} from '@react-aria/utils';
53
55
  import {
54
56
  Divider,
55
57
  listbox,
@@ -76,9 +78,8 @@ import {PressResponder} from '@react-aria/interactions';
76
78
  import {pressScale} from './pressScale';
77
79
  import {ProgressCircle} from './ProgressCircle';
78
80
  import {raw} from '../style/style-macro' with {type: 'macro'};
79
- import React, {createContext, forwardRef, ReactNode, useContext, useMemo, useRef, useState} from 'react';
81
+ import React, {createContext, forwardRef, ReactNode, useContext, useEffect, useMemo, useRef, useState} from 'react';
80
82
  import {useFocusableRef} from '@react-spectrum/utils';
81
- import {useGlobalListeners, useSlotId} from '@react-aria/utils';
82
83
  import {useLocale, useLocalizedStringFormatter} from '@react-aria/i18n';
83
84
  import {useScale} from './utils';
84
85
  import {useSpectrumContextProps} from './useSpectrumContextProps';
@@ -123,7 +124,13 @@ export interface PickerProps<T extends object, M extends SelectionMode = 'single
123
124
  /** Width of the menu. By default, matches width of the trigger. Note that the minimum width of the dropdown is always equal to the trigger's width. */
124
125
  menuWidth?: number,
125
126
  /** The current loading state of the Picker. */
126
- loadingState?: LoadingState
127
+ loadingState?: LoadingState,
128
+ /**
129
+ * Custom renderer for the picker value. Allows one to provide a custom element to render selected items.
130
+ *
131
+ * @note The returned ReactNode should not have interactable elements as it will break accessibility.
132
+ */
133
+ renderValue?: (selectedItems: T[]) => ReactNode
127
134
  }
128
135
 
129
136
  interface PickerButtonProps extends PickerStyleProps, ButtonRenderProps {}
@@ -227,7 +234,8 @@ const valueStyles = style({
227
234
  },
228
235
  truncate: true,
229
236
  display: 'flex',
230
- alignItems: 'center'
237
+ alignItems: 'center',
238
+ height: '100%'
231
239
  });
232
240
 
233
241
  const iconStyles = style({
@@ -298,6 +306,7 @@ export const Picker = /*#__PURE__*/ (forwardRef as forwardRefType)(function Pick
298
306
  placeholder = stringFormatter.format('picker.placeholder'),
299
307
  isQuiet,
300
308
  loadingState,
309
+ renderValue,
301
310
  onLoadMore,
302
311
  ...pickerProps
303
312
  } = props;
@@ -376,6 +385,7 @@ export const Picker = /*#__PURE__*/ (forwardRef as forwardRefType)(function Pick
376
385
  </FieldLabel>
377
386
  <PickerButton
378
387
  loadingState={loadingState}
388
+ renderValue={renderValue}
379
389
  isOpen={isOpen}
380
390
  isQuiet={isQuiet}
381
391
  isFocusVisible={isFocusVisible}
@@ -482,7 +492,14 @@ const avatarSize = {
482
492
  XL: 26
483
493
  } as const;
484
494
 
485
- interface PickerButtonInnerProps<T extends object> extends PickerStyleProps, Omit<AriaSelectRenderProps, 'isRequired' | 'isFocused'>, Pick<PickerProps<T>, 'loadingState'> {
495
+ // https://w3c.github.io/aria/#widget_roles
496
+ let INTERACTIVE_ARIA_ROLES = new Set([
497
+ 'application', 'button', 'checkbox', 'combobox', 'gridcell', 'link', 'menuitem',
498
+ 'menuitemcheckbox', 'menuitemradio', 'option', 'radio', 'searchbox', 'separator',
499
+ 'slider', 'spinbutton', 'switch', 'tab', 'textbox', 'treeitem'
500
+ ]);
501
+
502
+ interface PickerButtonInnerProps<T extends object> extends PickerStyleProps, Omit<AriaSelectRenderProps, 'isRequired' | 'isFocused'>, Pick<PickerProps<T>, 'loadingState' | 'renderValue'> {
486
503
  loadingCircle: ReactNode,
487
504
  buttonRef: RefObject<HTMLButtonElement | null>
488
505
  }
@@ -498,9 +515,40 @@ const PickerButton = createHideableComponent(function PickerButton<T extends obj
498
515
  isDisabled,
499
516
  loadingState,
500
517
  loadingCircle,
501
- buttonRef
518
+ buttonRef,
519
+ renderValue
502
520
  } = props;
503
521
  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/s2');
522
+ let renderValueRef = useRef(null);
523
+
524
+ let state = useContext(SelectStateContext)!;
525
+ useEffect(() => {
526
+ if (process.env.NODE_ENV === 'production' || !renderValue) {
527
+ return;
528
+ }
529
+
530
+ if (!renderValueRef.current) {
531
+ return;
532
+ }
533
+
534
+ let doc = getOwnerDocument(renderValueRef.current);
535
+ let walker = createShadowTreeWalker(
536
+ doc,
537
+ renderValueRef.current,
538
+ NodeFilter.SHOW_ELEMENT,
539
+ {
540
+ acceptNode(node: Element) {
541
+ let role = node.getAttribute('role');
542
+ let interactive = isFocusable(node) || (role != null && INTERACTIVE_ARIA_ROLES.has(role));
543
+ return interactive ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
544
+ }
545
+ }
546
+ );
547
+ let next = walker.nextNode();
548
+ if (next) {
549
+ console.warn('Picker\'s value should not have interactive children for accessibility.');
550
+ }
551
+ }, [state.selectedItems, renderValue]);
504
552
 
505
553
  // For mouse interactions, pickers open on press start. When the popover underlay appears
506
554
  // it covers the trigger button, causing onPressEnd to fire immediately and no press scaling
@@ -533,8 +581,20 @@ const PickerButton = createHideableComponent(function PickerButton<T extends obj
533
581
  })}>
534
582
  {(renderProps) => (
535
583
  <>
536
- <SelectValue className={valueStyles({isQuiet}) + ' ' + raw('&> :not([slot=icon], [slot=avatar], [slot=label], [data-slot=label]) {display: none;}')}>
584
+ <SelectValue
585
+ className={
586
+ valueStyles({isQuiet}) +
587
+ (renderValue ? '' : ' ' + raw('&> :not([slot=icon], [slot=avatar], [slot=label], [data-slot=label]) {display: none;}'))
588
+ }>
537
589
  {({selectedItems, defaultChildren}) => {
590
+ const selectedValues = selectedItems.filter((item): item is T => item != null);
591
+ const defaultRenderedValue = selectedItems.length <= 1
592
+ ? defaultChildren
593
+ : <Text slot="label">{stringFormatter.format('picker.selectedCount', {count: selectedItems.length})}</Text>;
594
+ const renderedValue = selectedItems.length > 0 && renderValue
595
+ ? renderValue(selectedValues)
596
+ : defaultRenderedValue;
597
+
538
598
  return (
539
599
  <Provider
540
600
  values={[
@@ -579,10 +639,11 @@ const PickerButton = createHideableComponent(function PickerButton<T extends obj
579
639
  }],
580
640
  [InsideSelectValueContext, true]
581
641
  ]}>
582
- {selectedItems.length <= 1
583
- ? defaultChildren
584
- : <Text slot="label">{stringFormatter.format('picker.selectedCount', {count: selectedItems.length})}</Text>
585
- }
642
+ {renderValue ? (
643
+ <div ref={renderValueRef} style={{display: 'contents'}}>
644
+ {renderedValue}
645
+ </div>
646
+ ) : renderedValue}
586
647
  </Provider>
587
648
  );
588
649
  }}
package/src/TableView.tsx CHANGED
@@ -17,10 +17,12 @@ import {
17
17
  ButtonContext,
18
18
  CellRenderProps,
19
19
  Collection,
20
+ CollectionRendererContext,
20
21
  ColumnRenderProps,
21
22
  ColumnResizer,
22
23
  ContextValue,
23
24
  DEFAULT_SLOT,
25
+ DefaultCollectionRenderer,
24
26
  Form,
25
27
  Key,
26
28
  OverlayTriggerStateContext,
@@ -59,7 +61,7 @@ import Close from '../s2wf-icons/S2_Icon_Close_20_N.svg';
59
61
  import {ColumnSize} from '@react-types/table';
60
62
  import {CustomDialog, DialogContainer} from '..';
61
63
  import {DOMProps, DOMRef, DOMRefValue, forwardRefType, GlobalDOMAttributes, LinkDOMProps, LoadingState, Node} from '@react-types/shared';
62
- import {getActiveElement, getOwnerDocument, nodeContains, useLayoutEffect, useObjectRef} from '@react-aria/utils';
64
+ import {getActiveElement, getOwnerDocument, isFocusWithin, nodeContains, useLayoutEffect, useObjectRef} from '@react-aria/utils';
63
65
  import {GridNode} from '@react-types/grid';
64
66
  import {IconContext} from './Icon';
65
67
  // @ts-ignore
@@ -439,7 +441,9 @@ export const TableBody = /*#__PURE__*/ (forwardRef as forwardRefType)(function T
439
441
  if (renderEmptyState != null && !isLoading) {
440
442
  emptyRender = (props: TableBodyRenderProps) => (
441
443
  <div className={centeredWrapper}>
442
- {renderEmptyState(props)}
444
+ <CollectionRendererContext.Provider value={DefaultCollectionRenderer}>
445
+ {renderEmptyState(props)}
446
+ </CollectionRendererContext.Provider>
443
447
  </div>
444
448
  );
445
449
  } else if (loadingState === 'loading') {
@@ -943,20 +947,13 @@ const commonCellStyles = {
943
947
  borderXWidth: 0,
944
948
  borderStyle: 'solid',
945
949
  position: 'relative',
946
- color: {
947
- default: 'gray-800',
948
- forcedColors: 'ButtonText'
949
- },
950
+ color: '--rowTextColor',
950
951
  outlineStyle: 'none',
951
952
  paddingX: 16 // table-edge-to-content
952
953
  } as const;
953
954
 
954
955
  const cell = style<CellRenderProps & S2TableProps & {isDivider: boolean}>({
955
956
  ...commonCellStyles,
956
- color: {
957
- default: baseColor('neutral-subdued'),
958
- isSelected: baseColor('neutral')
959
- },
960
957
  paddingY: centerPadding(),
961
958
  minHeight: {
962
959
  default: 40,
@@ -1301,7 +1298,7 @@ function EditableCellInner(props: EditableCellProps & {isFocusVisible: boolean,
1301
1298
  onOpenChange={setIsOpen}
1302
1299
  ref={popoverRef}
1303
1300
  shouldCloseOnInteractOutside={() => {
1304
- if (!nodeContains(popoverRef.current, document.activeElement)) {
1301
+ if (!isFocusWithin(popoverRef.current)) {
1305
1302
  return false;
1306
1303
  }
1307
1304
  formRef.current?.requestSubmit();
@@ -1393,6 +1390,16 @@ const rowBackgroundColor = {
1393
1390
  }
1394
1391
  } as const;
1395
1392
 
1393
+ const rowTextColor = {
1394
+ default: baseColor('neutral-subdued'),
1395
+ isSelected: baseColor('neutral'),
1396
+ isDisabled: {
1397
+ default: 'disabled',
1398
+ forcedColors: 'GrayText'
1399
+ },
1400
+ forcedColors: 'ButtonText'
1401
+ } as const;
1402
+
1396
1403
  const row = style<RowRenderProps & S2TableProps>({
1397
1404
  height: 'full',
1398
1405
  position: 'relative',
@@ -1402,6 +1409,10 @@ const row = style<RowRenderProps & S2TableProps>({
1402
1409
  type: 'backgroundColor',
1403
1410
  value: rowBackgroundColor
1404
1411
  },
1412
+ '--rowTextColor': {
1413
+ type: 'color',
1414
+ value: rowTextColor
1415
+ },
1405
1416
  '--rowFocusIndicatorColor': {
1406
1417
  type: 'outlineColor',
1407
1418
  value: {
@@ -1446,6 +1457,13 @@ const row = style<RowRenderProps & S2TableProps>({
1446
1457
  forcedColorAdjust: 'none'
1447
1458
  });
1448
1459
 
1460
+ const selectionCheckbox = style({
1461
+ visibility: {
1462
+ default: 'visible',
1463
+ ':is([slot="selection"][data-disabled="true"])': 'hidden'
1464
+ }
1465
+ });
1466
+
1449
1467
  export interface RowProps<T> extends Pick<RACRowProps<T>, 'id' | 'columns' | 'isDisabled' | 'onAction' | 'children' | 'textValue' | 'dependencies' | keyof GlobalDOMAttributes>, LinkDOMProps {}
1450
1468
 
1451
1469
  /**
@@ -1472,7 +1490,7 @@ export const Row = /*#__PURE__*/ (forwardRef as forwardRefType)(function Row<T e
1472
1490
  // The `spread` otherProps must be after className in Cell.
1473
1491
  // @ts-ignore
1474
1492
  <Cell isSticky className={checkboxCellStyle}>
1475
- <Checkbox slot="selection" />
1493
+ <Checkbox slot="selection" styles={selectionCheckbox} />
1476
1494
  </Cell>
1477
1495
  )}
1478
1496
  <Collection items={columns} dependencies={[...dependencies, columns]}>
package/src/Toast.tsx CHANGED
@@ -19,7 +19,7 @@ import Chevron from '../s2wf-icons/S2_Icon_ChevronDown_20_N.svg';
19
19
  import {CloseButton} from './CloseButton';
20
20
  import {createContext, ReactNode, useContext, useEffect, useMemo, useRef} from 'react';
21
21
  import {DOMProps} from '@react-types/shared';
22
- import {filterDOMProps, isWebKit, useEvent} from '@react-aria/utils';
22
+ import {filterDOMProps, getEventTarget, isWebKit, useEvent} from '@react-aria/utils';
23
23
  import {flushSync} from 'react-dom';
24
24
  import {focusRing, style} from '../style' with {type: 'macro'};
25
25
  import {FocusScope, useModalOverlay} from 'react-aria';
@@ -446,7 +446,7 @@ function SpectrumToastList({placement, align, reduceMotion}) {
446
446
  let toastListRef = useRef(null);
447
447
  useEvent(toastListRef, 'click', (e) => {
448
448
  // Have to check if this is a button because stopPropagation in react events doesn't affect native events.
449
- if (!isExpanded && !(e.target as Element)?.closest('button')) {
449
+ if (!isExpanded && !(getEventTarget(e) as Element)?.closest('button')) {
450
450
  toggleExpanded();
451
451
  }
452
452
  });
package/src/TreeView.tsx CHANGED
@@ -41,13 +41,16 @@ import {ProgressCircle} from './ProgressCircle';
41
41
  import {raw} from '../style/style-macro' with {type: 'macro'};
42
42
  import React, {createContext, forwardRef, JSXElementConstructor, ReactElement, ReactNode, useRef} from 'react';
43
43
  import {Text, TextContext} from './Content';
44
+ import {useActionBarContainer} from './ActionBar';
44
45
  import {useDOMRef} from '@react-spectrum/utils';
45
46
  import {useLocale, useLocalizedStringFormatter} from 'react-aria';
46
47
  import {useScale} from './utils';
47
48
 
48
49
  interface S2TreeProps {
49
50
  /** Handler that is called when a user performs an action on a row. */
50
- onAction?: (key: Key) => void
51
+ onAction?: (key: Key) => void,
52
+ /** Provides the ActionBar to display when items are selected in the TreeView. */
53
+ renderActionBar?: (selectedKeys: 'all' | Set<Key>) => ReactElement
51
54
  }
52
55
 
53
56
  export interface TreeViewProps<T> extends Omit<RACTreeProps<T>, 'style' | 'className' | 'render' | 'onRowAction' | 'selectionBehavior' | 'onScroll' | 'onCellAction' | 'dragAndDropHooks' | keyof GlobalDOMAttributes>, UnsafeStyles, S2TreeProps {
@@ -71,6 +74,16 @@ interface TreeRendererContextValue {
71
74
  const TreeRendererContext = createContext<TreeRendererContextValue>({});
72
75
 
73
76
 
77
+ const treeViewWrapper = style({
78
+ minHeight: 0,
79
+ minWidth: 0,
80
+ display: 'flex',
81
+ isolation: 'isolate',
82
+ disableTapHighlight: true,
83
+ position: 'relative',
84
+ overflow: 'clip'
85
+ }, getAllowedOverrides({height: true}));
86
+
74
87
  // TODO: the below is needed so the borders of the top and bottom row isn't cut off if the TreeView is wrapped within a container by always reserving the 2px needed for the
75
88
  // keyboard focus ring. Perhaps find a different way of rendering the outlines since the top of the item doesn't
76
89
  // scroll into view due to how the ring is offset. Alternatively, have the tree render the top/bottom outline like it does in Listview
@@ -94,7 +107,7 @@ const tree = style({
94
107
  type: 'width',
95
108
  value: 16
96
109
  }
97
- }, getAllowedOverrides({height: true}));
110
+ });
98
111
 
99
112
  /**
100
113
  * A tree view provides users with a way to navigate nested hierarchical information.
@@ -109,8 +122,11 @@ export const TreeView = /*#__PURE__*/ (forwardRef as forwardRefType)(function Tr
109
122
  }
110
123
 
111
124
  let domRef = useDOMRef(ref);
125
+ let scrollRef = useRef<HTMLElement | null>(null);
112
126
 
113
- return (
127
+ let {selectedKeys, onSelectionChange, actionBar, actionBarHeight} = useActionBarContainer({...props, scrollRef});
128
+
129
+ let treeContent = (
114
130
  <Virtualizer
115
131
  layout={ListLayout}
116
132
  layoutOptions={{
@@ -119,15 +135,36 @@ export const TreeView = /*#__PURE__*/ (forwardRef as forwardRefType)(function Tr
119
135
  <TreeRendererContext.Provider value={{renderer}}>
120
136
  <Tree
121
137
  {...props}
122
- style={UNSAFE_style}
123
- className={renderProps => (UNSAFE_className ?? '') + tree({...renderProps}, props.styles)}
138
+ style={{
139
+ ...(!props.renderActionBar ? UNSAFE_style : {}),
140
+ paddingBottom: actionBarHeight > 0 ? actionBarHeight + 8 : 0,
141
+ scrollPaddingBottom: actionBarHeight > 0 ? actionBarHeight + 8 : 0
142
+ }}
143
+ className={renderProps => (!props.renderActionBar ? (UNSAFE_className ?? '') : '') + tree({...renderProps})}
124
144
  selectionBehavior="toggle"
125
- ref={domRef}>
145
+ selectedKeys={selectedKeys}
146
+ defaultSelectedKeys={undefined}
147
+ onSelectionChange={onSelectionChange}
148
+ ref={props.renderActionBar ? (scrollRef as any) : domRef}>
126
149
  {props.children}
127
150
  </Tree>
128
151
  </TreeRendererContext.Provider>
129
152
  </Virtualizer>
130
153
  );
154
+
155
+ if (props.renderActionBar) {
156
+ return (
157
+ <div
158
+ ref={domRef}
159
+ className={(UNSAFE_className ?? '') + treeViewWrapper(null, props.styles)}
160
+ style={UNSAFE_style}>
161
+ {treeContent}
162
+ {actionBar}
163
+ </div>
164
+ );
165
+ }
166
+
167
+ return treeContent;
131
168
  });
132
169
 
133
170
  const rowBackgroundColor = {
package/src/index.ts CHANGED
@@ -37,7 +37,7 @@ export {ColorSwatch, ColorSwatchContext} from './ColorSwatch';
37
37
  export {ColorSwatchPicker, ColorSwatchPickerContext} from './ColorSwatchPicker';
38
38
  export {ColorWheel, ColorWheelContext} from './ColorWheel';
39
39
  export {ComboBox, ComboBoxItem, ComboBoxSection, ComboBoxContext} from './ComboBox';
40
- export {ContextualHelp, ContextualHelpContext} from './ContextualHelp';
40
+ export {ContextualHelp, ContextualHelpContext, ContextualHelpPopover} from './ContextualHelp';
41
41
  export {DateField, DateFieldContext} from './DateField';
42
42
  export {DatePicker, DatePickerContext} from './DatePicker';
43
43
  export {DateRangePicker, DateRangePickerContext} from './DateRangePicker';
@@ -57,7 +57,8 @@ export {Image, ImageContext} from './Image';
57
57
  export {ImageCoordinator} from './ImageCoordinator';
58
58
  export {InlineAlert, InlineAlertContext} from './InlineAlert';
59
59
  export {Link, LinkContext} from './Link';
60
- export {MenuItem, MenuTrigger, Menu, MenuSection, SubmenuTrigger, MenuContext} from './Menu';
60
+ export {ListView, ListViewContext, ListViewItem} from './ListView';
61
+ export {MenuItem, MenuTrigger, Menu, MenuSection, SubmenuTrigger, UnavailableMenuItemTrigger, MenuContext} from './Menu';
61
62
  export {Meter, MeterContext} from './Meter';
62
63
  export {NotificationBadge, NotificationBadgeContext} from './NotificationBadge';
63
64
  export {NumberField, NumberFieldContext} from './NumberField';
@@ -119,6 +120,7 @@ export type {ColorSwatchProps} from './ColorSwatch';
119
120
  export type {ColorSwatchPickerProps} from './ColorSwatchPicker';
120
121
  export type {ColorWheelProps} from './ColorWheel';
121
122
  export type {ComboBoxProps, ComboBoxItemProps, ComboBoxSectionProps} from './ComboBox';
123
+ export type {ContextualHelpProps, ContextualHelpStyleProps, ContextualHelpPopoverProps} from './ContextualHelp';
122
124
  export type {DateFieldProps} from './DateField';
123
125
  export type {DatePickerProps} from './DatePicker';
124
126
  export type {DateRangePickerProps} from './DateRangePicker';
@@ -136,7 +138,8 @@ export type {InlineAlertProps} from './InlineAlert';
136
138
  export type {ImageProps} from './Image';
137
139
  export type {ImageCoordinatorProps} from './ImageCoordinator';
138
140
  export type {LinkProps} from './Link';
139
- export type {MenuTriggerProps, MenuProps, MenuItemProps, MenuSectionProps, SubmenuTriggerProps} from './Menu';
141
+ export type {ListViewProps, ListViewItemProps} from './ListView';
142
+ export type {MenuTriggerProps, MenuProps, MenuItemProps, MenuSectionProps, SubmenuTriggerProps, UnavailableMenuItemTriggerProps} from './Menu';
140
143
  export type {MeterProps} from './Meter';
141
144
  export type {NotificationBadgeProps} from './NotificationBadge';
142
145
  export type {PickerProps, PickerItemProps, PickerSectionProps} from './Picker';