Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/autosuggest/autosuggest-option.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ const AutosuggestOption = (
ref: React.Ref<HTMLDivElement>
) => {
const baseProps = getBaseProps(rest);
const useEntered = option.type === 'use-entered';
const isParent = option.type === 'parent';
const isChild = option.type === 'child';
const useEntered = option?.type === 'use-entered';
const isParent = option?.type === 'parent';
const isChild = option?.type === 'child';
const { throughIndex, inGroupIndex, groupIndex } = getTestOptionIndexes(option) || {};

let optionContent;
Expand Down
2 changes: 1 addition & 1 deletion src/autosuggest/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { AutosuggestItem } from '../interfaces';
type SearchableFields = 'value' | 'label' | 'description' | 'labelTag';
type SearchableTagFields = 'tags' | 'filteringTags';

const isGroup = (option: AutosuggestItem) => option.type === 'parent';
const isGroup = (option: AutosuggestItem) => option?.type === 'parent';

const popLastGroup = (options: AutosuggestItem[]) => {
if (options.length) {
Expand Down
10 changes: 6 additions & 4 deletions src/button-dropdown/internal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
GeneratedAnalyticsMetadataButtonDropdownCollapse,
GeneratedAnalyticsMetadataButtonDropdownExpand,
} from './analytics-metadata/interfaces.js';
import { ButtonDropdownProps, InternalButtonDropdownProps } from './interfaces';
import { ButtonDropdownProps, InternalButtonDropdownProps, InternalItem } from './interfaces';
import ItemsList from './items-list';
import { useButtonDropdown } from './utils/use-button-dropdown';
import { isLinkItem } from './utils/utils.js';
Expand Down Expand Up @@ -180,18 +180,20 @@ const InternalButtonDropdown = React.forwardRef(
const triggerId = useUniqueId('awsui-button-dropdown__trigger');

const triggerHasBadge = () => {
const groupKey: keyof ButtonDropdownProps.ItemGroup = 'items';
const flatItems = items.flatMap(item => {
if ('items' in item) {
if (groupKey in item) {
return item.items;
}
return item;
});

const badgeKey: keyof InternalItem = 'badge';
return (
variant === 'icon' &&
!!flatItems?.find(item => {
if ('badge' in item) {
return item.badge;
if (badgeKey in item) {
return (item as InternalItem).badge;
}
})
);
Expand Down
3 changes: 2 additions & 1 deletion src/button-group/item-element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ const ItemElement = forwardRef(
};

const onClickHandler = (event: CustomEvent<ButtonGroupProps.ItemClickDetails>) => {
const hasPopoverFeedback = 'popoverFeedback' in item && item.popoverFeedback;
const feedbackKey: keyof ButtonGroupProps.IconButton = 'popoverFeedback';
const hasPopoverFeedback = feedbackKey in item && item.popoverFeedback;

if (hasPopoverFeedback) {
setTooltip({ item: item.id, feedback: true });
Expand Down
12 changes: 5 additions & 7 deletions src/flashbar/collapsible-flashbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import {
getFlashTypeCount,
getItemColor,
getVisibleCollapsedItems,
isRefObject,
isStackableItem,
StackableItem,
} from './utils';

Expand Down Expand Up @@ -214,11 +216,11 @@ export default function CollapsibleFlashbar({ items, style, ...restProps }: Inte
// we need to use different, more custom and more controlled animations.
const hasEntered = (item: StackableItem | FlashbarProps.MessageDefinition) =>
enteringItems.some(_item => _item.id && _item.id === item.id);
const hasLeft = (item: StackableItem | FlashbarProps.MessageDefinition) => !('expandedIndex' in item);
const hasLeft = (item: StackableItem | FlashbarProps.MessageDefinition) => !isStackableItem(item);
const hasEnteredOrLeft = (item: StackableItem | FlashbarProps.MessageDefinition) => hasEntered(item) || hasLeft(item);

const showInnerContent = (item: StackableItem | FlashbarProps.MessageDefinition) =>
isFlashbarStackExpanded || hasLeft(item) || ('expandedIndex' in item && item.expandedIndex === 0);
isFlashbarStackExpanded || hasLeft(item) || (isStackableItem(item) && item.expandedIndex === 0);

const shouldUseStandardAnimation = (item: StackableItem, index: number) => index === 0 && hasEnteredOrLeft(item);

Expand Down Expand Up @@ -301,11 +303,7 @@ export default function CollapsibleFlashbar({ items, style, ...restProps }: Inte
if (shouldUseStandardAnimation(item, index) && transitionRootElement) {
if (typeof transitionRootElement === 'function') {
transitionRootElement(el);
} else if (
transitionRootElement &&
typeof transitionRootElement === 'object' &&
'current' in transitionRootElement
) {
} else if (isRefObject(transitionRootElement)) {
(transitionRootElement as React.MutableRefObject<HTMLDivElement | null>).current = el;
}
}
Expand Down
7 changes: 2 additions & 5 deletions src/flashbar/non-collapsible-flashbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useFlashbar, useFlashbarVisibility } from './common';
import { TIMEOUT_FOR_ENTERING_ANIMATION } from './constant';
import { Flash } from './flash';
import { FlashbarProps, InternalFlashbarProps } from './interfaces';
import { isRefObject } from './utils';

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

Expand Down Expand Up @@ -121,11 +122,7 @@ export default function NonCollapsibleFlashbar({ items, i18nStrings, style, ...r
// If there's a transition root element ref, update it too
if (transitionRootElement && typeof transitionRootElement === 'function') {
transitionRootElement(el);
} else if (
transitionRootElement &&
typeof transitionRootElement === 'object' &&
'current' in transitionRootElement
) {
} else if (transitionRootElement && isRefObject(transitionRootElement)) {
(transitionRootElement as React.MutableRefObject<HTMLDivElement | null>).current = el;
}
}}
Expand Down
12 changes: 12 additions & 0 deletions src/flashbar/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React from 'react';

import { IconProps } from '../icon/interfaces';
import { FlashbarProps } from './interfaces';

Expand All @@ -13,6 +15,16 @@ export interface StackableItem extends FlashbarProps.MessageDefinition {
collapsedIndex?: number;
}

export function isStackableItem(item: StackableItem | FlashbarProps.MessageDefinition): item is StackableItem {
const key: keyof StackableItem = 'expandedIndex';
return key in item;
}

export function isRefObject<T>(ref: unknown): ref is React.RefObject<T> {
const key: keyof React.RefObject<T> = 'current';
return ref !== null && typeof ref === 'object' && key in ref;
}

const typesToColors: Record<FlashbarProps.Type, string> = {
error: 'red',
info: 'blue',
Expand Down
6 changes: 4 additions & 2 deletions src/mixed-line-bar-chart/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,15 @@ export const getKeyValue = (key: ChartDataTypes) => (key instanceof Date ? key.g
export function isYThreshold<T>(
series: MixedLineBarChartProps.ChartSeries<T>
): series is MixedLineBarChartProps.YThresholdSeries {
return series.type === 'threshold' && 'y' in series;
const key: keyof MixedLineBarChartProps.YThresholdSeries = 'y';
return series.type === 'threshold' && key in series;
}

export function isXThreshold<T>(
series: MixedLineBarChartProps.ChartSeries<T>
): series is MixedLineBarChartProps.XThresholdSeries<T> {
return series.type === 'threshold' && 'x' in series;
const key: keyof MixedLineBarChartProps.XThresholdSeries<T> = 'x';
return series.type === 'threshold' && key in series;
}

export function isDataSeries<T>(
Expand Down
6 changes: 4 additions & 2 deletions src/side-navigation/util.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,16 @@ export function checkDuplicateHrefs(items: ReadonlyArray<SideNavigationProps.Ite
const item = queue.shift()!;

// Check duplicated hrefs
if ('href' in item) {
const hrefKey: keyof SideNavigationProps.Link = 'href';
if (hrefKey in item) {
if (hrefs.has(item.href)) {
warnOnce('SideNavigation', `duplicate href in "${item.text}": ${item.href}`);
}
hrefs.add(item.href);
}

if ('items' in item) {
const itemsKey: keyof SideNavigationProps.Section = 'items';
if (itemsKey in item) {
queue.push(...item.items);
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/top-navigation/parts/utility.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react';
import clsx from 'clsx';

import { InternalButton } from '../../button/internal';
import { ButtonDropdownProps } from '../../button-dropdown/interfaces';
import { isLinkItem } from '../../button-dropdown/utils/utils';
import InternalIcon from '../../icon/internal';
import MenuDropdown, { MenuDropdownProps } from '../../internal/components/menu-dropdown';
Expand Down Expand Up @@ -133,7 +134,8 @@ function checkSafeUrlRecursively(itemOrGroup: MenuDropdownProps['items']) {
checkSafeUrl('TopNavigation', item.href);
}

if ('items' in item) {
const itemsKey: keyof ButtonDropdownProps.ItemGroup = 'items';
if (itemsKey in item) {
checkSafeUrlRecursively(item.items);
}
}
Expand Down
Loading