Skip to content

Commit c6d12d9

Browse files
committed
chore: Implement flashbar runtime API
1 parent 46bf2fc commit c6d12d9

File tree

17 files changed

+302
-195
lines changed

17 files changed

+302
-195
lines changed

src/app-layout/__tests__/__snapshots__/widget-contract-old.test.tsx.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,8 @@ Map {
13651365
"children": <div>
13661366
notifications
13671367
</div>,
1368+
"flashbarProps": null,
1369+
"setFlashbarProps": [Function],
13681370
},
13691371
"AppLayoutSplitPanelDrawerBottomImplementation" => {
13701372
"appLayoutInternals": {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import { act, render } from '@testing-library/react';
55

66
import AppLayout from '../../../lib/components/app-layout';
77
import { metrics } from '../../../lib/components/internal/metrics';
8+
import * as awsuiWidgetPlugins from '../../../lib/components/internal/plugins/widget';
9+
import * as awsuiWidgetInternal from '../../../lib/components/internal/plugins/widget/core';
810
import { DrawerPayload } from '../../../lib/components/internal/plugins/widget/interfaces';
9-
import * as awsuiWidgetPlugins from '../../../lib/components/internal/plugins/widget/internal';
1011
import createWrapper from '../../../lib/components/test-utils/dom';
1112
import { describeEachAppLayout, getGlobalDrawersTestUtils } from './utils';
1213

@@ -19,7 +20,7 @@ const drawerDefaults: DrawerPayload = {
1920
};
2021

2122
beforeEach(() => {
22-
awsuiWidgetPlugins.clearInitialMessages();
23+
awsuiWidgetInternal.clearInitialMessages();
2324
jest.resetAllMocks();
2425
});
2526

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ import AppLayout, { AppLayoutProps } from '../../../lib/components/app-layout';
1111
import { TOOLS_DRAWER_ID } from '../../../lib/components/app-layout/utils/use-drawers';
1212
import { awsuiPlugins, awsuiPluginsInternal } from '../../../lib/components/internal/plugins/api';
1313
import { DrawerConfig } from '../../../lib/components/internal/plugins/controllers/drawers';
14+
import * as awsuiWidgetInternal from '../../../lib/components/internal/plugins/widget/core';
15+
import * as awsuiWidgetPlugins from '../../../lib/components/internal/plugins/widget/index';
1416
import { DrawerPayload as WidgetDrawerPayload } from '../../../lib/components/internal/plugins/widget/interfaces';
15-
import * as awsuiWidgetPlugins from '../../../lib/components/internal/plugins/widget/internal';
1617
import SplitPanel from '../../../lib/components/split-panel';
1718
import createWrapper from '../../../lib/components/test-utils/dom';
1819
import {
@@ -31,7 +32,7 @@ import toolbarTriggerStyles from '../../../lib/components/app-layout/visual-refr
3132

3233
beforeEach(() => {
3334
awsuiPluginsInternal.appLayout.clearRegisteredDrawers();
34-
awsuiWidgetPlugins.clearInitialMessages();
35+
awsuiWidgetInternal.clearInitialMessages();
3536
activateAnalyticsMetadata(true);
3637
});
3738

src/app-layout/utils/use-ai-drawer.ts

Lines changed: 0 additions & 153 deletions
This file was deleted.

src/app-layout/visual-refresh-toolbar/drawer/global-ai-drawer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import customCssProps from '../../../internal/generated/custom-css-properties';
1111
import { usePrevious } from '../../../internal/hooks/use-previous';
1212
import { getLimitedValue } from '../../../split-panel/utils/size-utils';
1313
import { AppLayoutProps } from '../../interfaces';
14-
import { OnChangeParams } from '../../utils/use-ai-drawer';
1514
import { FocusControlState } from '../../utils/use-focus-control';
1615
import { AppLayoutInternals, InternalDrawer } from '../interfaces';
16+
import { OnChangeParams } from '../state/use-ai-drawer';
1717
import { useResize } from './use-resize';
1818

1919
import sharedStyles from '../../resize/styles.css.js';

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import React from 'react';
55

66
import { BreadcrumbGroupProps } from '../../breadcrumb-group/interfaces';
77
import { ButtonGroupProps } from '../../button-group/interfaces';
8+
import { FlashbarProps } from '../../flashbar/interfaces';
89
import { SplitPanelSideToggleProps } from '../../internal/context/split-panel-context';
910
import { NonCancelableEventHandler } from '../../internal/events';
1011
import { SomeOptional } from '../../internal/types';
@@ -90,6 +91,8 @@ interface AppLayoutWidgetizedState extends AppLayoutInternals {
9091
verticalOffsets: VerticalLayoutOutput;
9192
navigationAnimationDisabled: boolean;
9293
aiDrawerExpandedMode: boolean;
94+
flashbarProps: FlashbarProps | null;
95+
setFlashbarProps: (props: FlashbarProps | null) => void;
9396
splitPanelOffsets: {
9497
stickyVerticalBottomOffset: number;
9598
mainContentPaddingBlockEnd: number | undefined;

src/app-layout/visual-refresh-toolbar/notifications/index.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,26 @@ import clsx from 'clsx';
55

66
import { useResizeObserver } from '@cloudscape-design/component-toolkit/internal';
77

8+
import { FlashbarImplementation } from '../../../flashbar/implementation';
89
import { highContrastHeaderClassName } from '../../../internal/utils/content-header-utils';
9-
import { AppLayoutInternals } from '../interfaces';
10+
import { AppLayoutInternals, AppLayoutState } from '../interfaces';
1011
import { NotificationsSlot } from '../skeleton/slots';
12+
import { FlashbarPropsSetter } from '../state/runtime-notifications';
1113

1214
import testutilStyles from '../../test-classes/styles.css.js';
1315
import styles from './styles.css.js';
1416

1517
export interface AppLayoutNotificationsImplementationProps {
1618
appLayoutInternals: AppLayoutInternals;
19+
flashbarProps?: AppLayoutState['widgetizedState']['flashbarProps'];
20+
setFlashbarProps?: AppLayoutState['widgetizedState']['setFlashbarProps'];
1721
children: React.ReactNode;
1822
}
1923

2024
export function AppLayoutNotificationsImplementation({
2125
appLayoutInternals,
26+
flashbarProps,
27+
setFlashbarProps,
2228
children,
2329
}: AppLayoutNotificationsImplementationProps) {
2430
const { ariaLabels, stickyNotifications, setNotificationsHeight, verticalOffsets } = appLayoutInternals;
@@ -51,7 +57,8 @@ export function AppLayoutNotificationsImplementation({
5157
}}
5258
>
5359
<div className={testutilStyles.notifications} role="region" aria-label={ariaLabels?.notifications}>
54-
{children}
60+
<FlashbarPropsSetter.Provider value={setFlashbarProps ?? null}>{children}</FlashbarPropsSetter.Provider>
61+
{flashbarProps && <FlashbarImplementation {...flashbarProps} />}
5562
</div>
5663
</NotificationsSlot>
5764
);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import { createContext, useState } from 'react';
4+
5+
import { FlashbarProps } from '../../../flashbar/interfaces';
6+
import { WidgetMessage } from '../../../internal/plugins/widget/interfaces';
7+
8+
export const FlashbarPropsSetter = createContext<((props: FlashbarProps | null) => void) | null>(null);
9+
10+
export function useRuntimeNotifications() {
11+
const [flashbarProps, setFlashbarProps] = useState<FlashbarProps | null>(null);
12+
const [notifications, setNotifications] = useState<Array<FlashbarProps.MessageDefinition>>([]);
13+
14+
function notificationsMessageHandler(message: WidgetMessage) {
15+
if (message.type === 'emitNotification') {
16+
setNotifications(notifications => [...notifications, message.payload]);
17+
}
18+
}
19+
20+
return {
21+
flashbarProps: (flashbarProps || notifications.length > 0) && {
22+
...flashbarProps,
23+
items: [...(flashbarProps?.items ?? []), ...notifications],
24+
},
25+
setFlashbarProps,
26+
notificationsMessageHandler,
27+
};
28+
}

0 commit comments

Comments
 (0)