Skip to content

Commit f598161

Browse files
authored
feat: Method onToggleFocusMode for the left drawer (#3996)
1 parent 3b7067b commit f598161

File tree

6 files changed

+43
-1
lines changed

6 files changed

+43
-1
lines changed

pages/app-layout/utils/external-global-left-panel-widget.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,8 @@ registerLeftDrawer({
139139
onHeaderActionClick: ({ detail }) => {
140140
console.log('onHeaderActionClick: ', detail);
141141
},
142+
143+
onToggleFocusMode: ({ detail }) => {
144+
console.log('onToggleFocusMode: ', detail);
145+
},
142146
});

src/app-layout/__tests__/runtime-drawers-widgetized.test.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,31 @@ describeEachAppLayout({ themes: ['refresh-toolbar'] }, ({ size }) => {
257257
}
258258
);
259259

260+
test(`calls onToggleFocusMode handler by entering / exiting focus mode in left runtime drawer)`, () => {
261+
const drawerId = 'global-drawer';
262+
const onToggleFocusMode = jest.fn();
263+
awsuiWidgetPlugins.registerLeftDrawer({
264+
...drawerDefaults,
265+
id: drawerId,
266+
isExpandable: true,
267+
onToggleFocusMode: event => onToggleFocusMode(event.detail),
268+
});
269+
const renderProps = renderComponent(<AppLayout />);
270+
const { globalDrawersWrapper } = renderProps;
271+
272+
globalDrawersWrapper.findAiDrawerTrigger()!.click();
273+
if (size === 'mobile') {
274+
expect(globalDrawersWrapper.findExpandedModeButtonByActiveDrawerId(drawerId)).toBeFalsy();
275+
} else {
276+
createWrapper().findButtonGroup()!.findButtonById('expand')!.click();
277+
expect(globalDrawersWrapper.findDrawerById(drawerId)!.isDrawerInExpandedMode()).toBe(true);
278+
expect(onToggleFocusMode).toHaveBeenCalledWith({ isExpanded: true });
279+
createWrapper().findButtonGroup()!.findButtonById('expand')!.click();
280+
expect(globalDrawersWrapper.isLayoutInDrawerExpandedMode()).toBe(false);
281+
expect(onToggleFocusMode).toHaveBeenCalledWith({ isExpanded: false });
282+
}
283+
});
284+
260285
describe('metrics', () => {
261286
let sendPanoramaMetricSpy: jest.SpyInstance;
262287
beforeEach(() => {

src/app-layout/runtime-drawer/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ export const mapRuntimeConfigToAiDrawer = (
149149
onToggle?: NonCancelableEventHandler<DrawerStateChangeParams>;
150150
headerActions?: ReadonlyArray<ButtonGroupProps.Item>;
151151
exitExpandedModeTrigger?: React.ReactNode;
152+
onToggleFocusMode?: NonCancelableEventHandler<{ isExpanded: boolean }>;
152153
} => {
153154
const { mountContent, unmountContent, trigger, exitExpandedModeTrigger, ...runtimeDrawer } = runtimeConfig;
154155

src/app-layout/visual-refresh-toolbar/interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export type InternalDrawer = AppLayoutProps.Drawer & {
2727
headerActions?: ReadonlyArray<ButtonGroupProps.Item>;
2828
onHeaderActionClick?: NonCancelableEventHandler<ButtonGroupProps.ItemClickDetails>;
2929
position?: 'side' | 'bottom';
30+
onToggleFocusMode?: NonCancelableEventHandler<{ isExpanded: boolean }>;
3031
};
3132

3233
// Widgetization notice: structures in this file are shared multiple app layout instances, possibly different minor versions.

src/app-layout/visual-refresh-toolbar/state/use-app-layout.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export const useAppLayout = (
7171
const [navigationAnimationDisabled, setNavigationAnimationDisabled] = useState(true);
7272
const [splitPanelAnimationDisabled, setSplitPanelAnimationDisabled] = useState(true);
7373
const [isNested, setIsNested] = useState(false);
74-
const [expandedDrawerId, setExpandedDrawerId] = useState<string | null>(null);
74+
const [expandedDrawerId, setInternalExpandedDrawerId] = useState<string | null>(null);
7575
const rootRefInternal = useRef<HTMLDivElement>(null);
7676
// This workaround ensures the ref is defined before checking if the app layout is nested.
7777
// On initial render, the ref might be undefined because this component loads asynchronously via the widget API.
@@ -90,6 +90,16 @@ export const useAppLayout = (
9090
fireNonCancelableEvent(onToolsChange, { open });
9191
};
9292

93+
const setExpandedDrawerId = (value: string | null) => {
94+
setInternalExpandedDrawerId(value);
95+
96+
if (aiDrawer?.onToggleFocusMode && (value === aiDrawer?.id || value === null)) {
97+
fireNonCancelableEvent(aiDrawer.onToggleFocusMode, {
98+
isExpanded: !!value,
99+
});
100+
}
101+
};
102+
93103
const onGlobalDrawerFocus = (drawerId: string, open: boolean) => {
94104
globalDrawersFocusControl.setFocus({ force: true, drawerId, open });
95105
};

src/internal/plugins/widget/interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export interface DrawerPayload {
5050
unmountHeader?: (container: HTMLElement) => void;
5151
headerActions?: ReadonlyArray<ButtonGroupProps.Item>;
5252
onHeaderActionClick?: NonCancelableEventHandler<ButtonGroupProps.ItemClickDetails>;
53+
onToggleFocusMode?: NonCancelableEventHandler<{ isExpanded: boolean }>;
5354
position?: 'side' | 'bottom';
5455
}
5556

0 commit comments

Comments
 (0)