@greatapps/common 1.1.78 → 1.1.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ui/buttons/CopyButton.mjs +3 -0
- package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
- package/dist/hooks/copy-to-clipboard.hook.mjs +13 -1
- package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/ui/buttons/CopyButton.tsx +5 -0
- package/src/hooks/copy-to-clipboard.hook.tsx +14 -1
|
@@ -15,6 +15,9 @@ function CopyButton({
|
|
|
15
15
|
const { isCopied, copy } = useCopyToClipboard({
|
|
16
16
|
onSuccess: () => {
|
|
17
17
|
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "success", message: successMessage, toastId: t }));
|
|
18
|
+
},
|
|
19
|
+
onError: () => {
|
|
20
|
+
toast.custom((t) => /* @__PURE__ */ jsx(Toast, { variant: "error", message: "N\xE3o foi poss\xEDvel copiar o link", toastId: t }));
|
|
18
21
|
}
|
|
19
22
|
});
|
|
20
23
|
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/ui/buttons/CopyButton.tsx"],"sourcesContent":["import { Check, Copy } from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport { Toast } from \"../feedback/Toast\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../overlay/Tooltip\";\nimport useCopyToClipboard from \"../../../hooks/copy-to-clipboard.hook\";\nimport { cn } from \"../../../infra/utils/clsx\";\n\ninterface CopyButtonProps {\n textToCopy: string;\n size?: number;\n className?: string;\n tooltipText?: string;\n successMessage?: string;\n}\n\nexport function CopyButton({\n textToCopy,\n size = 14,\n className,\n tooltipText = \"Copiar link\",\n successMessage = \"Link copiado\",\n}: CopyButtonProps) {\n const { isCopied, copy } = useCopyToClipboard({\n onSuccess: () => {\n toast.custom((t) => (\n <Toast variant=\"success\" message={successMessage} toastId={t} />\n ));\n },\n });\n\n return (\n <Tooltip>\n <TooltipTrigger\n asChild\n onClick={(e: React.MouseEvent) => {\n e.stopPropagation();\n copy(textToCopy);\n }}\n >\n <span className={cn(\"cursor-pointer text-gray-500\", className)}>\n {isCopied ? <Check size={size} /> : <Copy size={size} />}\n </span>\n </TooltipTrigger>\n <TooltipContent>{isCopied ? \"Copiado!\" : tooltipText}</TooltipContent>\n </Tooltip>\n );\n}\n"],"mappings":"AAyBQ,
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/ui/buttons/CopyButton.tsx"],"sourcesContent":["import { Check, Copy } from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport { Toast } from \"../feedback/Toast\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../overlay/Tooltip\";\nimport useCopyToClipboard from \"../../../hooks/copy-to-clipboard.hook\";\nimport { cn } from \"../../../infra/utils/clsx\";\n\ninterface CopyButtonProps {\n textToCopy: string;\n size?: number;\n className?: string;\n tooltipText?: string;\n successMessage?: string;\n}\n\nexport function CopyButton({\n textToCopy,\n size = 14,\n className,\n tooltipText = \"Copiar link\",\n successMessage = \"Link copiado\",\n}: CopyButtonProps) {\n const { isCopied, copy } = useCopyToClipboard({\n onSuccess: () => {\n toast.custom((t) => (\n <Toast variant=\"success\" message={successMessage} toastId={t} />\n ));\n },\n onError: () => {\n toast.custom((t) => (\n <Toast variant=\"error\" message=\"Não foi possível copiar o link\" toastId={t} />\n ));\n },\n });\n\n return (\n <Tooltip>\n <TooltipTrigger\n asChild\n onClick={(e: React.MouseEvent) => {\n e.stopPropagation();\n copy(textToCopy);\n }}\n >\n <span className={cn(\"cursor-pointer text-gray-500\", className)}>\n {isCopied ? <Check size={size} /> : <Copy size={size} />}\n </span>\n </TooltipTrigger>\n <TooltipContent>{isCopied ? \"Copiado!\" : tooltipText}</TooltipContent>\n </Tooltip>\n );\n}\n"],"mappings":"AAyBQ,cAWJ,YAXI;AAzBR,SAAS,OAAO,YAAY;AAC5B,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,OAAO,wBAAwB;AAC/B,SAAS,UAAU;AAUZ,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA,cAAc;AAAA,EACd,iBAAiB;AACnB,GAAoB;AAClB,QAAM,EAAE,UAAU,KAAK,IAAI,mBAAmB;AAAA,IAC5C,WAAW,MAAM;AACf,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,WAAU,SAAS,gBAAgB,SAAS,GAAG,CAC/D;AAAA,IACH;AAAA,IACA,SAAS,MAAM;AACb,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAQ,wCAAiC,SAAS,GAAG,CAC7E;AAAA,IACH;AAAA,EACF,CAAC;AAED,SACE,qBAAC,WACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAO;AAAA,QACP,SAAS,CAAC,MAAwB;AAChC,YAAE,gBAAgB;AAClB,eAAK,UAAU;AAAA,QACjB;AAAA,QAEA,8BAAC,UAAK,WAAW,GAAG,gCAAgC,SAAS,GAC1D,qBAAW,oBAAC,SAAM,MAAY,IAAK,oBAAC,QAAK,MAAY,GACxD;AAAA;AAAA,IACF;AAAA,IACA,oBAAC,kBAAgB,qBAAW,aAAa,aAAY;AAAA,KACvD;AAEJ;","names":[]}
|
|
@@ -19,7 +19,19 @@ function useCopyToClipboard({
|
|
|
19
19
|
clearTimeout(timeoutRef.current);
|
|
20
20
|
}
|
|
21
21
|
try {
|
|
22
|
-
|
|
22
|
+
if (navigator.clipboard?.writeText) {
|
|
23
|
+
await navigator.clipboard.writeText(text);
|
|
24
|
+
} else {
|
|
25
|
+
const textarea = document.createElement("textarea");
|
|
26
|
+
textarea.value = text;
|
|
27
|
+
textarea.style.cssText = "position:fixed;top:-9999px;left:-9999px;opacity:0";
|
|
28
|
+
document.body.appendChild(textarea);
|
|
29
|
+
textarea.focus();
|
|
30
|
+
textarea.select();
|
|
31
|
+
const success = document.execCommand("copy");
|
|
32
|
+
document.body.removeChild(textarea);
|
|
33
|
+
if (!success) throw new Error("execCommand copy failed");
|
|
34
|
+
}
|
|
23
35
|
setIsCopied(true);
|
|
24
36
|
onSuccess?.();
|
|
25
37
|
timeoutRef.current = setTimeout(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/copy-to-clipboard.hook.tsx"],"sourcesContent":["import { useState, useCallback, useRef, useEffect } from \"react\";\n\ninterface UseCopyToClipboardOptions {\n feedbackDuration?: number;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n}\n\ninterface UseCopyToClipboardReturn {\n isCopied: boolean;\n copy: (text: string) => Promise<void>;\n}\n\nexport default function useCopyToClipboard({\n feedbackDuration = 2000,\n onSuccess,\n onError,\n}: UseCopyToClipboardOptions = {}): UseCopyToClipboardReturn {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n const copy = useCallback(\n async (text: string) => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n try {\n await navigator.clipboard.writeText(text);\n setIsCopied(true);\n onSuccess?.();\n\n timeoutRef.current = setTimeout(() => {\n setIsCopied(false);\n }, feedbackDuration);\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error(\"Failed to copy\"));\n }\n },\n [feedbackDuration, onSuccess, onError],\n );\n\n return { isCopied, copy };\n}\n"],"mappings":"AAAA,SAAS,UAAU,aAAa,QAAQ,iBAAiB;AAa1C,SAAR,mBAAoC;AAAA,EACzC,mBAAmB;AAAA,EACnB;AAAA,EACA;AACF,IAA+B,CAAC,GAA6B;AAC3D,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,aAAa,OAA8B,IAAI;AAErD,YAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,WAAW,SAAS;AACtB,qBAAa,WAAW,OAAO;AAAA,MACjC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO;AAAA,IACX,OAAO,SAAiB;AACtB,UAAI,WAAW,SAAS;AACtB,qBAAa,WAAW,OAAO;AAAA,MACjC;AAEA,UAAI;AACF,
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/copy-to-clipboard.hook.tsx"],"sourcesContent":["import { useState, useCallback, useRef, useEffect } from \"react\";\n\ninterface UseCopyToClipboardOptions {\n feedbackDuration?: number;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n}\n\ninterface UseCopyToClipboardReturn {\n isCopied: boolean;\n copy: (text: string) => Promise<void>;\n}\n\nexport default function useCopyToClipboard({\n feedbackDuration = 2000,\n onSuccess,\n onError,\n}: UseCopyToClipboardOptions = {}): UseCopyToClipboardReturn {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n const copy = useCallback(\n async (text: string) => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n try {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n } else {\n const textarea = document.createElement(\"textarea\");\n textarea.value = text;\n textarea.style.cssText = \"position:fixed;top:-9999px;left:-9999px;opacity:0\";\n document.body.appendChild(textarea);\n textarea.focus();\n textarea.select();\n const success = document.execCommand(\"copy\");\n document.body.removeChild(textarea);\n if (!success) throw new Error(\"execCommand copy failed\");\n }\n\n setIsCopied(true);\n onSuccess?.();\n\n timeoutRef.current = setTimeout(() => {\n setIsCopied(false);\n }, feedbackDuration);\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error(\"Failed to copy\"));\n }\n },\n [feedbackDuration, onSuccess, onError],\n );\n\n return { isCopied, copy };\n}\n"],"mappings":"AAAA,SAAS,UAAU,aAAa,QAAQ,iBAAiB;AAa1C,SAAR,mBAAoC;AAAA,EACzC,mBAAmB;AAAA,EACnB;AAAA,EACA;AACF,IAA+B,CAAC,GAA6B;AAC3D,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,aAAa,OAA8B,IAAI;AAErD,YAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,WAAW,SAAS;AACtB,qBAAa,WAAW,OAAO;AAAA,MACjC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO;AAAA,IACX,OAAO,SAAiB;AACtB,UAAI,WAAW,SAAS;AACtB,qBAAa,WAAW,OAAO;AAAA,MACjC;AAEA,UAAI;AACF,YAAI,UAAU,WAAW,WAAW;AAClC,gBAAM,UAAU,UAAU,UAAU,IAAI;AAAA,QAC1C,OAAO;AACL,gBAAM,WAAW,SAAS,cAAc,UAAU;AAClD,mBAAS,QAAQ;AACjB,mBAAS,MAAM,UAAU;AACzB,mBAAS,KAAK,YAAY,QAAQ;AAClC,mBAAS,MAAM;AACf,mBAAS,OAAO;AAChB,gBAAM,UAAU,SAAS,YAAY,MAAM;AAC3C,mBAAS,KAAK,YAAY,QAAQ;AAClC,cAAI,CAAC,QAAS,OAAM,IAAI,MAAM,yBAAyB;AAAA,QACzD;AAEA,oBAAY,IAAI;AAChB,oBAAY;AAEZ,mBAAW,UAAU,WAAW,MAAM;AACpC,sBAAY,KAAK;AAAA,QACnB,GAAG,gBAAgB;AAAA,MACrB,SAAS,OAAO;AACd,kBAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,gBAAgB,CAAC;AAAA,MACxE;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,WAAW,OAAO;AAAA,EACvC;AAEA,SAAO,EAAE,UAAU,KAAK;AAC1B;","names":[]}
|
package/package.json
CHANGED
|
@@ -26,6 +26,11 @@ export function CopyButton({
|
|
|
26
26
|
<Toast variant="success" message={successMessage} toastId={t} />
|
|
27
27
|
));
|
|
28
28
|
},
|
|
29
|
+
onError: () => {
|
|
30
|
+
toast.custom((t) => (
|
|
31
|
+
<Toast variant="error" message="Não foi possível copiar o link" toastId={t} />
|
|
32
|
+
));
|
|
33
|
+
},
|
|
29
34
|
});
|
|
30
35
|
|
|
31
36
|
return (
|
|
@@ -34,7 +34,20 @@ export default function useCopyToClipboard({
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
try {
|
|
37
|
-
|
|
37
|
+
if (navigator.clipboard?.writeText) {
|
|
38
|
+
await navigator.clipboard.writeText(text);
|
|
39
|
+
} else {
|
|
40
|
+
const textarea = document.createElement("textarea");
|
|
41
|
+
textarea.value = text;
|
|
42
|
+
textarea.style.cssText = "position:fixed;top:-9999px;left:-9999px;opacity:0";
|
|
43
|
+
document.body.appendChild(textarea);
|
|
44
|
+
textarea.focus();
|
|
45
|
+
textarea.select();
|
|
46
|
+
const success = document.execCommand("copy");
|
|
47
|
+
document.body.removeChild(textarea);
|
|
48
|
+
if (!success) throw new Error("execCommand copy failed");
|
|
49
|
+
}
|
|
50
|
+
|
|
38
51
|
setIsCopied(true);
|
|
39
52
|
onSuccess?.();
|
|
40
53
|
|