Skip to content

Commit 256134f

Browse files
authored
Merge pull request #6920 from Fireentity/fix/6856-sistent-copy-keeps-selection
Fix/6856 sistent copy keeps selection
2 parents ba5459f + 9d1ae06 commit 256134f

4 files changed

Lines changed: 101 additions & 266 deletions

File tree

src/components/CopyValue/index.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import React, { useCallback, useState } from "react";
2+
import { copyToClipboard } from "../CodeBlock/copy-to-clipboard";
3+
import { Box, CustomTooltip } from "@sistent/sistent";
4+
5+
const CopyValue = ({ copyValue }) => {
6+
const [copyState, setCopyState] = useState({
7+
isCopied: false
8+
});
9+
10+
const handleCopy = useCallback(async () => {
11+
await copyToClipboard(copyValue);
12+
13+
setCopyState({
14+
isCopied: true,
15+
});
16+
17+
setTimeout(() => {
18+
setCopyState({
19+
isCopied: false,
20+
});
21+
}, 2000);
22+
}, [copyValue]);
23+
24+
25+
const getTooltipTitle = () => {
26+
if (copyState.isCopied) {
27+
return "Copied";
28+
}
29+
return "Click to copy to clipboard";
30+
};
31+
32+
return (
33+
<CustomTooltip
34+
title={getTooltipTitle()}
35+
enterDelay={600}
36+
leaveDelay={100}
37+
placement="right"
38+
>
39+
<Box
40+
component="button"
41+
role="button"
42+
tabIndex={0}
43+
aria-label={`Copy ${copyValue} to clipboard`}
44+
sx={{
45+
display: "inline-flex",
46+
alignItems: "center",
47+
cursor: "pointer",
48+
padding: "4px 8px",
49+
borderRadius: "4px",
50+
background: "transparent",
51+
fontFamily: "monospace",
52+
fontSize: "0.875rem",
53+
color: (theme) => theme.palette.text.primary,
54+
transition: "all 0.2s ease-in-out",
55+
outline: "none",
56+
border: "2px solid",
57+
width: "fit-content",
58+
minWidth: "200px",
59+
borderColor: "transparent",
60+
boxShadow: "none",
61+
"&:hover, &:focus, &:active": {
62+
backgroundColor: (theme) => theme.palette.action.hover,
63+
boxShadow: "none",
64+
},
65+
"&:focus, &:active": {
66+
borderColor: (theme) => theme.palette.primary.main,
67+
boxShadow: "none",
68+
},
69+
...(copyState.isCopied && {
70+
borderColor: (theme) => theme.palette.primary.main,
71+
backgroundColor: (theme) => theme.palette.action.hover,
72+
}),
73+
}}
74+
onClick={handleCopy}
75+
>
76+
<span>{copyValue}</span>
77+
</Box>
78+
</CustomTooltip>
79+
);
80+
};
81+
82+
export default CopyValue;

src/sections/Projects/Sistent/identity/color/code.js

Lines changed: 10 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import React, { useState, useCallback } from "react";
1+
import React from "react";
22
import { navigate } from "gatsby";
33
import { useLocation } from "@reach/router";
44
import { SistentLayout } from "../../sistent-layout";
55
import { Col, Row } from "../../../../../reusecore/Layout";
66
import Button from "../../../../../reusecore/Button";
77
import { useStyledDarkMode } from "../../../../../theme/app/useStyledDarkMode";
88

9-
import { styled, Table, TableContainer, TableCell, TableRow, TableHead, TableBody, SistentThemeProvider, CustomTooltip, Box, } from "@sistent/sistent";
10-
import { copyToClipboard } from "../../../../../components/CodeBlock/copy-to-clipboard.js";
9+
import { styled, Table, TableContainer, TableCell, TableRow, TableHead, TableBody, SistentThemeProvider } from "@sistent/sistent";
10+
import CopyValue from "../../../../../components/CopyValue";
1111

1212
const brandColors = [
1313
{ tokenName: "keppel-70", token: "theme.palette.brand.default", name: "Keppel", hex: "#DAf3EB" },
@@ -401,170 +401,6 @@ const componentColors = [
401401
{ tokenName: "icon-disabled", token: "theme.palette.icon.disabled", Alias_of: "charcoal-50", hex: "#647176", role: "Color for icon components." },
402402
];
403403

404-
405-
const CopyColor = ({ hex, token, copyValue }) => {
406-
const [copyState, setCopyState] = useState({
407-
text: "Copy",
408-
isCopied: false,
409-
isHovered: false
410-
});
411-
412-
const handleCopy = useCallback(async () => {
413-
try {
414-
const valueToCopy = copyValue || hex || token;
415-
await copyToClipboard(valueToCopy);
416-
417-
setCopyState({
418-
text: "Copied!",
419-
isCopied: true,
420-
isHovered: false
421-
});
422-
423-
setTimeout(() => {
424-
setCopyState({
425-
text: "Copy",
426-
isCopied: false,
427-
isHovered: false
428-
});
429-
}, 2000);
430-
} catch (error) {
431-
console.error("Failed to copy to clipboard:", error);
432-
setCopyState({
433-
text: "Failed",
434-
isCopied: false,
435-
isHovered: false
436-
});
437-
438-
setTimeout(() => {
439-
setCopyState({
440-
text: "Copy",
441-
isCopied: false,
442-
isHovered: false
443-
});
444-
}, 1500);
445-
}
446-
}, [copyValue, hex, token]);
447-
448-
const handleMouseEnter = useCallback(() => {
449-
if (!copyState.isCopied) {
450-
setCopyState(prev => ({
451-
...prev,
452-
isHovered: true
453-
}));
454-
}
455-
}, [copyState.isCopied]);
456-
457-
const handleMouseLeave = useCallback(() => {
458-
setCopyState(prev => ({
459-
...prev,
460-
isHovered: false
461-
}));
462-
}, []);
463-
464-
465-
const getTooltipTitle = () => {
466-
if (copyState.isCopied) {
467-
return "Copied";
468-
}
469-
if (copyState.text === "Failed") {
470-
return "Failed to copy. Try again.";
471-
}
472-
return "Click to copy to clipboard";
473-
};
474-
475-
const getCopyValue = () => {
476-
return copyValue || hex || token;
477-
};
478-
479-
return (
480-
<CustomTooltip
481-
title={getTooltipTitle()}
482-
enterDelay={600}
483-
leaveDelay={100}
484-
placement="right"
485-
>
486-
<Box
487-
component="button"
488-
role="button"
489-
tabIndex={0}
490-
aria-label={`Copy ${getCopyValue()} to clipboard`}
491-
sx={{
492-
position: "relative",
493-
display: "inline-flex",
494-
alignItems: "center",
495-
cursor: "pointer",
496-
padding: "4px 8px",
497-
borderRadius: "4px",
498-
border: "none",
499-
background: "transparent",
500-
fontFamily: "monospace",
501-
fontSize: "0.875rem",
502-
color: (theme) => theme.palette.text.primary,
503-
transition: "all 0.2s ease-in-out",
504-
outline: "none",
505-
width: "fit-content",
506-
minWidth: "200px",
507-
"&:hover": {
508-
backgroundColor: (theme) =>
509-
!copyState.isCopied && (theme.palette.action?.hover || "rgba(0, 0, 0, 0.04)"),
510-
transform: !copyState.isCopied ? "translateY(-1px)" : "none",
511-
boxShadow: !copyState.isCopied ? "0 2px 4px rgba(0, 0, 0, 0.1)" : "none",
512-
},
513-
"&:focus": {
514-
backgroundColor: (theme) =>
515-
theme.palette.action?.hover || "rgba(0, 0, 0, 0.04)",
516-
outline: "2px solid",
517-
outlineColor: (theme) => theme.palette.primary.main,
518-
outlineOffset: "2px",
519-
},
520-
"&:active": {
521-
transform: "translateY(0)",
522-
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.1)",
523-
},
524-
...(copyState.isCopied && {
525-
border: "2px solid",
526-
borderColor: (theme) => theme.palette.success.main,
527-
backgroundColor: "transparent",
528-
"&:hover": {
529-
backgroundColor: "transparent",
530-
transform: "none",
531-
boxShadow: "none",
532-
}
533-
}),
534-
...(copyState.text === "Failed" && {
535-
border: "2px solid",
536-
borderColor: (theme) => theme.palette.error.main,
537-
backgroundColor: "transparent",
538-
"&:hover": {
539-
backgroundColor: "transparent",
540-
transform: "none",
541-
boxShadow: "none",
542-
}
543-
}),
544-
}}
545-
onClick={handleCopy}
546-
onMouseEnter={handleMouseEnter}
547-
onMouseLeave={handleMouseLeave}
548-
>
549-
<span>{getCopyValue()}</span>
550-
<Box
551-
component="span"
552-
sx={{
553-
marginLeft: "4px",
554-
fontSize: "0.75rem",
555-
opacity: 0,
556-
visibility: "hidden",
557-
width: "0px",
558-
overflow: "hidden",
559-
}}
560-
>
561-
{copyState.text}
562-
</Box>
563-
</Box>
564-
</CustomTooltip>
565-
);
566-
};
567-
568404
const PreviewBox = styled("div")(({ theme, bgcolor }) => ({
569405
backgroundColor: bgcolor,
570406
width: "2.6rem",
@@ -754,7 +590,7 @@ const ColorCode = () => {
754590
<StyledTableCell>{col.name}</StyledTableCell>
755591
<StyledTableCell>{col.hex}</StyledTableCell>
756592
<StyledTableCell sx={{ fontFamily: "monospace" }}>
757-
<CopyColor hex={col.token} />
593+
<CopyValue copyValue={col.token} />
758594
</StyledTableCell>
759595
<StyledTableCell align="center">
760596
<PreviewBox bgcolor={col.hex} />
@@ -791,7 +627,7 @@ const ColorCode = () => {
791627
<StyledTableCell>{col.name}</StyledTableCell>
792628
<StyledTableCell>{col.hex}</StyledTableCell>
793629
<StyledTableCell sx={{ fontFamily: "monospace" }}>
794-
<CopyColor hex={col.token} />
630+
<CopyValue copyValue={col.token} />
795631
</StyledTableCell>
796632
<StyledTableCell align="center">
797633
<PreviewBox bgcolor={col.hex} />
@@ -829,7 +665,7 @@ const ColorCode = () => {
829665
<StyledTableCell>{col.name}</StyledTableCell>
830666
<StyledTableCell>{col.hex}</StyledTableCell>
831667
<StyledTableCell sx={{ fontFamily: "monospace" }}>
832-
<CopyColor hex={col.token} />
668+
<CopyValue copyValue={col.token} />
833669
</StyledTableCell>
834670
<StyledTableCell align="center">
835671
<PreviewBox bgcolor={col.hex} />
@@ -876,7 +712,7 @@ const ColorCode = () => {
876712
<StyledTableCell>{col.Alias_of}</StyledTableCell>
877713
<StyledTableCell>{col.hex}</StyledTableCell>
878714
<StyledTableCell sx={{ fontFamily: "monospace" }}>
879-
<CopyColor hex={col.token} />
715+
<CopyValue copyValue={col.token} />
880716
</StyledTableCell>
881717
<StyledTableCell align="center">
882718
<PreviewBox bgcolor={col.hex} />
@@ -916,7 +752,7 @@ const ColorCode = () => {
916752
<StyledTableCell>{col.Alias_of}</StyledTableCell>
917753
<StyledTableCell>{col.hex}</StyledTableCell>
918754
<StyledTableCell sx={{ fontFamily: "monospace" }}>
919-
<CopyColor hex={col.token} />
755+
<CopyValue copyValue={col.token} />
920756
</StyledTableCell>
921757
<StyledTableCell align="center">
922758
<PreviewTextBox tokenName={col.tokenName} >Aa</PreviewTextBox>
@@ -956,7 +792,7 @@ const ColorCode = () => {
956792
<StyledTableCell>{col.Alias_of}</StyledTableCell>
957793
<StyledTableCell>{col.hex}</StyledTableCell>
958794
<StyledTableCell sx={{ fontFamily: "monospace" }}>
959-
<CopyColor hex={col.token} />
795+
<CopyValue copyValue={col.token} />
960796
</StyledTableCell>
961797
<StyledTableCell align="center">
962798
<PreviewBorderBox tokenName={col.tokenName} />
@@ -1001,7 +837,7 @@ const ColorCode = () => {
1001837
<StyledTableCell>{col.Alias_of}</StyledTableCell>
1002838
<StyledTableCell>{col.hex}</StyledTableCell>
1003839
<StyledTableCell sx={{ fontFamily: "monospace" }}>
1004-
<CopyColor hex={col.token} />
840+
<CopyValue copyValue={col.token} />
1005841
</StyledTableCell>
1006842
<StyledTableCell align="center">
1007843
<PreviewBox bgcolor={col.hex} />

0 commit comments

Comments
 (0)