Fixed expandable list and navigation menu (#8336)

For release 0.32

- Fixed expandable list dropdown UI bugs
- Added ScrollWrapper on navigation menus
This commit is contained in:
Lucas Bordeau
2024-11-05 12:34:00 +01:00
committed by GitHub
parent 9b0c74251f
commit 0893774cc1
5 changed files with 51 additions and 30 deletions

View File

@ -12,9 +12,10 @@ import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/
import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection'; import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { useFavorites } from '../hooks/useFavorites';
import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerAnimatedCollapseWrapper'; import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerAnimatedCollapseWrapper';
import { NavigationDrawerItemsCollapsedContainer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItemsCollapsedContainer'; import { NavigationDrawerItemsCollapsedContainer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItemsCollapsedContainer';
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { useFavorites } from '../hooks/useFavorites';
const StyledContainer = styled(NavigationDrawerSection)` const StyledContainer = styled(NavigationDrawerSection)`
width: 100%; width: 100%;
@ -115,9 +116,11 @@ export const CurrentWorkspaceMemberFavorites = () => {
</NavigationDrawerAnimatedCollapseWrapper> </NavigationDrawerAnimatedCollapseWrapper>
{isNavigationSectionOpen && ( {isNavigationSectionOpen && (
<NavigationDrawerItemsCollapsedContainer isGroup={isGroup}> <ScrollWrapper contextProviderName="navigationDrawer">
{draggableListContent} <NavigationDrawerItemsCollapsedContainer isGroup={isGroup}>
</NavigationDrawerItemsCollapsedContainer> {draggableListContent}
</NavigationDrawerItemsCollapsedContainer>
</ScrollWrapper>
)} )}
</StyledContainer> </StyledContainer>
); );

View File

@ -14,6 +14,11 @@ import { navigationDrawerExpandedMemorizedState } from '@/ui/navigation/states/n
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import styled from '@emotion/styled';
const StyledMainSection = styled(NavigationDrawerSection)`
min-height: fit-content;
`;
export const MainNavigationDrawerItems = () => { export const MainNavigationDrawerItems = () => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
@ -34,7 +39,7 @@ export const MainNavigationDrawerItems = () => {
return ( return (
<> <>
{!isMobile && ( {!isMobile && (
<NavigationDrawerSection> <StyledMainSection>
<NavigationDrawerItem <NavigationDrawerItem
label="Search" label="Search"
Icon={IconSearch} Icon={IconSearch}
@ -51,7 +56,7 @@ export const MainNavigationDrawerItems = () => {
}} }}
Icon={IconSettings} Icon={IconSettings}
/> />
</NavigationDrawerSection> </StyledMainSection>
)} )}
{isWorkspaceFavoriteEnabled && <NavigationDrawerOpenedSection />} {isWorkspaceFavoriteEnabled && <NavigationDrawerOpenedSection />}

View File

@ -23,7 +23,7 @@ const StyledDropdownMenu = styled.div<{
display: flex; display: flex;
height: 100%; height: auto;
flex-direction: column; flex-direction: column;
z-index: 30; z-index: 30;

View File

@ -1,7 +1,7 @@
import { ReactNode } from 'react';
import { css } from '@emotion/react'; import { css } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { offset, useFloating } from '@floating-ui/react'; import { FloatingPortal, offset, shift, useFloating } from '@floating-ui/react';
import { ReactNode } from 'react';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu'; import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
@ -40,9 +40,8 @@ export const ExpandedListDropdown = ({
withBorder, withBorder,
}: ExpandedListDropdownProps) => { }: ExpandedListDropdownProps) => {
const { refs, floatingStyles } = useFloating({ const { refs, floatingStyles } = useFloating({
// @ts-expect-error placement accepts 'start' as value even if the typing does not permit it placement: 'bottom-start',
placement: 'start', middleware: [offset({ mainAxis: -9, crossAxis: -7 }), shift()],
middleware: [offset({ mainAxis: -9, crossAxis: -7 })],
elements: { reference: anchorElement }, elements: { reference: anchorElement },
}); });
@ -52,18 +51,20 @@ export const ExpandedListDropdown = ({
}); });
return ( return (
<DropdownMenu <FloatingPortal>
ref={refs.setFloating} <DropdownMenu
style={floatingStyles} ref={refs.setFloating}
width={ style={floatingStyles}
anchorElement width={
? Math.max(220, anchorElement.getBoundingClientRect().width) anchorElement
: undefined ? Math.max(220, anchorElement.getBoundingClientRect().width)
} : undefined
> }
<StyledExpandedListContainer withBorder={withBorder}> >
{children} <StyledExpandedListContainer withBorder={withBorder}>
</StyledExpandedListContainer> {children}
</DropdownMenu> </StyledExpandedListContainer>
</DropdownMenu>
</FloatingPortal>
); );
}; };

View File

@ -2,7 +2,12 @@ import styled from '@emotion/styled';
import { expect } from '@storybook/jest'; import { expect } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/test'; import { userEvent, within } from '@storybook/test';
import { ComponentDecorator, MAIN_COLOR_NAMES, Tag } from 'twenty-ui'; import {
ComponentDecorator,
isDefined,
MAIN_COLOR_NAMES,
Tag,
} from 'twenty-ui';
import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList'; import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList';
@ -48,13 +53,20 @@ export const WithChipCount: Story = {
export const WithExpandedList: Story = { export const WithExpandedList: Story = {
...WithChipCount, ...WithChipCount,
play: async ({ canvasElement }) => { play: async () => {
const canvas = within(canvasElement); const root = document.getElementsByTagName('body')[0];
const chipCount = await canvas.findByText('+3');
if (!isDefined(root)) {
throw new Error('Root element not found');
}
const rootCanvas = within(root);
const chipCount = await rootCanvas.findByText('+3');
await userEvent.click(chipCount); await userEvent.click(chipCount);
expect(await canvas.findByText('Option 7')).toBeDefined(); expect(await rootCanvas.findByText('Option 7')).toBeDefined();
}, },
}; };