-
Notifications
You must be signed in to change notification settings - Fork 167
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Allow tab content to be retained in memory (#3233)
- Loading branch information
1 parent
1fe7f2c
commit b84fa40
Showing
6 changed files
with
220 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
import React, { useEffect, useState } from 'react'; | ||
|
||
import { FormField, Input } from '~components'; | ||
import SpaceBetween from '~components/space-between'; | ||
import Tabs, { TabsProps } from '~components/tabs'; | ||
|
||
import { IframeWrapper } from '../utils/iframe-wrapper'; | ||
|
||
const TabWithState = () => { | ||
const [value, setValue] = useState(''); | ||
return ( | ||
<FormField label="Input"> | ||
<Input value={value} onChange={e => setValue(e.detail.value)} /> | ||
</FormField> | ||
); | ||
}; | ||
|
||
const TabWithLoading = ({ id }: { id: string }) => { | ||
const [loaded, setLoaded] = useState(false); | ||
useEffect(() => { | ||
setTimeout(() => setLoaded(true), 1000); | ||
}, []); | ||
return <div id={id}>{loaded ? 'Loaded' : 'Loading...'}</div>; | ||
}; | ||
|
||
export default function TabsDemoPage() { | ||
const tabs: Array<TabsProps.Tab> = [ | ||
{ | ||
label: 'Tab with state', | ||
id: 'state', | ||
content: <TabWithState />, | ||
contentRenderStrategy: 'lazy', | ||
}, | ||
{ | ||
label: 'Tab with state (not retained)', | ||
id: 'state2', | ||
content: <TabWithState />, | ||
contentRenderStrategy: 'active', | ||
}, | ||
{ | ||
label: 'Lazy loading', | ||
id: 'lazy', | ||
content: <TabWithLoading id="loading-lazy" />, | ||
contentRenderStrategy: 'lazy', | ||
}, | ||
{ | ||
label: 'Eager loading', | ||
id: 'eager', | ||
content: <TabWithLoading id="loading-eager" />, | ||
contentRenderStrategy: 'eager', | ||
}, | ||
{ | ||
label: 'Eager loading iframe', | ||
id: 'eager-iframe', | ||
content: <IframeWrapper id="iframe" AppComponent={() => <TabWithState />} />, | ||
contentRenderStrategy: 'eager', | ||
}, | ||
]; | ||
return ( | ||
<> | ||
<h1>Tabs</h1> | ||
|
||
<SpaceBetween size="xs"> | ||
<div> | ||
<h2>Content render strategy</h2> | ||
<Tabs | ||
tabs={tabs} | ||
i18nStrings={{ scrollLeftAriaLabel: 'Scroll left', scrollRightAriaLabel: 'Scroll right' }} | ||
/> | ||
</div> | ||
</SpaceBetween> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
import { BasePageObject } from '@cloudscape-design/browser-test-tools/page-objects'; | ||
import useBrowser from '@cloudscape-design/browser-test-tools/use-browser'; | ||
|
||
import createWrapper from '../../../lib/components/test-utils/selectors'; | ||
|
||
const wrapper = createWrapper(); | ||
|
||
const setupTest = (testFn: (page: BasePageObject) => Promise<void>) => { | ||
return useBrowser(async browser => { | ||
const page = new BasePageObject(browser); | ||
await browser.url('#/light/tabs/content-render-strategy-integ'); | ||
await page.waitForVisible(wrapper.findTabs().findTabContent().toSelector()); | ||
await testFn(page); | ||
}); | ||
}; | ||
|
||
test( | ||
'strategy:eager tab content should already be available', | ||
setupTest(async page => { | ||
await expect(page.isExisting('#loading-eager')).resolves.toBeTruthy(); | ||
}) | ||
); | ||
test( | ||
'strategy:lazy tab content should load only when activated (but then remain)', | ||
setupTest(async page => { | ||
await expect(page.isExisting('#loading-lazy')).resolves.toBeFalsy(); | ||
await page.click(wrapper.findTabs().findTabLinkByIndex(3).toSelector()); | ||
await expect(page.isExisting('#loading-lazy')).resolves.toBeTruthy(); | ||
await page.click(wrapper.findTabs().findTabLinkByIndex(2).toSelector()); | ||
await expect(page.isExisting('#loading-lazy')).resolves.toBeTruthy(); | ||
}) | ||
); | ||
test( | ||
'strategy:eager tab state is retained when switching away and back', | ||
setupTest(async page => { | ||
const input = wrapper.findTabs().findTabContent().findInput().findNativeInput().toSelector(); | ||
await page.setValue(input, 'new value'); | ||
await expect(page.getValue(input)).resolves.toBe('new value'); | ||
await page.click(wrapper.findTabs().findTabLinkByIndex(3).toSelector()); | ||
await page.click(wrapper.findTabs().findTabLinkByIndex(1).toSelector()); | ||
await expect(page.getValue(input)).resolves.toBe('new value'); | ||
}) | ||
); | ||
test( | ||
'strategy:eager (iframe) tab state is retained when switching away and back', | ||
setupTest(async page => { | ||
const iframeInput = wrapper.findInput().findNativeInput().toSelector(); | ||
await page.click(wrapper.findTabs().findTabLinkByIndex(5).toSelector()); | ||
await page.runInsideIframe('iframe', true, async () => { | ||
await page.setValue(iframeInput, 'new value'); | ||
await expect(page.getValue(iframeInput)).resolves.toBe('new value'); | ||
}); | ||
await page.click(wrapper.findTabs().findTabLinkByIndex(3).toSelector()); | ||
await page.click(wrapper.findTabs().findTabLinkByIndex(5).toSelector()); | ||
await page.runInsideIframe('iframe', true, async () => { | ||
await expect(page.getValue(iframeInput)).resolves.toBe('new value'); | ||
}); | ||
}) | ||
); | ||
test( | ||
'strategy:active tab state is not retained when switching away and back', | ||
setupTest(async page => { | ||
const input = wrapper.findTabs().findTabContent().findInput().findNativeInput().toSelector(); | ||
await page.click(wrapper.findTabs().findTabLinkByIndex(2).toSelector()); | ||
await page.setValue(input, 'new value'); | ||
await expect(page.getValue(input)).resolves.toBe('new value'); | ||
await page.click(wrapper.findTabs().findTabLinkByIndex(3).toSelector()); | ||
await page.click(wrapper.findTabs().findTabLinkByIndex(2).toSelector()); | ||
await expect(page.getValue(input)).resolves.toBe(''); | ||
}) | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters