fix(twenty-front): match loading skeleton menu width to the nav drawer (#21278)
## What On the very first load (full browser refresh), the navigation skeleton didn't match the real `NavigationDrawer` width: it rendered an 8px-wider panel (an 8px wrapper padding on top of the 220px animated container) and right-aligned 204/196px item rows, so the menu visibly shifted and resized once the app finished loading. This makes every navigation skeleton mirror the real drawer geometry: a single `NAVIGATION_DRAWER_CONSTRAINTS.default`-wide (220px), border-box panel with the drawer's own padding, left-aligned, and skeleton bars that fill the content width like the real nav items (`width: 100%`). The same fill-width fix is applied to the in-drawer section skeletons so every navigation skeleton matches the real menu width. ## Verification - `tsgo` typecheck, `oxlint`, and `oxfmt` all clean on the changed files. --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
This commit is contained in:
@@ -7,31 +7,36 @@ import { NAVIGATION_DRAWER_CONSTRAINTS } from '@/ui/layout/resizable-panel/const
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { MainNavigationDrawerItemsSkeletonLoader } from '~/loading/components/MainNavigationDrawerItemsSkeletonLoader';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui-deprecated/theme-constants';
|
||||
import {
|
||||
ThemeContext,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui-deprecated/theme-constants';
|
||||
|
||||
const StyledAnimatedContainer = styled(motion.div)`
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding: ${themeCssVariables.spacing[3]} 0 ${themeCssVariables.spacing[4]}
|
||||
${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledItemsContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
height: calc(100dvh - 32px);
|
||||
margin-bottom: auto;
|
||||
max-width: 204px;
|
||||
min-width: 204px;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledSkeletonContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledSkeletonTitleContainer = styled.div`
|
||||
@@ -41,9 +46,7 @@ const StyledSkeletonTitleContainer = styled.div`
|
||||
gap: 10px;
|
||||
height: 32px;
|
||||
justify-content: center;
|
||||
|
||||
max-width: 196px;
|
||||
min-width: 196px;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const LeftPanelSkeletonLoader = () => {
|
||||
|
||||
+8
-4
@@ -1,4 +1,5 @@
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { css } from '@linaria/core';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
@@ -6,12 +7,15 @@ import { ThemeContext } from 'twenty-ui-deprecated/theme-constants';
|
||||
|
||||
const StyledSkeletonContainer = styled.div`
|
||||
align-items: flex-start;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
max-width: 196px;
|
||||
min-width: 196px;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const fillSkeletonContainer = css`
|
||||
display: block;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const MainNavigationDrawerItemsSkeletonLoader = ({
|
||||
@@ -38,7 +42,7 @@ export const MainNavigationDrawerItemsSkeletonLoader = ({
|
||||
{Array.from({ length }).map((_, index) => (
|
||||
<Skeleton
|
||||
key={index}
|
||||
width={196}
|
||||
containerClassName={fillSkeletonContainer}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -28,7 +28,6 @@ const StyledContainer = styled.div`
|
||||
|
||||
const StyledLeftPanelWrapper = styled.div`
|
||||
flex-shrink: 0;
|
||||
padding: 12px 0 12px 8px;
|
||||
`;
|
||||
|
||||
export const UserOrMetadataLoader = () => {
|
||||
|
||||
+9
-2
@@ -1,4 +1,5 @@
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { css } from '@linaria/core';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
@@ -19,6 +20,12 @@ const StyledSkeletonColumn = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const fillSkeletonContainer = css`
|
||||
display: block;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const NavigationMenuItemSkeletonLoader = () => {
|
||||
@@ -36,11 +43,11 @@ export const NavigationMenuItemSkeletonLoader = () => {
|
||||
/>
|
||||
<StyledSkeletonColumn>
|
||||
<Skeleton
|
||||
width={196}
|
||||
containerClassName={fillSkeletonContainer}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
<Skeleton
|
||||
width={196}
|
||||
containerClassName={fillSkeletonContainer}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
</StyledSkeletonColumn>
|
||||
|
||||
+11
-3
@@ -1,4 +1,5 @@
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { css } from '@linaria/core';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
@@ -8,11 +9,18 @@ import {
|
||||
} from 'twenty-ui-deprecated/theme-constants';
|
||||
|
||||
const StyledSkeletonColumn = styled.div`
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
height: 76px;
|
||||
padding-left: ${themeCssVariables.spacing[1]};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const fillSkeletonContainer = css`
|
||||
display: block;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader: React.FC =
|
||||
@@ -26,15 +34,15 @@ export const NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader: React.
|
||||
>
|
||||
<StyledSkeletonColumn>
|
||||
<Skeleton
|
||||
width={196}
|
||||
containerClassName={fillSkeletonContainer}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
<Skeleton
|
||||
width={196}
|
||||
containerClassName={fillSkeletonContainer}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
<Skeleton
|
||||
width={196}
|
||||
containerClassName={fillSkeletonContainer}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
</StyledSkeletonColumn>
|
||||
|
||||
+11
-3
@@ -1,5 +1,6 @@
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection';
|
||||
import { css } from '@linaria/core';
|
||||
import { styled } from '@linaria/react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { themeCssVariables } from 'twenty-ui-deprecated/theme-constants';
|
||||
@@ -13,10 +14,17 @@ const StyledTitleSkeleton = styled.div`
|
||||
`;
|
||||
|
||||
const StyledRowsContainer = styled.div`
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
padding-left: ${themeCssVariables.spacing[1]};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const fillSkeletonContainer = css`
|
||||
display: block;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const NavigationDrawerWorkspaceSectionSkeletonLoader = () => {
|
||||
@@ -35,15 +43,15 @@ export const NavigationDrawerWorkspaceSectionSkeletonLoader = () => {
|
||||
</StyledTitleSkeleton>
|
||||
<StyledRowsContainer>
|
||||
<Skeleton
|
||||
width={196}
|
||||
containerClassName={fillSkeletonContainer}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
<Skeleton
|
||||
width={196}
|
||||
containerClassName={fillSkeletonContainer}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
<Skeleton
|
||||
width={196}
|
||||
containerClassName={fillSkeletonContainer}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
</StyledRowsContainer>
|
||||
|
||||
Reference in New Issue
Block a user