@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.
- package/CHANGELOG.md +16 -1
- package/CONTRIBUTING.md +69 -2
- package/build/box-control/unit-control.js +2 -2
- package/build/box-control/unit-control.js.map +1 -1
- package/build/card/card/component.js +2 -2
- package/build/card/card/component.js.map +1 -1
- package/build/card/card-body/component.js +1 -1
- package/build/card/card-body/component.js.map +1 -1
- package/build/card/card-divider/component.js +1 -1
- package/build/card/card-divider/component.js.map +1 -1
- package/build/card/card-footer/component.js +1 -1
- package/build/card/card-footer/component.js.map +1 -1
- package/build/card/card-header/component.js +1 -1
- package/build/card/card-header/component.js.map +1 -1
- package/build/card/card-media/component.js +1 -1
- package/build/card/card-media/component.js.map +1 -1
- package/build/color-palette/index.native.js +35 -30
- package/build/color-palette/index.native.js.map +1 -1
- package/build/color-picker/component.js.map +1 -1
- package/build/color-picker/hex-input.js +6 -9
- package/build/color-picker/hex-input.js.map +1 -1
- package/build/confirm-dialog/component.js.map +1 -1
- package/build/divider/component.js.map +1 -1
- package/build/elevation/component.js +1 -1
- package/build/elevation/component.js.map +1 -1
- package/build/flex/flex/component.js +1 -1
- package/build/flex/flex/component.js.map +1 -1
- package/build/flex/flex-block/component.js +1 -1
- package/build/flex/flex-block/component.js.map +1 -1
- package/build/flex/flex-item/component.js +1 -1
- package/build/flex/flex-item/component.js.map +1 -1
- package/build/flyout/flyout/component.js +1 -1
- package/build/flyout/flyout/component.js.map +1 -1
- package/build/flyout/flyout-content/component.js +1 -1
- package/build/flyout/flyout-content/component.js.map +1 -1
- package/build/focal-point-picker/index.js +18 -12
- package/build/focal-point-picker/index.js.map +1 -1
- package/build/font-size-picker/index.js +0 -1
- package/build/font-size-picker/index.js.map +1 -1
- package/build/grid/component.js +1 -1
- package/build/grid/component.js.map +1 -1
- package/build/h-stack/component.js +1 -1
- package/build/h-stack/component.js.map +1 -1
- package/build/heading/component.js.map +1 -1
- package/build/index.js +12 -0
- package/build/index.js.map +1 -1
- package/build/index.native.js +15 -1
- package/build/index.native.js.map +1 -1
- package/build/input-control/index.js.map +1 -1
- package/build/input-control/input-base.js.map +1 -1
- package/build/input-control/input-field.js +7 -7
- package/build/input-control/input-field.js.map +1 -1
- package/build/input-control/reducer/reducer.js +3 -0
- package/build/input-control/reducer/reducer.js.map +1 -1
- package/build/item-group/item/component.js.map +1 -1
- package/build/item-group/item-group/component.js.map +1 -1
- package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +1 -1
- package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js.map +1 -1
- package/build/mobile/color-settings/palette.screen.native.js +26 -9
- package/build/mobile/color-settings/palette.screen.native.js.map +1 -1
- package/build/mobile/global-styles-context/utils.native.js +63 -9
- package/build/mobile/global-styles-context/utils.native.js.map +1 -1
- package/build/navigator/index.js +16 -0
- package/build/navigator/index.js.map +1 -1
- package/build/navigator/navigator-back-button/component.js +72 -0
- package/build/navigator/navigator-back-button/component.js.map +1 -0
- package/build/navigator/navigator-back-button/hook.js +49 -0
- package/build/navigator/navigator-back-button/hook.js.map +1 -0
- package/build/navigator/navigator-back-button/index.js +16 -0
- package/build/navigator/navigator-back-button/index.js.map +1 -0
- package/build/navigator/navigator-button/component.js +71 -0
- package/build/navigator/navigator-button/component.js.map +1 -0
- package/build/navigator/navigator-button/hook.js +59 -0
- package/build/navigator/navigator-button/hook.js.map +1 -0
- package/build/navigator/navigator-button/index.js +16 -0
- package/build/navigator/navigator-button/index.js.map +1 -0
- package/build/navigator/navigator-provider/component.js +11 -21
- package/build/navigator/navigator-provider/component.js.map +1 -1
- package/build/navigator/navigator-screen/component.js +14 -22
- package/build/navigator/navigator-screen/component.js.map +1 -1
- package/build/resizable-box/index.js.map +1 -1
- package/build/resizable-box/resize-tooltip/index.js.map +1 -1
- package/build/resizable-box/resize-tooltip/label.js.map +1 -1
- package/build/scrollable/component.js +1 -1
- package/build/scrollable/component.js.map +1 -1
- package/build/select-control/index.js.map +1 -1
- package/build/spacer/component.js.map +1 -1
- package/build/surface/component.js +1 -1
- package/build/surface/component.js.map +1 -1
- package/build/text/component.js +1 -1
- package/build/text/component.js.map +1 -1
- package/build/text-control/index.js +2 -2
- package/build/text-control/index.js.map +1 -1
- package/build/toggle-group-control/toggle-group-control/component.js.map +1 -1
- package/build/toggle-group-control/toggle-group-control-option/component.js.map +1 -1
- package/build/tools-panel/tools-panel/component.js.map +1 -1
- package/build/tools-panel/tools-panel-header/component.js.map +1 -1
- package/build/tools-panel/tools-panel-item/component.js.map +1 -1
- package/build/tree-grid/index.js +50 -6
- package/build/tree-grid/index.js.map +1 -1
- package/build/truncate/component.js +1 -1
- package/build/truncate/component.js.map +1 -1
- package/build/ui/control-group/component.js +1 -1
- package/build/ui/control-group/component.js.map +1 -1
- package/build/ui/control-label/component.js +1 -1
- package/build/ui/control-label/component.js.map +1 -1
- package/build/ui/form-group/form-group.js +1 -1
- package/build/ui/form-group/form-group.js.map +1 -1
- package/build/ui/shortcut/component.js.map +1 -1
- package/build/ui/spinner/component.js +1 -1
- package/build/ui/spinner/component.js.map +1 -1
- package/build/ui/tooltip/component.js +1 -1
- package/build/ui/tooltip/component.js.map +1 -1
- package/build/ui/tooltip/content.js +1 -1
- package/build/ui/tooltip/content.js.map +1 -1
- package/build/unit-control/index.js.map +1 -1
- package/build/v-stack/component.js +1 -1
- package/build/v-stack/component.js.map +1 -1
- package/build/visually-hidden/component.js +1 -1
- package/build/visually-hidden/component.js.map +1 -1
- package/build/z-stack/component.js.map +1 -1
- package/build-module/box-control/unit-control.js +1 -1
- package/build-module/box-control/unit-control.js.map +1 -1
- package/build-module/card/card/component.js +2 -2
- package/build-module/card/card/component.js.map +1 -1
- package/build-module/card/card-body/component.js +1 -1
- package/build-module/card/card-body/component.js.map +1 -1
- package/build-module/card/card-divider/component.js +1 -1
- package/build-module/card/card-divider/component.js.map +1 -1
- package/build-module/card/card-footer/component.js +1 -1
- package/build-module/card/card-footer/component.js.map +1 -1
- package/build-module/card/card-header/component.js +1 -1
- package/build-module/card/card-header/component.js.map +1 -1
- package/build-module/card/card-media/component.js +1 -1
- package/build-module/card/card-media/component.js.map +1 -1
- package/build-module/color-palette/index.native.js +36 -31
- package/build-module/color-palette/index.native.js.map +1 -1
- package/build-module/color-picker/component.js.map +1 -1
- package/build-module/color-picker/hex-input.js +6 -9
- package/build-module/color-picker/hex-input.js.map +1 -1
- package/build-module/confirm-dialog/component.js.map +1 -1
- package/build-module/divider/component.js.map +1 -1
- package/build-module/elevation/component.js +1 -1
- package/build-module/elevation/component.js.map +1 -1
- package/build-module/flex/flex/component.js +1 -1
- package/build-module/flex/flex/component.js.map +1 -1
- package/build-module/flex/flex-block/component.js +1 -1
- package/build-module/flex/flex-block/component.js.map +1 -1
- package/build-module/flex/flex-item/component.js +1 -1
- package/build-module/flex/flex-item/component.js.map +1 -1
- package/build-module/flyout/flyout/component.js +1 -1
- package/build-module/flyout/flyout/component.js.map +1 -1
- package/build-module/flyout/flyout-content/component.js +1 -1
- package/build-module/flyout/flyout-content/component.js.map +1 -1
- package/build-module/focal-point-picker/index.js +18 -12
- package/build-module/focal-point-picker/index.js.map +1 -1
- package/build-module/font-size-picker/index.js +0 -1
- package/build-module/font-size-picker/index.js.map +1 -1
- package/build-module/grid/component.js +1 -1
- package/build-module/grid/component.js.map +1 -1
- package/build-module/h-stack/component.js +1 -1
- package/build-module/h-stack/component.js.map +1 -1
- package/build-module/heading/component.js.map +1 -1
- package/build-module/index.js +1 -1
- package/build-module/index.js.map +1 -1
- package/build-module/index.native.js +1 -1
- package/build-module/index.native.js.map +1 -1
- package/build-module/input-control/index.js.map +1 -1
- package/build-module/input-control/input-base.js.map +1 -1
- package/build-module/input-control/input-field.js +6 -6
- package/build-module/input-control/input-field.js.map +1 -1
- package/build-module/input-control/reducer/reducer.js +3 -0
- package/build-module/input-control/reducer/reducer.js.map +1 -1
- package/build-module/item-group/item/component.js.map +1 -1
- package/build-module/item-group/item-group/component.js.map +1 -1
- package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +1 -1
- package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js.map +1 -1
- package/build-module/mobile/color-settings/palette.screen.native.js +27 -10
- package/build-module/mobile/color-settings/palette.screen.native.js.map +1 -1
- package/build-module/mobile/global-styles-context/utils.native.js +60 -10
- package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
- package/build-module/navigator/index.js +2 -0
- package/build-module/navigator/index.js.map +1 -1
- package/build-module/navigator/navigator-back-button/component.js +59 -0
- package/build-module/navigator/navigator-back-button/component.js.map +1 -0
- package/build-module/navigator/navigator-back-button/hook.js +36 -0
- package/build-module/navigator/navigator-back-button/hook.js.map +1 -0
- package/build-module/navigator/navigator-back-button/index.js +2 -0
- package/build-module/navigator/navigator-back-button/index.js.map +1 -0
- package/build-module/navigator/navigator-button/component.js +58 -0
- package/build-module/navigator/navigator-button/component.js.map +1 -0
- package/build-module/navigator/navigator-button/hook.js +46 -0
- package/build-module/navigator/navigator-button/hook.js.map +1 -0
- package/build-module/navigator/navigator-button/index.js +2 -0
- package/build-module/navigator/navigator-button/index.js.map +1 -0
- package/build-module/navigator/navigator-provider/component.js +11 -21
- package/build-module/navigator/navigator-provider/component.js.map +1 -1
- package/build-module/navigator/navigator-screen/component.js +13 -22
- package/build-module/navigator/navigator-screen/component.js.map +1 -1
- package/build-module/resizable-box/index.js.map +1 -1
- package/build-module/resizable-box/resize-tooltip/index.js.map +1 -1
- package/build-module/resizable-box/resize-tooltip/label.js.map +1 -1
- package/build-module/scrollable/component.js +1 -1
- package/build-module/scrollable/component.js.map +1 -1
- package/build-module/select-control/index.js +1 -1
- package/build-module/select-control/index.js.map +1 -1
- package/build-module/spacer/component.js.map +1 -1
- package/build-module/surface/component.js +1 -1
- package/build-module/surface/component.js.map +1 -1
- package/build-module/text/component.js +1 -1
- package/build-module/text/component.js.map +1 -1
- package/build-module/text-control/index.js +2 -2
- package/build-module/text-control/index.js.map +1 -1
- package/build-module/toggle-group-control/toggle-group-control/component.js.map +1 -1
- package/build-module/toggle-group-control/toggle-group-control-option/component.js.map +1 -1
- package/build-module/tools-panel/tools-panel/component.js.map +1 -1
- package/build-module/tools-panel/tools-panel-header/component.js.map +1 -1
- package/build-module/tools-panel/tools-panel-item/component.js.map +1 -1
- package/build-module/tree-grid/index.js +51 -7
- package/build-module/tree-grid/index.js.map +1 -1
- package/build-module/truncate/component.js +1 -1
- package/build-module/truncate/component.js.map +1 -1
- package/build-module/ui/control-group/component.js +1 -1
- package/build-module/ui/control-group/component.js.map +1 -1
- package/build-module/ui/control-label/component.js +1 -1
- package/build-module/ui/control-label/component.js.map +1 -1
- package/build-module/ui/form-group/form-group.js +1 -1
- package/build-module/ui/form-group/form-group.js.map +1 -1
- package/build-module/ui/shortcut/component.js.map +1 -1
- package/build-module/ui/spinner/component.js +1 -1
- package/build-module/ui/spinner/component.js.map +1 -1
- package/build-module/ui/tooltip/component.js +1 -1
- package/build-module/ui/tooltip/component.js.map +1 -1
- package/build-module/ui/tooltip/content.js +1 -1
- package/build-module/ui/tooltip/content.js.map +1 -1
- package/build-module/unit-control/index.js.map +1 -1
- package/build-module/v-stack/component.js +1 -1
- package/build-module/v-stack/component.js.map +1 -1
- package/build-module/visually-hidden/component.js +1 -1
- package/build-module/visually-hidden/component.js.map +1 -1
- package/build-module/z-stack/component.js.map +1 -1
- package/build-types/card/card-divider/hook.d.ts +0 -1
- package/build-types/card/card-divider/hook.d.ts.map +1 -1
- package/build-types/color-picker/styles.d.ts +2 -4
- package/build-types/color-picker/styles.d.ts.map +1 -1
- package/build-types/confirm-dialog/component.d.ts +2 -6
- package/build-types/confirm-dialog/component.d.ts.map +1 -1
- package/build-types/flyout/flyout/hook.d.ts +0 -1
- package/build-types/flyout/flyout/hook.d.ts.map +1 -1
- package/build-types/input-control/index.d.ts +3 -3
- package/build-types/input-control/index.d.ts.map +1 -1
- package/build-types/input-control/input-base.d.ts +2 -2
- package/build-types/input-control/input-base.d.ts.map +1 -1
- package/build-types/input-control/input-field.d.ts +1 -3
- package/build-types/input-control/input-field.d.ts.map +1 -1
- package/build-types/input-control/reducer/reducer.d.ts.map +1 -1
- package/build-types/input-control/types.d.ts +1 -1
- package/build-types/input-control/types.d.ts.map +1 -1
- package/build-types/navigator/index.d.ts +2 -0
- package/build-types/navigator/index.d.ts.map +1 -1
- package/build-types/navigator/navigator-back-button/component.d.ts +38 -0
- package/build-types/navigator/navigator-back-button/component.d.ts.map +1 -0
- package/build-types/navigator/navigator-back-button/hook.d.ts +282 -0
- package/build-types/navigator/navigator-back-button/hook.d.ts.map +1 -0
- package/build-types/navigator/navigator-back-button/index.d.ts +2 -0
- package/build-types/navigator/navigator-back-button/index.d.ts.map +1 -0
- package/build-types/navigator/navigator-button/component.d.ts +37 -0
- package/build-types/navigator/navigator-button/component.d.ts.map +1 -0
- package/build-types/navigator/navigator-button/hook.d.ts +282 -0
- package/build-types/navigator/navigator-button/hook.d.ts.map +1 -0
- package/build-types/navigator/navigator-button/index.d.ts +2 -0
- package/build-types/navigator/navigator-button/index.d.ts.map +1 -0
- package/build-types/navigator/navigator-provider/component.d.ts +10 -20
- package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
- package/build-types/navigator/navigator-screen/component.d.ts +10 -20
- package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
- package/build-types/navigator/types.d.ts +21 -0
- package/build-types/navigator/types.d.ts.map +1 -1
- package/build-types/number-control/styles/number-control-styles.d.ts +1 -1
- package/build-types/resizable-box/index.d.ts +2 -2
- package/build-types/resizable-box/index.d.ts.map +1 -1
- package/build-types/resizable-box/resize-tooltip/index.d.ts.map +1 -1
- package/build-types/select-control/index.d.ts +1 -3
- package/build-types/select-control/index.d.ts.map +1 -1
- package/build-types/ui/context/wordpress-component.d.ts +2 -6
- package/build-types/ui/context/wordpress-component.d.ts.map +1 -1
- package/build-types/unit-control/index.d.ts +1 -3
- package/build-types/unit-control/index.d.ts.map +1 -1
- package/build-types/z-stack/component.d.ts.map +1 -1
- package/package.json +8 -7
- package/src/alignment-matrix-control/README.md +4 -0
- package/src/alignment-matrix-control/stories/index.js +1 -1
- package/src/base-control/stories/index.js +65 -22
- package/src/box-control/stories/index.js +4 -1
- package/src/box-control/unit-control.js +1 -1
- package/src/card/card/component.js +1 -1
- package/src/card/card-body/component.js +1 -1
- package/src/card/card-divider/component.js +1 -1
- package/src/card/card-footer/component.js +1 -1
- package/src/card/card-header/component.js +1 -1
- package/src/card/card-media/component.js +1 -1
- package/src/color-palette/index.native.js +92 -75
- package/src/color-palette/style.native.scss +10 -5
- package/src/color-picker/component.tsx +2 -2
- package/src/color-picker/hex-input.tsx +9 -9
- package/src/confirm-dialog/component.tsx +2 -2
- package/src/divider/component.tsx +2 -2
- package/src/elevation/component.js +1 -1
- package/src/flex/flex/component.js +1 -1
- package/src/flex/flex-block/component.js +1 -1
- package/src/flex/flex-item/component.js +1 -1
- package/src/flyout/flyout/component.js +1 -1
- package/src/flyout/flyout-content/component.js +1 -1
- package/src/focal-point-picker/README.md +7 -0
- package/src/focal-point-picker/index.js +12 -7
- package/src/focal-point-picker/stories/index.js +30 -0
- package/src/focal-point-picker/test/index.js +44 -0
- package/src/font-size-picker/index.js +0 -1
- package/src/form-file-upload/README.md +1 -1
- package/src/form-file-upload/stories/index.js +51 -0
- package/src/grid/component.js +1 -1
- package/src/h-stack/component.js +1 -1
- package/src/heading/component.tsx +2 -2
- package/src/index.js +2 -0
- package/src/index.native.js +5 -1
- package/src/input-control/index.tsx +2 -2
- package/src/input-control/input-base.tsx +2 -2
- package/src/input-control/input-field.tsx +4 -6
- package/src/input-control/reducer/reducer.ts +3 -0
- package/src/input-control/stories/index.js +1 -1
- package/src/input-control/types.ts +1 -1
- package/src/item-group/item/component.tsx +2 -2
- package/src/item-group/item-group/component.tsx +2 -2
- package/src/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +10 -1
- package/src/mobile/color-settings/palette.screen.native.js +39 -9
- package/src/mobile/color-settings/style.native.scss +4 -0
- package/src/mobile/global-styles-context/test/fixtures/theme.native.js +27 -0
- package/src/mobile/global-styles-context/test/utils.native.js +2 -2
- package/src/mobile/global-styles-context/utils.native.js +75 -6
- package/src/navigation/stories/index.js +1 -1
- package/src/navigator/index.ts +2 -0
- package/src/navigator/navigator-back-button/README.md +31 -0
- package/src/navigator/navigator-back-button/component.tsx +62 -0
- package/src/navigator/navigator-back-button/hook.ts +40 -0
- package/src/navigator/navigator-back-button/index.ts +1 -0
- package/src/navigator/navigator-button/README.md +38 -0
- package/src/navigator/navigator-button/component.tsx +61 -0
- package/src/navigator/navigator-button/hook.ts +55 -0
- package/src/navigator/navigator-button/index.ts +1 -0
- package/src/navigator/navigator-provider/README.md +20 -33
- package/src/navigator/navigator-provider/component.tsx +12 -22
- package/src/navigator/navigator-screen/README.md +1 -1
- package/src/navigator/navigator-screen/component.tsx +14 -23
- package/src/navigator/stories/index.js +24 -37
- package/src/navigator/test/index.js +89 -34
- package/src/navigator/types.ts +26 -0
- package/src/number-control/stories/index.js +1 -1
- package/src/radio/stories/index.js +1 -1
- package/src/radio-group/stories/index.js +4 -1
- package/src/resizable-box/index.tsx +2 -2
- package/src/resizable-box/resize-tooltip/index.tsx +2 -2
- package/src/resizable-box/resize-tooltip/label.tsx +2 -2
- package/src/scrollable/component.js +1 -1
- package/src/select-control/index.tsx +2 -3
- package/src/spacer/component.tsx +2 -2
- package/src/surface/component.js +1 -1
- package/src/text/component.js +1 -1
- package/src/text-control/index.js +2 -2
- package/src/toggle-group-control/stories/index.js +1 -1
- package/src/toggle-group-control/toggle-group-control/component.tsx +2 -2
- package/src/toggle-group-control/toggle-group-control-option/component.tsx +2 -2
- package/src/tools-panel/stories/index.js +0 -1
- package/src/tools-panel/tools-panel/component.tsx +2 -2
- package/src/tools-panel/tools-panel-header/component.tsx +2 -2
- package/src/tools-panel/tools-panel-item/component.tsx +2 -2
- package/src/tree-grid/README.md +24 -1
- package/src/tree-grid/index.js +66 -7
- package/src/tree-grid/stories/index.js +4 -1
- package/src/tree-grid/test/__snapshots__/index.js.snap +1 -14
- package/src/tree-grid/test/index.js +226 -7
- package/src/truncate/component.js +1 -1
- package/src/ui/context/wordpress-component.ts +2 -2
- package/src/ui/control-group/component.js +1 -1
- package/src/ui/control-label/component.js +1 -1
- package/src/ui/form-group/form-group.js +1 -1
- package/src/ui/shortcut/component.tsx +2 -2
- package/src/ui/spinner/component.js +1 -1
- package/src/ui/tooltip/component.js +1 -1
- package/src/ui/tooltip/content.js +1 -1
- package/src/unit-control/index.tsx +2 -2
- package/src/unit-control/stories/index.js +1 -1
- package/src/v-stack/component.js +1 -1
- package/src/visually-hidden/component.js +1 -1
- package/src/z-stack/component.tsx +2 -2
- package/tsconfig.tsbuildinfo +1 -1
- 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
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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 {
|
|
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:
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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>
|
|
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
|
|
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 {
|
|
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:
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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>
|
|
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 {
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
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: " "'><=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
|
|
34
|
-
const { goTo } = useNavigator();
|
|
44
|
+
function CustomNavigatorButton( { path, onClick, ...props } ) {
|
|
35
45
|
return (
|
|
36
|
-
<
|
|
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
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
<
|
|
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
|
-
{
|
|
68
|
+
path={ path }
|
|
69
|
+
{ ...props }
|
|
67
70
|
/>
|
|
68
71
|
);
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
function
|
|
72
|
-
const { goBack } = useNavigator();
|
|
74
|
+
function CustomNavigatorBackButton( { onClick, ...props } ) {
|
|
73
75
|
return (
|
|
74
|
-
<
|
|
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
|
-
<
|
|
93
|
+
<CustomNavigatorButton
|
|
93
94
|
path={ PATHS.NOT_FOUND }
|
|
94
95
|
onClick={ onNavigatorButtonClick }
|
|
95
96
|
>
|
|
96
97
|
Navigate to non-existing screen.
|
|
97
|
-
</
|
|
98
|
-
<
|
|
98
|
+
</CustomNavigatorButton>
|
|
99
|
+
<CustomNavigatorButton
|
|
99
100
|
path={ PATHS.CHILD }
|
|
100
101
|
onClick={ onNavigatorButtonClick }
|
|
101
102
|
>
|
|
102
103
|
Navigate to child screen.
|
|
103
|
-
</
|
|
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
|
-
<
|
|
115
|
+
<CustomNavigatorButtonWithFocusRestoration
|
|
109
116
|
path={ PATHS.NESTED }
|
|
110
117
|
onClick={ onNavigatorButtonClick }
|
|
111
118
|
>
|
|
112
119
|
Navigate to nested screen.
|
|
113
|
-
</
|
|
114
|
-
<
|
|
120
|
+
</CustomNavigatorButtonWithFocusRestoration>
|
|
121
|
+
<CustomNavigatorBackButton onClick={ onNavigatorButtonClick }>
|
|
115
122
|
Go back
|
|
116
|
-
</
|
|
123
|
+
</CustomNavigatorBackButton>
|
|
117
124
|
</NavigatorScreen>
|
|
118
125
|
|
|
119
126
|
<NavigatorScreen path={ PATHS.NESTED }>
|
|
120
127
|
<p>This is the nested screen.</p>
|
|
121
|
-
<
|
|
128
|
+
<CustomNavigatorBackButton onClick={ onNavigatorButtonClick }>
|
|
122
129
|
Go back
|
|
123
|
-
</
|
|
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
|
} );
|