diff --git a/package.json b/package.json index abf681c3f6..62e95ff583 100644 --- a/package.json +++ b/package.json @@ -176,7 +176,7 @@ { "path": "lib/components/internal/widget-exports.js", "brotli": false, - "limit": "963 kB", + "limit": "964 kB", "ignore": "react-dom" } ], diff --git a/pages/app-layout/utils/external-global-left-panel-widget.tsx b/pages/app-layout/utils/external-global-left-panel-widget.tsx index 28e874e974..5283d3362f 100644 --- a/pages/app-layout/utils/external-global-left-panel-widget.tsx +++ b/pages/app-layout/utils/external-global-left-panel-widget.tsx @@ -76,6 +76,23 @@ registerLeftDrawer({ `, }, + exitExpandedModeTrigger: { + customIcon: ` + + `, + }, + onResize: event => { console.log('resize', event.detail); }, diff --git a/src/app-layout/__tests__/runtime-drawers-widgetized.test.tsx b/src/app-layout/__tests__/runtime-drawers-widgetized.test.tsx index 2a34c2621d..5a6b3b2129 100644 --- a/src/app-layout/__tests__/runtime-drawers-widgetized.test.tsx +++ b/src/app-layout/__tests__/runtime-drawers-widgetized.test.tsx @@ -191,27 +191,40 @@ describeEachAppLayout({ themes: ['refresh-toolbar'] }, ({ size }) => { } }); - test('should exit focus mode by clicking on a custom exit button in the AI global drawer', () => { - awsuiWidgetPlugins.registerLeftDrawer({ - ...drawerDefaults, - ariaLabels: { - exitExpandedModeButton: 'exitExpandedModeButton', - }, - isExpandable: true, - }); - const { globalDrawersWrapper } = renderComponent(); - - globalDrawersWrapper.findAiDrawerTrigger()!.click(); - if (size === 'mobile') { - expect(globalDrawersWrapper.findExpandedModeButtonByActiveDrawerId(drawerDefaults.id)).toBeFalsy(); - } else { - createWrapper().findButtonGroup()!.findButtonById('expand')!.click(); - expect(globalDrawersWrapper.findDrawerById(drawerDefaults.id)!.isDrawerInExpandedMode()).toBe(true); - expect(globalDrawersWrapper.isLayoutInDrawerExpandedMode()).toBe(true); - globalDrawersWrapper.findLeaveExpandedModeButtonInAIDrawer()!.click(); - expect(globalDrawersWrapper.isLayoutInDrawerExpandedMode()).toBe(false); + test.each(['standard', 'custom', 'custom-invalid'] as const)( + 'should exit focus mode by clicking on a %s exit button in the AI global drawer', + type => { + awsuiWidgetPlugins.registerLeftDrawer({ + ...drawerDefaults, + ariaLabels: { + exitExpandedModeButton: 'exitExpandedModeButton', + }, + isExpandable: true, + ...(type === 'custom' && { + exitExpandedModeTrigger: { + customIcon: ` + + `, + }, + }), + ...(type === 'custom-invalid' && { + exitExpandedModeTrigger: {}, + }), + }); + const { globalDrawersWrapper } = renderComponent(); + + globalDrawersWrapper.findAiDrawerTrigger()!.click(); + if (size === 'mobile') { + expect(globalDrawersWrapper.findExpandedModeButtonByActiveDrawerId(drawerDefaults.id)).toBeFalsy(); + } else { + createWrapper().findButtonGroup()!.findButtonById('expand')!.click(); + expect(globalDrawersWrapper.findDrawerById(drawerDefaults.id)!.isDrawerInExpandedMode()).toBe(true); + expect(globalDrawersWrapper.isLayoutInDrawerExpandedMode()).toBe(true); + globalDrawersWrapper.findLeaveExpandedModeButtonInAIDrawer()!.click(); + expect(globalDrawersWrapper.isLayoutInDrawerExpandedMode()).toBe(false); + } } - }); + ); describe('metrics', () => { let sendPanoramaMetricSpy: jest.SpyInstance; diff --git a/src/app-layout/runtime-drawer/index.tsx b/src/app-layout/runtime-drawer/index.tsx index 0336991328..684af8820a 100644 --- a/src/app-layout/runtime-drawer/index.tsx +++ b/src/app-layout/runtime-drawer/index.tsx @@ -99,6 +99,14 @@ function checkForUnsupportedProps(headerActions: ReadonlyArray { + if (!runtimeTrigger) { + return undefined; + } + // eslint-disable-next-line react/no-danger + return ; +}; + export const mapRuntimeConfigToDrawer = ( runtimeConfig: RuntimeDrawerConfig ): AppLayoutProps.Drawer & { @@ -114,10 +122,7 @@ export const mapRuntimeConfigToDrawer = ( trigger: trigger ? { ...(trigger.iconSvg && { - iconSvg: ( - // eslint-disable-next-line react/no-danger - - ), + iconSvg: convertRuntimeTriggerToReactNode(trigger.iconSvg), }), } : undefined, @@ -142,22 +147,22 @@ export const mapRuntimeConfigToAiDrawer = ( orderPriority?: number; onToggle?: NonCancelableEventHandler; headerActions?: ReadonlyArray; + exitExpandedModeTrigger?: React.ReactNode; } => { - const { mountContent, unmountContent, trigger, ...runtimeDrawer } = runtimeConfig; + const { mountContent, unmountContent, trigger, exitExpandedModeTrigger, ...runtimeDrawer } = runtimeConfig; return { ...runtimeDrawer, ariaLabels: { drawerName: runtimeDrawer.ariaLabels.content ?? '', ...runtimeDrawer.ariaLabels }, - trigger: trigger + ...(trigger && { + trigger: { + customIcon: convertRuntimeTriggerToReactNode(trigger?.customIcon), + iconSvg: convertRuntimeTriggerToReactNode(trigger?.iconSvg), + }, + }), + exitExpandedModeTrigger: exitExpandedModeTrigger ? { - customIcon: trigger?.customIcon ? ( - // eslint-disable-next-line react/no-danger - - ) : undefined, - iconSvg: trigger.iconSvg ? ( - // eslint-disable-next-line react/no-danger - - ) : undefined, + customIcon: convertRuntimeTriggerToReactNode(exitExpandedModeTrigger?.customIcon), } : undefined, content: ( diff --git a/src/app-layout/visual-refresh-toolbar/drawer/global-ai-drawer.tsx b/src/app-layout/visual-refresh-toolbar/drawer/global-ai-drawer.tsx index 2e549367f3..c86ea70a08 100644 --- a/src/app-layout/visual-refresh-toolbar/drawer/global-ai-drawer.tsx +++ b/src/app-layout/visual-refresh-toolbar/drawer/global-ai-drawer.tsx @@ -38,7 +38,13 @@ interface AIDrawerProps { interface AppLayoutGlobalAiDrawerImplementationProps { appLayoutInternals: AppLayoutInternals; show: boolean; - activeAiDrawer: InternalDrawer | null; + activeAiDrawer: + | (InternalDrawer & { + exitExpandedModeTrigger?: { + customIcon?: React.ReactNode; + }; + }) + | null; aiDrawerProps: AIDrawerProps; } @@ -207,16 +213,31 @@ export function AppLayoutGlobalAiDrawerImplementation({ {!isMobile && isExpanded && activeAiDrawer?.ariaLabels?.exitExpandedModeButton && (
- + {activeAiDrawer?.exitExpandedModeTrigger?.customIcon ? ( + + ) : ( + + )}
)} diff --git a/src/app-layout/visual-refresh-toolbar/drawer/styles.scss b/src/app-layout/visual-refresh-toolbar/drawer/styles.scss index e59fad8595..f956f6b28b 100644 --- a/src/app-layout/visual-refresh-toolbar/drawer/styles.scss +++ b/src/app-layout/visual-refresh-toolbar/drawer/styles.scss @@ -381,6 +381,13 @@ $ai-drawer-heider-height: 41px; outline: none; } } + + > .drawer-back-to-console-custom-button { + all: initial; + display: flex; + cursor: pointer; + text-align: center; + } } } } diff --git a/src/internal/plugins/widget/interfaces.ts b/src/internal/plugins/widget/interfaces.ts index d74ed6233b..34056f1fa5 100644 --- a/src/internal/plugins/widget/interfaces.ts +++ b/src/internal/plugins/widget/interfaces.ts @@ -39,6 +39,9 @@ export interface DrawerPayload { iconSvg?: string; customIcon?: string; }; + exitExpandedModeTrigger?: { + customIcon?: string; + }; mountContent: (container: HTMLElement, mountContext: MountContentContext) => void; unmountContent: (container: HTMLElement) => void; preserveInactiveContent?: boolean;