Skip to content

Commit b2c1e43

Browse files
committed
Add button to copy example code
1 parent fa2df93 commit b2c1e43

File tree

5 files changed

+78
-10
lines changed

5 files changed

+78
-10
lines changed

src/components/Button/Button.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import { Link, useLocation } from 'react-router-dom';
33

44
type TButtonProps = {
55
children: React.ReactNode,
6+
title?: string,
67
clickHandler?: () => void,
78
url?: string,
89
active?: boolean
910
};
1011

11-
const Button: React.FC<TButtonProps> = ({ children, clickHandler, url, active = false }) => {
12+
const Button: React.FC<TButtonProps> = ({ children, title, clickHandler, url, active = false }) => {
1213

1314
const { pathname } = useLocation();
1415

@@ -21,6 +22,7 @@ const Button: React.FC<TButtonProps> = ({ children, clickHandler, url, active =
2122
url ?
2223
<Link
2324
to={url}
25+
title={title}
2426
className={`button ${isActive ? 'button--active' : ''}`}
2527
tabIndex={isActive ? -1 : 0}
2628
aria-current={isActive}
@@ -30,6 +32,7 @@ const Button: React.FC<TButtonProps> = ({ children, clickHandler, url, active =
3032
:
3133
<button
3234
type="button"
35+
title={title}
3336
className={`button ${isActive ? 'button--active' : ''}`}
3437
tabIndex={isActive ? -1 : 0}
3538
onClick={clickHandler}

src/components/HelperItem/HelperItem.sass

+22-5
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,30 @@
126126
margin-right: 0
127127

128128
&__header
129+
display: flex
130+
align-items: center
129131
margin: 0 0 12px 0
130-
font-weight: 400
131-
color: $color-grey
132-
font-size: 16px
133132

134-
@media(min-width: $width-mobile)
135-
font-size: 18px
133+
& .button
134+
margin-left: auto
135+
136+
& svg
137+
fill: $color-green-dark
138+
width: 12px
139+
height: 12px
140+
141+
@media(min-width: $width-mobile)
142+
width: 14px
143+
height: 14px
144+
145+
& h3
146+
margin: 0
147+
font-weight: 400
148+
color: $color-grey
149+
font-size: 16px
150+
151+
@media(min-width: $width-mobile)
152+
font-size: 18px
136153

137154
&__description code,
138155
&__example pre

src/components/HelperItem/HelperItem.tsx

+34-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import React, { useEffect } from 'react';
2+
import { useDispatch } from 'react-redux';
23
import { THelper } from '@services/Api';
4+
import copyText from '@utils/copyText';
35

46
import Anchor from '@components/Anchor';
57
import Tooltip from '@components/Tooltip';
8+
import Button from '@components/Button';
9+
import ActionCreator from '@store/actions';
610
import { AppRoutes, HelperLinks } from '@consts/const';
711

812
type THelperItemProps = {
@@ -12,6 +16,8 @@ type THelperItemProps = {
1216

1317
const HelperItem: React.FC<THelperItemProps> = ({helper, isOpen}) => {
1418

19+
const dispatch = useDispatch();
20+
1521
const codeLinesCount = (helper.usage.match(/\n/g)||[]).length + 1;
1622

1723
useEffect(() => {
@@ -24,6 +30,15 @@ const HelperItem: React.FC<THelperItemProps> = ({helper, isOpen}) => {
2430
} catch(e) {}
2531
}, []);
2632

33+
const copyClickHandler = (text: string) => {
34+
const isCopied = copyText(text);
35+
dispatch(ActionCreator.setInfoMessage({
36+
label: isCopied ? '😊' : '😭',
37+
text: isCopied ? 'Copied' : 'Doesn\'t copied'
38+
}));
39+
dispatch(ActionCreator.showMessage());
40+
};
41+
2742
return (
2843
<details className="helper" open={isOpen}>
2944
<summary>
@@ -54,7 +69,9 @@ const HelperItem: React.FC<THelperItemProps> = ({helper, isOpen}) => {
5469
</div>
5570
</div>
5671
<div className="helper__column">
57-
<h3 className="helper__header">What it used for?</h3>
72+
<div className="helper__header">
73+
<h3>What it used for?</h3>
74+
</div>
5875
<p
5976
className="helper__description"
6077
dangerouslySetInnerHTML={
@@ -66,7 +83,9 @@ const HelperItem: React.FC<THelperItemProps> = ({helper, isOpen}) => {
6683
</p>
6784
{ helper.demo &&
6885
<>
69-
<h3 className="helper__header">How it works?</h3>
86+
<div className="helper__header">
87+
<h3>How it works?</h3>
88+
</div>
7089
<a className="helper__demo" href={`${HelperLinks.DEMO}/${helper.demo}`} target="_blank" rel="noreferrer">
7190
<img src={`${HelperLinks.DEMO}/${helper.demo}`} alt="demo" />
7291
<svg width="18" height="18">
@@ -78,9 +97,20 @@ const HelperItem: React.FC<THelperItemProps> = ({helper, isOpen}) => {
7897
</div>
7998
</div>
8099
<div className="helper__example">
81-
<h3 className="helper__header">How to use it?</h3>
100+
<div className="helper__header">
101+
<h3>How to use it?</h3>
102+
{
103+
helper.usage
104+
&&
105+
<Button title="Copy example code" clickHandler={() => copyClickHandler(helper.usage)}>
106+
<svg width="14" height="14">
107+
<use xlinkHref="#copy" />
108+
</svg>
109+
</Button>
110+
}
111+
</div>
82112
{
83-
helper.usage.length
113+
helper.usage
84114
?
85115
<pre>
86116
<div className="helper__code-lines">

src/components/SvgSprite/SvgSprite.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ const SvgSprite: React.FC = () => (
2525
<symbol id="question" viewBox="0 0 24 24">
2626
<path d="M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm1.25 17c0 .69-.559 1.25-1.25 1.25-.689 0-1.25-.56-1.25-1.25s.561-1.25 1.25-1.25c.691 0 1.25.56 1.25 1.25zm1.393-9.998c-.608-.616-1.515-.955-2.551-.955-2.18 0-3.59 1.55-3.59 3.95h2.011c0-1.486.829-2.013 1.538-2.013.634 0 1.307.421 1.364 1.226.062.847-.39 1.277-.962 1.821-1.412 1.343-1.438 1.993-1.432 3.468h2.005c-.013-.664.03-1.203.935-2.178.677-.73 1.519-1.638 1.536-3.022.011-.924-.284-1.719-.854-2.297z"/>
2727
</symbol>
28+
<symbol id="copy" viewBox="0 0 24 24">
29+
<path d="M16 10c3.469 0 2 4 2 4s4-1.594 4 2v6h-10v-12h4zm.827-2h-6.827v16h14v-8.842c0-2.392-4.011-7.158-7.173-7.158zm-8.827 12h-6v-16h4l2.102 2h3.898l2-2h4v2.145c.656.143 1.327.391 2 .754v-4.899h-3c-1.229 0-2.18-1.084-3-2h-8c-.82.916-1.771 2-3 2h-3v20h8v-2zm2-18c.553 0 1 .448 1 1s-.447 1-1 1-1-.448-1-1 .447-1 1-1zm4 18h6v-1h-6v1zm0-2h6v-1h-6v1zm0-2h6v-1h-6v1z"/>
30+
</symbol>
2831
</svg>
2932
</div>
3033
);

src/utils/copyText.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const copyText = (text: string): boolean => {
2+
let isCopied = false;
3+
const tempInput = document.createElement('textarea');
4+
tempInput.innerHTML = text;
5+
document.body.appendChild(tempInput);
6+
tempInput.select();
7+
try {
8+
isCopied = document.execCommand('copy');
9+
// eslint-disable-next-line no-empty
10+
} catch (err) {}
11+
document.body.removeChild(tempInput);
12+
return isCopied;
13+
};
14+
15+
export default copyText;

0 commit comments

Comments
 (0)