Skip to content

Commit 2182159

Browse files
authored
Merge branch 'master' into fix/newcomers-table-horizontal-scroll
2 parents b83b1bf + 1d74873 commit 2182159

1 file changed

Lines changed: 140 additions & 15 deletions

File tree

  • src/sections/Projects/Sistent/identity/color

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

Lines changed: 140 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from "react";
1+
import React, { useState, useCallback } from "react";
22
import { navigate } from "gatsby";
33
import { useLocation } from "@reach/router";
44
import { SistentLayout } from "../../sistent-layout";
@@ -378,7 +378,7 @@ const textColors = [
378378
{ "tokenName": "text-tertiary", "token": "theme.palette.text.tertiary", "Alias_of": "charcoal-60", "hex": "#8c999e", "role": "Second level text color to indicate lower prominence and establish visual hierarchy." },
379379
{ "tokenName": "text-inverse", "token": "theme.palette.text.inverse", "Alias_of": "charcoal-10", "hex": "#000d12", "role": "This text color is the polar opposite of the default text color in any theme." },
380380
{ "tokenName": "text-disabled", "token": "theme.palette.text.disabled", "Alias_of": "charcoal-50", "hex": "#647176", "role": "This text color is the polar opposite of the default text color in any theme." },
381-
{ "tokenName": "text-constant-white", "token": "theme.palette.text.constant.white", "Alias_of": "charcoal-100", "hex": "#fdfdfd", "role": "This text color remains constant across both themes and is used on surfaces that dont change as themes change." },
381+
{ "tokenName": "text-constant-white", "token": "theme.palette.text.constant.white", "Alias_of": "charcoal-100", "hex": "#fdfdfd", "role": "This text color remains constant across both themes and is used on surfaces that don't change as themes change." },
382382
{ "tokenName": "text-brand", "token": "theme.palette.text.brand", "Alias_of": "keppel-40", "hex": "#00b39f", "role": "Color for text relating to the brand." },
383383
{ "tokenName": "text-info", "token": "theme.palette.text.info", "Alias_of": "blue-40", "hex": "#2196f3", "role": "Color for text relating to notifications and information." },
384384
{ "tokenName": "text-success", "token": "theme.palette.text.success", "Alias_of": "green-40", "hex": "#36bc3b", "role": "Color for text relating to success." },
@@ -402,39 +402,164 @@ const componentColors = [
402402
];
403403

404404

405-
const CopyColor = ({ hex , token }) => {
406-
const [copyText, setCopyText] = useState("Copy");
405+
const CopyColor = ({ hex, token, copyValue }) => {
406+
const [copyState, setCopyState] = useState({
407+
text: "Copy",
408+
isCopied: false,
409+
isHovered: false
410+
});
407411

408-
const handleCopy = async () => {
409-
await copyToClipboard(hex || token);
410-
setCopyText("Copied");
411-
setTimeout(() => setCopyText("Copy"), 1000);
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;
412477
};
413478

414479
return (
415480
<CustomTooltip
416-
title={copyText === "Copied" ? "Copied" : "Copy"}
417-
enterDelay={800}
418-
leaveDelay={10}
481+
title={getTooltipTitle()}
482+
enterDelay={600}
483+
leaveDelay={100}
419484
placement="right"
420485
>
421486
<Box
487+
component="button"
488+
role="button"
489+
tabIndex={0}
490+
aria-label={`Copy ${getCopyValue()} to clipboard`}
422491
sx={{
423492
position: "relative",
424493
display: "inline-flex",
425494
alignItems: "center",
426495
cursor: "pointer",
427-
padding: "2px 4px",
428-
borderRadius: "3px",
429-
transition: "background-color 0.2s ease",
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",
430507
"&: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": {
431514
backgroundColor: (theme) =>
432515
theme.palette.action?.hover || "rgba(0, 0, 0, 0.04)",
516+
outline: "2px solid",
517+
outlineColor: (theme) => theme.palette.primary.main,
518+
outlineOffset: "2px",
433519
},
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+
}),
434544
}}
435545
onClick={handleCopy}
546+
onMouseEnter={handleMouseEnter}
547+
onMouseLeave={handleMouseLeave}
436548
>
437-
<span>{hex || token }</span>
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>
438563
</Box>
439564
</CustomTooltip>
440565
);

0 commit comments

Comments
 (0)