Skip to content

Commit

Permalink
fix: Incorporate split panel height when rendering stickyVerticalBott…
Browse files Browse the repository at this point in the history
…omOffset value
  • Loading branch information
just-boris committed Jan 27, 2025
1 parent 5daebff commit d82e217
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 15 deletions.
27 changes: 20 additions & 7 deletions src/app-layout/__integ__/app-layout-split-panel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import useBrowser from '@cloudscape-design/browser-test-tools/use-browser';
import createWrapper from '../../../lib/components/test-utils/selectors';
import { scrollbarThickness } from '../../__integ__/scrollbars';
import { viewports } from './constants';
import { AppLayoutSplitViewPage } from './utils';
import { AppLayoutSplitViewPage, getUrlParams } from './utils';

import mobileStyles from '../../../lib/components/app-layout/mobile-toolbar/styles.selectors.js';
import tableScrollbarStyles from '../../../lib/components/table/sticky-scrollbar/styles.selectors.js';

const scrollbarSelector = `.${tableScrollbarStyles['sticky-scrollbar-visible']}`;

const wrapper = createWrapper().findAppLayout();

Expand All @@ -19,11 +22,7 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as const)('%s', theme =>
return useBrowser(async browser => {
const page = new AppLayoutSplitViewPage(browser);
await page.setWindowSize(viewports.desktop);
const params = new URLSearchParams({
visualRefresh: `${theme.startsWith('refresh')}`,
appLayoutToolbar: `${theme === 'refresh-toolbar'}`,
});
await browser.url(`${url}?${params.toString()}`);
await browser.url(`${url}?${getUrlParams(theme)}`);
await page.waitForVisible(wrapper.findContentRegion().toSelector());
await testFn(page);
});
Expand Down Expand Up @@ -274,7 +273,7 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as const)('%s', theme =>
})
);

describe('interaction with table sticky header', () => {
describe('interaction with table sticky elements', () => {
// bottom padding is included into the offset in VR but not in classic
const splitPanelPadding = theme === 'refresh' ? 40 : 0;

Expand All @@ -298,5 +297,19 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as const)('%s', theme =>
await expect(page.getContentOffsetBottom(theme)).resolves.toEqual(windowHeight / 2 + splitPanelPadding + 'px');
}, '#/light/app-layout/with-full-page-table-and-split-panel')
);

test(
'bottom split panel does not block table sticky scrollbar',
setupTest(async page => {
// open tools panel to narrow the content area and display horizontal scroll on table
await page.click(wrapper.findToolsToggle().toSelector());
await expect(page.isClickable(scrollbarSelector)).resolves.toBe(true);
await page.click(wrapper.findSplitPanelOpenButton().toSelector());
await expect(
page.isDisplayedInViewport(wrapper.findSplitPanel().findOpenPanelBottom().toSelector())
).resolves.toBe(true);
await expect(page.isClickable(scrollbarSelector)).resolves.toBe(true);
}, '#/light/app-layout/with-sticky-table-and-split-panel')
);
});
});
30 changes: 30 additions & 0 deletions src/app-layout/visual-refresh-toolbar/compute-layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,36 @@ export function computeVerticalLayout({
return { toolbar, notifications, header, drawers };
}

interface SplitPanelOffsetInput {
hasSplitPanel: boolean;
placement: AppLayoutPropsWithDefaults['placement'];
splitPanelPosition: 'bottom' | 'side';
splitPanelOpen: boolean;
splitPanelHeaderHeight: number;
splitPanelFullHeight: number;
}

export function computeSplitPanelOffsets({
hasSplitPanel,
splitPanelPosition,
placement,
splitPanelOpen,
splitPanelFullHeight,
splitPanelHeaderHeight,
}: SplitPanelOffsetInput) {
if (!hasSplitPanel || splitPanelPosition !== 'bottom') {
return {
stickyVerticalBottomOffset: placement.insetBlockEnd,
mainContentPaddingBlockEnd: undefined,
};
}
const mainContentBottomOffset = splitPanelOpen ? splitPanelFullHeight : splitPanelHeaderHeight;
return {
stickyVerticalBottomOffset: mainContentBottomOffset + placement.insetBlockEnd,
mainContentPaddingBlockEnd: mainContentBottomOffset,
};
}

export function getDrawerStyles(
verticalOffsets: VerticalLayoutOutput,
isMobile: boolean,
Expand Down
25 changes: 17 additions & 8 deletions src/app-layout/visual-refresh-toolbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ import { MIN_DRAWER_SIZE, OnChangeParams, useDrawers } from '../utils/use-drawer
import { useFocusControl, useMultipleFocusControl } from '../utils/use-focus-control';
import { useSplitPanelFocusControl } from '../utils/use-split-panel-focus-control';
import { ActiveDrawersContext } from '../utils/visibility-context';
import { computeHorizontalLayout, computeVerticalLayout, CONTENT_PADDING } from './compute-layout';
import {
computeHorizontalLayout,
computeSplitPanelOffsets,
computeVerticalLayout,
CONTENT_PADDING,
} from './compute-layout';
import { AppLayoutVisibilityContext } from './contexts';
import { AppLayoutInternals } from './interfaces';
import {
Expand Down Expand Up @@ -461,6 +466,15 @@ const AppLayoutVisualRefreshToolbar = React.forwardRef<AppLayoutProps.Ref, AppLa
}
}, [hasToolbar]);

const splitPanelOffsets = computeSplitPanelOffsets({
placement,
hasSplitPanel: !!splitPanel,
splitPanelOpen,
splitPanelPosition,
splitPanelFullHeight: splitPanelReportedSize,
splitPanelHeaderHeight: splitPanelHeaderBlockSize,
});

return (
<AppLayoutVisibilityContext.Provider value={isIntersecting}>
{/* Rendering a hidden copy of breadcrumbs to trigger their deduplication */}
Expand All @@ -469,16 +483,11 @@ const AppLayoutVisualRefreshToolbar = React.forwardRef<AppLayoutProps.Ref, AppLa
ref={useMergeRefs(intersectionObserverRef, rootRef)}
isNested={isNested}
style={{
paddingBlockEnd:
splitPanelPosition === 'bottom'
? splitPanelOpen
? splitPanelReportedSize
: splitPanelHeaderBlockSize
: '',
paddingBlockEnd: splitPanelOffsets.mainContentPaddingBlockEnd,
...(hasToolbar || !isNested
? {
[globalVars.stickyVerticalTopOffset]: `${verticalOffsets.header}px`,
[globalVars.stickyVerticalBottomOffset]: `${placement.insetBlockEnd}px`,
[globalVars.stickyVerticalBottomOffset]: `${splitPanelOffsets.stickyVerticalBottomOffset}px`,
}
: {}),
...(!isMobile ? { minWidth: `${minContentWidth}px` } : {}),
Expand Down

0 comments on commit d82e217

Please sign in to comment.