Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Add renderWithPortal API to CopyToClipboard component #2445

Closed
wants to merge 1 commit into from
Closed
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
1 change: 1 addition & 0 deletions pages/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ function isAppLayoutPage(pageId?: string) {
'grid-navigation-custom',
'expandable-rows-test',
'container/sticky-permutations',
'copy-to-clipboard/scenario-split-panel',
];
return pageId !== undefined && appLayoutPages.some(match => pageId.includes(match));
}
Expand Down
123 changes: 123 additions & 0 deletions pages/copy-to-clipboard/scenario-split-panel.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React from 'react';
import AppLayout from '~components/app-layout';
import SplitPanel from '~components/split-panel';
import ScreenshotArea from '../utils/screenshot-area';
import { Breadcrumbs, Navigation } from '../app-layout/utils/content-blocks';
import labels from '../app-layout/utils/labels';
import CopyToClipboard from '~components/copy-to-clipboard';
import Header from '~components/header';
import SpaceBetween from '~components/space-between';
import Container from '~components/container';

export default function () {
return (
<ScreenshotArea gutters={false}>
<AppLayout
ariaLabels={labels}
breadcrumbs={<Breadcrumbs />}
navigation={<Navigation />}
toolsHide={true}
splitPanelOpen={true}
splitPanel={
<SplitPanel
header="Split panel header"
i18nStrings={{
preferencesTitle: 'Preferences',
preferencesPositionLabel: 'Split panel position',
preferencesPositionDescription: 'Choose the default split panel position for the service.',
preferencesPositionSide: 'Side',
preferencesPositionBottom: 'Bottom',
preferencesConfirm: 'Confirm',
preferencesCancel: 'Cancel',
closeButtonAriaLabel: 'Close panel',
openButtonAriaLabel: 'Open panel',
resizeHandleAriaLabel: 'Slider',
}}
>
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Augue neque gravida in fermentum. Suspendisse sed nisi lacus sed viverra tellus in
hac. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Lectus proin nibh nisl condimentum id
venenatis. Penatibus et magnis dis parturient montes nascetur ridiculus mus mauris. Nisi porta lorem
mollis aliquam ut porttitor leo a. Facilisi morbi tempus iaculis urna. Odio tempor orci dapibus ultrices
in iaculis nunc.
</p>
<CopyToClipboard
copyButtonText="Copy dummy text"
copyErrorText="Dumym text failed to copy"
copySuccessText="Dumy text copied"
textToCopy="Pharetra et ultrices neque ornare"
/>
<p>
Ut diam quam nulla porttitor massa id neque. Duis at tellus at urna condimentum mattis pellentesque id
nibh. Metus vulputate eu scelerisque felis imperdiet proin fermentum.
</p>
<p>
Orci porta non pulvinar neque laoreet suspendisse interdum consectetur libero. Varius quam quisque id
diam vel. Risus viverra adipiscing at in. Orci sagittis eu volutpat odio facilisis mauris. Mauris vitae
ultricies leo integer malesuada nunc. Sem et tortor consequat id porta nibh. Semper auctor neque vitae
tempus quam pellentesque.
</p>
<p>
Pharetra et ultrices neque ornare. Bibendum neque egestas congue quisque egestas diam in arcu cursus.
Porttitor eget dolor morbi non arcu risus quis. Integer quis auctor elit sed vulputate mi sit. Mauris
nunc congue nisi vitae suscipit tellus mauris a diam. Diam donec adipiscing tristique risus nec feugiat
in. Arcu felis bibendum ut tristique et egestas quis. Nulla porttitor massa id neque aliquam vestibulum
morbi blandit. In hac habitasse platea dictumst quisque sagittis. Sollicitudin tempor id eu nisl nunc mi
ipsum.
</p>
<p>
Ut diam quam nulla porttitor massa id neque. Duis at tellus at urna condimentum mattis pellentesque id
nibh. Metus vulputate eu scelerisque felis imperdiet proin fermentum.
</p>
<p>
Ornare aenean euismod elementum nisi quis. Elementum curabitur vitae nunc sed velit dignissim sodales.
Amet tellus cras adipiscing enim eu. Id interdum velit laoreet id donec ultrices tincidunt. Ullamcorper
eget nulla facilisi etiam. Sodales neque sodales ut etiam sit amet nisl purus. Auctor urna nunc id
cursus metus aliquam eleifend mi in. Urna condimentum mattis pellentesque id. Porta lorem mollis aliquam
ut porttitor leo a. Lectus quam id leo in vitae turpis massa sed. Pharetra pharetra massa massa
ultricies mi.
</p>
<p>
Pharetra et ultrices neque ornare. Bibendum neque egestas congue quisque egestas diam in arcu cursus.
Porttitor eget dolor morbi non arcu risus quis. Integer quis auctor elit sed vulputate mi sit. Mauris
nunc congue nisi vitae suscipit tellus mauris a diam. Diam donec adipiscing tristique risus nec feugiat
in. Arcu felis bibendum ut tristique et egestas quis. Nulla porttitor massa id neque aliquam vestibulum
morbi blandit. In hac habitasse platea dictumst quisque sagittis. Sollicitudin tempor id eu nisl nunc mi
ipsum. Ornare aenean euismod elementum nisi quis. Elementum curabitur vitae nunc sed velit dignissim
sodales. Amet tellus cras adipiscing enim eu. Id interdum velit laoreet id donec ultrices tincidunt.
Ullamcorper eget nulla facilisi etiam. Sodales neque sodales ut etiam sit amet nisl purus. Auctor urna
nunc id cursus metus aliquam eleifend mi in. Urna condimentum mattis pellentesque id. Porta lorem mollis
aliquam ut porttitor leo a. Lectus quam id leo in vitae turpis massa sed. Pharetra pharetra massa massa
ultricies mi.
</p>
<div data-testid="scroll-me">The end</div>
</div>
</SplitPanel>
}
content={
<div>
<SpaceBetween size="l">
<Header variant="h1" description="Basic demo with split panel">
Demo page copy-to-clipboard inside split panel
</Header>
<Container header={<Header variant="h2">Demo container</Header>}>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Augue neque gravida in fermentum. Suspendisse sed nisi lacus sed viverra tellus
in hac. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Lectus proin nibh nisl
condimentum id venenatis. Penatibus et magnis dis parturient montes nascetur ridiculus mus mauris.
Nisi porta lorem mollis aliquam ut porttitor leo a. Facilisi morbi tempus iaculis urna. Odio tempor
orci dapibus ultrices in iaculis nunc.
</p>
</Container>
</SpaceBetween>
</div>
}
/>
</ScreenshotArea>
);
}
11 changes: 11 additions & 0 deletions src/__tests__/__snapshots__/documenter.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5764,6 +5764,17 @@ use the \`id\` attribute, consider setting it on a parent element instead.",
"optional": true,
"type": "string",
},
Object {
"defaultValue": "false",
"description": "By default, the popover is constrained to fit inside its parent
[stacking context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context).
Enabling this property will allow the popover to be rendered in the root stack context using
[React Portals](https://reactjs.org/docs/portals.html).
Enable this setting if you need the popover to ignore its parent stacking context.",
"name": "popoverRenderWithPortal",
"optional": true,
"type": "boolean",
},
Object {
"description": "The text content to be copied. It is displayed next to the copy button when \`variant=\\"inline\\"\`, and is not shown otherwise.",
"name": "textToCopy",
Expand Down
15 changes: 13 additions & 2 deletions src/copy-to-clipboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,24 @@ import { getExternalProps } from '../internal/utils/external-props';

export { CopyToClipboardProps };

export default function CopyToClipboard({ variant = 'button', ...restProps }: CopyToClipboardProps) {
export default function CopyToClipboard({
variant = 'button',
popoverRenderWithPortal = false,
...restProps
}: CopyToClipboardProps) {
const baseProps = useBaseComponent('CopyToClipboard', {
props: { variant },
});
const filteredProps = getExternalProps(restProps);

return <InternalCopyToClipboard variant={variant} {...baseProps} {...filteredProps} />;
return (
<InternalCopyToClipboard
variant={variant}
popoverRenderWithPortal={popoverRenderWithPortal}
{...baseProps}
{...filteredProps}
/>
);
}

applyDisplayName(CopyToClipboard, 'CopyToClipboard');
9 changes: 9 additions & 0 deletions src/copy-to-clipboard/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ export interface CopyToClipboardProps extends BaseComponentProps {
* The message shown when the text is not copied due to an error, see [https://w3c.github.io/clipboard-apis/#dom-clipboard-writetext](https://w3c.github.io/clipboard-apis/#dom-clipboard-writetext).
*/
copyErrorText: string;

/**
* By default, the popover is constrained to fit inside its parent
* [stacking context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context).
* Enabling this property will allow the popover to be rendered in the root stack context using
* [React Portals](https://reactjs.org/docs/portals.html).
* Enable this setting if you need the popover to ignore its parent stacking context.
*/
popoverRenderWithPortal?: boolean;
}

export namespace CopyToClipboardProps {
Expand Down
3 changes: 2 additions & 1 deletion src/copy-to-clipboard/internal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default function InternalCopyToClipboard({
copySuccessText,
copyErrorText,
textToCopy,
popoverRenderWithPortal,
__internalRootRef = null,
...restProps
}: InternalCopyToClipboardProps) {
Expand Down Expand Up @@ -64,7 +65,7 @@ export default function InternalCopyToClipboard({
position="top"
triggerType="custom"
dismissButton={false}
renderWithPortal={true}
renderWithPortal={popoverRenderWithPortal}
content={<InternalStatusIndicator type={status}>{statusText}</InternalStatusIndicator>}
>
<InternalButton
Expand Down
6 changes: 2 additions & 4 deletions src/test-utils/dom/copy-to-clipboard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ export default class CopyToClipboardWrapper extends ComponentWrapper {
return this.findComponent(`.${ButtonWrapper.rootSelector}`, ButtonWrapper)!;
}

findStatusText(): null | ElementWrapper {
return this.findComponent(`.${PopoverWrapper.rootSelector}`, PopoverWrapper)!.findContent({
renderWithPortal: true,
});
findStatusText(options = { renderWithPortal: false }): null | ElementWrapper {
return this.findComponent(`.${PopoverWrapper.rootSelector}`, PopoverWrapper)!.findContent(options);
}

findTextToCopy(): null | ElementWrapper {
Expand Down
Loading