@wordpress/components 19.4.1 → 19.5.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 (396) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/CONTRIBUTING.md +69 -2
  3. package/build/box-control/unit-control.js +2 -2
  4. package/build/box-control/unit-control.js.map +1 -1
  5. package/build/card/card/component.js +2 -2
  6. package/build/card/card/component.js.map +1 -1
  7. package/build/card/card-body/component.js +1 -1
  8. package/build/card/card-body/component.js.map +1 -1
  9. package/build/card/card-divider/component.js +1 -1
  10. package/build/card/card-divider/component.js.map +1 -1
  11. package/build/card/card-footer/component.js +1 -1
  12. package/build/card/card-footer/component.js.map +1 -1
  13. package/build/card/card-header/component.js +1 -1
  14. package/build/card/card-header/component.js.map +1 -1
  15. package/build/card/card-media/component.js +1 -1
  16. package/build/card/card-media/component.js.map +1 -1
  17. package/build/color-palette/index.native.js +35 -30
  18. package/build/color-palette/index.native.js.map +1 -1
  19. package/build/color-picker/component.js.map +1 -1
  20. package/build/color-picker/hex-input.js +6 -9
  21. package/build/color-picker/hex-input.js.map +1 -1
  22. package/build/confirm-dialog/component.js.map +1 -1
  23. package/build/divider/component.js.map +1 -1
  24. package/build/elevation/component.js +1 -1
  25. package/build/elevation/component.js.map +1 -1
  26. package/build/flex/flex/component.js +1 -1
  27. package/build/flex/flex/component.js.map +1 -1
  28. package/build/flex/flex-block/component.js +1 -1
  29. package/build/flex/flex-block/component.js.map +1 -1
  30. package/build/flex/flex-item/component.js +1 -1
  31. package/build/flex/flex-item/component.js.map +1 -1
  32. package/build/flyout/flyout/component.js +1 -1
  33. package/build/flyout/flyout/component.js.map +1 -1
  34. package/build/flyout/flyout-content/component.js +1 -1
  35. package/build/flyout/flyout-content/component.js.map +1 -1
  36. package/build/focal-point-picker/index.js +18 -12
  37. package/build/focal-point-picker/index.js.map +1 -1
  38. package/build/font-size-picker/index.js +0 -1
  39. package/build/font-size-picker/index.js.map +1 -1
  40. package/build/grid/component.js +1 -1
  41. package/build/grid/component.js.map +1 -1
  42. package/build/h-stack/component.js +1 -1
  43. package/build/h-stack/component.js.map +1 -1
  44. package/build/heading/component.js.map +1 -1
  45. package/build/index.js +12 -0
  46. package/build/index.js.map +1 -1
  47. package/build/index.native.js +15 -1
  48. package/build/index.native.js.map +1 -1
  49. package/build/input-control/index.js.map +1 -1
  50. package/build/input-control/input-base.js.map +1 -1
  51. package/build/input-control/input-field.js +7 -7
  52. package/build/input-control/input-field.js.map +1 -1
  53. package/build/input-control/reducer/reducer.js +3 -0
  54. package/build/input-control/reducer/reducer.js.map +1 -1
  55. package/build/item-group/item/component.js.map +1 -1
  56. package/build/item-group/item-group/component.js.map +1 -1
  57. package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +1 -1
  58. package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js.map +1 -1
  59. package/build/mobile/color-settings/palette.screen.native.js +26 -9
  60. package/build/mobile/color-settings/palette.screen.native.js.map +1 -1
  61. package/build/mobile/global-styles-context/utils.native.js +63 -9
  62. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  63. package/build/navigator/index.js +16 -0
  64. package/build/navigator/index.js.map +1 -1
  65. package/build/navigator/navigator-back-button/component.js +72 -0
  66. package/build/navigator/navigator-back-button/component.js.map +1 -0
  67. package/build/navigator/navigator-back-button/hook.js +49 -0
  68. package/build/navigator/navigator-back-button/hook.js.map +1 -0
  69. package/build/navigator/navigator-back-button/index.js +16 -0
  70. package/build/navigator/navigator-back-button/index.js.map +1 -0
  71. package/build/navigator/navigator-button/component.js +71 -0
  72. package/build/navigator/navigator-button/component.js.map +1 -0
  73. package/build/navigator/navigator-button/hook.js +59 -0
  74. package/build/navigator/navigator-button/hook.js.map +1 -0
  75. package/build/navigator/navigator-button/index.js +16 -0
  76. package/build/navigator/navigator-button/index.js.map +1 -0
  77. package/build/navigator/navigator-provider/component.js +11 -21
  78. package/build/navigator/navigator-provider/component.js.map +1 -1
  79. package/build/navigator/navigator-screen/component.js +14 -22
  80. package/build/navigator/navigator-screen/component.js.map +1 -1
  81. package/build/resizable-box/index.js.map +1 -1
  82. package/build/resizable-box/resize-tooltip/index.js.map +1 -1
  83. package/build/resizable-box/resize-tooltip/label.js.map +1 -1
  84. package/build/scrollable/component.js +1 -1
  85. package/build/scrollable/component.js.map +1 -1
  86. package/build/select-control/index.js.map +1 -1
  87. package/build/spacer/component.js.map +1 -1
  88. package/build/surface/component.js +1 -1
  89. package/build/surface/component.js.map +1 -1
  90. package/build/text/component.js +1 -1
  91. package/build/text/component.js.map +1 -1
  92. package/build/text-control/index.js +2 -2
  93. package/build/text-control/index.js.map +1 -1
  94. package/build/toggle-group-control/toggle-group-control/component.js.map +1 -1
  95. package/build/toggle-group-control/toggle-group-control-option/component.js.map +1 -1
  96. package/build/tools-panel/tools-panel/component.js.map +1 -1
  97. package/build/tools-panel/tools-panel-header/component.js.map +1 -1
  98. package/build/tools-panel/tools-panel-item/component.js.map +1 -1
  99. package/build/tree-grid/index.js +50 -6
  100. package/build/tree-grid/index.js.map +1 -1
  101. package/build/truncate/component.js +1 -1
  102. package/build/truncate/component.js.map +1 -1
  103. package/build/ui/control-group/component.js +1 -1
  104. package/build/ui/control-group/component.js.map +1 -1
  105. package/build/ui/control-label/component.js +1 -1
  106. package/build/ui/control-label/component.js.map +1 -1
  107. package/build/ui/form-group/form-group.js +1 -1
  108. package/build/ui/form-group/form-group.js.map +1 -1
  109. package/build/ui/shortcut/component.js.map +1 -1
  110. package/build/ui/spinner/component.js +1 -1
  111. package/build/ui/spinner/component.js.map +1 -1
  112. package/build/ui/tooltip/component.js +1 -1
  113. package/build/ui/tooltip/component.js.map +1 -1
  114. package/build/ui/tooltip/content.js +1 -1
  115. package/build/ui/tooltip/content.js.map +1 -1
  116. package/build/unit-control/index.js.map +1 -1
  117. package/build/v-stack/component.js +1 -1
  118. package/build/v-stack/component.js.map +1 -1
  119. package/build/visually-hidden/component.js +1 -1
  120. package/build/visually-hidden/component.js.map +1 -1
  121. package/build/z-stack/component.js.map +1 -1
  122. package/build-module/box-control/unit-control.js +1 -1
  123. package/build-module/box-control/unit-control.js.map +1 -1
  124. package/build-module/card/card/component.js +2 -2
  125. package/build-module/card/card/component.js.map +1 -1
  126. package/build-module/card/card-body/component.js +1 -1
  127. package/build-module/card/card-body/component.js.map +1 -1
  128. package/build-module/card/card-divider/component.js +1 -1
  129. package/build-module/card/card-divider/component.js.map +1 -1
  130. package/build-module/card/card-footer/component.js +1 -1
  131. package/build-module/card/card-footer/component.js.map +1 -1
  132. package/build-module/card/card-header/component.js +1 -1
  133. package/build-module/card/card-header/component.js.map +1 -1
  134. package/build-module/card/card-media/component.js +1 -1
  135. package/build-module/card/card-media/component.js.map +1 -1
  136. package/build-module/color-palette/index.native.js +36 -31
  137. package/build-module/color-palette/index.native.js.map +1 -1
  138. package/build-module/color-picker/component.js.map +1 -1
  139. package/build-module/color-picker/hex-input.js +6 -9
  140. package/build-module/color-picker/hex-input.js.map +1 -1
  141. package/build-module/confirm-dialog/component.js.map +1 -1
  142. package/build-module/divider/component.js.map +1 -1
  143. package/build-module/elevation/component.js +1 -1
  144. package/build-module/elevation/component.js.map +1 -1
  145. package/build-module/flex/flex/component.js +1 -1
  146. package/build-module/flex/flex/component.js.map +1 -1
  147. package/build-module/flex/flex-block/component.js +1 -1
  148. package/build-module/flex/flex-block/component.js.map +1 -1
  149. package/build-module/flex/flex-item/component.js +1 -1
  150. package/build-module/flex/flex-item/component.js.map +1 -1
  151. package/build-module/flyout/flyout/component.js +1 -1
  152. package/build-module/flyout/flyout/component.js.map +1 -1
  153. package/build-module/flyout/flyout-content/component.js +1 -1
  154. package/build-module/flyout/flyout-content/component.js.map +1 -1
  155. package/build-module/focal-point-picker/index.js +18 -12
  156. package/build-module/focal-point-picker/index.js.map +1 -1
  157. package/build-module/font-size-picker/index.js +0 -1
  158. package/build-module/font-size-picker/index.js.map +1 -1
  159. package/build-module/grid/component.js +1 -1
  160. package/build-module/grid/component.js.map +1 -1
  161. package/build-module/h-stack/component.js +1 -1
  162. package/build-module/h-stack/component.js.map +1 -1
  163. package/build-module/heading/component.js.map +1 -1
  164. package/build-module/index.js +1 -1
  165. package/build-module/index.js.map +1 -1
  166. package/build-module/index.native.js +1 -1
  167. package/build-module/index.native.js.map +1 -1
  168. package/build-module/input-control/index.js.map +1 -1
  169. package/build-module/input-control/input-base.js.map +1 -1
  170. package/build-module/input-control/input-field.js +6 -6
  171. package/build-module/input-control/input-field.js.map +1 -1
  172. package/build-module/input-control/reducer/reducer.js +3 -0
  173. package/build-module/input-control/reducer/reducer.js.map +1 -1
  174. package/build-module/item-group/item/component.js.map +1 -1
  175. package/build-module/item-group/item-group/component.js.map +1 -1
  176. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +1 -1
  177. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js.map +1 -1
  178. package/build-module/mobile/color-settings/palette.screen.native.js +27 -10
  179. package/build-module/mobile/color-settings/palette.screen.native.js.map +1 -1
  180. package/build-module/mobile/global-styles-context/utils.native.js +60 -10
  181. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  182. package/build-module/navigator/index.js +2 -0
  183. package/build-module/navigator/index.js.map +1 -1
  184. package/build-module/navigator/navigator-back-button/component.js +59 -0
  185. package/build-module/navigator/navigator-back-button/component.js.map +1 -0
  186. package/build-module/navigator/navigator-back-button/hook.js +36 -0
  187. package/build-module/navigator/navigator-back-button/hook.js.map +1 -0
  188. package/build-module/navigator/navigator-back-button/index.js +2 -0
  189. package/build-module/navigator/navigator-back-button/index.js.map +1 -0
  190. package/build-module/navigator/navigator-button/component.js +58 -0
  191. package/build-module/navigator/navigator-button/component.js.map +1 -0
  192. package/build-module/navigator/navigator-button/hook.js +46 -0
  193. package/build-module/navigator/navigator-button/hook.js.map +1 -0
  194. package/build-module/navigator/navigator-button/index.js +2 -0
  195. package/build-module/navigator/navigator-button/index.js.map +1 -0
  196. package/build-module/navigator/navigator-provider/component.js +11 -21
  197. package/build-module/navigator/navigator-provider/component.js.map +1 -1
  198. package/build-module/navigator/navigator-screen/component.js +13 -22
  199. package/build-module/navigator/navigator-screen/component.js.map +1 -1
  200. package/build-module/resizable-box/index.js.map +1 -1
  201. package/build-module/resizable-box/resize-tooltip/index.js.map +1 -1
  202. package/build-module/resizable-box/resize-tooltip/label.js.map +1 -1
  203. package/build-module/scrollable/component.js +1 -1
  204. package/build-module/scrollable/component.js.map +1 -1
  205. package/build-module/select-control/index.js +1 -1
  206. package/build-module/select-control/index.js.map +1 -1
  207. package/build-module/spacer/component.js.map +1 -1
  208. package/build-module/surface/component.js +1 -1
  209. package/build-module/surface/component.js.map +1 -1
  210. package/build-module/text/component.js +1 -1
  211. package/build-module/text/component.js.map +1 -1
  212. package/build-module/text-control/index.js +2 -2
  213. package/build-module/text-control/index.js.map +1 -1
  214. package/build-module/toggle-group-control/toggle-group-control/component.js.map +1 -1
  215. package/build-module/toggle-group-control/toggle-group-control-option/component.js.map +1 -1
  216. package/build-module/tools-panel/tools-panel/component.js.map +1 -1
  217. package/build-module/tools-panel/tools-panel-header/component.js.map +1 -1
  218. package/build-module/tools-panel/tools-panel-item/component.js.map +1 -1
  219. package/build-module/tree-grid/index.js +51 -7
  220. package/build-module/tree-grid/index.js.map +1 -1
  221. package/build-module/truncate/component.js +1 -1
  222. package/build-module/truncate/component.js.map +1 -1
  223. package/build-module/ui/control-group/component.js +1 -1
  224. package/build-module/ui/control-group/component.js.map +1 -1
  225. package/build-module/ui/control-label/component.js +1 -1
  226. package/build-module/ui/control-label/component.js.map +1 -1
  227. package/build-module/ui/form-group/form-group.js +1 -1
  228. package/build-module/ui/form-group/form-group.js.map +1 -1
  229. package/build-module/ui/shortcut/component.js.map +1 -1
  230. package/build-module/ui/spinner/component.js +1 -1
  231. package/build-module/ui/spinner/component.js.map +1 -1
  232. package/build-module/ui/tooltip/component.js +1 -1
  233. package/build-module/ui/tooltip/component.js.map +1 -1
  234. package/build-module/ui/tooltip/content.js +1 -1
  235. package/build-module/ui/tooltip/content.js.map +1 -1
  236. package/build-module/unit-control/index.js.map +1 -1
  237. package/build-module/v-stack/component.js +1 -1
  238. package/build-module/v-stack/component.js.map +1 -1
  239. package/build-module/visually-hidden/component.js +1 -1
  240. package/build-module/visually-hidden/component.js.map +1 -1
  241. package/build-module/z-stack/component.js.map +1 -1
  242. package/build-types/card/card-divider/hook.d.ts +0 -1
  243. package/build-types/card/card-divider/hook.d.ts.map +1 -1
  244. package/build-types/color-picker/styles.d.ts +2 -4
  245. package/build-types/color-picker/styles.d.ts.map +1 -1
  246. package/build-types/confirm-dialog/component.d.ts +2 -6
  247. package/build-types/confirm-dialog/component.d.ts.map +1 -1
  248. package/build-types/flyout/flyout/hook.d.ts +0 -1
  249. package/build-types/flyout/flyout/hook.d.ts.map +1 -1
  250. package/build-types/input-control/index.d.ts +3 -3
  251. package/build-types/input-control/index.d.ts.map +1 -1
  252. package/build-types/input-control/input-base.d.ts +2 -2
  253. package/build-types/input-control/input-base.d.ts.map +1 -1
  254. package/build-types/input-control/input-field.d.ts +1 -3
  255. package/build-types/input-control/input-field.d.ts.map +1 -1
  256. package/build-types/input-control/reducer/reducer.d.ts.map +1 -1
  257. package/build-types/input-control/types.d.ts +1 -1
  258. package/build-types/input-control/types.d.ts.map +1 -1
  259. package/build-types/navigator/index.d.ts +2 -0
  260. package/build-types/navigator/index.d.ts.map +1 -1
  261. package/build-types/navigator/navigator-back-button/component.d.ts +38 -0
  262. package/build-types/navigator/navigator-back-button/component.d.ts.map +1 -0
  263. package/build-types/navigator/navigator-back-button/hook.d.ts +282 -0
  264. package/build-types/navigator/navigator-back-button/hook.d.ts.map +1 -0
  265. package/build-types/navigator/navigator-back-button/index.d.ts +2 -0
  266. package/build-types/navigator/navigator-back-button/index.d.ts.map +1 -0
  267. package/build-types/navigator/navigator-button/component.d.ts +37 -0
  268. package/build-types/navigator/navigator-button/component.d.ts.map +1 -0
  269. package/build-types/navigator/navigator-button/hook.d.ts +282 -0
  270. package/build-types/navigator/navigator-button/hook.d.ts.map +1 -0
  271. package/build-types/navigator/navigator-button/index.d.ts +2 -0
  272. package/build-types/navigator/navigator-button/index.d.ts.map +1 -0
  273. package/build-types/navigator/navigator-provider/component.d.ts +10 -20
  274. package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
  275. package/build-types/navigator/navigator-screen/component.d.ts +10 -20
  276. package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
  277. package/build-types/navigator/types.d.ts +21 -0
  278. package/build-types/navigator/types.d.ts.map +1 -1
  279. package/build-types/number-control/styles/number-control-styles.d.ts +1 -1
  280. package/build-types/resizable-box/index.d.ts +2 -2
  281. package/build-types/resizable-box/index.d.ts.map +1 -1
  282. package/build-types/resizable-box/resize-tooltip/index.d.ts.map +1 -1
  283. package/build-types/select-control/index.d.ts +1 -3
  284. package/build-types/select-control/index.d.ts.map +1 -1
  285. package/build-types/ui/context/wordpress-component.d.ts +2 -6
  286. package/build-types/ui/context/wordpress-component.d.ts.map +1 -1
  287. package/build-types/unit-control/index.d.ts +1 -3
  288. package/build-types/unit-control/index.d.ts.map +1 -1
  289. package/build-types/z-stack/component.d.ts.map +1 -1
  290. package/package.json +8 -7
  291. package/src/alignment-matrix-control/README.md +4 -0
  292. package/src/alignment-matrix-control/stories/index.js +1 -1
  293. package/src/base-control/stories/index.js +65 -22
  294. package/src/box-control/stories/index.js +4 -1
  295. package/src/box-control/unit-control.js +1 -1
  296. package/src/card/card/component.js +1 -1
  297. package/src/card/card-body/component.js +1 -1
  298. package/src/card/card-divider/component.js +1 -1
  299. package/src/card/card-footer/component.js +1 -1
  300. package/src/card/card-header/component.js +1 -1
  301. package/src/card/card-media/component.js +1 -1
  302. package/src/color-palette/index.native.js +92 -75
  303. package/src/color-palette/style.native.scss +10 -5
  304. package/src/color-picker/component.tsx +2 -2
  305. package/src/color-picker/hex-input.tsx +9 -9
  306. package/src/confirm-dialog/component.tsx +2 -2
  307. package/src/divider/component.tsx +2 -2
  308. package/src/elevation/component.js +1 -1
  309. package/src/flex/flex/component.js +1 -1
  310. package/src/flex/flex-block/component.js +1 -1
  311. package/src/flex/flex-item/component.js +1 -1
  312. package/src/flyout/flyout/component.js +1 -1
  313. package/src/flyout/flyout-content/component.js +1 -1
  314. package/src/focal-point-picker/README.md +7 -0
  315. package/src/focal-point-picker/index.js +12 -7
  316. package/src/focal-point-picker/stories/index.js +30 -0
  317. package/src/focal-point-picker/test/index.js +44 -0
  318. package/src/font-size-picker/index.js +0 -1
  319. package/src/form-file-upload/README.md +1 -1
  320. package/src/form-file-upload/stories/index.js +51 -0
  321. package/src/grid/component.js +1 -1
  322. package/src/h-stack/component.js +1 -1
  323. package/src/heading/component.tsx +2 -2
  324. package/src/index.js +2 -0
  325. package/src/index.native.js +5 -1
  326. package/src/input-control/index.tsx +2 -2
  327. package/src/input-control/input-base.tsx +2 -2
  328. package/src/input-control/input-field.tsx +4 -6
  329. package/src/input-control/reducer/reducer.ts +3 -0
  330. package/src/input-control/stories/index.js +1 -1
  331. package/src/input-control/types.ts +1 -1
  332. package/src/item-group/item/component.tsx +2 -2
  333. package/src/item-group/item-group/component.tsx +2 -2
  334. package/src/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +10 -1
  335. package/src/mobile/color-settings/palette.screen.native.js +39 -9
  336. package/src/mobile/color-settings/style.native.scss +4 -0
  337. package/src/mobile/global-styles-context/test/fixtures/theme.native.js +27 -0
  338. package/src/mobile/global-styles-context/test/utils.native.js +2 -2
  339. package/src/mobile/global-styles-context/utils.native.js +75 -6
  340. package/src/navigation/stories/index.js +1 -1
  341. package/src/navigator/index.ts +2 -0
  342. package/src/navigator/navigator-back-button/README.md +31 -0
  343. package/src/navigator/navigator-back-button/component.tsx +62 -0
  344. package/src/navigator/navigator-back-button/hook.ts +40 -0
  345. package/src/navigator/navigator-back-button/index.ts +1 -0
  346. package/src/navigator/navigator-button/README.md +38 -0
  347. package/src/navigator/navigator-button/component.tsx +61 -0
  348. package/src/navigator/navigator-button/hook.ts +55 -0
  349. package/src/navigator/navigator-button/index.ts +1 -0
  350. package/src/navigator/navigator-provider/README.md +20 -33
  351. package/src/navigator/navigator-provider/component.tsx +12 -22
  352. package/src/navigator/navigator-screen/README.md +1 -1
  353. package/src/navigator/navigator-screen/component.tsx +14 -23
  354. package/src/navigator/stories/index.js +24 -37
  355. package/src/navigator/test/index.js +89 -34
  356. package/src/navigator/types.ts +26 -0
  357. package/src/number-control/stories/index.js +1 -1
  358. package/src/radio/stories/index.js +1 -1
  359. package/src/radio-group/stories/index.js +4 -1
  360. package/src/resizable-box/index.tsx +2 -2
  361. package/src/resizable-box/resize-tooltip/index.tsx +2 -2
  362. package/src/resizable-box/resize-tooltip/label.tsx +2 -2
  363. package/src/scrollable/component.js +1 -1
  364. package/src/select-control/index.tsx +2 -3
  365. package/src/spacer/component.tsx +2 -2
  366. package/src/surface/component.js +1 -1
  367. package/src/text/component.js +1 -1
  368. package/src/text-control/index.js +2 -2
  369. package/src/toggle-group-control/stories/index.js +1 -1
  370. package/src/toggle-group-control/toggle-group-control/component.tsx +2 -2
  371. package/src/toggle-group-control/toggle-group-control-option/component.tsx +2 -2
  372. package/src/tools-panel/stories/index.js +0 -1
  373. package/src/tools-panel/tools-panel/component.tsx +2 -2
  374. package/src/tools-panel/tools-panel-header/component.tsx +2 -2
  375. package/src/tools-panel/tools-panel-item/component.tsx +2 -2
  376. package/src/tree-grid/README.md +24 -1
  377. package/src/tree-grid/index.js +66 -7
  378. package/src/tree-grid/stories/index.js +4 -1
  379. package/src/tree-grid/test/__snapshots__/index.js.snap +1 -14
  380. package/src/tree-grid/test/index.js +226 -7
  381. package/src/truncate/component.js +1 -1
  382. package/src/ui/context/wordpress-component.ts +2 -2
  383. package/src/ui/control-group/component.js +1 -1
  384. package/src/ui/control-label/component.js +1 -1
  385. package/src/ui/form-group/form-group.js +1 -1
  386. package/src/ui/shortcut/component.tsx +2 -2
  387. package/src/ui/spinner/component.js +1 -1
  388. package/src/ui/tooltip/component.js +1 -1
  389. package/src/ui/tooltip/content.js +1 -1
  390. package/src/unit-control/index.tsx +2 -2
  391. package/src/unit-control/stories/index.js +1 -1
  392. package/src/v-stack/component.js +1 -1
  393. package/src/visually-hidden/component.js +1 -1
  394. package/src/z-stack/component.tsx +2 -2
  395. package/tsconfig.tsbuildinfo +1 -1
  396. package/src/tools-panel/stories/typography-panel.js +0 -215
@@ -0,0 +1,61 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ForwardedRef } from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { contextConnect, WordPressComponentProps } from '../../ui/context';
10
+ import { View } from '../../view';
11
+ import { useNavigatorButton } from './hook';
12
+ import type { NavigatorButtonProps } from '../types';
13
+
14
+ function NavigatorButton(
15
+ props: WordPressComponentProps< NavigatorButtonProps, 'button' >,
16
+ forwardedRef: ForwardedRef< any >
17
+ ) {
18
+ const navigatorButtonProps = useNavigatorButton( props );
19
+
20
+ return <View ref={ forwardedRef } { ...navigatorButtonProps } />;
21
+ }
22
+
23
+ /**
24
+ * The `NavigatorButton` component can be used to navigate to a screen and should
25
+ * be used in combination with the `NavigatorProvider`, the `NavigatorScreen`
26
+ * and the `NavigatorBackButton` components (or the `useNavigator` hook).
27
+ *
28
+ * @example
29
+ * ```jsx
30
+ * import {
31
+ * __experimentalNavigatorProvider as NavigatorProvider,
32
+ * __experimentalNavigatorScreen as NavigatorScreen,
33
+ * __experimentalNavigatorButton as NavigatorButton,
34
+ * __experimentalNavigatorBackButton as NavigatorBackButton,
35
+ * } from '@wordpress/components';
36
+ *
37
+ * const MyNavigation = () => (
38
+ * <NavigatorProvider initialPath="/">
39
+ * <NavigatorScreen path="/">
40
+ * <p>This is the home screen.</p>
41
+ * <NavigatorButton path="/child">
42
+ * Navigate to child screen.
43
+ * </NavigatorButton>
44
+ * </NavigatorScreen>
45
+ *
46
+ * <NavigatorScreen path="/child">
47
+ * <p>This is the child screen.</p>
48
+ * <NavigatorBackButton>
49
+ * Go back
50
+ * </NavigatorBackButton>
51
+ * </NavigatorScreen>
52
+ * </NavigatorProvider>
53
+ * );
54
+ * ```
55
+ */
56
+ const ConnectedNavigatorButton = contextConnect(
57
+ NavigatorButton,
58
+ 'NavigatorButton'
59
+ );
60
+
61
+ export default ConnectedNavigatorButton;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useCallback } from '@wordpress/element';
5
+ import { escapeAttribute } from '@wordpress/escape-html';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { useContextSystem, WordPressComponentProps } from '../../ui/context';
14
+ import Button from '../../button';
15
+ import useNavigator from '../use-navigator';
16
+ import type { NavigatorButtonProps } from '../types';
17
+
18
+ const cssSelectorForAttribute = ( attrName: string, attrValue: string ) =>
19
+ `[${ attrName }="${ attrValue }"]`;
20
+
21
+ export function useNavigatorButton(
22
+ props: WordPressComponentProps< NavigatorButtonProps, 'button' >
23
+ ) {
24
+ const {
25
+ path,
26
+ onClick,
27
+ as = Button,
28
+ attributeName = 'id',
29
+ ...otherProps
30
+ } = useContextSystem( props, 'NavigatorButton' );
31
+
32
+ const escapedPath = escapeAttribute( path );
33
+
34
+ const { goTo } = useNavigator();
35
+ const handleClick: React.MouseEventHandler< HTMLButtonElement > = useCallback(
36
+ ( e ) => {
37
+ e.preventDefault();
38
+ goTo( escapedPath, {
39
+ focusTargetSelector: cssSelectorForAttribute(
40
+ attributeName,
41
+ escapedPath
42
+ ),
43
+ } );
44
+ onClick?.( e );
45
+ },
46
+ [ goTo, onClick ]
47
+ );
48
+
49
+ return {
50
+ as,
51
+ onClick: handleClick,
52
+ ...otherProps,
53
+ [ attributeName ]: escapedPath,
54
+ };
55
+ }
@@ -0,0 +1 @@
1
+ export { default } from './component';
@@ -4,47 +4,34 @@
4
4
  This feature is still experimental. “Experimental” means this is an early implementation subject to drastic and breaking changes.
5
5
  </div>
6
6
 
7
- The `NavigatorProvider` component allows rendering nested panels or menus (via the [`NavigatorScreen` component](/packages/components/src/navigator/navigator-screen/README.md)) and navigate between these different states (via the `useNavigator` hook). The Global Styles sidebar is an example of this.
7
+ The `NavigatorProvider` component allows rendering nested views/panels/menus (via the [`NavigatorScreen` component](/packages/components/src/navigator/navigator-screen/README.md)) and navigate between these different states (via the [`NavigatorButton`](/packages/components/src/navigator/navigator-button/README.md) and [`NavigatorBackButton`](/packages/components/src/navigator/navigator-back-button/README.md) components or the `useNavigator` hook). The Global Styles sidebar is an example of this.
8
8
 
9
9
  ## Usage
10
10
 
11
11
  ```jsx
12
12
  import {
13
- __experimentalNavigatorProvider as NavigatorProvider,
14
- __experimentalNavigatorScreen as NavigatorScreen,
15
- __experimentalUseNavigator as useNavigator,
13
+ __experimentalNavigatorProvider as NavigatorProvider,
14
+ __experimentalNavigatorScreen as NavigatorScreen,
15
+ __experimentalNavigatorButton as NavigatorButton,
16
+ __experimentalNavigatorBackButton as NavigatorBackButton,
16
17
  } from '@wordpress/components';
17
18
 
18
- function NavigatorButton( { path, ...props } ) {
19
- const { goTo } = useNavigator();
20
- return (
21
- <Button
22
- variant="primary"
23
- onClick={ () => goTo( path ) }
24
- { ...props }
25
- />
26
- );
27
- }
28
-
29
- function NavigatorBackButton( props ) {
30
- const { goBack } = useNavigator();
31
- return <Button variant="secondary" onClick={ () => goBack() } { ...props } />;
32
- }
33
-
34
19
  const MyNavigation = () => (
35
- <NavigatorProvider initialPath="/">
36
- <NavigatorScreen path="/">
37
- <p>This is the home screen.</p>
38
- <NavigatorButton path="/child">
39
- Navigate to child screen.
40
- </NavigatorButton>
41
- </NavigatorScreen>
42
-
43
- <NavigatorScreen path="/child">
44
- <p>This is the child screen.</p>
45
- <NavigatorBackButton>Go back</NavigatorBackButton>
46
- </NavigatorScreen>
47
- </NavigatorProvider>
20
+ <NavigatorProvider initialPath="/">
21
+ <NavigatorScreen path="/">
22
+ <p>This is the home screen.</p>
23
+ <NavigatorButton path="/child">
24
+ Navigate to child screen.
25
+ </NavigatorButton>
26
+ </NavigatorScreen>
27
+
28
+ <NavigatorScreen path="/child">
29
+ <p>This is the child screen.</p>
30
+ <NavigatorBackButton>
31
+ Go back
32
+ </NavigatorBackButton>
33
+ </NavigatorScreen>
34
+ </NavigatorProvider>
48
35
  );
49
36
  ```
50
37
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import type { Ref } from 'react';
4
+ import type { ForwardedRef } from 'react';
5
5
  import { css } from '@emotion/react';
6
6
 
7
7
  /**
@@ -28,7 +28,7 @@ import type {
28
28
 
29
29
  function NavigatorProvider(
30
30
  props: WordPressComponentProps< NavigatorProviderProps, 'div' >,
31
- forwardedRef: Ref< any >
31
+ forwardedRef: ForwardedRef< any >
32
32
  ) {
33
33
  const {
34
34
  initialPath,
@@ -100,44 +100,34 @@ function NavigatorProvider(
100
100
  }
101
101
 
102
102
  /**
103
- * The `NavigatorProvider` component allows rendering nested panels or menus (via the `NavigatorScreen` component) and navigate between these different states (via the `useNavigator` hook).
103
+ * The `NavigatorProvider` component allows rendering nested views/panels/menus
104
+ * (via the `NavigatorScreen` component and navigate between these different
105
+ * view (via the `NavigatorButton` and `NavigatorBackButton` components or the
106
+ * `useNavigator` hook).
104
107
  *
105
108
  * @example
106
109
  * ```jsx
107
110
  * import {
108
111
  * __experimentalNavigatorProvider as NavigatorProvider,
109
112
  * __experimentalNavigatorScreen as NavigatorScreen,
110
- * __experimentalUseNavigator as useNavigator,
113
+ * __experimentalNavigatorButton as NavigatorButton,
114
+ * __experimentalNavigatorBackButton as NavigatorBackButton,
111
115
  * } from '@wordpress/components';
112
116
  *
113
- * function NavigatorButton( { path, ...props } ) {
114
- * const { goTo } = useNavigator();
115
- * return (
116
- * <Button
117
- * variant="primary"
118
- * onClick={ () => goTo( path ) }
119
- * { ...props }
120
- * />
121
- * );
122
- * }
123
- *
124
- * function NavigatorBackButton( props ) {
125
- * const { goBack } = useNavigator();
126
- * return <Button variant="secondary" onClick={ () => goBack() } { ...props } />;
127
- * }
128
- *
129
117
  * const MyNavigation = () => (
130
118
  * <NavigatorProvider initialPath="/">
131
119
  * <NavigatorScreen path="/">
132
120
  * <p>This is the home screen.</p>
133
- * <NavigatorButton path="/child">
121
+ * <NavigatorButton path="/child">
134
122
  * Navigate to child screen.
135
123
  * </NavigatorButton>
136
124
  * </NavigatorScreen>
137
125
  *
138
126
  * <NavigatorScreen path="/child">
139
127
  * <p>This is the child screen.</p>
140
- * <NavigatorBackButton>Go back</NavigatorBackButton>
128
+ * <NavigatorBackButton>
129
+ * Go back
130
+ * </NavigatorBackButton>
141
131
  * </NavigatorScreen>
142
132
  * </NavigatorProvider>
143
133
  * );
@@ -4,7 +4,7 @@
4
4
  This feature is still experimental. “Experimental” means this is an early implementation subject to drastic and breaking changes.
5
5
  </div>
6
6
 
7
- The `NavigatorScreen` component represents a single view/screen/panel/menu and is supposed to be used in combination with [the `NavigatorProvider` component](/packages/components/src/navigator/navigator-provider/README.md).
7
+ The `NavigatorScreen` component represents a single view/screen/panel and should be used in combination with the [`NavigatorProvider`](/packages/components/src/navigator/navigator-provider/README.md), the [`NavigatorButton`](/packages/components/src/navigator/navigator-button/README.md) and the [`NavigatorBackButton`](/packages/components/src/navigator/navigator-back-button/README.md) components (or the `useNavigator` hook).
8
8
 
9
9
  ## Usage
10
10
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import type { Ref } from 'react';
4
+ import type { ForwardedRef } from 'react';
5
5
  // eslint-disable-next-line no-restricted-imports
6
6
  import { motion, MotionProps } from 'framer-motion';
7
7
  import { css } from '@emotion/react';
@@ -17,6 +17,7 @@ import {
17
17
  usePrevious,
18
18
  } from '@wordpress/compose';
19
19
  import { isRTL } from '@wordpress/i18n';
20
+ import { escapeAttribute } from '@wordpress/escape-html';
20
21
 
21
22
  /**
22
23
  * Internal dependencies
@@ -43,7 +44,7 @@ type Props = Omit<
43
44
  keyof MotionProps
44
45
  >;
45
46
 
46
- function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) {
47
+ function NavigatorScreen( props: Props, forwardedRef: ForwardedRef< any > ) {
47
48
  const { children, className, path, ...otherProps } = useContextSystem(
48
49
  props,
49
50
  'NavigatorScreen'
@@ -51,7 +52,7 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) {
51
52
 
52
53
  const prefersReducedMotion = useReducedMotion();
53
54
  const { location } = useContext( NavigatorContext );
54
- const isMatch = location.path === path;
55
+ const isMatch = location.path === escapeAttribute( path );
55
56
  const wrapperRef = useRef< HTMLDivElement >( null );
56
57
 
57
58
  const previousLocation = usePrevious( location );
@@ -171,44 +172,34 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) {
171
172
  }
172
173
 
173
174
  /**
174
- * The `NavigatorScreen` component represents a single view/screen/panel/menu and is supposed to be used in combination with the `NavigatorProvider` component.
175
+ * The `NavigatorScreen` component represents a single view/screen/panel and
176
+ * should be used in combination with the `NavigatorProvider`, the
177
+ * `NavigatorButton` and the `NavigatorBackButton` components (or the `useNavigator`
178
+ * hook).
175
179
  *
176
180
  * @example
177
181
  * ```jsx
178
182
  * import {
179
183
  * __experimentalNavigatorProvider as NavigatorProvider,
180
184
  * __experimentalNavigatorScreen as NavigatorScreen,
181
- * __experimentalUseNavigator as useNavigator,
185
+ * __experimentalNavigatorButton as NavigatorButton,
186
+ * __experimentalNavigatorBackButton as NavigatorBackButton,
182
187
  * } from '@wordpress/components';
183
188
  *
184
- * function NavigatorButton( { path, ...props } ) {
185
- * const { goTo } = useNavigator();
186
- * return (
187
- * <Button
188
- * variant="primary"
189
- * onClick={ () => goTo( path ) }
190
- * { ...props }
191
- * />
192
- * );
193
- * }
194
- *
195
- * function NavigatorBackButton( props ) {
196
- * const { goBack } = useNavigator();
197
- * return <Button variant="secondary" onClick={ () => goBack() } { ...props } />;
198
- * }
199
- *
200
189
  * const MyNavigation = () => (
201
190
  * <NavigatorProvider initialPath="/">
202
191
  * <NavigatorScreen path="/">
203
192
  * <p>This is the home screen.</p>
204
- * <NavigatorButton path="/child">
193
+ * <NavigatorButton path="/child">
205
194
  * Navigate to child screen.
206
195
  * </NavigatorButton>
207
196
  * </NavigatorScreen>
208
197
  *
209
198
  * <NavigatorScreen path="/child">
210
199
  * <p>This is the child screen.</p>
211
- * <NavigatorBackButton>Go back</NavigatorBackButton>
200
+ * <NavigatorBackButton>
201
+ * Go back
202
+ * </NavigatorBackButton>
212
203
  * </NavigatorScreen>
213
204
  * </NavigatorProvider>
214
205
  * );
@@ -11,43 +11,18 @@ import { Card, CardBody, CardFooter, CardHeader } from '../../card';
11
11
  import { HStack } from '../../h-stack';
12
12
  import { Flyout } from '../../flyout';
13
13
  import { useCx } from '../../utils/hooks/use-cx';
14
- import { NavigatorProvider, NavigatorScreen, useNavigator } from '../';
14
+ import {
15
+ NavigatorProvider,
16
+ NavigatorScreen,
17
+ NavigatorButton,
18
+ NavigatorBackButton,
19
+ } from '../';
15
20
 
16
21
  export default {
17
22
  title: 'Components (Experimental)/Navigator',
18
23
  component: NavigatorProvider,
19
24
  };
20
25
 
21
- function NavigatorButton( { path, ...props } ) {
22
- const { goTo } = useNavigator();
23
- const dataAttrName = 'data-navigator-focusable-id';
24
- const dataAttrValue = path;
25
-
26
- const dataAttrCssSelector = `[${ dataAttrName }="${ dataAttrValue }"]`;
27
-
28
- const buttonProps = {
29
- ...props,
30
- [ dataAttrName ]: dataAttrValue,
31
- };
32
-
33
- return (
34
- <Button
35
- variant="secondary"
36
- onClick={ () =>
37
- goTo( path, { focusTargetSelector: dataAttrCssSelector } )
38
- }
39
- { ...buttonProps }
40
- />
41
- );
42
- }
43
-
44
- function NavigatorBackButton( props ) {
45
- const { goBack } = useNavigator();
46
- return (
47
- <Button variant="secondary" onClick={ () => goBack() } { ...props } />
48
- );
49
- }
50
-
51
26
  const MyNavigation = () => {
52
27
  const cx = useCx();
53
28
  return (
@@ -61,15 +36,21 @@ const MyNavigation = () => {
61
36
  <p>This is the home screen.</p>
62
37
 
63
38
  <HStack justify="flex-start" wrap>
64
- <NavigatorButton path="/child">
39
+ <NavigatorButton variant="secondary" path="/child">
65
40
  Navigate to child screen.
66
41
  </NavigatorButton>
67
42
 
68
- <NavigatorButton path="/overflow-child">
43
+ <NavigatorButton
44
+ variant="secondary"
45
+ path="/overflow-child"
46
+ >
69
47
  Navigate to screen with horizontal overflow.
70
48
  </NavigatorButton>
71
49
 
72
- <NavigatorButton path="/stickies">
50
+ <NavigatorButton
51
+ variant="secondary"
52
+ path="/stickies"
53
+ >
73
54
  Navigate to screen with sticky content.
74
55
  </NavigatorButton>
75
56
 
@@ -93,7 +74,9 @@ const MyNavigation = () => {
93
74
  <Card>
94
75
  <CardBody>
95
76
  <p>This is the child screen.</p>
96
- <NavigatorBackButton>Go back</NavigatorBackButton>
77
+ <NavigatorBackButton variant="secondary">
78
+ Go back
79
+ </NavigatorBackButton>
97
80
  </CardBody>
98
81
  </Card>
99
82
  </NavigatorScreen>
@@ -101,7 +84,9 @@ const MyNavigation = () => {
101
84
  <NavigatorScreen path="/overflow-child">
102
85
  <Card>
103
86
  <CardBody>
104
- <NavigatorBackButton>Go back</NavigatorBackButton>
87
+ <NavigatorBackButton variant="secondary">
88
+ Go back
89
+ </NavigatorBackButton>
105
90
  <div
106
91
  className={ cx(
107
92
  css( `
@@ -129,7 +114,9 @@ const MyNavigation = () => {
129
114
  <NavigatorScreen path="/stickies">
130
115
  <Card>
131
116
  <Sticky as={ CardHeader } z="2">
132
- <NavigatorBackButton>Go back</NavigatorBackButton>
117
+ <NavigatorBackButton variant="secondary">
118
+ Go back
119
+ </NavigatorBackButton>
133
120
  </Sticky>
134
121
  <CardBody>
135
122
  <Sticky top="69px" colors="papayawhip/peachpuff">
@@ -6,7 +6,12 @@ import { render, screen, fireEvent } from '@testing-library/react';
6
6
  /**
7
7
  * Internal dependencies
8
8
  */
9
- import { NavigatorProvider, NavigatorScreen, useNavigator } from '../';
9
+ import {
10
+ NavigatorProvider,
11
+ NavigatorScreen,
12
+ NavigatorButton,
13
+ NavigatorBackButton,
14
+ } from '../';
10
15
 
11
16
  jest.mock( 'framer-motion', () => {
12
17
  const actual = jest.requireActual( 'framer-motion' );
@@ -23,57 +28,53 @@ jest.mock( 'framer-motion', () => {
23
28
  };
24
29
  } );
25
30
 
31
+ const INVALID_HTML_ATTRIBUTE = {
32
+ raw: ' "\'><=invalid_path',
33
+ escaped: " &quot;'&gt;<=invalid_path",
34
+ };
35
+
26
36
  const PATHS = {
27
37
  HOME: '/',
28
38
  CHILD: '/child',
29
39
  NESTED: '/child/nested',
40
+ INVALID_HTML_ATTRIBUTE: INVALID_HTML_ATTRIBUTE.raw,
30
41
  NOT_FOUND: '/not-found',
31
42
  };
32
43
 
33
- function NavigatorButton( { path, onClick, ...props } ) {
34
- const { goTo } = useNavigator();
44
+ function CustomNavigatorButton( { path, onClick, ...props } ) {
35
45
  return (
36
- <button
46
+ <NavigatorButton
37
47
  onClick={ () => {
38
- goTo( path );
39
48
  // Used to spy on the values passed to `navigator.goTo`
40
49
  onClick?.( { type: 'goTo', path } );
41
50
  } }
51
+ path={ path }
42
52
  { ...props }
43
53
  />
44
54
  );
45
55
  }
46
56
 
47
- function NavigatorButtonWithFocusRestoration( { path, onClick, ...props } ) {
48
- const { goTo } = useNavigator();
49
- const dataAttrName = 'data-navigator-focusable-id';
50
- const dataAttrValue = path;
51
-
52
- const dataAttrCssSelector = `[${ dataAttrName }="${ dataAttrValue }"]`;
53
-
54
- const buttonProps = {
55
- ...props,
56
- [ dataAttrName ]: dataAttrValue,
57
- };
58
-
57
+ function CustomNavigatorButtonWithFocusRestoration( {
58
+ path,
59
+ onClick,
60
+ ...props
61
+ } ) {
59
62
  return (
60
- <button
63
+ <NavigatorButton
61
64
  onClick={ () => {
62
- goTo( path, { focusTargetSelector: dataAttrCssSelector } );
63
65
  // Used to spy on the values passed to `navigator.goTo`
64
66
  onClick?.( { type: 'goTo', path } );
65
67
  } }
66
- { ...buttonProps }
68
+ path={ path }
69
+ { ...props }
67
70
  />
68
71
  );
69
72
  }
70
73
 
71
- function NavigatorBackButton( { onClick, ...props } ) {
72
- const { goBack } = useNavigator();
74
+ function CustomNavigatorBackButton( { onClick, ...props } ) {
73
75
  return (
74
- <button
76
+ <NavigatorBackButton
75
77
  onClick={ () => {
76
- goBack();
77
78
  // Used to spy on the values passed to `navigator.goBack`
78
79
  onClick?.( { type: 'goBack' } );
79
80
  } }
@@ -89,38 +90,51 @@ const MyNavigation = ( {
89
90
  <NavigatorProvider initialPath={ initialPath }>
90
91
  <NavigatorScreen path={ PATHS.HOME }>
91
92
  <p>This is the home screen.</p>
92
- <NavigatorButton
93
+ <CustomNavigatorButton
93
94
  path={ PATHS.NOT_FOUND }
94
95
  onClick={ onNavigatorButtonClick }
95
96
  >
96
97
  Navigate to non-existing screen.
97
- </NavigatorButton>
98
- <NavigatorButtonWithFocusRestoration
98
+ </CustomNavigatorButton>
99
+ <CustomNavigatorButton
99
100
  path={ PATHS.CHILD }
100
101
  onClick={ onNavigatorButtonClick }
101
102
  >
102
103
  Navigate to child screen.
103
- </NavigatorButtonWithFocusRestoration>
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>
104
111
  </NavigatorScreen>
105
112
 
106
113
  <NavigatorScreen path={ PATHS.CHILD }>
107
114
  <p>This is the child screen.</p>
108
- <NavigatorButtonWithFocusRestoration
115
+ <CustomNavigatorButtonWithFocusRestoration
109
116
  path={ PATHS.NESTED }
110
117
  onClick={ onNavigatorButtonClick }
111
118
  >
112
119
  Navigate to nested screen.
113
- </NavigatorButtonWithFocusRestoration>
114
- <NavigatorBackButton onClick={ onNavigatorButtonClick }>
120
+ </CustomNavigatorButtonWithFocusRestoration>
121
+ <CustomNavigatorBackButton onClick={ onNavigatorButtonClick }>
115
122
  Go back
116
- </NavigatorBackButton>
123
+ </CustomNavigatorBackButton>
117
124
  </NavigatorScreen>
118
125
 
119
126
  <NavigatorScreen path={ PATHS.NESTED }>
120
127
  <p>This is the nested screen.</p>
121
- <NavigatorBackButton onClick={ onNavigatorButtonClick }>
128
+ <CustomNavigatorBackButton onClick={ onNavigatorButtonClick }>
122
129
  Go back
123
- </NavigatorBackButton>
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>
124
138
  </NavigatorScreen>
125
139
 
126
140
  { /* A `NavigatorScreen` with `path={ PATHS.NOT_FOUND }` is purposefully not included */ }
@@ -143,6 +157,13 @@ const getNestedScreen = ( { throwIfNotFound } = {} ) =>
143
157
  getNavigationScreenByText( 'This is the nested screen.', {
144
158
  throwIfNotFound,
145
159
  } );
160
+ const getInvalidHTMLPathScreen = ( { throwIfNotFound } = {} ) =>
161
+ getNavigationScreenByText(
162
+ 'This is the screen with an invalid HTML value as a path.',
163
+ {
164
+ throwIfNotFound,
165
+ }
166
+ );
146
167
 
147
168
  const getNavigationButtonByText = ( text, { throwIfNotFound = true } = {} ) => {
148
169
  const fnName = throwIfNotFound ? 'getByRole' : 'queryByRole';
@@ -160,6 +181,13 @@ const getToNestedScreenButton = ( { throwIfNotFound } = {} ) =>
160
181
  getNavigationButtonByText( 'Navigate to nested screen.', {
161
182
  throwIfNotFound,
162
183
  } );
184
+ const getToInvalidHTMLPathScreenButton = ( { throwIfNotFound } = {} ) =>
185
+ getNavigationButtonByText(
186
+ 'Navigate to screen with an invalid HTML value as a path.',
187
+ {
188
+ throwIfNotFound,
189
+ }
190
+ );
163
191
  const getBackButton = ( { throwIfNotFound } = {} ) =>
164
192
  getNavigationButtonByText( 'Go back', {
165
193
  throwIfNotFound,
@@ -350,4 +378,31 @@ describe( 'Navigator', () => {
350
378
  expect( getHomeScreen() ).toBeInTheDocument();
351
379
  expect( getToChildScreenButton() ).toHaveFocus();
352
380
  } );
381
+
382
+ it( 'should escape the value of the `path` prop', () => {
383
+ render( <MyNavigation /> );
384
+
385
+ expect( getHomeScreen() ).toBeInTheDocument();
386
+ expect( getToInvalidHTMLPathScreenButton() ).toBeInTheDocument();
387
+
388
+ // The following line tests the implementation details, but it's necessary
389
+ // as this would be otherwise transparent to the user.
390
+ expect( getToInvalidHTMLPathScreenButton() ).toHaveAttribute(
391
+ 'id',
392
+ INVALID_HTML_ATTRIBUTE.escaped
393
+ );
394
+
395
+ // Navigate to screen with an invalid HTML value for its `path`
396
+ fireEvent.click( getToInvalidHTMLPathScreenButton() );
397
+
398
+ expect( getInvalidHTMLPathScreen() ).toBeInTheDocument();
399
+ expect( getBackButton() ).toBeInTheDocument();
400
+
401
+ // Navigate back to home screen, check that the focus restoration selector
402
+ // worked correctly despite the escaping
403
+ fireEvent.click( getBackButton() );
404
+
405
+ expect( getHomeScreen() ).toBeInTheDocument();
406
+ expect( getToInvalidHTMLPathScreenButton() ).toHaveFocus();
407
+ } );
353
408
  } );