import { ButtonGroupProps, ItemRuntime } from '../../../button-group/interfaces'; import { NonCancelableEventHandler } from '../../events'; interface Message { type: Type; payload: Payload; } type DrawerVisibilityChange = (callback: (isVisible: boolean) => void) => void; interface MountContentContext { onVisibilityChange: DrawerVisibilityChange; } interface DrawerStateChangeParams { isOpen: boolean; initiatedByUserAction?: boolean; } export interface DrawerPayload { id: string; ariaLabels: { content?: string; closeButton?: string; triggerButton?: string; resizeHandle?: string; resizeHandleTooltipText?: string; expandedModeButton?: string; exitExpandedModeButton?: string; }; isExpandable?: boolean; resizable?: boolean; defaultSize?: number; onResize?: NonCancelableEventHandler<{ size: number; id: string; }>; defaultActive?: boolean; trigger?: { iconSvg?: string; customIcon?: string; }; exitExpandedModeTrigger?: { customIcon?: string; }; mountContent: (container: HTMLElement, mountContext: MountContentContext) => void; unmountContent: (container: HTMLElement) => void; preserveInactiveContent?: boolean; onToggle?: NonCancelableEventHandler; mountHeader?: (container: HTMLElement) => void; unmountHeader?: (container: HTMLElement) => void; headerActions?: ReadonlyArray; onHeaderActionClick?: NonCancelableEventHandler; onToggleFocusMode?: NonCancelableEventHandler<{ isExpanded: boolean; }>; position?: 'side' | 'bottom'; } type Destructor = () => void; export type MountContentPart = (container: HTMLElement, data: T) => Destructor | void; /** * Describes a single feature entry in the notification drawer. * * The generic type `T` determines how feature text content is provided: * - When `T` is `string`, the values are rendered as plain text. * - When `T` is `ReactNode`, you must also provide `mountItem` on the parent * `FeatureNotificationsPayload` so the framework can mount the React content * into the DOM container. */ export interface Feature { /** Unique identifier used for persistence tracking (seen/unseen state) and list keying. */ id: string; /** Primary title displayed as the feature heading in both the notification drawer and the feature prompt popover. */ header: T; /** Descriptive body rendered below the header in the notification drawer and the feature prompt popover. */ content: T; /** Optional category label rendered between the release date and the content in the notification drawer. */ contentCategory?: T; /** Publication date of the feature. Used for default filtering (last 90 days), descending sort order, and display formatting. */ releaseDate: Date; } export interface FeatureNotificationsPersistenceConfig { uniqueKey: string; } type FeatureId = string; type FeatureReleaseDateString = string; export type PersistedFeaturesDict = Record; export type PersistFeatureNotifications = (persistenceConfig: FeatureNotificationsPersistenceConfig, value: PersistedFeaturesDict) => Promise; export type RetrieveFeatureNotifications = (persistenceConfig: FeatureNotificationsPersistenceConfig) => Promise; export interface FeatureNotificationsPayload { /** * Unique identifier for the feature notifications. */ id: string; /** * When set to `true`, prevents the feature prompt from automatically appearing * when unseen features are detected during registration. The prompt can still * be shown programmatically via the `showFeaturePromptIfPossible` message. * * @default false */ suppressFeaturePrompt?: boolean; /** * List of features to display in the notification drawer. Each feature is filtered * by `filterFeatures` (or a default 90-day recency filter), sorted by `releaseDate` * in descending order, and tracked for seen/unseen state via persistence. The latest * unseen feature is used to populate the feature prompt, and opening the drawer marks * all features as seen. */ features: Array>; /** * Mounting function used to render each feature's `header`, `content`, and * `contentCategory` values into the DOM. Required when `T` is `ReactNode` * (or any non-string type) so the framework can mount the content into the * provided container element. When `T` is `string`, this can be omitted and * values are rendered as plain text. * * The function receives the target `container` element and the `data` value * (one of the feature's text fields), and should return an optional destructor * that will be called on unmount to clean up resources (e.g. `root.unmount()`). * * @example * ```ts * import { createRoot } from 'react-dom/client'; * * mountItem: (container, data) => { * const root = createRoot(container); * root.render(data); * return () => root.unmount(); * } * ``` */ mountItem?: MountContentPart; /** * Optional URL rendered as a "View all feature releases" link at the bottom of the notification * drawer, allowing users to navigate to a dedicated page with the full list of * features. */ featuresPageLink?: string; /** * Optional predicate to control which features are displayed. Applied to each * feature before sorting. When omitted, a default filter is used that only * keeps features with a `releaseDate` within the last 90 days. */ filterFeatures?: (item: Feature) => boolean; /** * Configuration for persisting seen/unseen state of features. The `uniqueKey` * is used as the storage key when saving and retrieving which features the user * has already viewed. When omitted, a default key (`'awsui-feature-notifications'`) * is used. */ persistenceConfig?: FeatureNotificationsPersistenceConfig; /** * @internal * Optional override for saving the seen/unseen state of features. When provided, * this function is called instead of the built-in persistence mechanism when the * user opens the notification drawer and all features are marked as seen. * Receives the `persistenceConfig` and a dictionary mapping feature IDs to their * release date strings. */ __persistFeatureNotifications?: PersistFeatureNotifications; /** * @internal * Optional override for retrieving the previously persisted seen/unseen state of * features. When provided, this function is called instead of the built-in retrieval * mechanism during registration to determine which features the user has already viewed. * Should return a dictionary mapping feature IDs to their release date strings. */ __retrieveFeatureNotifications?: RetrieveFeatureNotifications; i18nStrings?: { titleText?: string; viewAllText?: string; closeButtonAriaLabel?: string; contentAriaLabel?: string; triggerButtonAriaLabel?: string; resizeHandleAriaLabel?: string; }; } export type FeatureNotificationsPayloadPublic = Omit, '__persistFeatureNotifications' | '__retrieveFeatureNotifications'>; export type RegisterDrawerMessage = Message<'registerLeftDrawer' | 'registerBottomDrawer', DrawerPayload>; export type RegisterFeatureNotificationsMessage = Message<'registerFeatureNotifications', FeatureNotificationsPayload>; export type UpdateDrawerConfigMessage = Message<'updateDrawerConfig', Pick & Partial>>; export type OpenDrawerMessage = Message<'openDrawer', { id: string; }>; export type CloseDrawerMessage = Message<'closeDrawer', { id: string; }>; export type ResizeDrawerMessage = Message<'resizeDrawer', { id: string; size: number; }>; export type ExpandDrawerMessage = Message<'expandDrawer', { id: string; }>; export interface ExitExpandedModeMessage { type: 'exitExpandedMode'; } export interface ShowFeaturePromptIfPossible { type: 'showFeaturePromptIfPossible'; } export interface ClearFeatureNotifications { type: 'clearFeatureNotifications'; } export type AppLayoutUpdateMessage = UpdateDrawerConfigMessage | OpenDrawerMessage | CloseDrawerMessage | ResizeDrawerMessage | ExpandDrawerMessage | ExitExpandedModeMessage | RegisterFeatureNotificationsMessage | ShowFeaturePromptIfPossible | ClearFeatureNotifications; export type InitialMessage = RegisterDrawerMessage | RegisterFeatureNotificationsMessage; export type WidgetMessage = InitialMessage | AppLayoutUpdateMessage; export {};