1
0
forked from M-Labs/web2019

Add copy to clipboard button in ShowJSON

Signed-off-by: Egor Savkin <es@m-labs.hk>
This commit is contained in:
Egor Savkin 2024-01-08 16:58:37 +08:00
parent 83be26ecbb
commit e87c4a16a8
2 changed files with 46 additions and 2 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,10 +1,28 @@
import React from "react"; import React, {useState} from "react";
import {Modal} from "react-bootstrap"; import {Modal} from "react-bootstrap";
import {useShopStore} from "./shop_store"; import {useShopStore} from "./shop_store";
import {useClickAway} from "./options/useClickAway"; import {useClickAway} from "./options/useClickAway";
// #!render_count // #!render_count
import {useRenderCount} from "@uidotdev/usehooks"; import {useRenderCount} from "@uidotdev/usehooks";
import {Validation} from "./validate";
const copyButtonStates = {
[Validation.OK]: {
style: "btn-outline-success",
content: "✓ copied"
},
[Validation.Empty]: {
style: "btn-outline-primary",
content: "Copy"
},
[Validation.Invalid]: {
style: "btn-outline-danger",
content: "Error"
},
};
export function ShowJSON() { export function ShowJSON() {
// #!render_count // #!render_count
@ -15,6 +33,8 @@ export function ShowJSON() {
const closeDescription = useShopStore((state) => state.closeDescription); const closeDescription = useShopStore((state) => state.closeDescription);
const showDescription = useShopStore((state) => state.showDescription); const showDescription = useShopStore((state) => state.showDescription);
const [copiedState, setCopiedState] = useState(Validation.Empty);
// #!render_count // #!render_count
console.log("ShowJSON renders: ", renderCount) console.log("ShowJSON renders: ", renderCount)
@ -24,6 +44,24 @@ export function ShowJSON() {
} }
); );
const copyToClipboard = (text) => {
try {
navigator.clipboard.writeText(text)
.then((_value) => { // success
setCopiedState(Validation.OK);
setTimeout(() => {setCopiedState(Validation.Empty)}, 1500);
}, (reason) => { // error
setCopiedState(Validation.Invalid);
setTimeout(() => {setCopiedState(Validation.Empty)}, 3000);
console.warn("Copy to clipboard rejected: ", reason)
});
} catch (e) {
setCopiedState(Validation.Invalid);
setTimeout(() => {setCopiedState(Validation.Empty)}, 3000);
console.warn("Copy to clipboard error: ", e)
}
};
return (<> return (<>
<input <input
className="btn btn-outline-primary w-100 m-0 mb-2 mb-sm-0 me-sm-2" className="btn btn-outline-primary w-100 m-0 mb-2 mb-sm-0 me-sm-2"
@ -41,6 +79,12 @@ export function ShowJSON() {
placeholder="There should be description of the crate"/> placeholder="There should be description of the crate"/>
<div className="d-flex flex-column flex-sm-row justify-content-end"> <div className="d-flex flex-column flex-sm-row justify-content-end">
<a type="button"
onClick={() => {copyToClipboard(description)}}
className={"btn btn-sm m-0 mb-1 mt-2 mb-sm-0 me-sm-2 " + copyButtonStates[copiedState].style}
>
{ copyButtonStates[copiedState].content }
</a>
<a type="button" onClick={closeDescription} <a type="button" onClick={closeDescription}
className="btn btn-sm btn-outline-primary m-0 mb-1 mt-2 mb-sm-0 me-sm-2">Close</a> className="btn btn-sm btn-outline-primary m-0 mb-1 mt-2 mb-sm-0 me-sm-2">Close</a>
</div> </div>