Skip to content
Closed

test #3715

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
98 changes: 98 additions & 0 deletions pages/button-dropdown/icon-expandable.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useContext } from 'react';

import ButtonDropdown, { ButtonDropdownProps } from '~components/button-dropdown';
import SpaceBetween from '~components/space-between';

import AppContext, { AppContextType } from '../app/app-context';
import ScreenshotArea from '../utils/screenshot-area';

import styles from './styles.scss';

export const items: ButtonDropdownProps['items'] = [
{
id: 'category1',
text: 'category1',
iconName: 'gen-ai',
items: [...Array(2)].map((_, index) => ({
id: 'category1Subitem' + index,
text: 'Sub item ' + index,
})),
},
{
id: 'category2',
text: 'category2',
iconUrl: 'data:image/png;base64,aaaa',
items: [...Array(2)].map((_, index) => ({
id: 'category2Subitem' + index,
text: 'Cat 2 Sub item ' + index,
})),
},
{
id: 'item1',
text: 'Item 1',
iconName: 'settings',
},
{
id: 'category3',
text: 'category3',
iconSvg: (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" focusable="false">
<path
d="M2 4V12C2 12.5523 2.44772 13 3 13H13C13.5523 13 14 12.5523 14 12V6C14 5.44772 13.5523 5 13 5H8L6 3H3C2.44772 3 2 3.44772 2 4Z"
fill="currentColor"
/>
</svg>
),
items: [...Array(2)].map((_, index) => ({
id: 'category3Subitem' + index,
text: 'Sub item ' + index,
})),
},
];

type DemoContext = React.Context<
AppContextType<{
expandableGroups: boolean;
}>
>;

export default function IconExpandableButtonDropdown() {
const {
urlParams: { expandableGroups = true },
setUrlParams,
} = useContext(AppContext as DemoContext);

return (
<div className={styles.container}>
<article>
<h1>Icon Expandable Dropdown</h1>
<SpaceBetween size="m">
<label>
<input
id="expandableGroups"
type="checkbox"
checked={expandableGroups}
onChange={e => setUrlParams({ expandableGroups: !!e.target.checked })}
/>{' '}
expandableGroups
</label>
<ScreenshotArea
style={{
paddingBlockStart: 10,
paddingBlockEnd: 300,
paddingInlineStart: 10,
paddingInlineEnd: 100,
display: 'inline-block',
}}
>
<ButtonDropdown expandableGroups={expandableGroups} items={items}>
Dropdown with Icons
</ButtonDropdown>
</ScreenshotArea>
</SpaceBetween>
</article>
</div>
);
}
42 changes: 42 additions & 0 deletions src/button-dropdown/__tests__/button-dropdown-items.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ const checkRenderedGroup = (
);
}
}

if (group.iconName || group.iconSvg || group.iconUrl) {
expect(renderedItem.findIcon()).toBeTruthy();
}
};

const checkElementItem = (
Expand Down Expand Up @@ -432,6 +436,44 @@ const items: ButtonDropdownProps.Items = [
wrapper.openDropdown();
expect(wrapper.findItemById('i1')!.findAllIcons()).toHaveLength(2);
});

test.each([true, false])('in category headers when expandableGroups is %s', expandableGroups => {
const svg = (
<svg className="test-svg" focusable="false">
<circle className="test-svg-inner" cx="8" cy="8" r="7" />
</svg>
);
const groupedCategories: ButtonDropdownProps.ItemOrGroup[] = [
{
id: 'category1',
text: 'category1',
iconName: 'folder',
items: [{ id: 'i1', text: 'item1' }],
},
{
id: 'category2',
text: 'category2',
iconUrl: 'data:image/png;base64,aaaa',
items: [{ id: 'i2', text: 'item2' }],
},
{
id: 'category3',
text: 'category3',
iconSvg: svg,
items: [{ id: 'i3', text: 'item3' }],
},
];
const wrapper = renderButtonDropdown({ ...props, expandableGroups, items: groupedCategories });
wrapper.openDropdown();

if (expandableGroups) {
expect(wrapper.findExpandableCategoryById('category1')!.findIcon()).toBeTruthy();
expect(wrapper.findExpandableCategoryById('category2')!.findIcon()).toBeTruthy();
expect(wrapper.findExpandableCategoryById('category3')!.findIcon()).toBeTruthy();
} else {
expect(wrapper.findOpenDropdown()!.findAllIcons()).toHaveLength(3);
}
});
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
import React from 'react';
import { render } from '@testing-library/react';

import MobileExpandableCategoryElement from '../../../lib/components/button-dropdown/category-elements/mobile-expandable-category-element';
import MobileExpandableGroup from '../../../lib/components/button-dropdown/mobile-expandable-group/mobile-expandable-group';
import createWrapper from '../../../lib/components/test-utils/dom';

const renderComponent = (component: React.ReactElement) => {
const renderResult = render(component);
return createWrapper(renderResult.container);
};

describe('MobileExpandableGroup Component', () => {
test('is closed by default', () => {
const wrapper = renderComponent(
Expand All @@ -29,3 +29,46 @@ describe('MobileExpandableGroup Component', () => {
expect(wrapper.find(`[data-open=true]`)).not.toBe(null);
});
});

describe('MobileExpandableCategoryElement icon rendering', () => {
const mockProps = {
onItemActivate: jest.fn(),
onGroupToggle: jest.fn(),
targetItem: null,
isHighlighted: jest.fn(() => false),
isKeyboardHighlight: jest.fn(() => false),
isExpanded: jest.fn(() => false),
lastInDropdown: false,
highlightItem: jest.fn(),
disabled: false,
variant: 'normal' as const,
position: '1',
};

test('renders icon when iconName provided', () => {
const item = { id: 'test', text: 'Test', iconName: 'settings' as const, items: [] };
const wrapper = renderComponent(<MobileExpandableCategoryElement item={item} {...mockProps} />);
expect(wrapper.findIcon()).toBeTruthy();
});

test('renders icon when iconUrl provided', () => {
const item = { id: 'test', text: 'Test', iconUrl: 'data:image/png;base64,test', items: [] };
const wrapper = renderComponent(<MobileExpandableCategoryElement item={item} {...mockProps} />);
expect(wrapper.findIcon()).toBeTruthy();
});

test('renders icon when iconSvg provided', () => {
const item = {
id: 'test',
text: 'Test',
iconSvg: (
<svg focusable="false">
<circle />
</svg>
),
items: [],
};
const wrapper = renderComponent(<MobileExpandableCategoryElement item={item} {...mockProps} />);
expect(wrapper.findIcon()).toBeTruthy();
});
});
6 changes: 6 additions & 0 deletions src/button-dropdown/category-elements/category-element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import React from 'react';
import clsx from 'clsx';

import InternalIcon from '../../icon/internal';
import { CategoryProps } from '../interfaces';
import ItemsList from '../items-list';

Expand Down Expand Up @@ -31,6 +32,11 @@ const CategoryElement = ({
>
{item.text && (
<p className={clsx(styles.header, { [styles.disabled]: disabled })} aria-hidden="true">
{(item.iconName || item.iconUrl || item.iconSvg) && (
<span className={styles['icon-wrapper']}>
<InternalIcon name={item.iconName} url={item.iconUrl} svg={item.iconSvg} alt={item.iconAlt} />
</span>
)}
{item.text}
</p>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ const ExpandableCategoryElement = ({
} as GeneratedAnalyticsMetadataButtonDropdownExpand | GeneratedAnalyticsMetadataButtonDropdownCollapse)
)}
>
{(item.iconName || item.iconUrl || item.iconSvg) && (
<span className={styles['icon-wrapper']}>
<InternalIcon name={item.iconName} url={item.iconUrl} svg={item.iconSvg} alt={item.iconAlt} />
</span>
)}
{item.text}
<span className={clsx(styles['expand-icon'], styles['expand-icon-right'])}>
<InternalIcon name="caret-down-filled" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ const MobileExpandableCategoryElement = ({
} as GeneratedAnalyticsMetadataButtonDropdownExpand)
)}
>
{(item.iconName || item.iconUrl || item.iconSvg) && (
<span className={styles['icon-wrapper']}>
<InternalIcon name={item.iconName} url={item.iconUrl} svg={item.iconSvg} alt={item.iconAlt} />
</span>
)}
{item.text}
<span
className={clsx(styles['expand-icon'], {
Expand Down
10 changes: 8 additions & 2 deletions src/button-dropdown/category-elements/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
font-weight: bold;
display: flex;
justify-content: space-between;
align-items: center;
// to compensate for the loss of padding due to the removal of the left and right borders
// and differences in default divider + selected border widths (visual refresh)
padding-block: styles.$option-padding-with-border-placeholder-vertical;
Expand All @@ -33,6 +34,7 @@
border-block-start-color: awsui.$color-border-dropdown-group;
border-block-end-color: awsui.$color-border-dropdown-group;
cursor: pointer;

&.disabled {
cursor: default;
}
Expand Down Expand Up @@ -99,9 +101,10 @@

.expand-icon {
position: relative;
inset-inline-start: awsui.$space-s;
inset-inline-end: calc(-1 * #{awsui.$space-s});
inline-size: awsui.$space-m;
display: inline-block;
margin-inline-start: auto;

@include styles.with-motion {
transition: transform awsui.$motion-duration-rotate-180 awsui.$motion-easing-rotate-180;
Expand All @@ -113,7 +116,6 @@

&-right {
transform: rotate(-90deg);

@include styles.with-direction('rtl') {
transform: rotate(90deg);
}
Expand All @@ -132,3 +134,7 @@
.in-dropdown {
margin-block-end: -1px;
}

.icon-wrapper {
margin-inline-end: awsui.$space-xxs;
}
Loading