diff --git a/src/client/components/elements/CopyToClipboard/index.js b/src/client/components/elements/CopyToClipboard/index.js new file mode 100644 index 0000000000..226eec970f --- /dev/null +++ b/src/client/components/elements/CopyToClipboard/index.js @@ -0,0 +1,62 @@ +import React, { useEffect, useState, useRef } from 'react'; +import PropTypes from 'prop-types'; +import Copy from '../../icons/Copy'; +import Tooltip from '../Tooltip'; + +import './index.scss'; + +const baseClass = 'copy-to-clipboard'; + +const CopyToClipboard = ({ value }) => { + const ref = useRef(null); + const [copied, setCopied] = useState(false); + const [hovered, setHovered] = useState(false); + + useEffect(() => { + if (copied && !hovered) { + setTimeout(() => { + setCopied(false); + }, 1500); + } + }, [copied, hovered]); + + return ( + + ); +}; + +CopyToClipboard.propTypes = { + value: PropTypes.string.isRequired, +}; + +export default CopyToClipboard; diff --git a/src/client/components/elements/CopyToClipboard/index.scss b/src/client/components/elements/CopyToClipboard/index.scss new file mode 100644 index 0000000000..3adcc1d55b --- /dev/null +++ b/src/client/components/elements/CopyToClipboard/index.scss @@ -0,0 +1,35 @@ +@import '../../../scss/styles.scss'; + +.copy-to-clipboard { + @extend %btn-reset; + position: relative; + cursor: pointer; + vertical-align: middle; + + textarea { + position: absolute; + opacity: 0; + z-index: -1; + height: 0px; + width: 0px; + } + + .tooltip { + pointer-events: none; + opacity: 0; + visibility: hidden; + } + + &:focus, + &:active { + outline: none; + } + + &:hover { + .tooltip { + opacity: 1; + visibility: visible; + + } + } +} diff --git a/src/client/components/elements/Tooltip/index.scss b/src/client/components/elements/Tooltip/index.scss index 24494c7e99..3a1fa58652 100644 --- a/src/client/components/elements/Tooltip/index.scss +++ b/src/client/components/elements/Tooltip/index.scss @@ -6,7 +6,7 @@ z-index: 2; top: 0; left: 50%; - transform: translateX(-50%); + transform: translate3d(-50%, -120%, 0); padding: 0 base(.4); color: white; line-height: $baseline; diff --git a/src/client/components/icons/Copy/index.js b/src/client/components/icons/Copy/index.js new file mode 100644 index 0000000000..cd93673ae6 --- /dev/null +++ b/src/client/components/icons/Copy/index.js @@ -0,0 +1,27 @@ +import React from 'react'; + +import './index.scss'; + +const Copy = () => { + return ( + + ); +}; + +export default Copy; diff --git a/src/client/components/icons/Copy/index.scss b/src/client/components/icons/Copy/index.scss new file mode 100644 index 0000000000..ee2c4ad1f8 --- /dev/null +++ b/src/client/components/icons/Copy/index.scss @@ -0,0 +1,12 @@ +@import '../../../scss/styles'; + +.icon--copy { + height: $baseline; + width: $baseline; + + .stroke { + fill: none; + stroke: $color-dark-gray; + stroke-width: $style-stroke-width-s; + } +} diff --git a/src/client/components/views/collections/Edit/Default.js b/src/client/components/views/collections/Edit/Default.js index 9435ddc7fa..f3d558a7bb 100644 --- a/src/client/components/views/collections/Edit/Default.js +++ b/src/client/components/views/collections/Edit/Default.js @@ -8,6 +8,7 @@ import Form from '../../../forms/Form'; import PreviewButton from '../../../elements/PreviewButton'; import FormSubmit from '../../../forms/Submit'; import RenderFields from '../../../forms/RenderFields'; +import CopyToClipboard from '../../../elements/CopyToClipboard'; import * as fieldTypes from '../../../forms/field-types'; import './index.scss'; @@ -34,6 +35,8 @@ const DefaultEditView = (props) => { preview, } = collection; + const apiURL = `${serverURL}${api}/${slug}/${id}`; + return (