Skip to content

Commit

Permalink
fix: bug in SideNav when sideNavItems comes delayed (#2419)
Browse files Browse the repository at this point in the history
OKTA-832344 fix: bug in SideNav when sideNavItems comes delayed
chore: undo unneeded type
feat: add story for delayed prop setting
feat: enhance story for SideNav to show isLoading in interim
benschell-okta authored Nov 18, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 11351f9 commit bce2083
Showing 2 changed files with 43 additions and 5 deletions.
14 changes: 10 additions & 4 deletions packages/odyssey-react-mui/src/labs/SideNav/SideNav.tsx
Original file line number Diff line number Diff line change
@@ -301,7 +301,13 @@ const SideNav = ({
const { t } = useTranslation();
const [sideNavItemsList, updateSideNavItemsList] = useState(sideNavItems);

// The default value (sideNavItems) passed to useState is ONLY used by the useState hook for
// the very first value. Subsequent updates to the prop (sideNavItems) need to cause the state
// to update!
useEffect(() => updateSideNavItemsList(sideNavItems), [sideNavItems]);

useEffect(() => {
// This is called directly in this effect AND perhaps as a result of the ResizeObserver
const updateIsContentScrollable = () => {
if (
scrollableContentRef.current &&
@@ -381,7 +387,7 @@ const SideNav = ({
}
cancelAnimationFrame(resizeObserverDebounceTimer); // Ensure timer is cleared on component unmount
};
}, [sideNavItems]);
}, [sideNavItemsList]);

const scrollIntoViewRef = useRef<HTMLLIElement>(null);
/**
@@ -390,7 +396,7 @@ const SideNav = ({
* call scrollIntoView in the effect
*/
const firstSideNavItemIdWithIsSelected = useMemo(() => {
const flattenedItems = sideNavItems.flatMap((sideNavItem) =>
const flattenedItems = sideNavItemsList.flatMap((sideNavItem) =>
sideNavItem.nestedNavItems
? [sideNavItem, ...sideNavItem.nestedNavItems]
: sideNavItem,
@@ -399,7 +405,7 @@ const SideNav = ({
(sideNavItem) => sideNavItem.isSelected,
);
return firstItemWithIsSelected?.id;
}, [sideNavItems]);
}, [sideNavItemsList]);
/**
* Once we've rendered and if we have an item to scroll to, do the scroll action.
* This must rely on checking firstSideNavItemIdWithIsSelected or it will not run
@@ -409,7 +415,7 @@ const SideNav = ({
if (firstSideNavItemIdWithIsSelected && scrollIntoViewRef.current) {
scrollIntoViewRef.current.scrollIntoView();
}
}, [firstSideNavItemIdWithIsSelected, scrollIntoViewRef]);
}, [firstSideNavItemIdWithIsSelected]);

/**
* We only want to put a ref on a node iff it is the first selected node.
Original file line number Diff line number Diff line change
@@ -10,7 +10,11 @@
* See the License for the specific language governing permissions and limitations under the License.
*/

import { SideNav, SideNavProps } from "@okta/odyssey-react-mui/labs";
import {
SideNav,
SideNavItem,
SideNavProps,
} from "@okta/odyssey-react-mui/labs";
import { Meta, StoryObj } from "@storybook/react";
import { MuiThemeDecorator } from "../../../../.storybook/components";
import {
@@ -37,6 +41,7 @@ import {
} from "@storybook/testing-library";
import { PlaywrightProps } from "../../odyssey-mui/storybookTypes";
import PlaceholderLogo from "../PickerWithOptionAdornment/PlaceholderLogo";
import { useEffect, useState } from "react";

const storybookMeta: Meta<SideNavProps> = {
title: "Labs Components/SideNav",
@@ -454,3 +459,30 @@ export const CustomLogoImage: StoryObj<typeof SideNav> = {
);
},
};

export const DelayedSideNavItems: StoryObj<typeof SideNav> = {
args: {
isLoading: true,
},
render: function C({ sideNavItems, isLoading, ...props }) {
const [sideNavItemsInState, setSideNavItemsInState] = useState<
SideNavItem[]
>([]);
const [isLoadingInState, setIsLoadingInState] = useState(isLoading);
useEffect(() => {
setTimeout(() => {
setSideNavItemsInState(sideNavItems);
setIsLoadingInState(false);
}, 1000);
});
return (
<div style={{ height: "100vh" }}>
<SideNav
sideNavItems={sideNavItemsInState}
isLoading={isLoadingInState}
{...props}
/>
</div>
);
},
};

0 comments on commit bce2083

Please sign in to comment.