diff --git a/packages/components/src/navigator/context.js b/packages/components/src/navigator/context.js deleted file mode 100644 index 2113ae4908286..0000000000000 --- a/packages/components/src/navigator/context.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * WordPress dependencies - */ -import { createContext } from '@wordpress/element'; - -export const NavigatorContext = createContext(); diff --git a/packages/components/src/navigator/context.ts b/packages/components/src/navigator/context.ts new file mode 100644 index 0000000000000..17b26fb9c14ad --- /dev/null +++ b/packages/components/src/navigator/context.ts @@ -0,0 +1,12 @@ +/** + * WordPress dependencies + */ +import { createContext } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import type { NavigatorContext as NavigatorContextType } from './types'; + +const initialContextValue: NavigatorContextType = [ {}, () => {} ]; +export const NavigatorContext = createContext( initialContextValue ); diff --git a/packages/components/src/navigator/index.js b/packages/components/src/navigator/index.ts similarity index 100% rename from packages/components/src/navigator/index.js rename to packages/components/src/navigator/index.ts diff --git a/packages/components/src/navigator/navigator-provider/README.md b/packages/components/src/navigator/navigator-provider/README.md index dead39a0bb7f6..4ce48a75790b8 100644 --- a/packages/components/src/navigator/navigator-provider/README.md +++ b/packages/components/src/navigator/navigator-provider/README.md @@ -60,8 +60,7 @@ The initial active path. - Required: No - -## The navigator object +## The `navigator` object You can retrieve a `navigator` instance by using the `useNavigator` hook. diff --git a/packages/components/src/navigator/navigator-provider/component.js b/packages/components/src/navigator/navigator-provider/component.js deleted file mode 100644 index a49553ac5377c..0000000000000 --- a/packages/components/src/navigator/navigator-provider/component.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * WordPress dependencies - */ -import { useState } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import { NavigatorContext } from '../context'; - -function NavigatorProvider( { initialPath, children } ) { - const [ path, setPath ] = useState( { path: initialPath } ); - - return ( - - { children } - - ); -} - -export default NavigatorProvider; diff --git a/packages/components/src/navigator/navigator-provider/component.tsx b/packages/components/src/navigator/navigator-provider/component.tsx new file mode 100644 index 0000000000000..5f8e82e613721 --- /dev/null +++ b/packages/components/src/navigator/navigator-provider/component.tsx @@ -0,0 +1,96 @@ +/** + * External dependencies + */ +// eslint-disable-next-line no-restricted-imports +import type { Ref } from 'react'; + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { + contextConnect, + useContextSystem, + WordPressComponentProps, +} from '../../ui/context'; +import { View } from '../../view'; +import { NavigatorContext } from '../context'; +import type { NavigatorProviderProps, NavigatorPath } from '../types'; + +function NavigatorProvider( + props: WordPressComponentProps< NavigatorProviderProps, 'div' >, + forwardedRef: Ref< any > +) { + const { initialPath, children, ...otherProps } = useContextSystem( + props, + 'NavigatorProvider' + ); + + const [ path, setPath ] = useState< NavigatorPath >( { + path: initialPath, + } ); + + return ( + + + { children } + + + ); +} + +/** + * The `NavigatorProvider` component allows rendering nested panels or menus (via the `NavigatorScreen` component) and navigate between these different states (via the `useNavigator` hook). + * The Global Styles sidebar is an example of this. The `Navigator*` family of components is _not_ opinionated in terms of UI, and can be composed with any UI components to navigate between the nested screens. + * + * @example + * ```jsx + * import { + * __experimentalNavigatorProvider as NavigatorProvider, + * __experimentalNavigatorScreen as NavigatorScreen, + * __experimentalUseNavigator as useNavigator, + * } from '@wordpress/components'; + * + * function NavigatorButton( { + * path, + * isBack = false, + * ...props + * } ) { + * const navigator = useNavigator(); + * return ( + *