|
1 | 1 | import PropTypes from 'prop-types';
|
2 | 2 | import React, { useEffect, useRef, useState } from 'react';
|
3 | 3 | import Clipboard from 'clipboard';
|
4 |
| -import classNames from 'classnames'; |
5 | 4 | import { useTranslation } from 'react-i18next';
|
| 5 | +import styled from 'styled-components'; |
6 | 6 |
|
| 7 | +import { remSize, prop } from '../../../theme'; |
| 8 | +import Button from '../../../common/Button'; |
7 | 9 | import ShareIcon from '../../../images/share.svg';
|
8 | 10 |
|
| 11 | +const CopyableInputWrapper = styled.div` |
| 12 | + //.copyable-input |
| 13 | + padding-bottom: ${remSize(30)}; |
| 14 | + display: flex; |
| 15 | +
|
| 16 | + ${({ hasPreviewLink }) => |
| 17 | + hasPreviewLink && |
| 18 | + ` |
| 19 | + .copyable-input--with-preview & { |
| 20 | + border-radius: 2px 0 0 2px; |
| 21 | + } |
| 22 | + `} |
| 23 | +`; |
| 24 | + |
| 25 | +const CopyableInputValueContainer = styled.div` |
| 26 | + //.copyable-input__value-container |
| 27 | + position: relative; |
| 28 | + width: 100%; |
| 29 | +
|
| 30 | + &.tooltipped-no-delay { |
| 31 | + transition-delay: 0s; |
| 32 | + } |
| 33 | +
|
| 34 | + ${({ isCopied }) => |
| 35 | + isCopied && |
| 36 | + ` |
| 37 | + .tooltipped::after { |
| 38 | + background-color: ${prop('buttonBackgroundHoverColor')}; |
| 39 | + color: ${prop('button-hover-color')}; |
| 40 | + font-family: Montserrat, sans-serif; |
| 41 | + font-size: ${remSize(12)}; |
| 42 | + } |
| 43 | +
|
| 44 | + .tooltipped-n::before, |
| 45 | + .tooltipped::before { |
| 46 | + background-color: ${prop('buttonBackgroundHoverColor')}; |
| 47 | + color: ${prop('buttonBackgroundHoverColor')}; |
| 48 | + } |
| 49 | + `} |
| 50 | +`; |
| 51 | + |
| 52 | +const InputLabel = styled.label` |
| 53 | + //.copyable-input__label |
| 54 | + width: 100%; |
| 55 | + font-size: ${remSize(11)}; |
| 56 | + padding-bottom: ${remSize(5)}; |
| 57 | + color: ${prop('inactiveTextColor')}; |
| 58 | +`; |
| 59 | + |
| 60 | +const InputLabelContainer = styled.div` |
| 61 | + //.copyable-input__label-container |
| 62 | + width: 100%; |
| 63 | + font-size: ${remSize(11)}; |
| 64 | + padding-bottom: ${remSize(5)}; |
| 65 | + color: ${prop('inactiveTextColor')}; |
| 66 | +`; |
| 67 | + |
| 68 | +const InputField = styled.input` |
| 69 | + //.copyable-input__value |
| 70 | + width: 100%; |
| 71 | + font-size: ${remSize(16)}; |
| 72 | + .copyable-input--with-preview & { |
| 73 | + border-radius: 2px 0 0 2px; |
| 74 | + } |
| 75 | +`; |
| 76 | + |
| 77 | +const PreviewLink = styled(Button)` |
| 78 | + //.copyable-input__preview |
| 79 | + align-self: flex-end; |
| 80 | + border-radius: 0 2px 2px 0; |
| 81 | + padding: ${remSize(2)}; |
| 82 | +
|
| 83 | + & svg { |
| 84 | + height: ${remSize(30)}; |
| 85 | + width: ${remSize(30)}; |
| 86 | + } |
| 87 | +`; |
| 88 | + |
9 | 89 | const CopyableInput = ({ label, value, hasPreviewLink }) => {
|
10 | 90 | const { t } = useTranslation();
|
11 | 91 |
|
@@ -33,48 +113,37 @@ const CopyableInput = ({ label, value, hasPreviewLink }) => {
|
33 | 113 | }, [inputRef, setIsCopied]);
|
34 | 114 |
|
35 | 115 | return (
|
36 |
| - <div |
37 |
| - className={classNames( |
38 |
| - 'copyable-input', |
39 |
| - hasPreviewLink && 'copyable-input--with-preview' |
40 |
| - )} |
41 |
| - > |
42 |
| - <div |
43 |
| - className={classNames( |
44 |
| - 'copyable-input__value-container', |
45 |
| - 'tooltipped-no-delay', |
46 |
| - isCopied && 'tooltipped tooltipped-n' |
47 |
| - )} |
| 116 | + <CopyableInputWrapper hasPreviewLink={hasPreviewLink}> |
| 117 | + <CopyableInputValueContainer |
| 118 | + isCopied={isCopied} |
48 | 119 | aria-label={t('CopyableInput.CopiedARIA')}
|
49 | 120 | onMouseLeave={() => setIsCopied(false)}
|
| 121 | + className={`tooltipped-no-delay ${ |
| 122 | + isCopied ? 'tooltipped tooltipped-n' : '' |
| 123 | + }`} |
50 | 124 | >
|
51 |
| - <label |
52 |
| - className="copyable-input__label" |
53 |
| - htmlFor={`copyable-input__value-${label}`} |
54 |
| - > |
55 |
| - <div className="copyable-input__label-container">{label}</div> |
56 |
| - <input |
| 125 | + <InputLabel htmlFor={`copyable-input__value-${label}`}> |
| 126 | + <InputLabelContainer>{label}</InputLabelContainer> |
| 127 | + <InputField |
57 | 128 | type="text"
|
58 |
| - className="copyable-input__value" |
59 | 129 | id={`copyable-input__value-${label}`}
|
60 | 130 | value={value}
|
61 | 131 | ref={inputRef}
|
62 | 132 | readOnly
|
63 | 133 | />
|
64 |
| - </label> |
65 |
| - </div> |
| 134 | + </InputLabel> |
| 135 | + </CopyableInputValueContainer> |
66 | 136 | {hasPreviewLink && (
|
67 |
| - <a |
| 137 | + <PreviewLink |
68 | 138 | target="_blank"
|
69 | 139 | rel="noopener noreferrer"
|
70 | 140 | href={value}
|
71 |
| - className="copyable-input__preview" |
72 | 141 | aria-label={t('CopyableInput.CopiedARIA', { label })}
|
73 | 142 | >
|
74 | 143 | <ShareIcon focusable="false" aria-hidden="true" />
|
75 |
| - </a> |
| 144 | + </PreviewLink> |
76 | 145 | )}
|
77 |
| - </div> |
| 146 | + </CopyableInputWrapper> |
78 | 147 | );
|
79 | 148 | };
|
80 | 149 |
|
|
0 commit comments