cauldron
cauldron copied to clipboard
Add "Copy" button to cauldron
Copy button is a component that accepts an optional Cauldron Button variant (defaulting to tertiary) to render an in interactive element to copy a specified string of text.
Interface
interface CopyButtonProps extends React.ComponentProps<typeof Button> {
value: string
children?: ContentNode
notificationLabel?: ContentNode
hideVisibleLabel?: boolean
tooltipPlacement?: React.ComponentProps<typeof Tooltip>['placement']
variant?: Extract<typeof Button, 'primary' | 'secondary' | 'tertiary'>
onCopy?: (text: string) => void
}
variantshould default to the Button variant,tertiarychildrenshould default to the string, CopynotificationLabelshould default to the string, CopiedtooltipPlacementoptional prop to position the tooltip
Implementation
By default, the Button will have a visible label that will be displayed with children. When hideVisibleLabel is set, children should be wrapped in an Offscreen component with a tooltip displayed instead.
When the button is clicked, the text should be copied to the clipboard with a visible notification and offscreen aria-live notification using the notificationLabel text.
The existing copy icon should be updated to match the one from the design.
Notification
When copied, a temporary notification should be visible to indicate a successful copy. This includes the following sequence:
- Display a tooltip with the value of
notificationLabel - Icon changes to icon
check-solid - An
aria-live="polite"announcement should occur with the value ofnotificationLabel
After 2s, all of the original content can revert back to its original state.
[!NOTE] The tooltip that appears for when the label is visible or hidden via
hideVisibleLabelshould always have anaria-associationofnone. The button should always have an explicit accessible name that doesn't change, so it's unnecessary to associate the accessible name or accessible description with the tooltip.
Usage
This component is essentially a thin polymorphic wrapper around <Button> to add additional copy functionality.
<CopyButton
value="Text to Copy"
onCopy={...}
>
Copy to Clipboard
</CopyButton>
Rather than using a polymorphic component (e.g. as), I think passing a child would be simpler, similar to an internal component we have in another project I could show you. Thoughts?
@thuey I would like to see it. I was primarily thinking of a polymorphic component for 2 reasons:
- Allowing for a standard implementation to be rendered without needing to be concerned with the inner children / polymorphic
- Ensuring that internal events were directly bound to the element as opposed to using event delegation
I think there's pros/cons to both methods so I guess it would be good to weigh them and see where we land.
For an example of copy functionality, look at the existing CopyToClipboardButton component for Cauldron docs: https://github.com/dequelabs/cauldron/blob/develop/docs/components/CopyToClipboardButton.tsx