diff --git a/lib/reactotron-core-ui/src/components/ContentView/index.tsx b/lib/reactotron-core-ui/src/components/ContentView/index.tsx index 7f5a7378b..d86f0e292 100644 --- a/lib/reactotron-core-ui/src/components/ContentView/index.tsx +++ b/lib/reactotron-core-ui/src/components/ContentView/index.tsx @@ -21,9 +21,10 @@ interface Props { // value: object | string | number | boolean | null | undefined value: any treeLevel?: number + copyToClipboard?: (text: string) => void } -export default function ContentView({ value, treeLevel }: Props) { +export default function ContentView({ value, treeLevel, copyToClipboard }: Props) { if (value === null) return null if (value === undefined) return undefined @@ -54,7 +55,7 @@ export default function ContentView({ value, treeLevel }: Props) { return isShallow(checkValue) ? ( makeTable(checkValue) ) : ( - + ) } diff --git a/lib/reactotron-core-ui/src/components/TreeView/index.tsx b/lib/reactotron-core-ui/src/components/TreeView/index.tsx index 19fd365e7..3c4068a53 100644 --- a/lib/reactotron-core-ui/src/components/TreeView/index.tsx +++ b/lib/reactotron-core-ui/src/components/TreeView/index.tsx @@ -29,6 +29,22 @@ const theme = { const MutedContainer = styled.span` color: ${(props) => props.theme.highlight}; + display: inline-flex; +` + +const ButtonCopy = styled.button` + margin-left: 6px; + padding: 0 6px; + font-size: 10px; + border: none; + border-radius: 3px; + cursor: pointer; + color: ${(props) => props.theme.background}; + background-color: ${(props) => props.theme.highlight}; + + &:hover { + opacity: 0.85; + } ` const getTreeTheme = (baseTheme: ReactotronTheme) => ({ @@ -41,9 +57,10 @@ interface Props { // value: object value: any level?: number + copyToClipboard?: (text: string) => void } -export default function TreeView({ value, level = 1 }: Props) { +export default function TreeView({ value, level = 1, copyToClipboard }: Props) { const colorScheme = useColorScheme() return ( @@ -54,7 +71,18 @@ export default function TreeView({ value, level = 1 }: Props) { theme={getTreeTheme(themes[colorScheme])} getItemString={(type, data, itemType, itemString) => { if (type === "Object") { - return {itemType} + const handleCopy = copyToClipboard + ? (event: React.MouseEvent) => { + event.stopPropagation() + copyToClipboard(JSON.stringify(data, null, 2)) + } + : undefined + return ( + + {itemType} + {handleCopy && Copy} + + ) } return ( diff --git a/lib/reactotron-core-ui/src/timelineCommands/ApiResponseCommand/index.tsx b/lib/reactotron-core-ui/src/timelineCommands/ApiResponseCommand/index.tsx index 9db3ff5fd..e06008426 100644 --- a/lib/reactotron-core-ui/src/timelineCommands/ApiResponseCommand/index.tsx +++ b/lib/reactotron-core-ui/src/timelineCommands/ApiResponseCommand/index.tsx @@ -167,7 +167,9 @@ const ApiResponseCommand: FunctionComponent = ({ {!!request.params && tabBuilder(Tab.RequestParams, "Request Params")} {tabBuilder(Tab.RequestHeaders, "Request Headers")} - {onTab === Tab.ResponseBody && } + {onTab === Tab.ResponseBody && ( + + )} {onTab === Tab.ResponseHeaders && } {onTab === Tab.RequestBody && } {onTab === Tab.RequestParams && }