@wordpress/components 21.1.0 → 21.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 (309) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/build/border-box-control/utils.js +42 -2
  3. package/build/border-box-control/utils.js.map +1 -1
  4. package/build/combobox-control/index.js +0 -1
  5. package/build/combobox-control/index.js.map +1 -1
  6. package/build/custom-select-control/index.js +4 -2
  7. package/build/custom-select-control/index.js.map +1 -1
  8. package/build/draggable/index.js +3 -6
  9. package/build/draggable/index.js.map +1 -1
  10. package/build/font-size-picker/index.js +46 -55
  11. package/build/font-size-picker/index.js.map +1 -1
  12. package/build/font-size-picker/styles.js +73 -0
  13. package/build/font-size-picker/styles.js.map +1 -0
  14. package/build/font-size-picker/types.js +6 -0
  15. package/build/font-size-picker/types.js.map +1 -0
  16. package/build/font-size-picker/utils.js +17 -15
  17. package/build/font-size-picker/utils.js.map +1 -1
  18. package/build/form-token-field/token-input.js +20 -1
  19. package/build/form-token-field/token-input.js.map +1 -1
  20. package/build/index.js +12 -0
  21. package/build/index.js.map +1 -1
  22. package/build/menu-item/index.js +4 -3
  23. package/build/menu-item/index.js.map +1 -1
  24. package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js +10 -3
  25. package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js.map +1 -1
  26. package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +12 -3
  27. package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js.map +1 -1
  28. package/build/mobile/bottom-sheet/sub-sheet/index.native.js +4 -1
  29. package/build/mobile/bottom-sheet/sub-sheet/index.native.js.map +1 -1
  30. package/build/mobile/color-settings/index.native.js +3 -1
  31. package/build/mobile/color-settings/index.native.js.map +1 -1
  32. package/build/mobile/color-settings/picker-screen.native.js +3 -1
  33. package/build/mobile/color-settings/picker-screen.native.js.map +1 -1
  34. package/build/mobile/image/index.native.js +3 -1
  35. package/build/mobile/image/index.native.js.map +1 -1
  36. package/build/mobile/keyboard-avoiding-view/index.ios.js +3 -1
  37. package/build/mobile/keyboard-avoiding-view/index.ios.js.map +1 -1
  38. package/build/mobile/link-picker/index.native.js +3 -1
  39. package/build/mobile/link-picker/index.native.js.map +1 -1
  40. package/build/mobile/link-picker/link-picker-results.native.js +3 -1
  41. package/build/mobile/link-picker/link-picker-results.native.js.map +1 -1
  42. package/build/mobile/link-picker/link-picker-screen.native.js +3 -1
  43. package/build/mobile/link-picker/link-picker-screen.native.js.map +1 -1
  44. package/build/mobile/link-settings/index.native.js +24 -6
  45. package/build/mobile/link-settings/index.native.js.map +1 -1
  46. package/build/mobile/link-settings/link-settings-screen.native.js +3 -1
  47. package/build/mobile/link-settings/link-settings-screen.native.js.map +1 -1
  48. package/build/mobile/segmented-control/index.native.js +6 -2
  49. package/build/mobile/segmented-control/index.native.js.map +1 -1
  50. package/build/mobile/utils/use-unit-converter-to-mobile.native.js +6 -2
  51. package/build/mobile/utils/use-unit-converter-to-mobile.native.js.map +1 -1
  52. package/build/navigator/navigator-screen/component.js +8 -1
  53. package/build/navigator/navigator-screen/component.js.map +1 -1
  54. package/build/notice/index.native.js +15 -19
  55. package/build/notice/index.native.js.map +1 -1
  56. package/build/notice/list.native.js +2 -3
  57. package/build/notice/list.native.js.map +1 -1
  58. package/build/palette-edit/index.js +1 -1
  59. package/build/palette-edit/index.js.map +1 -1
  60. package/build/popover/index.js +29 -32
  61. package/build/popover/index.js.map +1 -1
  62. package/build/popover/limit-shift.js +145 -0
  63. package/build/popover/limit-shift.js.map +1 -0
  64. package/build/popover/utils.js +55 -15
  65. package/build/popover/utils.js.map +1 -1
  66. package/build/resizable-box/resize-tooltip/utils.js +12 -14
  67. package/build/resizable-box/resize-tooltip/utils.js.map +1 -1
  68. package/build/sandbox/index.js +13 -8
  69. package/build/sandbox/index.js.map +1 -1
  70. package/build/sandbox/index.native.js +3 -1
  71. package/build/sandbox/index.native.js.map +1 -1
  72. package/build/search-control/index.native.js +6 -2
  73. package/build/search-control/index.native.js.map +1 -1
  74. package/build/slot-fill/bubbles-virtually/slot-fill-context.js +8 -2
  75. package/build/slot-fill/bubbles-virtually/slot-fill-context.js.map +1 -1
  76. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js +31 -41
  77. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  78. package/build/slot-fill/bubbles-virtually/use-slot-fills.js +39 -0
  79. package/build/slot-fill/bubbles-virtually/use-slot-fills.js.map +1 -0
  80. package/build/slot-fill/bubbles-virtually/use-slot.js +13 -4
  81. package/build/slot-fill/bubbles-virtually/use-slot.js.map +1 -1
  82. package/build/slot-fill/index.js +8 -0
  83. package/build/slot-fill/index.js.map +1 -1
  84. package/build/toggle-group-control/toggle-group-control-option-base/styles.js +8 -8
  85. package/build/toggle-group-control/toggle-group-control-option-base/styles.js.map +1 -1
  86. package/build/tools-panel/styles.js +27 -12
  87. package/build/tools-panel/styles.js.map +1 -1
  88. package/build/tools-panel/tools-panel-header/component.js +19 -6
  89. package/build/tools-panel/tools-panel-header/component.js.map +1 -1
  90. package/build/tools-panel/tools-panel-header/hook.js +4 -0
  91. package/build/tools-panel/tools-panel-header/hook.js.map +1 -1
  92. package/build-module/border-box-control/utils.js +36 -1
  93. package/build-module/border-box-control/utils.js.map +1 -1
  94. package/build-module/combobox-control/index.js +0 -1
  95. package/build-module/combobox-control/index.js.map +1 -1
  96. package/build-module/custom-select-control/index.js +2 -1
  97. package/build-module/custom-select-control/index.js.map +1 -1
  98. package/build-module/draggable/index.js +2 -5
  99. package/build-module/draggable/index.js.map +1 -1
  100. package/build-module/font-size-picker/index.js +45 -53
  101. package/build-module/font-size-picker/index.js.map +1 -1
  102. package/build-module/font-size-picker/styles.js +62 -0
  103. package/build-module/font-size-picker/styles.js.map +1 -0
  104. package/build-module/font-size-picker/types.js +2 -0
  105. package/build-module/font-size-picker/types.js.map +1 -0
  106. package/build-module/font-size-picker/utils.js +21 -15
  107. package/build-module/font-size-picker/utils.js.map +1 -1
  108. package/build-module/form-token-field/token-input.js +21 -2
  109. package/build-module/form-token-field/token-input.js.map +1 -1
  110. package/build-module/index.js +2 -2
  111. package/build-module/index.js.map +1 -1
  112. package/build-module/menu-item/index.js +4 -3
  113. package/build-module/menu-item/index.js.map +1 -1
  114. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js +10 -3
  115. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js.map +1 -1
  116. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +12 -3
  117. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js.map +1 -1
  118. package/build-module/mobile/bottom-sheet/sub-sheet/index.native.js +4 -1
  119. package/build-module/mobile/bottom-sheet/sub-sheet/index.native.js.map +1 -1
  120. package/build-module/mobile/color-settings/index.native.js +3 -1
  121. package/build-module/mobile/color-settings/index.native.js.map +1 -1
  122. package/build-module/mobile/color-settings/picker-screen.native.js +3 -1
  123. package/build-module/mobile/color-settings/picker-screen.native.js.map +1 -1
  124. package/build-module/mobile/image/index.native.js +3 -1
  125. package/build-module/mobile/image/index.native.js.map +1 -1
  126. package/build-module/mobile/keyboard-avoiding-view/index.ios.js +3 -1
  127. package/build-module/mobile/keyboard-avoiding-view/index.ios.js.map +1 -1
  128. package/build-module/mobile/link-picker/index.native.js +3 -1
  129. package/build-module/mobile/link-picker/index.native.js.map +1 -1
  130. package/build-module/mobile/link-picker/link-picker-results.native.js +3 -1
  131. package/build-module/mobile/link-picker/link-picker-results.native.js.map +1 -1
  132. package/build-module/mobile/link-picker/link-picker-screen.native.js +3 -1
  133. package/build-module/mobile/link-picker/link-picker-screen.native.js.map +1 -1
  134. package/build-module/mobile/link-settings/index.native.js +24 -6
  135. package/build-module/mobile/link-settings/index.native.js.map +1 -1
  136. package/build-module/mobile/link-settings/link-settings-screen.native.js +3 -1
  137. package/build-module/mobile/link-settings/link-settings-screen.native.js.map +1 -1
  138. package/build-module/mobile/segmented-control/index.native.js +6 -2
  139. package/build-module/mobile/segmented-control/index.native.js.map +1 -1
  140. package/build-module/mobile/utils/use-unit-converter-to-mobile.native.js +6 -2
  141. package/build-module/mobile/utils/use-unit-converter-to-mobile.native.js.map +1 -1
  142. package/build-module/navigator/navigator-screen/component.js +8 -1
  143. package/build-module/navigator/navigator-screen/component.js.map +1 -1
  144. package/build-module/notice/index.native.js +16 -21
  145. package/build-module/notice/index.native.js.map +1 -1
  146. package/build-module/notice/list.native.js +3 -3
  147. package/build-module/notice/list.native.js.map +1 -1
  148. package/build-module/palette-edit/index.js +1 -1
  149. package/build-module/palette-edit/index.js.map +1 -1
  150. package/build-module/popover/index.js +31 -35
  151. package/build-module/popover/index.js.map +1 -1
  152. package/build-module/popover/limit-shift.js +136 -0
  153. package/build-module/popover/limit-shift.js.map +1 -0
  154. package/build-module/popover/utils.js +55 -15
  155. package/build-module/popover/utils.js.map +1 -1
  156. package/build-module/resizable-box/resize-tooltip/utils.js +13 -15
  157. package/build-module/resizable-box/resize-tooltip/utils.js.map +1 -1
  158. package/build-module/sandbox/index.js +13 -8
  159. package/build-module/sandbox/index.js.map +1 -1
  160. package/build-module/sandbox/index.native.js +3 -1
  161. package/build-module/sandbox/index.native.js.map +1 -1
  162. package/build-module/search-control/index.native.js +6 -2
  163. package/build-module/search-control/index.native.js.map +1 -1
  164. package/build-module/slot-fill/bubbles-virtually/slot-fill-context.js +7 -2
  165. package/build-module/slot-fill/bubbles-virtually/slot-fill-context.js.map +1 -1
  166. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js +30 -42
  167. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  168. package/build-module/slot-fill/bubbles-virtually/use-slot-fills.js +27 -0
  169. package/build-module/slot-fill/bubbles-virtually/use-slot-fills.js.map +1 -0
  170. package/build-module/slot-fill/bubbles-virtually/use-slot.js +13 -5
  171. package/build-module/slot-fill/bubbles-virtually/use-slot.js.map +1 -1
  172. package/build-module/slot-fill/index.js +1 -0
  173. package/build-module/slot-fill/index.js.map +1 -1
  174. package/build-module/toggle-group-control/toggle-group-control-option-base/styles.js +7 -7
  175. package/build-module/toggle-group-control/toggle-group-control-option-base/styles.js.map +1 -1
  176. package/build-module/tools-panel/styles.js +23 -12
  177. package/build-module/tools-panel/styles.js.map +1 -1
  178. package/build-module/tools-panel/tools-panel-header/component.js +19 -7
  179. package/build-module/tools-panel/tools-panel-header/component.js.map +1 -1
  180. package/build-module/tools-panel/tools-panel-header/hook.js +4 -0
  181. package/build-module/tools-panel/tools-panel-header/hook.js.map +1 -1
  182. package/build-style/style-rtl.css +14 -100
  183. package/build-style/style.css +14 -100
  184. package/build-types/border-box-control/utils.d.ts +1 -3
  185. package/build-types/border-box-control/utils.d.ts.map +1 -1
  186. package/build-types/custom-select-control/index.d.ts +13 -0
  187. package/build-types/custom-select-control/index.d.ts.map +1 -0
  188. package/build-types/custom-select-control/styles.d.ts +9 -0
  189. package/build-types/custom-select-control/styles.d.ts.map +1 -0
  190. package/build-types/draggable/index.d.ts.map +1 -1
  191. package/build-types/external-link/styles/external-link-styles.d.ts +1 -1
  192. package/build-types/focal-point-picker/styles/focal-point-style.d.ts +3 -3
  193. package/build-types/font-size-picker/index.d.ts +5 -0
  194. package/build-types/font-size-picker/index.d.ts.map +1 -0
  195. package/build-types/font-size-picker/stories/e2e/index.d.ts +16 -0
  196. package/build-types/font-size-picker/stories/e2e/index.d.ts.map +1 -0
  197. package/build-types/font-size-picker/stories/index.d.ts +31 -0
  198. package/build-types/font-size-picker/stories/index.d.ts.map +1 -0
  199. package/build-types/font-size-picker/styles.d.ts +27 -0
  200. package/build-types/font-size-picker/styles.d.ts.map +1 -0
  201. package/build-types/font-size-picker/test/index.d.ts +2 -0
  202. package/build-types/font-size-picker/test/index.d.ts.map +1 -0
  203. package/build-types/font-size-picker/test/utils.d.ts +2 -0
  204. package/build-types/font-size-picker/test/utils.d.ts.map +1 -0
  205. package/build-types/font-size-picker/types.d.ts +93 -0
  206. package/build-types/font-size-picker/types.d.ts.map +1 -0
  207. package/build-types/font-size-picker/utils.d.ts +41 -0
  208. package/build-types/font-size-picker/utils.d.ts.map +1 -0
  209. package/build-types/form-token-field/token-input.d.ts.map +1 -1
  210. package/build-types/menu-item/index.d.ts.map +1 -1
  211. package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
  212. package/build-types/popover/index.d.ts.map +1 -1
  213. package/build-types/popover/limit-shift.d.ts +87 -0
  214. package/build-types/popover/limit-shift.d.ts.map +1 -0
  215. package/build-types/popover/test/index.d.ts +2 -0
  216. package/build-types/popover/test/index.d.ts.map +1 -0
  217. package/build-types/popover/types.d.ts +1 -1
  218. package/build-types/popover/types.d.ts.map +1 -1
  219. package/build-types/popover/utils.d.ts.map +1 -1
  220. package/build-types/range-control/types.d.ts +0 -32
  221. package/build-types/range-control/types.d.ts.map +1 -1
  222. package/build-types/slot-fill/bubbles-virtually/slot-fill-context.d.ts +2 -2
  223. package/build-types/slot-fill/bubbles-virtually/slot-fill-context.d.ts.map +1 -1
  224. package/build-types/slot-fill/bubbles-virtually/slot-fill-provider.d.ts.map +1 -1
  225. package/build-types/slot-fill/bubbles-virtually/use-slot-fills.d.ts +2 -0
  226. package/build-types/slot-fill/bubbles-virtually/use-slot-fills.d.ts.map +1 -0
  227. package/build-types/slot-fill/bubbles-virtually/use-slot.d.ts.map +1 -1
  228. package/build-types/slot-fill/index.d.ts +1 -0
  229. package/build-types/slot-fill/index.d.ts.map +1 -1
  230. package/build-types/spinner/index.d.ts +1 -1
  231. package/build-types/toggle-group-control/toggle-group-control-option-base/styles.d.ts +1 -1
  232. package/build-types/toggle-group-control/toggle-group-control-option-base/styles.d.ts.map +1 -1
  233. package/build-types/tools-panel/styles.d.ts +6 -0
  234. package/build-types/tools-panel/styles.d.ts.map +1 -1
  235. package/build-types/tools-panel/tools-panel-header/component.d.ts.map +1 -1
  236. package/build-types/tools-panel/tools-panel-header/hook.d.ts +1 -0
  237. package/build-types/tools-panel/tools-panel-header/hook.d.ts.map +1 -1
  238. package/build-types/tools-panel/types.d.ts +1 -0
  239. package/build-types/tools-panel/types.d.ts.map +1 -1
  240. package/package.json +19 -18
  241. package/src/alignment-matrix-control/test/index.js +17 -62
  242. package/src/border-box-control/test/utils.js +48 -0
  243. package/src/border-box-control/utils.ts +44 -1
  244. package/src/combobox-control/index.js +0 -5
  245. package/src/custom-select-control/index.js +2 -1
  246. package/src/draggable/index.js +2 -5
  247. package/src/font-size-picker/{index.js → index.tsx} +113 -79
  248. package/src/font-size-picker/stories/e2e/{index.js → index.tsx} +13 -4
  249. package/src/font-size-picker/stories/{index.js → index.tsx} +42 -36
  250. package/src/font-size-picker/styles.ts +44 -0
  251. package/src/font-size-picker/test/{index.js → index.tsx} +1 -1
  252. package/src/font-size-picker/test/{utils.js → utils.ts} +6 -2
  253. package/src/font-size-picker/types.ts +98 -0
  254. package/src/font-size-picker/{utils.js → utils.ts} +51 -27
  255. package/src/form-token-field/test/index.tsx +22 -1
  256. package/src/form-token-field/token-input.tsx +25 -3
  257. package/src/index.js +2 -1
  258. package/src/menu-item/README.md +7 -0
  259. package/src/menu-item/index.js +11 -5
  260. package/src/menu-item/style.scss +1 -0
  261. package/src/menu-item/test/index.js +36 -0
  262. package/src/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js +9 -0
  263. package/src/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +11 -0
  264. package/src/mobile/bottom-sheet/sub-sheet/index.native.js +3 -0
  265. package/src/mobile/color-settings/index.native.js +3 -0
  266. package/src/mobile/color-settings/picker-screen.native.js +3 -0
  267. package/src/mobile/image/index.native.js +3 -0
  268. package/src/mobile/keyboard-avoiding-view/index.ios.js +3 -0
  269. package/src/mobile/link-picker/index.native.js +3 -0
  270. package/src/mobile/link-picker/link-picker-results.native.js +3 -0
  271. package/src/mobile/link-picker/link-picker-screen.native.js +3 -0
  272. package/src/mobile/link-settings/index.native.js +18 -0
  273. package/src/mobile/link-settings/link-settings-screen.native.js +3 -0
  274. package/src/mobile/segmented-control/index.native.js +6 -0
  275. package/src/mobile/utils/use-unit-converter-to-mobile.native.js +6 -0
  276. package/src/navigator/navigator-screen/component.tsx +8 -1
  277. package/src/navigator/test/index.js +119 -54
  278. package/src/notice/index.native.js +17 -20
  279. package/src/notice/list.native.js +7 -3
  280. package/src/palette-edit/index.js +1 -1
  281. package/src/placeholder/style.scss +3 -3
  282. package/src/popover/index.tsx +26 -42
  283. package/src/popover/limit-shift.ts +205 -0
  284. package/src/popover/test/index.tsx +230 -0
  285. package/src/popover/types.ts +1 -0
  286. package/src/popover/utils.ts +58 -16
  287. package/src/range-control/types.ts +0 -33
  288. package/src/resizable-box/resize-tooltip/utils.ts +13 -13
  289. package/src/sandbox/index.js +13 -7
  290. package/src/sandbox/index.native.js +3 -0
  291. package/src/search-control/index.native.js +6 -0
  292. package/src/slot-fill/bubbles-virtually/slot-fill-context.js +6 -2
  293. package/src/slot-fill/bubbles-virtually/slot-fill-provider.js +51 -58
  294. package/src/slot-fill/bubbles-virtually/use-slot-fills.js +24 -0
  295. package/src/slot-fill/bubbles-virtually/use-slot.js +11 -6
  296. package/src/slot-fill/index.js +1 -0
  297. package/src/style.scss +0 -1
  298. package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +1 -0
  299. package/src/toggle-group-control/toggle-group-control-option-base/styles.ts +9 -7
  300. package/src/tools-panel/stories/index.js +27 -0
  301. package/src/tools-panel/styles.ts +28 -1
  302. package/src/tools-panel/tools-panel-header/component.tsx +12 -5
  303. package/src/tools-panel/tools-panel-header/hook.ts +5 -0
  304. package/src/tools-panel/types.ts +1 -0
  305. package/tsconfig.json +0 -2
  306. package/tsconfig.tsbuildinfo +1 -1
  307. package/src/font-size-picker/style.scss +0 -78
  308. package/src/popover/test/__snapshots__/index.js.snap +0 -34
  309. package/src/popover/test/index.js +0 -164
@@ -74,12 +74,18 @@ const SegmentedControls = ( {
74
74
  useEffect( () => {
75
75
  setActiveSegmentIndex( selectedSegmentIndex );
76
76
  segmentHandler( segments[ selectedSegmentIndex ] );
77
+ // Disable reason: deferring this refactor to the native team.
78
+ // see https://github.com/WordPress/gutenberg/pull/41166
79
+ // eslint-disable-next-line react-hooks/exhaustive-deps
77
80
  }, [] );
78
81
 
79
82
  useEffect( () => {
80
83
  positionAnimationValue.setValue(
81
84
  calculateEndValue( activeSegmentIndex )
82
85
  );
86
+ // Disable reason: deferring this refactor to the native team.
87
+ // see https://github.com/WordPress/gutenberg/pull/41166
88
+ // eslint-disable-next-line react-hooks/exhaustive-deps
83
89
  }, [ segmentsDimensions ] );
84
90
 
85
91
  const containerStyle = usePreferredColorSchemeStyle(
@@ -78,6 +78,9 @@ const useConvertUnitToMobile = ( value, unit ) => {
78
78
  return () => {
79
79
  dimensionsChangeSubscription.remove();
80
80
  };
81
+ // Disable reason: deferring this refactor to the native team.
82
+ // see https://github.com/WordPress/gutenberg/pull/41166
83
+ // eslint-disable-next-line react-hooks/exhaustive-deps
81
84
  }, [] );
82
85
 
83
86
  const onDimensionsChange = useCallback( ( { window } ) => {
@@ -94,6 +97,9 @@ const useConvertUnitToMobile = ( value, unit ) => {
94
97
  valueToConvert,
95
98
  valueUnit
96
99
  );
100
+ // Disable reason: deferring this refactor to the native team.
101
+ // see https://github.com/WordPress/gutenberg/pull/41166
102
+ // eslint-disable-next-line react-hooks/exhaustive-deps
97
103
  }, [ windowSizes, value, unit ] );
98
104
  };
99
105
 
@@ -83,6 +83,14 @@ function NavigatorScreen( props: Props, forwardedRef: ForwardedRef< any > ) {
83
83
  return;
84
84
  }
85
85
 
86
+ const activeElement = wrapperRef.current.ownerDocument.activeElement;
87
+
88
+ // If an element is already focused within the wrapper do not focus the
89
+ // element. This prevents inputs or buttons from losing focus unecessarily.
90
+ if ( wrapperRef.current.contains( activeElement ) ) {
91
+ return;
92
+ }
93
+
86
94
  let elementToFocus: HTMLElement | null = null;
87
95
 
88
96
  // When navigating back, if a selector is provided, use it to look for the
@@ -99,7 +107,6 @@ function NavigatorScreen( props: Props, forwardedRef: ForwardedRef< any > ) {
99
107
  const firstTabbable = (
100
108
  focus.tabbable.find( wrapperRef.current ) as HTMLElement[]
101
109
  )[ 0 ];
102
-
103
110
  elementToFocus = firstTabbable ?? wrapperRef.current;
104
111
  }
105
112
 
@@ -2,6 +2,12 @@
2
2
  * External dependencies
3
3
  */
4
4
  import { render, screen, fireEvent } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
6
+
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+ import { useState } from '@wordpress/element';
5
11
 
6
12
  /**
7
13
  * Internal dependencies
@@ -86,60 +92,74 @@ function CustomNavigatorBackButton( { onClick, ...props } ) {
86
92
  const MyNavigation = ( {
87
93
  initialPath = PATHS.HOME,
88
94
  onNavigatorButtonClick,
89
- } ) => (
90
- <NavigatorProvider initialPath={ initialPath }>
91
- <NavigatorScreen path={ PATHS.HOME }>
92
- <p>This is the home screen.</p>
93
- <CustomNavigatorButton
94
- path={ PATHS.NOT_FOUND }
95
- onClick={ onNavigatorButtonClick }
96
- >
97
- Navigate to non-existing screen.
98
- </CustomNavigatorButton>
99
- <CustomNavigatorButton
100
- path={ PATHS.CHILD }
101
- onClick={ onNavigatorButtonClick }
102
- >
103
- Navigate to child screen.
104
- </CustomNavigatorButton>
105
- <CustomNavigatorButton
106
- path={ PATHS.INVALID_HTML_ATTRIBUTE }
107
- onClick={ onNavigatorButtonClick }
108
- >
109
- Navigate to screen with an invalid HTML value as a path.
110
- </CustomNavigatorButton>
111
- </NavigatorScreen>
112
-
113
- <NavigatorScreen path={ PATHS.CHILD }>
114
- <p>This is the child screen.</p>
115
- <CustomNavigatorButtonWithFocusRestoration
116
- path={ PATHS.NESTED }
117
- onClick={ onNavigatorButtonClick }
118
- >
119
- Navigate to nested screen.
120
- </CustomNavigatorButtonWithFocusRestoration>
121
- <CustomNavigatorBackButton onClick={ onNavigatorButtonClick }>
122
- Go back
123
- </CustomNavigatorBackButton>
124
- </NavigatorScreen>
125
-
126
- <NavigatorScreen path={ PATHS.NESTED }>
127
- <p>This is the nested screen.</p>
128
- <CustomNavigatorBackButton onClick={ onNavigatorButtonClick }>
129
- Go back
130
- </CustomNavigatorBackButton>
131
- </NavigatorScreen>
132
-
133
- <NavigatorScreen path={ PATHS.INVALID_HTML_ATTRIBUTE }>
134
- <p>This is the screen with an invalid HTML value as a path.</p>
135
- <CustomNavigatorBackButton onClick={ onNavigatorButtonClick }>
136
- Go back
137
- </CustomNavigatorBackButton>
138
- </NavigatorScreen>
139
-
140
- { /* A `NavigatorScreen` with `path={ PATHS.NOT_FOUND }` is purposefully not included. */ }
141
- </NavigatorProvider>
142
- );
95
+ } ) => {
96
+ const [ inputValue, setInputValue ] = useState( '' );
97
+ return (
98
+ <NavigatorProvider initialPath={ initialPath }>
99
+ <NavigatorScreen path={ PATHS.HOME }>
100
+ <p>This is the home screen.</p>
101
+ <CustomNavigatorButton
102
+ path={ PATHS.NOT_FOUND }
103
+ onClick={ onNavigatorButtonClick }
104
+ >
105
+ Navigate to non-existing screen.
106
+ </CustomNavigatorButton>
107
+ <CustomNavigatorButton
108
+ path={ PATHS.CHILD }
109
+ onClick={ onNavigatorButtonClick }
110
+ >
111
+ Navigate to child screen.
112
+ </CustomNavigatorButton>
113
+ <CustomNavigatorButton
114
+ path={ PATHS.INVALID_HTML_ATTRIBUTE }
115
+ onClick={ onNavigatorButtonClick }
116
+ >
117
+ Navigate to screen with an invalid HTML value as a path.
118
+ </CustomNavigatorButton>
119
+ </NavigatorScreen>
120
+
121
+ <NavigatorScreen path={ PATHS.CHILD }>
122
+ <p>This is the child screen.</p>
123
+ <CustomNavigatorButtonWithFocusRestoration
124
+ path={ PATHS.NESTED }
125
+ onClick={ onNavigatorButtonClick }
126
+ >
127
+ Navigate to nested screen.
128
+ </CustomNavigatorButtonWithFocusRestoration>
129
+ <CustomNavigatorBackButton onClick={ onNavigatorButtonClick }>
130
+ Go back
131
+ </CustomNavigatorBackButton>
132
+
133
+ <label htmlFor="test-input">This is a test input</label>
134
+ <input
135
+ name="test-input"
136
+ // eslint-disable-next-line no-restricted-syntax
137
+ id="test-input"
138
+ onChange={ ( e ) => {
139
+ setInputValue( e.target.value );
140
+ } }
141
+ value={ inputValue }
142
+ />
143
+ </NavigatorScreen>
144
+
145
+ <NavigatorScreen path={ PATHS.NESTED }>
146
+ <p>This is the nested screen.</p>
147
+ <CustomNavigatorBackButton onClick={ onNavigatorButtonClick }>
148
+ Go back
149
+ </CustomNavigatorBackButton>
150
+ </NavigatorScreen>
151
+
152
+ <NavigatorScreen path={ PATHS.INVALID_HTML_ATTRIBUTE }>
153
+ <p>This is the screen with an invalid HTML value as a path.</p>
154
+ <CustomNavigatorBackButton onClick={ onNavigatorButtonClick }>
155
+ Go back
156
+ </CustomNavigatorBackButton>
157
+ </NavigatorScreen>
158
+
159
+ { /* A `NavigatorScreen` with `path={ PATHS.NOT_FOUND }` is purposefully not included. */ }
160
+ </NavigatorProvider>
161
+ );
162
+ };
143
163
 
144
164
  const getNavigationScreenByText = ( text, { throwIfNotFound = true } = {} ) => {
145
165
  const fnName = throwIfNotFound ? 'getByText' : 'queryByText';
@@ -194,6 +214,28 @@ const getBackButton = ( { throwIfNotFound } = {} ) =>
194
214
  } );
195
215
 
196
216
  describe( 'Navigator', () => {
217
+ const originalGetClientRects = window.Element.prototype.getClientRects;
218
+
219
+ // `getClientRects` needs to be mocked so that `isVisible` from the `@wordpress/dom`
220
+ // `focusable` module can pass, in a JSDOM env where the DOM elements have no width/height.
221
+ const mockedGetClientRects = jest.fn( () => [
222
+ {
223
+ x: 0,
224
+ y: 0,
225
+ width: 100,
226
+ height: 100,
227
+ },
228
+ ] );
229
+
230
+ beforeAll( () => {
231
+ window.Element.prototype.getClientRects =
232
+ jest.fn( mockedGetClientRects );
233
+ } );
234
+
235
+ afterAll( () => {
236
+ window.Element.prototype.getClientRects = originalGetClientRects;
237
+ } );
238
+
197
239
  it( 'should render', () => {
198
240
  render( <MyNavigation /> );
199
241
 
@@ -404,4 +446,27 @@ describe( 'Navigator', () => {
404
446
  expect( getHomeScreen() ).toBeInTheDocument();
405
447
  expect( getToInvalidHTMLPathScreenButton() ).toHaveFocus();
406
448
  } );
449
+
450
+ it( 'should keep focus on the element that is being interacted with, while re-rendering', async () => {
451
+ const user = userEvent.setup( {
452
+ advanceTimers: jest.advanceTimersByTime,
453
+ } );
454
+
455
+ render( <MyNavigation /> );
456
+
457
+ expect( getHomeScreen() ).toBeInTheDocument();
458
+ expect( getToChildScreenButton() ).toBeInTheDocument();
459
+
460
+ // Navigate to child screen.
461
+ await user.click( getToChildScreenButton() );
462
+
463
+ expect( getChildScreen() ).toBeInTheDocument();
464
+ expect( getBackButton() ).toBeInTheDocument();
465
+ expect( getToNestedScreenButton() ).toHaveFocus();
466
+
467
+ // Interact with the input, the focus should stay on the input element.
468
+ const input = screen.getByLabelText( 'This is a test input' );
469
+ await user.type( input, 'd' );
470
+ expect( input ).toHaveFocus();
471
+ } );
407
472
  } );
@@ -14,7 +14,7 @@ import { BlurView } from '@react-native-community/blur';
14
14
  /**
15
15
  * WordPress dependencies
16
16
  */
17
- import { useEffect, useRef, Platform } from '@wordpress/element';
17
+ import { useEffect, useRef, useCallback, Platform } from '@wordpress/element';
18
18
  import { usePreferredColorSchemeStyle } from '@wordpress/compose';
19
19
 
20
20
  /**
@@ -30,40 +30,37 @@ const Notice = ( { onNoticeHidden, content, id, status } ) => {
30
30
  const timer = useRef( null );
31
31
 
32
32
  useEffect( () => {
33
- startAnimation();
34
-
35
- return () => {
36
- clearTimeout( timer?.current );
37
- };
38
- }, [] );
39
-
40
- function onHide() {
33
+ // start animation
41
34
  Animated.timing( animationValue, {
42
- toValue: 0,
43
- duration: 150,
35
+ toValue: 1,
36
+ duration: 300,
44
37
  useNativeDriver: true,
45
38
  easing: Easing.out( Easing.quad ),
46
39
  } ).start( ( { finished } ) => {
47
40
  if ( finished && onNoticeHidden ) {
48
- onNoticeHidden( id );
41
+ timer.current = setTimeout( () => {
42
+ onHide();
43
+ }, HIDE_TIMER );
49
44
  }
50
45
  } );
51
- }
52
46
 
53
- function startAnimation() {
47
+ return () => {
48
+ clearTimeout( timer?.current );
49
+ };
50
+ }, [ animationValue, onHide, onNoticeHidden ] );
51
+
52
+ const onHide = useCallback( () => {
54
53
  Animated.timing( animationValue, {
55
- toValue: 1,
56
- duration: 300,
54
+ toValue: 0,
55
+ duration: 150,
57
56
  useNativeDriver: true,
58
57
  easing: Easing.out( Easing.quad ),
59
58
  } ).start( ( { finished } ) => {
60
59
  if ( finished && onNoticeHidden ) {
61
- timer.current = setTimeout( () => {
62
- onHide();
63
- }, HIDE_TIMER );
60
+ onNoticeHidden( id );
64
61
  }
65
62
  } );
66
- }
63
+ }, [ animationValue, onNoticeHidden, id ] );
67
64
 
68
65
  const noticeSolidStyles = usePreferredColorSchemeStyle(
69
66
  styles.noticeSolid,
@@ -14,6 +14,7 @@ import { store as noticesStore } from '@wordpress/notices';
14
14
  */
15
15
  import Notice from './';
16
16
  import styles from './style.scss';
17
+ import { useCallback } from '@wordpress/element';
17
18
 
18
19
  function NoticeList() {
19
20
  const { notices } = useSelect( ( select ) => {
@@ -25,9 +26,12 @@ function NoticeList() {
25
26
 
26
27
  const { removeNotice } = useDispatch( noticesStore );
27
28
 
28
- function onRemoveNotice( id ) {
29
- removeNotice( id );
30
- }
29
+ const onRemoveNotice = useCallback(
30
+ ( id ) => {
31
+ removeNotice( id );
32
+ },
33
+ [ removeNotice ]
34
+ );
31
35
 
32
36
  if ( ! notices.length ) {
33
37
  return null;
@@ -316,7 +316,7 @@ export default function PaletteEdit( {
316
316
  <PaletteHStackHeader>
317
317
  <PaletteHeading>{ paletteLabel }</PaletteHeading>
318
318
  <PaletteActionsContainer>
319
- { isEditing && (
319
+ { hasElements && isEditing && (
320
320
  <DoneButton
321
321
  isSmall
322
322
  onClick={ () => {
@@ -178,9 +178,9 @@
178
178
  min-width: 100px;
179
179
 
180
180
  // Blur the background so layered dashed placeholders are still visually separate.
181
- // We also provide a semitransparent background so as to allow duotones to sheen through.
181
+ // Make the background transparent to not interfere with the background overlay in placeholder-style() pseudo element
182
182
  backdrop-filter: blur(100px);
183
- background-color: rgba($white, 0.1);
183
+ background-color: transparent;
184
184
 
185
185
  // Invert the colors in themes deemed dark.
186
186
  .is-dark-theme & {
@@ -234,5 +234,5 @@
234
234
  width: 100%;
235
235
  height: 100%;
236
236
  stroke: currentColor;
237
- stroke-dasharray: 3;
237
+ opacity: 0.25;
238
238
  }
@@ -10,9 +10,9 @@ import {
10
10
  autoUpdate,
11
11
  arrow,
12
12
  offset as offsetMiddleware,
13
- limitShift,
14
13
  size,
15
14
  Middleware,
15
+ MiddlewareArguments,
16
16
  } from '@floating-ui/react-dom';
17
17
  // eslint-disable-next-line no-restricted-imports
18
18
  import {
@@ -34,7 +34,6 @@ import {
34
34
  useMemo,
35
35
  useState,
36
36
  useCallback,
37
- useEffect,
38
37
  } from '@wordpress/element';
39
38
  import {
40
39
  useViewportMatch,
@@ -65,6 +64,7 @@ import type {
65
64
  PopoverAnchorRefReference,
66
65
  PopoverAnchorRefTopBottom,
67
66
  } from './types';
67
+ import { limitShift as customLimitShift } from './limit-shift';
68
68
 
69
69
  /**
70
70
  * Name of slot in which popover should fill.
@@ -281,42 +281,31 @@ const UnforwardedPopover = (
281
281
  * https://floating-ui.com/docs/react-dom#variables-inside-middleware-functions.
282
282
  */
283
283
  const frameOffsetRef = useRef( getFrameOffset( referenceOwnerDocument ) );
284
- /**
285
- * Store the offset prop in a ref, due to constraints with floating-ui:
286
- * https://floating-ui.com/docs/react-dom#variables-inside-middleware-functions.
287
- */
288
- const offsetRef = useRef( offsetProp );
289
284
 
290
285
  const middleware = [
291
- offsetMiddleware( ( { placement: currentPlacement } ) => {
292
- if ( ! frameOffsetRef.current ) {
293
- return offsetRef.current;
294
- }
295
-
296
- const isTopBottomPlacement =
297
- currentPlacement.includes( 'top' ) ||
298
- currentPlacement.includes( 'bottom' );
299
-
300
- // The main axis should represent the gap between the
301
- // floating element and the reference element. The cross
302
- // axis is always perpendicular to the main axis.
303
- const mainAxis = isTopBottomPlacement ? 'y' : 'x';
304
- const crossAxis = mainAxis === 'x' ? 'y' : 'x';
305
-
306
- // When the popover is before the reference, subtract the offset,
307
- // of the main axis else add it.
308
- const hasBeforePlacement =
309
- currentPlacement.includes( 'top' ) ||
310
- currentPlacement.includes( 'left' );
311
- const mainAxisModifier = hasBeforePlacement ? -1 : 1;
312
-
313
- return {
314
- mainAxis:
315
- offsetRef.current +
316
- frameOffsetRef.current[ mainAxis ] * mainAxisModifier,
317
- crossAxis: frameOffsetRef.current[ crossAxis ],
318
- };
319
- } ),
286
+ // Custom middleware which adjusts the popover's position by taking into
287
+ // account the offset of the anchor's iframe (if any) compared to the page.
288
+ {
289
+ name: 'frameOffset',
290
+ fn( { x, y }: MiddlewareArguments ) {
291
+ if ( ! frameOffsetRef.current ) {
292
+ return {
293
+ x,
294
+ y,
295
+ };
296
+ }
297
+
298
+ return {
299
+ x: x + frameOffsetRef.current.x,
300
+ y: y + frameOffsetRef.current.y,
301
+ data: {
302
+ // This will be used in the customLimitShift() function.
303
+ amount: frameOffsetRef.current,
304
+ },
305
+ };
306
+ },
307
+ },
308
+ offsetMiddleware( offsetProp ),
320
309
  computedFlipProp ? flipMiddleware() : undefined,
321
310
  computedResizeProp
322
311
  ? size( {
@@ -339,7 +328,7 @@ const UnforwardedPopover = (
339
328
  shouldShift
340
329
  ? shiftMiddleware( {
341
330
  crossAxis: true,
342
- limiter: limitShift(),
331
+ limiter: customLimitShift(),
343
332
  padding: 1, // Necessary to avoid flickering at the edge of the viewport.
344
333
  } )
345
334
  : undefined,
@@ -395,11 +384,6 @@ const UnforwardedPopover = (
395
384
  } ),
396
385
  } );
397
386
 
398
- useEffect( () => {
399
- offsetRef.current = offsetProp;
400
- update();
401
- }, [ offsetProp, update ] );
402
-
403
387
  const arrowCallbackRef = useCallback(
404
388
  ( node ) => {
405
389
  arrowRef.current = node;