Skip to content
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

feat: Public layout component #3208

Open
wants to merge 59 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
b08c0c2
feat: PageLayout component
georgylobko Jan 16, 2025
7db9b3d
chore: U tests for trigerless navigation and drawers
georgylobko Jan 16, 2025
610983d
chore: Update snapshots
georgylobko Jan 21, 2025
060df7f
chore: Clean up a testing page for page-layout
georgylobko Jan 21, 2025
3646600
chore: App layout internal props refactoring
georgylobko Jan 21, 2025
457fe76
Merge remote-tracking branch 'origin/main' into feat/public-layout-co…
georgylobko Jan 21, 2025
1074be4
chore: Document optional trigger scenario for PageLayout
georgylobko Jan 21, 2025
ce4393f
chore: Document optional trigger scenario for PageLayout
georgylobko Jan 21, 2025
b6fd838
chore: Don't display the toolbar if neither navigation trigger is pro…
georgylobko Jan 21, 2025
e164d82
Merge branch 'main' into feat/public-layout-component
georgylobko Jan 21, 2025
a77bf17
chore: Omit disableBodyScroll prop
georgylobko Jan 23, 2025
f61d5c0
feat: Set useAppLayoutToolbarEnabled to true for the public layout co…
georgylobko Jan 24, 2025
63e9618
Merge branch 'main' into feat/public-layout-component
georgylobko Jan 24, 2025
0cf8021
feat: focusNavigation API
georgylobko Jan 24, 2025
05bdf0d
chore: focusNavigation on without-toolbar.page.tsx
georgylobko Jan 24, 2025
604a5bc
chore: toolbarHide API
georgylobko Jan 24, 2025
b5e432b
chore: Cleanup
georgylobko Jan 24, 2025
3a5ba52
Merge branch 'main' into feat/public-layout-component
georgylobko Jan 24, 2025
dffa826
chore: Update snapshots
georgylobko Jan 24, 2025
ff8c5d0
chore: Add u tests
georgylobko Jan 24, 2025
e6c0aef
Merge branch 'main' into feat/public-layout-component
georgylobko Jan 27, 2025
2ca92dd
feat: navigationTriggerHide prop
georgylobko Jan 30, 2025
f1e10f0
fix: U tests
georgylobko Jan 30, 2025
1d319ab
Merge branch 'main' into feat/public-layout-component
georgylobko Jan 30, 2025
fef9d66
chore: Introduce BaseLayoutProps
georgylobko Jan 30, 2025
1bb2102
chore: Add a dedup condition to check if split panel's trigger is hid…
georgylobko Jan 31, 2025
77be6f5
Merge branch 'main' into feat/public-layout-component
georgylobko Jan 31, 2025
1851665
chore: Introduce a warning when PageLayout is used in classic theme
georgylobko Feb 4, 2025
56fe031
Merge branch 'main' into feat/public-layout-component
georgylobko Feb 5, 2025
56575f3
chore: U test for toolbarless scenario
georgylobko Feb 5, 2025
2cd3a3b
chore: Rename page-layout to app-layout-toolbar
georgylobko Feb 6, 2025
d60372e
Merge branch 'main' into feat/public-layout-component
georgylobko Feb 6, 2025
8833c38
chore: Rename integ test
georgylobko Feb 6, 2025
6e533af
chore: Don't pass split panel props into the toolbar if splitPanelTog…
georgylobko Feb 6, 2025
6cef166
chore: Throw an error when app layout toolbar is rendered in classic …
georgylobko Feb 6, 2025
bc4f76b
chore: Functional tests for vr/classic components
georgylobko Feb 6, 2025
5c456be
chore: Skip vr only components in classic for a11y tests
georgylobko Feb 6, 2025
4bb7a31
chore: Skip vr only components in classic for a11y tests
georgylobko Feb 6, 2025
34bf270
Merge branch 'main' into feat/public-layout-component
georgylobko Feb 6, 2025
0db8c86
chore: Small fixes
georgylobko Feb 6, 2025
400fae4
chore: Adjust drawers api description
georgylobko Feb 6, 2025
9eef6a1
chore: Update doc snapshot
georgylobko Feb 6, 2025
85106ff
chore: Replace useVisualRefresh by symbols in functional tests
georgylobko Feb 11, 2025
fe5898e
feat: Make dedup logic for app layout toolbar component apply only un…
georgylobko Feb 12, 2025
e026042
chore: Small eslint fix
georgylobko Feb 12, 2025
369ed49
Merge branch 'main' into feat/public-layout-component
georgylobko Feb 12, 2025
9b7fd81
chore: Integ test for nested app layout toolbars
georgylobko Feb 12, 2025
8760dd5
Merge remote-tracking branch 'origin/main' into feat/public-layout-co…
georgylobko Feb 12, 2025
61b009c
fix: Remove redundant navigationTriggerHide
georgylobko Feb 12, 2025
867f79f
Merge branch 'main' into feat/public-layout-component
georgylobko Feb 12, 2025
5a2c9eb
chore: Small refactoring
georgylobko Feb 12, 2025
785c664
chore: Small refactoring
georgylobko Feb 12, 2025
cf3ef8e
chore: Reuse pages/utils in pages/app-layout-toolbar from pages/app-l…
georgylobko Feb 13, 2025
c9ace4e
chore: Remove styles.scss from pages/app-layout-toolbar
georgylobko Feb 13, 2025
6178811
Merge branch 'main' into feat/public-layout-component
georgylobko Feb 13, 2025
8d306d9
Merge branch 'main' into feat/public-layout-component
georgylobko Feb 17, 2025
273633b
chore: Switch globalWithFlags[Symbol.for('awsui-visual-refresh-flag')…
georgylobko Feb 18, 2025
c21e321
chore: Refactoring. Introduce useAppLayoutToolbarPublicEnabled hook
georgylobko Feb 18, 2025
5b0b82f
Merge branch 'main' into feat/public-layout-component
georgylobko Feb 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: Don't display the toolbar if neither navigation trigger is pro…
…vided nor at least one drawer with trigger
georgylobko committed Jan 21, 2025
commit b6fd83897a0c5994840248fdbe2aede1876f5c1c
118 changes: 118 additions & 0 deletions pages/page-layout/without-toolbar.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useRef, useState } from 'react';

import { Button, ContentLayout, Header, HelpPanel, Link, PageLayout, SpaceBetween } from '~components';
import { PageLayoutProps } from '~components/page-layout';

import { Containers, CustomDrawerContent, Navigation } from './utils/content-blocks';
import { drawerLabels } from './utils/drawers';
import appLayoutLabels from './utils/labels';

export default function WithDrawers() {
const [activeDrawerId, setActiveDrawerId] = useState<string | null>(null);
const [helpPathSlug, setHelpPathSlug] = useState<string>('default');
const [isToolsOpen, setIsToolsOpen] = useState(false);
const [isNavigationOpen, setIsNavigationOpen] = useState(true);
const appLayoutRef = useRef<PageLayoutProps.Ref>(null);

const drawersProps: Pick<PageLayoutProps, 'activeDrawerId' | 'onDrawerChange' | 'drawers'> | null = {
activeDrawerId: activeDrawerId,
drawers: [
{
ariaLabels: {
closeButton: 'ProHelp close button',
drawerName: 'ProHelp drawer content',
triggerButton: 'ProHelp trigger button',
resizeHandle: 'ProHelp resize handle',
},
content: <CustomDrawerContent />,
id: 'pro-help',
},
],
onDrawerChange: event => {
setActiveDrawerId(event.detail.activeDrawerId);
},
};

return (
<PageLayout
ariaLabels={{ ...appLayoutLabels, ...drawerLabels }}
ref={appLayoutRef}
content={
<ContentLayout
disableOverlap={true}
header={
<SpaceBetween size="m">
<Header
variant="h1"
description="Sometimes you need custom triggers for drawers and navigation to get the job done."
info={
<Link
data-testid="info-link-header"
variant="info"
onFollow={() => {
setHelpPathSlug('header');
setIsToolsOpen(true);
appLayoutRef.current?.focusToolsClose();
}}
>
Info
</Link>
}
>
Page layout without the toolbar
</Header>

<SpaceBetween size="xs">
<Button onClick={() => setIsNavigationOpen(current => !current)}>Toggle navigation</Button>

<Button
onClick={() => {
setActiveDrawerId('pro-help');
appLayoutRef.current?.focusActiveDrawer();
}}
>
Open a drawer without trigger
</Button>
<Button onClick={() => setActiveDrawerId(null)}>Close a drawer without trigger</Button>
</SpaceBetween>
</SpaceBetween>
}
>
<Header
info={
<Link
data-testid="info-link-content"
variant="info"
onFollow={() => {
setHelpPathSlug('content');
setIsToolsOpen(true);
}}
>
Info
</Link>
}
>
Content
</Header>
<Containers />
</ContentLayout>
}
onToolsChange={event => {
setIsToolsOpen(event.detail.open);
}}
tools={<Info helpPathSlug={helpPathSlug} />}
toolsOpen={isToolsOpen}
navigationTriggerHide={true}
navigationOpen={isNavigationOpen}
navigation={<Navigation />}
onNavigationChange={event => setIsNavigationOpen(event.detail.open)}
{...drawersProps}
/>
);
}

function Info({ helpPathSlug }: { helpPathSlug: string }) {
return <HelpPanel header={<h2>Info</h2>}>Here is some info for you: {helpPathSlug}</HelpPanel>;
}
3 changes: 3 additions & 0 deletions src/app-layout/__tests__/multi-layout-props.test.tsx
Original file line number Diff line number Diff line change
@@ -26,6 +26,9 @@ describe('mergeMultiAppLayoutProps', () => {
id: 'drawer1',
ariaLabels: { drawerName: 'Drawer 1' },
content: <div>Drawer 1 Content</div>,
trigger: {
iconName: 'contact',
},
},
],
onActiveDrawerChange: mockParentActiveDrawerChange,
14 changes: 11 additions & 3 deletions src/app-layout/visual-refresh-toolbar/multi-layout.ts
Original file line number Diff line number Diff line change
@@ -52,7 +52,11 @@ export function mergeProps(
const toolbar: ToolbarProps = {};
for (const props of [ownProps, ...additionalProps]) {
toolbar.ariaLabels = Object.assign(toolbar.ariaLabels ?? {}, props.ariaLabels);
if (props.drawers && !checkAlreadyExists(!!toolbar.drawers, 'tools or drawers')) {
if (
props.drawers &&
props.drawers.some(drawer => drawer.trigger) &&
!checkAlreadyExists(!!toolbar.drawers, 'tools or drawers')
) {
toolbar.drawers = props.drawers;
toolbar.activeDrawerId = props.activeDrawerId;
toolbar.drawersFocusRef = props.drawersFocusRef;
@@ -64,7 +68,11 @@ export function mergeProps(
toolbar.activeGlobalDrawersIds = props.activeGlobalDrawersIds;
toolbar.onActiveGlobalDrawersChange = props.onActiveGlobalDrawersChange;
}
if (props.navigation && !checkAlreadyExists(!!toolbar.hasNavigation, 'navigation')) {
if (
props.navigation &&
!props.navigationTriggerHide &&
!checkAlreadyExists(!!toolbar.hasNavigation, 'navigation')
) {
toolbar.hasNavigation = true;
toolbar.navigationOpen = props.navigationOpen;
toolbar.navigationFocusRef = props.navigationFocusRef;
@@ -84,7 +92,7 @@ export function mergeProps(
}
}
// do not render toolbar if no fields are defined, except ariaLabels, which are always there
return Object.keys(toolbar).filter(key => key !== 'ariaLabels').length > 0 ? toolbar : null;
return Object.keys(toolbar).filter(key => !['ariaLabels', 'hasNavigation'].includes(key)).length > 0 ? toolbar : null;
}

export function useMultiAppLayout(props: SharedProps, isEnabled: boolean) {

Unchanged files with check annotations Beta

setupTest(async page => {
const lastAnchorLink = wrapper.findAnchorLinkByHref('#section-1-2-1-1');
await page.windowScrollTo({ top: 99999 }); // Very high value to ensure we are scrolled to the end
return expect(await page.getElementAttribute(lastAnchorLink.toSelector(), 'aria-current')).toBe('true');

Check warning on line 69 in src/anchor-navigation/__integ__/anchor-navigation.test.ts

GitHub Actions / dry-run / Components integration tests shards (4)

RETRY 1: AnchorNavigation › scrolling to the end of the page makes the last anchor item active

expect(received).toBe(expected) // Object.is equality Expected: "true" Received: null at src/anchor-navigation/__integ__/anchor-navigation.test.ts:69:98 at src/anchor-navigation/__integ__/anchor-navigation.test.ts:22:7 at Object.<anonymous> (node_modules/@cloudscape-design/browser-test-tools/use-browser.js:36:13)
})
);
});