Skip to content

Commit

Permalink
chore: Widgetize flashbar
Browse files Browse the repository at this point in the history
  • Loading branch information
just-boris committed Mar 6, 2025
1 parent 8ec9c2d commit 45bc6af
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 24 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@
{
"path": "lib/components/internal/widget-exports.js",
"brotli": false,
"limit": "750 kB"
"limit": "820 kB"
}
],
"browserslist": [
Expand Down
11 changes: 7 additions & 4 deletions src/flashbar/collapsible-flashbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ import { Transition } from '../internal/components/transition';
import { getVisualContextClassname } from '../internal/components/visual-context';
import customCssProps from '../internal/generated/custom-css-properties';
import { useEffectOnUpdate } from '../internal/hooks/use-effect-on-update';
import { useMergeRefs } from '../internal/hooks/use-merge-refs';
import { useUniqueId } from '../internal/hooks/use-unique-id';
import { useVisualRefresh } from '../internal/hooks/use-visual-mode';
import { scrollElementIntoView } from '../internal/utils/scrollable-containers';
import { throttle } from '../internal/utils/throttle';
import { GeneratedAnalyticsMetadataFlashbarExpand } from './analytics-metadata/interfaces';
import { getComponentsAnalyticsMetadata, getItemAnalyticsMetadata } from './analytics-metadata/utils';
import { useFlashbar } from './common';
import { Flash, focusFlashById } from './flash';
import { FlashbarProps } from './interfaces';
import { FlashbarProps, InternalFlashbarProps } from './interfaces';
import { counterTypes, getFlashTypeCount, getItemColor, getVisibleCollapsedItems, StackableItem } from './utils';

import styles from './styles.css.js';
Expand All @@ -33,10 +35,11 @@ const maxNonCollapsibleItems = 1;

const resizeListenerThrottleDelay = 100;

export default function CollapsibleFlashbar({ items, ...restProps }: FlashbarProps) {
export default function CollapsibleFlashbar({ __internalRootRef, items, ...restProps }: InternalFlashbarProps) {
const [enteringItems, setEnteringItems] = useState<ReadonlyArray<FlashbarProps.MessageDefinition>>([]);
const [exitingItems, setExitingItems] = useState<ReadonlyArray<FlashbarProps.MessageDefinition>>([]);
const [isFlashbarStackExpanded, setIsFlashbarStackExpanded] = useState(false);
const isVisualRefresh = useVisualRefresh();

const getElementsToAnimate = useCallback(() => {
const flashElements = isFlashbarStackExpanded ? expandedItemRefs.current : collapsedItemRefs.current;
Expand All @@ -48,7 +51,7 @@ export default function CollapsibleFlashbar({ items, ...restProps }: FlashbarPro
setInitialAnimationState(rects);
}, [getElementsToAnimate]);

const { baseProps, breakpoint, isReducedMotion, isVisualRefresh, mergedRef, ref } = useFlashbar({
const { baseProps, breakpoint, isReducedMotion, mergedRef, ref } = useFlashbar({
items,
...restProps,
onItemsAdded: newItems => {
Expand Down Expand Up @@ -308,7 +311,7 @@ export default function CollapsibleFlashbar({ items, ...restProps }: FlashbarPro
isFlashbarStackExpanded && styles.expanded,
isVisualRefresh && styles['visual-refresh']
)}
ref={mergedRef}
ref={useMergeRefs(mergedRef, __internalRootRef)}
{...getAnalyticsMetadataAttribute(getComponentsAnalyticsMetadata(items.length, true, isFlashbarStackExpanded))}
>
{isFlashbarStackExpanded && renderList()}
Expand Down
9 changes: 1 addition & 8 deletions src/flashbar/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import { useReducedMotion, warnOnce } from '@cloudscape-design/component-toolkit

import { getBaseProps } from '../internal/base-component';
import { useContainerBreakpoints } from '../internal/hooks/container-queries';
import useBaseComponent from '../internal/hooks/use-base-component';
import { useMergeRefs } from '../internal/hooks/use-merge-refs';
import { useVisualRefresh } from '../internal/hooks/use-visual-mode';
import { isDevelopment } from '../internal/is-development';
import { focusFlashById } from './flash';
import { FlashbarProps } from './interfaces';
Expand All @@ -25,16 +23,12 @@ export function useFlashbar({
onItemsRemoved?: (items: FlashbarProps.MessageDefinition[]) => void;
onItemsChanged?: (options?: { allItemsHaveId?: boolean; isReducedMotion?: boolean }) => void;
}) {
const { __internalRootRef } = useBaseComponent('Flashbar', {
props: { stackItems: restProps.stackItems },
});
const allItemsHaveId = useMemo(() => items.every(item => 'id' in item), [items]);
const baseProps = getBaseProps(restProps);
const ref = useRef<HTMLDivElement | null>(null);
const [breakpoint, breakpointRef] = useContainerBreakpoints(['xs']);
const mergedRef = useMergeRefs(ref, breakpointRef, __internalRootRef);
const mergedRef = useMergeRefs(ref, breakpointRef);
const isReducedMotion = useReducedMotion(ref);
const isVisualRefresh = useVisualRefresh();
const [previousItems, setPreviousItems] = useState<ReadonlyArray<FlashbarProps.MessageDefinition>>(items);
const [nextFocusId, setNextFocusId] = useState<string | null>(null);

Expand Down Expand Up @@ -76,7 +70,6 @@ export function useFlashbar({
baseProps,
breakpoint,
isReducedMotion,
isVisualRefresh,
mergedRef,
ref,
};
Expand Down
18 changes: 18 additions & 0 deletions src/flashbar/implementation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React from 'react';

import { createWidgetizedComponent } from '../internal/widgets';
import CollapsibleFlashbar from './collapsible-flashbar';
import { InternalFlashbarProps } from './interfaces';
import NonCollapsibleFlashbar from './non-collapsible-flashbar';

export function FlashbarImplementation(props: InternalFlashbarProps) {
if (props.stackItems) {
return <CollapsibleFlashbar {...props} />;
} else {
return <NonCollapsibleFlashbar {...props} />;
}
}

export const createWidgetizedFlashbar = createWidgetizedComponent(FlashbarImplementation);
13 changes: 6 additions & 7 deletions src/flashbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@
// SPDX-License-Identifier: Apache-2.0
import React from 'react';

import useBaseComponent from '../internal/hooks/use-base-component';
import { applyDisplayName } from '../internal/utils/apply-display-name';
import CollapsibleFlashbar from './collapsible-flashbar';
import { FlashbarProps } from './interfaces';
import NonCollapsibleFlashbar from './non-collapsible-flashbar';
import { InternalFlashbar } from './internal';

export { FlashbarProps };

export default function Flashbar(props: FlashbarProps) {
if (props.stackItems) {
return <CollapsibleFlashbar {...props} />;
} else {
return <NonCollapsibleFlashbar {...props} />;
}
const { __internalRootRef } = useBaseComponent('Flashbar', {
props: { stackItems: props.stackItems },
});
return <InternalFlashbar __internalRootRef={__internalRootRef} {...props} />;
}

applyDisplayName(Flashbar, 'Flashbar');
3 changes: 3 additions & 0 deletions src/flashbar/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react';

import { ButtonProps } from '../button/interfaces';
import { BaseComponentProps } from '../internal/base-component';
import { InternalBaseComponentProps } from '../internal/hooks/use-base-component';

export namespace FlashbarProps {
export interface MessageDefinition {
Expand Down Expand Up @@ -99,3 +100,5 @@ export interface FlashbarProps extends BaseComponentProps {
*/
i18nStrings?: FlashbarProps.I18nStrings;
}

export type InternalFlashbarProps = FlashbarProps & InternalBaseComponentProps;
5 changes: 5 additions & 0 deletions src/flashbar/internal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { createWidgetizedFlashbar } from './implementation';

export const InternalFlashbar = createWidgetizedFlashbar();
16 changes: 12 additions & 4 deletions src/flashbar/non-collapsible-flashbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,24 @@ import { getAnalyticsMetadataAttribute } from '@cloudscape-design/component-tool

import { useInternalI18n } from '../i18n/context';
import { Transition } from '../internal/components/transition';
import { useMergeRefs } from '../internal/hooks/use-merge-refs';
import { useVisualRefresh } from '../internal/hooks/use-visual-mode';
import { getComponentsAnalyticsMetadata, getItemAnalyticsMetadata } from './analytics-metadata/utils';
import { useFlashbar } from './common';
import { TIMEOUT_FOR_ENTERING_ANIMATION } from './constant';
import { Flash } from './flash';
import { FlashbarProps } from './interfaces';
import { FlashbarProps, InternalFlashbarProps } from './interfaces';

import styles from './styles.css.js';

export default function NonCollapsibleFlashbar({ items, i18nStrings, ...restProps }: FlashbarProps) {
const { allItemsHaveId, baseProps, breakpoint, isReducedMotion, isVisualRefresh, mergedRef } = useFlashbar({
export default function NonCollapsibleFlashbar({
__internalRootRef,
items,
i18nStrings,
...restProps
}: InternalFlashbarProps) {
const isVisualRefresh = useVisualRefresh();
const { allItemsHaveId, baseProps, breakpoint, isReducedMotion, mergedRef } = useFlashbar({
items,
...restProps,
});
Expand Down Expand Up @@ -125,7 +133,7 @@ export default function NonCollapsibleFlashbar({ items, i18nStrings, ...restProp
<div
{...baseProps}
className={clsx(baseProps.className, styles.flashbar, styles[`breakpoint-${breakpoint}`])}
ref={mergedRef}
ref={useMergeRefs(mergedRef, __internalRootRef)}
>
{renderFlatItemsWithTransitions()}
{renderFlatItemsWithoutTransitions()}
Expand Down
1 change: 1 addition & 0 deletions src/internal/widget-exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export { AppLayoutToolbarImplementation as AppLayoutToolbar } from '../app-layou
export { SplitPanelImplementation as SplitPanel } from '../split-panel/implementation';
export { BreadcrumbGroupImplementation as BreadcrumbGroup } from '../breadcrumb-group/implementation';
export { DrawerImplementation as Drawer } from '../drawer/implementation';
export { FlashbarImplementation as Flashbar } from '../flashbar/implementation';
export { SideNavigationImplementation as SideNavigation } from '../side-navigation/implementation';
export { HelpPanelImplementation as HelpPanel } from '../help-panel/implementation';

0 comments on commit 45bc6af

Please sign in to comment.