-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Navigator: stabilize and export APIs #64613
Merged
ciampo
merged 38 commits into
trunk
from
feat/stabilize-navigator/introduce-stable-version
Sep 27, 2024
Merged
Changes from all commits
Commits
Show all changes
38 commits
Select commit
Hold shift + click to select a range
fdd212c
Remove experimental status from Storybook
ciampo 03b69f7
NavigatorProvider => Navigator (internally)
ciampo b2273a7
Move legacy exports to separate file
ciampo f2897cc
Export overloaded notation
ciampo c35b80f
Use overloaded notation in Storybook
ciampo f659276
Use overloaded notation in unit tests (skipping deprecated component …
ciampo a489aa7
Update docs manifest.json
ciampo af0c4d9
Navigator: update docs
ciampo ca58f31
Navigator.BackButton: update docs
ciampo adf9678
NavigatorToParentButton: delete README
ciampo 7fc6593
Navigator.Button: update docs
ciampo 37384e6
NavigatorScreen: update docs
ciampo 30dbe5f
Restore `NavigatorToParentButton` test
ciampo f4da1e6
Use dot notation in context namespaces too
ciampo d9fe1d8
Use named export for `NavigatorToParentButton` too
ciampo 1d27a89
Fixup docs manifest
ciampo 2617d23
Export stable version from components package
ciampo 24d0bc3
CHANGELOG
ciampo d21bb27
Change index.ts extension to tsx to allow Storybook to extract JSDocs…
ciampo c805a37
Remove unnecessary and mispelled display name for top-level `Navigator`
ciampo aa9b28a
Remove @example tag from top-level export
ciampo 212e29c
Clean up unused imports
ciampo 0cdc3f4
Fix storybook styles
ciampo a2699e9
Update new section of the docs
ciampo eb0276d
Update more docs
ciampo 7228e33
Update deprecation warning
ciampo 585faac
Update and align docs
ciampo c0a754f
Fix tests warning checks
ciampo 521ca86
Typo
ciampo 72cd0bc
Fix useContextSystem names
ciampo 0987fac
Remove mentions of the `useNavigator` hook
ciampo ca7ac76
useNavigator JSDocs
ciampo 1d29ff1
Move all READMEs under the main README
ciampo 616015a
Move README to component's root folder
ciampo 4639c0b
Update types JSDocs to match README
ciampo 4ea2a09
Update docs manifest
ciampo 999795a
Fix JSDocs typos, grammar, and broken links.
ciampo 578c98a
Update storybook selector
ciampo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
# `Navigator` | ||
|
||
`Navigator` is a collection components that allow rendering nested views/panels/menus (via the `Navigator.Screen` component) and navigate between them (via the `Navigator.Button` and `Navigator.BackButton` components). | ||
|
||
## Usage | ||
|
||
```jsx | ||
import { Navigator } from '@wordpress/components'; | ||
|
||
const MyNavigation = () => ( | ||
<Navigator initialPath="/"> | ||
<Navigator.Screen path="/"> | ||
<p>This is the home screen.</p> | ||
<Navigator.Button path="/child"> | ||
Navigate to child screen. | ||
</Navigator.Button> | ||
</Navigator.Screen> | ||
<Navigator.Screen path="/child"> | ||
<p>This is the child screen.</p> | ||
<Navigator.BackButton>Go back</Navigator.BackButton> | ||
</Navigator.Screen> | ||
</Navigator> | ||
); | ||
``` | ||
|
||
### Hierarchical `path`s | ||
|
||
`Navigator` assumes that screens are organized hierarchically according to their `path`, which should follow a URL-like scheme where each path segment starts with and is separated by the `/` character. | ||
|
||
`Navigator` will treat "back" navigations as going to the parent screen — it is, therefore, the responsibility of the consumer of the component to create the correct screen hierarchy. | ||
|
||
For example: | ||
|
||
- `/` is the root of all paths. There should always be a screen with `path="/"`; | ||
- `/parent/child` is a child of `/parent`; | ||
- `/parent/child/grand-child` is a child of `/parent/child`; | ||
- `/parent/:param` is a child of `/parent` as well; | ||
- if the current screen has a `path="/parent/child/grand-child"`, when going "back" `Navigator` will try to recursively navigate the path hierarchy until a matching screen (or the root `/`) is found. | ||
|
||
### Height and animations | ||
|
||
Due to how `Navigator.Screen` animations work, it is recommended that the `Navigator` component is assigned a `height` to prevent some potential UI jumps while moving across screens. | ||
|
||
### Individual components | ||
|
||
`Navigator` is comprised of four individual components: | ||
|
||
- `Navigator`: a wrapper component and context provider. It holds the main logic for hiding and showing screens. | ||
- `Navigator.Screen`: represents a single view/screen/panel; | ||
- `Navigator.Button`: renders a button that allows navigating to a different `Navigator.Screen`; | ||
- `Navigator.BackButton`: renders a button that allows navigating to the parent `Navigator.Screen` (see the section above about hierarchical paths). | ||
|
||
For advanced usages, consumers can use the `useNavigator` hook. | ||
|
||
#### `Navigator` | ||
|
||
##### Props | ||
|
||
###### `initialPath`: `string` | ||
|
||
The initial active path. | ||
|
||
- Required: Yes | ||
|
||
###### `children`: `string` | ||
|
||
The children elements. | ||
|
||
- Required: Yes | ||
|
||
#### `Navigator.Screen` | ||
|
||
###### `path`: `string` | ||
|
||
The screen's path, matched against the current path stored in the navigator. | ||
|
||
`Navigator` assumes that screens are organized hierarchically according to their `path`, which should follow a URL-like scheme where each path segment starts with and is separated by the `/` character. | ||
|
||
`Navigator` will treat "back" navigations as going to the parent screen — it is, therefore, the responsibility of the consumer of the component to create the correct screen hierarchy. | ||
|
||
For example: | ||
|
||
- `/` is the root of all paths. There should always be a screen with `path="/"`. | ||
- `/parent/child` is a child of `/parent`. | ||
- `/parent/child/grand-child` is a child of `/parent/child`. | ||
- `/parent/:param` is a child of `/parent` as well. | ||
- if the current screen has a `path` with value `/parent/child/grand-child`, when going "back" `Navigator` will try to recursively navigate the path hierarchy until a matching screen (or the root `/`) is found. | ||
|
||
- Required: Yes | ||
|
||
###### `children`: `string` | ||
|
||
The children elements. | ||
|
||
- Required: Yes | ||
|
||
##### `Navigator.Button` | ||
|
||
###### `path`: `string` | ||
|
||
The path of the screen to navigate to. The value of this prop needs to be [a valid value for an HTML attribute](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2). | ||
|
||
- Required: Yes | ||
|
||
###### `attributeName`: `string` | ||
|
||
The HTML attribute used to identify the `Navigator.Button`, which is used by `Navigator` to restore focus. | ||
|
||
- Required: No | ||
- Default: `id` | ||
|
||
###### `children`: `string` | ||
|
||
The children elements. | ||
|
||
- Required: No | ||
|
||
###### Inherited props | ||
|
||
`Navigator.Button` also inherits all of the [`Button` props](/packages/components/src/button/README.md#props), except for `href` and `target`. | ||
|
||
##### `Navigator.BackButton` | ||
|
||
###### `children`: `string` | ||
|
||
The children elements. | ||
|
||
- Required: No | ||
|
||
###### Inherited props | ||
|
||
`Navigator.BackButton` also inherits all of the [`Button` props](/packages/components/src/button/README.md#props), except for `href` and `target`. | ||
|
||
###### `useNavigator` | ||
|
||
You can retrieve a `navigator` instance by using the `useNavigator` hook. | ||
|
||
The `navigator` instance has a few properties: | ||
|
||
###### `goTo`: `( path: string, options: NavigateOptions ) => void` | ||
|
||
The `goTo` function allows navigating to a given path. The second argument can augment the navigation operations with different options. | ||
|
||
The available options are: | ||
|
||
- `focusTargetSelector`: `string`. An optional property used to specify the CSS selector used to restore focus on the matching element when navigating back; | ||
- `isBack`: `boolean`. An optional property used to specify whether the navigation should be considered as backwards (thus enabling focus restoration when possible, and causing the animation to be backwards too); | ||
- `skipFocus`: `boolean`. An optional property used to opt out of `Navigator`'s focus management, useful when the consumer of the component wants to manage focus themselves; | ||
|
||
###### `goBack`: `( path: string, options: NavigateOptions ) => void` | ||
|
||
The `goBack` function allows navigating to the parent screen. Parent/child navigation only works if the paths you define are hierarchical (see note above). | ||
|
||
When a match is not found, the function will try to recursively navigate the path hierarchy until a matching screen (or the root `/`) is found. | ||
|
||
The available options are the same as for the `goTo` method, except for the `isBack` property, which is not available for the `goBack` method. | ||
|
||
###### `location`: `NavigatorLocation` | ||
|
||
The `location` object represents the current location, and has a few properties: | ||
|
||
- `path`: `string`. The path associated to the location. | ||
- `isBack`: `boolean`. A flag that is `true` when the current location was reached by navigating backwards. | ||
- `isInitial`: `boolean`. A flag that is `true` only for the initial location. | ||
|
||
###### `params`: `Record< string, string | string[] >` | ||
|
||
The parsed record of parameters from the current location. For example if the current screen path is `/product/:productId` and the location is `/product/123`, then `params` will be `{ productId: '123' }`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { Navigator as TopLevelNavigator } from './navigator/component'; | ||
import { NavigatorScreen } from './navigator-screen/component'; | ||
import { NavigatorButton } from './navigator-button/component'; | ||
import { NavigatorBackButton } from './navigator-back-button/component'; | ||
export { useNavigator } from './use-navigator'; | ||
|
||
/** | ||
* The `Navigator` component allows rendering nested views/panels/menus | ||
* (via the `Navigator.Screen` component) and navigate between them | ||
* (via the `Navigator.Button` and `Navigator.BackButton` components). | ||
* | ||
* ```jsx | ||
* import { Navigator } from '@wordpress/components'; | ||
* | ||
* const MyNavigation = () => ( | ||
* <Navigator initialPath="/"> | ||
* <Navigator.Screen path="/"> | ||
* <p>This is the home screen.</p> | ||
* <Navigator.Button path="/child"> | ||
* Navigate to child screen. | ||
* </Navigator.Button> | ||
* </Navigator.Screen> | ||
* | ||
* <Navigator.Screen path="/child"> | ||
* <p>This is the child screen.</p> | ||
* <Navigator.BackButton> | ||
* Go back | ||
* </Navigator.BackButton> | ||
* </Navigator.Screen> | ||
* </Navigator> | ||
* ); | ||
* ``` | ||
*/ | ||
export const Navigator = Object.assign( TopLevelNavigator, { | ||
/** | ||
* The `Navigator.Screen` component represents a single view/screen/panel and | ||
* should be used in combination with the `Navigator`, the `Navigator.Button` | ||
* and the `Navigator.BackButton` components. | ||
* | ||
* @example | ||
* ```jsx | ||
* import { Navigator } from '@wordpress/components'; | ||
* | ||
* const MyNavigation = () => ( | ||
* <Navigator initialPath="/"> | ||
* <Navigator.Screen path="/"> | ||
* <p>This is the home screen.</p> | ||
* <Navigator.Button path="/child"> | ||
* Navigate to child screen. | ||
* </Navigator.Button> | ||
* </Navigator.Screen> | ||
* | ||
* <Navigator.Screen path="/child"> | ||
* <p>This is the child screen.</p> | ||
* <Navigator.BackButton> | ||
* Go back | ||
* </Navigator.BackButton> | ||
* </Navigator.Screen> | ||
* </Navigator> | ||
* ); | ||
* ``` | ||
*/ | ||
Screen: Object.assign( NavigatorScreen, { | ||
displayName: 'Navigator.Screen', | ||
} ), | ||
ciampo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** | ||
* The `Navigator.Button` component can be used to navigate to a screen and | ||
* should be used in combination with the `Navigator`, the `Navigator.Screen` | ||
* and the `Navigator.BackButton` components. | ||
* | ||
* @example | ||
* ```jsx | ||
* import { Navigator } from '@wordpress/components'; | ||
* | ||
* const MyNavigation = () => ( | ||
* <Navigator initialPath="/"> | ||
* <Navigator.Screen path="/"> | ||
* <p>This is the home screen.</p> | ||
* <Navigator.Button path="/child"> | ||
* Navigate to child screen. | ||
* </Navigator.Button> | ||
* </Navigator.Screen> | ||
* | ||
* <Navigator.Screen path="/child"> | ||
* <p>This is the child screen.</p> | ||
* <Navigator.BackButton> | ||
* Go back | ||
* </Navigator.BackButton> | ||
* </Navigator.Screen> | ||
* </Navigator> | ||
* ); | ||
* ``` | ||
*/ | ||
Button: Object.assign( NavigatorButton, { | ||
displayName: 'Navigator.Button', | ||
} ), | ||
/** | ||
* The `Navigator.BackButton` component can be used to navigate to a screen and | ||
* should be used in combination with the `Navigator`, the `Navigator.Screen` | ||
* and the `Navigator.Button` components. | ||
* | ||
* @example | ||
* ```jsx | ||
* import { Navigator } from '@wordpress/components'; | ||
* | ||
* const MyNavigation = () => ( | ||
* <Navigator initialPath="/"> | ||
* <Navigator.Screen path="/"> | ||
* <p>This is the home screen.</p> | ||
* <Navigator.Button path="/child"> | ||
* Navigate to child screen. | ||
* </Navigator.Button> | ||
* </Navigator.Screen> | ||
* | ||
* <Navigator.Screen path="/child"> | ||
* <p>This is the child screen.</p> | ||
* <Navigator.BackButton> | ||
* Go back | ||
* </Navigator.BackButton> | ||
* </Navigator.Screen> | ||
* </Navigator> | ||
* ); | ||
* ``` | ||
*/ | ||
BackButton: Object.assign( NavigatorBackButton, { | ||
displayName: 'Navigator.BackButton', | ||
} ), | ||
} ); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, removing things from the manifest is not going to remove it from the Block Editor Handbook 😱 There are some extra steps, see #60003 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! I'll follow-up accordingly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a reminder we'll need to take care of this one after merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @WordPress/wordpress-org-meta-team , could you help with this? We need to update the Block Editor Handbook, removing the following components:
NavigatorProvider
NavigatorButton
NavigatorBackButton
NavigatorScreen
NavigatorToParentButton
If possible, we'd also like to set a redirect for those pages being removed. The redirect should point to the
Navigator
component.Could you please help with that? Thank you 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These updates have shipped. I noticed the formatting on the new doc loses consistency around the
Navigator.Button
point (heading is not bold):There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
Good catch! Opened #65763 to fix it