Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ exports[`CodeSnippet copy ranges renders as expected 1`] = `
aria-controls="radix-4"
aria-expanded="false"
aria-haspopup="dialog"
class="inline-block"
data-state="closed"
type="button"
>
Expand Down Expand Up @@ -392,6 +393,7 @@ exports[`CodeSnippet copy ranges renders as expected 1`] = `
aria-controls="radix-5"
aria-expanded="false"
aria-haspopup="dialog"
class="inline-block"
data-state="closed"
type="button"
>
Expand Down Expand Up @@ -628,6 +630,7 @@ exports[`CodeSnippet highlighted, no ranges, with onCopy callback renders as exp
aria-controls="radix-0"
aria-expanded="false"
aria-haspopup="dialog"
class="inline-block"
data-state="closed"
type="button"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,15 @@ exports[`CopyButton all props renders as expected 1`] = `
aria-controls="radix-4"
aria-expanded="false"
aria-haspopup="dialog"
class="inline-block"
data-state="closed"
type="button"
>
<button
class="px6 py6 btn btn--purple btn--stroke block"
<span
data-state="closed"
data-testid="foo"
type="button"
>
<svg
aria-hidden="true"
class="events-none icon"
data-testid="icon-clipboard"
focusable="false"
style="width: 18px; height: 18px;"
>
<use
xlink:href="#icon-clipboard"
xmlns:xlink="http://www.w3.org/1999/xlink"
/>
</svg>
<span
style="position: absolute; border: 0px; width: 1px; height: 1px; padding: 0px; margin: -1px; overflow: hidden; clip: rect(0px, 0px, 0px, 0px); white-space: nowrap; word-wrap: normal;"
>
clipboard
</span>
</button>
A custom child in place of the visual button
</span>
</div>
</span>
</div>
Expand All @@ -66,6 +48,7 @@ exports[`CopyButton basic renders as expected 1`] = `
aria-controls="radix-0"
aria-expanded="false"
aria-haspopup="dialog"
class="inline-block"
data-state="closed"
type="button"
>
Expand Down
4 changes: 4 additions & 0 deletions src/components/copy-button/copy-button.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ describe('CopyButton', () => {
className: 'px6 py6 btn btn--purple btn--stroke',
focusTrapPaused: true,
block: true,
tooltipTheme: 'dark',
children: (
<span>A custom child in place of the visual button</span>
),
passthroughProps: {
'data-testid': 'foo'
}
Expand Down
34 changes: 24 additions & 10 deletions src/components/copy-button/copy-button.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactElement, useState, useEffect, useCallback, HTMLAttributes} from 'react';
import React, { ReactElement, useState, useEffect, useCallback, HTMLAttributes, ReactNode} from 'react';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import Clipboard from 'clipboard/dist/clipboard.min.js';
Expand All @@ -14,6 +14,8 @@ interface Props {
block?: boolean;
focusTrapPaused?: boolean;
className?: string;
themeTooltip?: 'light' | 'dark';
children?: ReactNode;
passthroughProps?: HTMLAttributes<HTMLButtonElement>;
}

Expand All @@ -31,6 +33,8 @@ export default function CopyButton({
block = false,
focusTrapPaused,
className = 'btn btn--xs py3 px3 round',
children,
themeTooltip = 'light',
passthroughProps
}: Props): ReactElement {
const [clipboard, setClipboard] = useState(null);
Expand Down Expand Up @@ -98,6 +102,14 @@ export default function CopyButton({
block
});

const body = children ? children : <button
type="button"
className={buttonClasses}
{...passthroughProps}
>
<Icon name={iconName} />
</button>

// data-clipboard-text and the container ref are used by clipboard.js
// to copy text. Note that this wont have as nice a failure mode.
return (
Expand All @@ -112,23 +124,19 @@ export default function CopyButton({
<Popover
content={<div className="txt-s">Copied!</div>}
active={showingFeedback}
coloring={themeTooltip}
placement="top"
alignment="center"
hideWhenAnchorIsOffscreen={true}
padding="small"
>
<div>
<div className="inline-block">
<Tooltip
disabled={showingFeedback}
coloring={themeTooltip}
content="Copy"
>
<button
type="button"
className={buttonClasses}
{...passthroughProps}
>
<Icon name={iconName} />
</button>
{body}
</Tooltip>
</div>
</Popover>
Expand Down Expand Up @@ -169,7 +177,13 @@ CopyButton.propTypes = {
/**
* An object of props that you want to pass through to the `<button>`.
*/
passthroughProps: PropTypes.object
passthroughProps: PropTypes.object,
/**
* Either `'light'` or `'dark'`. This value is passed as the `coloring` prop found in Tooltip and Popover.
*/
themeTooltip: PropTypes.oneOf(['light', 'dark']),
/** Optional content to represent the button. */
children: PropTypes.node
};

CopyButton.isCopySupported = () => {
Expand Down
13 changes: 13 additions & 0 deletions src/components/copy-button/examples/copy-button-c.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
Optional child.
*/
import React from 'react';
import CopyButton from '../copy-button';

export default function Example() {
return (
<CopyButton themeTooltip="dark" text="Some copy from the custom element">
<button className="w240 btn">Just a custom element</button>
</CopyButton>
);
}