-
Notifications
You must be signed in to change notification settings - Fork 376
feat(docked nav): add support for docked nav layout #12175
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
Changes from all commits
42b7e54
454aa8c
36a8927
e178dfc
add8809
9e10bdd
2678d65
c43c253
660a46d
6c019f2
b0ff4c5
88f0e92
ded5c6c
72833ae
860f035
e09d1b6
a682a09
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { | ||
| Compass, | ||
| CompassContent, | ||
| CompassMainHeader, | ||
| CompassPanel, | ||
| CompassMainHeaderContent | ||
| } from '@patternfly/react-core'; | ||
| import './compass.css'; | ||
|
|
||
| export const CompassBasic: React.FunctionComponent = () => { | ||
| const dockContent = <div>Content</div>; | ||
| const mainContent = ( | ||
| <CompassContent> | ||
| <CompassMainHeader> | ||
| <CompassPanel> | ||
| <CompassMainHeaderContent> | ||
| <div>Content title</div> | ||
| </CompassMainHeaderContent> | ||
| </CompassPanel> | ||
| </CompassMainHeader> | ||
| <div>Content</div> | ||
| </CompassContent> | ||
| ); | ||
| return <Compass dock={dockContent} main={mainContent} />; | ||
| }; | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,14 @@ | ||
| import { cloneElement, Fragment, isValidElement, useContext, useEffect, useRef, useState } from 'react'; | ||
| import { | ||
| cloneElement, | ||
| Fragment, | ||
| isValidElement, | ||
| useContext, | ||
| useEffect, | ||
| useRef, | ||
| useState, | ||
| forwardRef, | ||
| MutableRefObject | ||
| } from 'react'; | ||
| import styles from '@patternfly/react-styles/css/components/Nav/nav'; | ||
| import menuStyles from '@patternfly/react-styles/css/components/Menu/menu'; | ||
| import dividerStyles from '@patternfly/react-styles/css/components/Divider/divider'; | ||
|
|
@@ -42,9 +52,13 @@ export interface NavItemProps extends Omit<React.HTMLProps<HTMLAnchorElement>, ' | |
| ouiaId?: number | string; | ||
| /** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */ | ||
| ouiaSafe?: boolean; | ||
| /** React ref for the anchor element within the nav item. */ | ||
| anchorRef?: React.Ref<HTMLAnchorElement>; | ||
| /** @hide Forwarded ref */ | ||
| innerRef?: React.Ref<HTMLLIElement>; | ||
| } | ||
|
|
||
| export const NavItem: React.FunctionComponent<NavItemProps> = ({ | ||
| const NavItemBase: React.FunctionComponent<NavItemProps> = ({ | ||
| children, | ||
| styleChildren = true, | ||
| className, | ||
|
|
@@ -61,13 +75,16 @@ export const NavItem: React.FunctionComponent<NavItemProps> = ({ | |
| ouiaSafe, | ||
| zIndex = 9999, | ||
| icon, | ||
| innerRef, | ||
| anchorRef, | ||
| ...props | ||
| }: NavItemProps) => { | ||
| const { flyoutRef, setFlyoutRef, navRef } = useContext(NavContext); | ||
| const { isSidebarOpen } = useContext(PageSidebarContext); | ||
| const [flyoutTarget, setFlyoutTarget] = useState(null); | ||
| const [isHovered, setIsHovered] = useState(false); | ||
| const ref = useRef<HTMLLIElement>(undefined); | ||
| const _ref = useRef<HTMLLIElement>(undefined); | ||
| const ref = (innerRef as MutableRefObject<HTMLLIElement>) || _ref; | ||
| const flyoutVisible = ref === flyoutRef; | ||
|
Comment on lines
+86
to
88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical ref handling issue remains unaddressed—callback refs will silently fail. The previous critical review flagged unsafe ref handling, but the core runtime logic was not fixed:
Apply this fix to safely handle both callback and object refs: - const _ref = useRef<HTMLLIElement>(undefined);
- const ref = (innerRef as MutableRefObject<HTMLLIElement>) || _ref;
- const flyoutVisible = ref === flyoutRef;
+ const _ref = useRef<HTMLLIElement>(null);
+ const ref = _ref;
+
+ // Safely forward to both innerRef and local ref
+ const setRef = useCallback((node: HTMLLIElement | null) => {
+ _ref.current = node;
+ if (typeof innerRef === 'function') {
+ innerRef(node);
+ } else if (innerRef) {
+ (innerRef as MutableRefObject<HTMLLIElement>).current = node;
+ }
+ }, [innerRef]);
+
+ const flyoutVisible = flyoutRef?.current === ref?.current;Then update line 272: - ref={ref}
+ ref={setRef}
🤖 Prompt for AI Agents |
||
| const popperRef = useRef<HTMLDivElement>(undefined); | ||
| const hasFlyout = flyout !== undefined; | ||
|
|
@@ -180,6 +197,7 @@ export const NavItem: React.FunctionComponent<NavItemProps> = ({ | |
| const preventLinkDefault = preventDefault || !to; | ||
| return ( | ||
| <Component | ||
| ref={anchorRef} | ||
| href={to} | ||
| onClick={(e: any) => context.onSelect(e, groupId, itemId, to, preventLinkDefault, onClick)} | ||
| className={css( | ||
|
|
@@ -208,6 +226,7 @@ export const NavItem: React.FunctionComponent<NavItemProps> = ({ | |
| className: css(styles.navLink, isActive && styles.modifiers.current, child.props && child.props.className) | ||
| }), | ||
| tabIndex: child.props.tabIndex || tabIndex, | ||
| ref: anchorRef, | ||
| children: hasFlyout ? ( | ||
| <Fragment> | ||
| {child.props.children} | ||
|
|
@@ -267,4 +286,9 @@ export const NavItem: React.FunctionComponent<NavItemProps> = ({ | |
|
|
||
| return navItem; | ||
| }; | ||
|
|
||
| export const NavItem = forwardRef<HTMLLIElement, NavItemProps>((props, ref) => ( | ||
| <NavItemBase {...props} innerRef={ref} /> | ||
| )); | ||
|
|
||
| NavItem.displayName = 'NavItem'; | ||
Uh oh!
There was an error while loading. Please reload this page.