Skip to content

Commit

Permalink
Merge branch 'main' into cansua/blue-dialog-contribution
Browse files Browse the repository at this point in the history
  • Loading branch information
cansuaa authored Jan 31, 2025
2 parents 25ed07c + 2a72da2 commit ecbc736
Show file tree
Hide file tree
Showing 33 changed files with 502 additions and 525 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
name: Release

on:
workflow_dispatch:
inputs:
role-to-assume:
type: string
description: Use to override the AWS role used during release
required: false
project-name:
type: string
description: Use to override the CodeBuild project called
required: false
push:
branches:
- main
Expand All @@ -18,3 +28,5 @@ jobs:
secrets: inherit
with:
skip-test: true
role-to-assume: ${{ inputs.role-to-assume }}
project-name: ${{ inputs.project-name }}
54 changes: 50 additions & 4 deletions pages/table/editable.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import React, { ForwardedRef, forwardRef, useContext, useEffect, useRef, useState } from 'react';

import { Box, Button, Checkbox, Link, Modal, SpaceBetween } from '~components';
import { Box, Button, Checkbox, Modal, SpaceBetween } from '~components';
import Alert from '~components/alert';
import Autosuggest, { AutosuggestProps } from '~components/autosuggest';
import Header from '~components/header';
Expand All @@ -20,6 +20,7 @@ type PageContext = React.Context<
AppContextType<{
resizableColumns: boolean;
enableKeyboardNavigation: boolean;
expandableRows: boolean;
}>
>;

Expand Down Expand Up @@ -62,7 +63,27 @@ const columns: TableProps.ColumnDefinition<DistributionInfo>[] = [
header: 'Distribution ID',
sortingField: 'Id',
width: 180,
cell: (item: DistributionInfo) => <Link href={`/#/distributions/${item.Id}`}>{item.Id}</Link>,
cell: (item: DistributionInfo) => item.Id,
editConfig: {
ariaLabel: 'Distribution ID',
editIconAriaLabel: 'editable',
errorIconAriaLabel: 'Distribution ID Error',
editingCell(item, { currentValue, setValue }: TableProps.CellContext<string>) {
return (
<Input
autoFocus={true}
value={currentValue ?? item.Id}
onChange={withDirtyState(event => setValue(event.detail.value))}
/>
);
},
disabledReason(item) {
if (item.Id.includes('E2')) {
return "You don't have the necessary permissions to edit this item.";
}
return undefined;
},
},
},
{
id: 'DomainName',
Expand Down Expand Up @@ -222,7 +243,7 @@ const Demo = forwardRef(
) => {
const [items, setItems] = useState(initialItems);
const {
urlParams: { resizableColumns = true, enableKeyboardNavigation = false },
urlParams: { resizableColumns = true, enableKeyboardNavigation = false, expandableRows = false },
} = useContext(AppContext as PageContext);

const handleSubmit: TableProps.SubmitEditFunction<DistributionInfo> = async (currentItem, column, newValue) => {
Expand Down Expand Up @@ -251,6 +272,8 @@ const Demo = forwardRef(
setClean();
};

const [expandedItems, setExpandedItems] = useState<DistributionInfo[]>([]);

return (
<Table
ref={tableRef}
Expand All @@ -273,14 +296,33 @@ const Demo = forwardRef(
stickyHeader={true}
resizableColumns={resizableColumns}
enableKeyboardNavigation={enableKeyboardNavigation}
expandableRows={
expandableRows
? {
getItemChildren: item => [
{ ...item, Id: item.Id + '-1' },
{ ...item, Id: item.Id + '-2' },
],
isItemExpandable: item => !item.Id.endsWith('-1') && !item.Id.endsWith('-2'),
expandedItems,
onExpandableItemToggle: ({ detail }) => {
if (detail.expanded) {
return setExpandedItems(prev => [...prev, detail.item]);
} else {
return setExpandedItems(prev => prev.filter(item => item !== detail.item));
}
},
}
: undefined
}
/>
);
}
);

export default function () {
const {
urlParams: { resizableColumns = true, enableKeyboardNavigation = false },
urlParams: { resizableColumns = true, enableKeyboardNavigation = false, expandableRows = false },
setUrlParams,
} = useContext(AppContext as PageContext);
const [modalVisible, setModalVisible] = useState(false);
Expand Down Expand Up @@ -321,6 +363,10 @@ export default function () {
>
Keyboard navigation
</Checkbox>

<Checkbox checked={expandableRows} onChange={event => setUrlParams({ expandableRows: event.detail.checked })}>
Expandable rows
</Checkbox>
</SpaceBetween>

<input data-testid="focus" aria-label="focus input" />
Expand Down
21 changes: 20 additions & 1 deletion pages/table/sticky-columns.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import ScreenshotArea from '../utils/screenshot-area';
import { generateItems, Instance } from './generate-data';
import { columnsConfig } from './shared-configs';

import styles from './styles.scss';

type DemoContext = React.Context<
AppContextType<{
loading: boolean;
Expand Down Expand Up @@ -125,7 +127,7 @@ const COLUMN_DEFINITIONS: TableProps.ColumnDefinition<ExtendedInstance>[] = [
{
id: 'description-10',
header: 'Description',
cell: item => <Link href="#">Link: {item.description}</Link> || '-',
cell: item => <Link href="#">Link: {item.description || '-'}</Link>,
sortingField: 'description',
},
{
Expand Down Expand Up @@ -340,6 +342,23 @@ export default () => {
ariaLabels={{ ...ariaLabels, tableLabel: 'Inline editing table' }}
header={<Header>Large table with inline editing</Header>}
/>
<div className={styles['borderless-wrapper']}>
<Table
{...collectionProps}
variant="borderless"
data-test-id="borderless-table"
stickyColumns={{
first: parseInt(urlParams.stickyColumnsFirst || '0'),
last: parseInt(urlParams.stickyColumnsLast || '0'),
}}
{...urlParams}
ariaLabels={{ ...ariaLabels, tableLabel: 'Borderless table' }}
columnDefinitions={COLUMN_DEFINITIONS}
selectedItems={selectedItems}
onSelectionChange={({ detail: { selectedItems } }) => setSelectedItems(selectedItems)}
items={items}
/>
</div>
</SpaceBetween>
</ScreenshotArea>
);
Expand Down
9 changes: 9 additions & 0 deletions pages/table/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
@use '~design-tokens' as tokens;

.borderless-wrapper {
background-color: tokens.$color-background-status-warning;
}
4 changes: 2 additions & 2 deletions src/alert/__tests__/runtime-content.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ describe('asynchronous rendering', () => {
const message = `"${method}" called after component unmounted`;
expect(consoleWarnSpy).toBeCalledWith('[AwsUi]', '[alert-content-replacer]', message);
expect(sendPanoramaMetricSpy).toBeCalledWith({
eventName: 'awsui-runtime-api-warning',
eventContext: 'awsui-runtime-api-warning',
eventDetail: {
component: 'alert-content-replacer',
version: expect.any(String),
Expand Down Expand Up @@ -374,7 +374,7 @@ test('can only register a single provider', () => {
)
);
expect(sendPanoramaMetricSpy).toHaveBeenCalledWith({
eventName: 'awsui-runtime-api-warning',
eventContext: 'awsui-runtime-api-warning',
eventDetail: {
component: 'alert-flash-content',
version: expect.any(String),
Expand Down
11 changes: 10 additions & 1 deletion src/app-layout/__integ__/app-layout-drawers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { viewports } from './constants';
import { testIf } from './utils';

const wrapper = createWrapper().findAppLayout();
import vrDrawerStyles from '../../../lib/components/app-layout/visual-refresh/styles.selectors.js';
import vrToolbarDrawerStyles from '../../../lib/components/app-layout/visual-refresh-toolbar/drawer/styles.selectors.js';

class AppLayoutDrawersPage extends BasePageObject {
async openFirstDrawer() {
Expand Down Expand Up @@ -242,7 +244,14 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as const)('%s', theme =>
setupTest({ theme }, async page => {
await page.openFirstDrawer();
const resizeHandleBefore = await page.getResizeHandlePosition();
await page.elementScrollTo(wrapper.findActiveDrawer().toSelector(), { top: 100 });
const scrollableContainer =
theme === 'classic'
? wrapper.findActiveDrawer().toSelector()
: theme === 'refresh'
? `.${vrDrawerStyles['drawer-content-container']}`
: `.${vrToolbarDrawerStyles['drawer-content-container']}`;

await page.elementScrollTo(scrollableContainer, { top: 100 });
const resizeHandleAfter = await page.getResizeHandlePosition();
await expect(resizeHandleAfter).toEqual(resizeHandleBefore);
})
Expand Down
27 changes: 20 additions & 7 deletions src/app-layout/__integ__/app-layout-split-panel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import useBrowser from '@cloudscape-design/browser-test-tools/use-browser';
import createWrapper from '../../../lib/components/test-utils/selectors';
import { scrollbarThickness } from '../../__integ__/scrollbars';
import { viewports } from './constants';
import { AppLayoutSplitViewPage } from './utils';
import { AppLayoutSplitViewPage, getUrlParams } from './utils';

import mobileStyles from '../../../lib/components/app-layout/mobile-toolbar/styles.selectors.js';
import tableScrollbarStyles from '../../../lib/components/table/sticky-scrollbar/styles.selectors.js';

const scrollbarSelector = `.${tableScrollbarStyles['sticky-scrollbar-visible']}`;

const wrapper = createWrapper().findAppLayout();

Expand All @@ -19,11 +22,7 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as const)('%s', theme =>
return useBrowser(async browser => {
const page = new AppLayoutSplitViewPage(browser);
await page.setWindowSize(viewports.desktop);
const params = new URLSearchParams({
visualRefresh: `${theme.startsWith('refresh')}`,
appLayoutToolbar: `${theme === 'refresh-toolbar'}`,
});
await browser.url(`${url}?${params.toString()}`);
await browser.url(`${url}?${getUrlParams(theme)}`);
await page.waitForVisible(wrapper.findContentRegion().toSelector());
await testFn(page);
});
Expand Down Expand Up @@ -274,7 +273,7 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as const)('%s', theme =>
})
);

describe('interaction with table sticky header', () => {
describe('interaction with table sticky elements', () => {
// bottom padding is included into the offset in VR but not in classic
const splitPanelPadding = theme === 'refresh' ? 40 : 0;

Expand All @@ -298,5 +297,19 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as const)('%s', theme =>
await expect(page.getContentOffsetBottom(theme)).resolves.toEqual(windowHeight / 2 + splitPanelPadding + 'px');
}, '#/light/app-layout/with-full-page-table-and-split-panel')
);

test(
'bottom split panel does not block table sticky scrollbar',
setupTest(async page => {
// open tools panel to narrow the content area and display horizontal scroll on table
await page.click(wrapper.findToolsToggle().toSelector());
await expect(page.isClickable(scrollbarSelector)).resolves.toBe(true);
await page.click(wrapper.findSplitPanelOpenButton().toSelector());
await expect(
page.isDisplayedInViewport(wrapper.findSplitPanel().findOpenPanelBottom().toSelector())
).resolves.toBe(true);
await expect(page.isClickable(scrollbarSelector)).resolves.toBe(true);
}, '#/light/app-layout/with-sticky-table-and-split-panel')
);
});
});
15 changes: 13 additions & 2 deletions src/app-layout/__integ__/runtime-drawers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import createWrapper, { AppLayoutWrapper } from '../../../lib/components/test-ut
import { viewports } from './constants';
import { getUrlParams, Theme } from './utils';

import vrDrawerStyles from '../../../lib/components/app-layout/visual-refresh/styles.selectors.js';
import vrToolbarDrawerStyles from '../../../lib/components/app-layout/visual-refresh-toolbar/drawer/styles.selectors.js';

const wrapper = createWrapper().findAppLayout();
const findDrawerById = (wrapper: AppLayoutWrapper, id: string) => {
return wrapper.find(`[data-testid="awsui-app-layout-drawer-${id}"]`);
Expand Down Expand Up @@ -117,7 +120,14 @@ describe.each(['classic', 'refresh', 'refresh-toolbar'] as Theme[])('%s', theme
const getScrollPosition = () => page.getBoundingBox('[data-testid="drawer-sticky-header"]');
const scrollBefore = await getScrollPosition();

await page.elementScrollTo(wrapper.findActiveDrawer().toSelector(), { top: 100 });
const scrollableContainer =
theme === 'classic'
? wrapper.findActiveDrawer().toSelector()
: theme === 'refresh'
? `.${vrDrawerStyles['drawer-content-container']}`
: `.${vrToolbarDrawerStyles['drawer-content-container']}`;

await page.elementScrollTo(scrollableContainer, { top: 100 });
await expect(getScrollPosition()).resolves.toEqual(scrollBefore);
await expect(page.isDisplayed('[data-testid="drawer-sticky-header"]')).resolves.toBe(true);
})
Expand Down Expand Up @@ -316,7 +326,8 @@ describe('Visual refresh toolbar only', () => {
const getScrollPosition = () => page.getBoundingBox('[data-testid="drawer-sticky-header"]');
const scrollBefore = await getScrollPosition();

await page.elementScrollTo(wrapper.findActiveDrawer().toSelector(), { top: 100 });
const scrollableContainer = `.${vrToolbarDrawerStyles['drawer-content-container']}`;
await page.elementScrollTo(scrollableContainer, { top: 100 });
await expect(getScrollPosition()).resolves.toEqual(scrollBefore);
await expect(page.isDisplayed('[data-testid="drawer-sticky-header"]')).resolves.toBe(true);
})
Expand Down
30 changes: 30 additions & 0 deletions src/app-layout/visual-refresh-toolbar/compute-layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,36 @@ export function computeVerticalLayout({
return { toolbar, notifications, header, drawers };
}

interface SplitPanelOffsetInput {
hasSplitPanel: boolean;
placement: AppLayoutPropsWithDefaults['placement'];
splitPanelPosition: 'bottom' | 'side';
splitPanelOpen: boolean;
splitPanelHeaderHeight: number;
splitPanelFullHeight: number;
}

export function computeSplitPanelOffsets({
hasSplitPanel,
splitPanelPosition,
placement,
splitPanelOpen,
splitPanelFullHeight,
splitPanelHeaderHeight,
}: SplitPanelOffsetInput) {
if (!hasSplitPanel || splitPanelPosition !== 'bottom') {
return {
stickyVerticalBottomOffset: placement.insetBlockEnd,
mainContentPaddingBlockEnd: undefined,
};
}
const mainContentBottomOffset = splitPanelOpen ? splitPanelFullHeight : splitPanelHeaderHeight;
return {
stickyVerticalBottomOffset: mainContentBottomOffset + placement.insetBlockEnd,
mainContentPaddingBlockEnd: mainContentBottomOffset,
};
}

export function getDrawerStyles(
verticalOffsets: VerticalLayoutOutput,
isMobile: boolean,
Expand Down
Loading

0 comments on commit ecbc736

Please sign in to comment.