feat: add copyToClipboard button

This commit is contained in:
Luca Tagliabue 2023-08-23 11:24:02 +02:00
parent 8e07c1d1d3
commit 25d7b5e8d4
4 changed files with 46 additions and 7 deletions

View File

@ -190,7 +190,7 @@ const App = () => (
Sort object keys with <code>sortObjectKeys</code> prop.
</p>
<div>
<JSONTree data={data} theme={theme} sortObjectKeys />
<JSONTree data={data} theme={theme} sortObjectKeys expandCollapseAll={{}}/>
</div>
<p>Collapsed root node</p>
<div>

View File

@ -2,9 +2,11 @@ import {
faArrowDown,
faArrowRight,
faUndo,
faCopy,
faCheck,
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { ReactNode } from 'react';
import React, { ReactNode, useState } from 'react';
import { ExpandCollapseAll } from '.';
import { useExpandCollapseAllContext } from './expandCollapseContext';
import { StylingFunction } from 'react-base16-styling';
@ -12,6 +14,7 @@ import { StylingFunction } from 'react-base16-styling';
interface Props {
expandCollapseAll: ExpandCollapseAll;
styling: StylingFunction;
value: unknown;
}
interface ExpandButtonProps {
@ -24,11 +27,17 @@ interface CollapseButtonProps {
collapseIcon?: ReactNode;
}
interface CopyToClipboardButtonProps {
copyToClipboardIcon?: ReactNode;
copiedToClipboardIcon?: ReactNode;
value: unknown;
}
interface DefaultButtonProps {
defaultIcon?: ReactNode;
}
function ExpandCollapseButtons({ expandCollapseAll, styling }: Props) {
function ExpandCollapseButtons({ expandCollapseAll, styling, value }: Props) {
const { enableDefaultButton } = useExpandCollapseAllContext();
const expandableDefaultValue = expandCollapseAll?.defaultValue || 'expand';
@ -39,6 +48,12 @@ function ExpandCollapseButtons({ expandCollapseAll, styling }: Props) {
<DefaultButton defaultIcon={expandCollapseAll?.defaultIcon} />
)}
<CopyToClipboardButton
copyToClipboardIcon={expandCollapseAll?.copyToClipboardIcon}
copiedToClipboardIcon={expandCollapseAll?.copiedToClipboardIcon}
value={value}
/>
<ExpandButton
expandableDefaultValue={expandableDefaultValue}
expandIcon={expandCollapseAll?.expandIcon}
@ -108,6 +123,26 @@ function CollapseButton({
return <></>;
}
function CopyToClipboardButton({copyToClipboardIcon, copiedToClipboardIcon, value}:CopyToClipboardButtonProps) {
const [isCopied, setIsCopied] = useState(false);
const handleOnCopyToClipboard = async () => {
await navigator.clipboard.writeText(JSON.stringify(value, null, 2));
setIsCopied(true)
}
if(isCopied){
return (<div role="presentation" onClick={handleOnCopyToClipboard}>
{copiedToClipboardIcon || <FontAwesomeIcon icon={faCheck} />}
</div>);
}
return (
<div role="presentation" onClick={handleOnCopyToClipboard}>
{copyToClipboardIcon || <FontAwesomeIcon icon={faCopy} />}
</div>)
}
function DefaultButton({ defaultIcon }: DefaultButtonProps) {
const { setExpandAllState, setEnableDefaultButton } =
useExpandCollapseAllContext();
@ -122,8 +157,6 @@ function DefaultButton({ defaultIcon }: DefaultButtonProps) {
{defaultIcon || <FontAwesomeIcon icon={faUndo} />}
</div>
);
return <></>;
}
export default ExpandCollapseButtons;

View File

@ -20,6 +20,7 @@ interface Props {
children: ReactNode;
expandCollapseAll?: ExpandCollapseAll;
styling: StylingFunction;
value: unknown;
}
const ExpandCollapseAllContext = createContext<Context>({} as Context);
@ -28,11 +29,12 @@ function ExpandCollapseAllContextProvider({
expandCollapseAll,
children,
styling,
value,
}: Props) {
const [enableDefaultButton, setEnableDefaultButton] = useState(false);
const [expandAllState, setExpandAllState] = useState();
const value = useMemo(
const contextValue = useMemo(
() => ({
enableDefaultButton,
setEnableDefaultButton,
@ -43,12 +45,13 @@ function ExpandCollapseAllContextProvider({
);
return (
<ExpandCollapseAllContext.Provider value={value}>
<ExpandCollapseAllContext.Provider value={contextValue}>
{children}
{expandCollapseAll && (
<ExpandCollapseButtons
expandCollapseAll={expandCollapseAll}
styling={styling}
value={value}
/>
)}
</ExpandCollapseAllContext.Provider>

View File

@ -29,6 +29,8 @@ interface ExpandCollapseAll {
defaultValue?: 'expand' | 'collapse';
expandIcon?: ReactNode;
collapseIcon?: ReactNode;
copyToClipboardIcon?: ReactNode;
copiedToClipboardIcon?: ReactNode;
defaultIcon?: ReactNode;
}
@ -70,6 +72,7 @@ export function JSONTree({
<ExpandCollapseAllButtonsContext
expandCollapseAll={expandCollapseAll}
styling={styling}
value={value}
>
<JSONNode
keyPath={hideRoot ? [] : keyPath}