diff --git a/packages/react/navigation-menu/src/NavigationMenu.stories.tsx b/packages/react/navigation-menu/src/NavigationMenu.stories.tsx index e8badc91e2..cb79f9a969 100644 --- a/packages/react/navigation-menu/src/NavigationMenu.stories.tsx +++ b/packages/react/navigation-menu/src/NavigationMenu.stories.tsx @@ -369,6 +369,55 @@ export const Submenus = () => { ); }; +export const WithPortalContainer = () => { + const [portalContainer, setPortalContainer] = React.useState(null); + + return ( + + +
+ + + Portaled Products + + + + + + + + + Not Portaled Products + + + + + + + + ); +}; + /* -----------------------------------------------------------------------------------------------*/ const StoryFrame: React.FC<{ children: React.ReactNode }> = ({ children }) => { diff --git a/packages/react/navigation-menu/src/NavigationMenu.tsx b/packages/react/navigation-menu/src/NavigationMenu.tsx index e450ce8dba..3725e76176 100644 --- a/packages/react/navigation-menu/src/NavigationMenu.tsx +++ b/packages/react/navigation-menu/src/NavigationMenu.tsx @@ -16,6 +16,7 @@ import { usePrevious } from '@radix-ui/react-use-previous'; import { useLayoutEffect } from '@radix-ui/react-use-layout-effect'; import { useCallbackRef } from '@radix-ui/react-use-callback-ref'; import * as VisuallyHiddenPrimitive from '@radix-ui/react-visually-hidden'; +import { Portal as PortalPrimitive } from '@radix-ui/react-portal'; import type { Scope } from '@radix-ui/react-context'; @@ -1100,6 +1101,49 @@ const FocusGroup = React.forwardRef( } ); +/* ------------------------------------------------------------------------------------------------- + * NaviationMenuPortal + * -----------------------------------------------------------------------------------------------*/ + +const PORTAL_NAME = 'NavigationMenuPortal'; + +type PortalContextValue = { forceMount?: true }; +const [PortalProvider] = createNavigationMenuContext(PORTAL_NAME, { + forceMount: undefined, +}); + +type PortalProps = React.ComponentPropsWithoutRef; +interface NavigationMenuPortalProps { + children?: React.ReactNode; + /** + * Specify a container element to portal the content into. + */ + container?: PortalProps['container']; + /** + * Used to force mounting when more control is needed. Useful when + * controlling animation with React animation libraries. + */ + forceMount?: true; +} + +const NavigationMenuPortal: React.FC = ( + props: ScopedProps +) => { + const { __scopeNavigationMenu, forceMount, children } = props; + const context = useNavigationMenuContext(PORTAL_NAME, __scopeNavigationMenu); + return ( + + {React.Children.map(children, (child) => ( + + {child} + + ))} + + ); +}; + +NavigationMenuPortal.displayName = PORTAL_NAME; + /* -----------------------------------------------------------------------------------------------*/ const ARROW_KEYS = ['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown']; @@ -1249,6 +1293,7 @@ const Link = NavigationMenuLink; const Indicator = NavigationMenuIndicator; const Content = NavigationMenuContent; const Viewport = NavigationMenuViewport; +const Portal = NavigationMenuPortal; export { createNavigationMenuScope, @@ -1262,6 +1307,7 @@ export { NavigationMenuIndicator, NavigationMenuContent, NavigationMenuViewport, + NavigationMenuPortal, // Root, Sub, @@ -1272,6 +1318,7 @@ export { Indicator, Content, Viewport, + Portal, }; export type { NavigationMenuProps, @@ -1283,4 +1330,5 @@ export type { NavigationMenuIndicatorProps, NavigationMenuContentProps, NavigationMenuViewportProps, + NavigationMenuPortalProps, }; diff --git a/packages/react/navigation-menu/src/index.ts b/packages/react/navigation-menu/src/index.ts index 3183133ff1..8e1f9b68b8 100644 --- a/packages/react/navigation-menu/src/index.ts +++ b/packages/react/navigation-menu/src/index.ts @@ -11,6 +11,7 @@ export { NavigationMenuIndicator, NavigationMenuContent, NavigationMenuViewport, + NavigationMenuPortal, // Root, Sub, @@ -21,6 +22,7 @@ export { Indicator, Content, Viewport, + Portal, } from './NavigationMenu'; export type { NavigationMenuProps, @@ -32,4 +34,5 @@ export type { NavigationMenuIndicatorProps, NavigationMenuContentProps, NavigationMenuViewportProps, + NavigationMenuPortalProps, } from './NavigationMenu'; diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000000..927fc25700 --- /dev/null +++ b/readme.txt @@ -0,0 +1,24 @@ +Commencer par git clone le repo : https://github.com/zephyr-dassouli/radixui-primitives +On a créé une branche pour chaque composant. +Choisir la branche du composant à tester avec git checkout. + +1) Se rendre dans le dossier ssr-testing du repo + +2) Installation de Node.js +sudo apt install npm + +3) Installation de yarn +sudo npm install -g yarn + +4) Setup de yarn dans le repo +sudo yarn install + +5) Build du projet +sudo yarn build + +6) Lancement du serveur local de test +sudo yarn start +Par défaut, le port utilisé est le 3000. Si déjà utilisé +sudo PORT=3001 yarn start + +7) Test du composant associé à la branche