From 0f8e41fc7c7b9375d6a0bda90c2ac059d21de157 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Fri, 31 Jan 2025 10:49:09 +0530 Subject: [PATCH] chore: Function Render of State Inspector (#38893) --- .../CodeEditor/PeekOverlayPopup/Analytics.ts | 38 ---- .../PeekOverlayPopup/PeekOverlayPopup.tsx | 192 ++++++------------ .../CodeEditor/PeekOverlayPopup/constants.ts | 3 + .../CodeEditor/PeekOverlayPopup/styles.ts | 43 ++++ .../CodeEditor/PeekOverlayPopup/utils.ts | 16 ++ .../editorComponents/CodeEditor/index.tsx | 7 +- .../StateInspector/StateInspector.test.tsx | 50 ++++- .../StateInspector/StateInspector.tsx | 29 +-- .../JSONViewer/JSONViewer.tsx | 16 ++ .../editorComponents/JSONViewer/constants.ts | 22 ++ .../editorComponents/JSONViewer/index.ts | 3 + .../JsonWrapper.tsx => JSONViewer/styles.ts} | 55 +++-- .../editorComponents/JSONViewer/types.ts | 9 + 13 files changed, 262 insertions(+), 221 deletions(-) delete mode 100644 app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/Analytics.ts create mode 100644 app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/constants.ts create mode 100644 app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/styles.ts create mode 100644 app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/utils.ts create mode 100644 app/client/src/components/editorComponents/JSONViewer/JSONViewer.tsx create mode 100644 app/client/src/components/editorComponents/JSONViewer/constants.ts create mode 100644 app/client/src/components/editorComponents/JSONViewer/index.ts rename app/client/src/components/editorComponents/{CodeEditor/PeekOverlayPopup/JsonWrapper.tsx => JSONViewer/styles.ts} (69%) create mode 100644 app/client/src/components/editorComponents/JSONViewer/types.ts diff --git a/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/Analytics.ts b/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/Analytics.ts deleted file mode 100644 index e3234c245c..0000000000 --- a/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/Analytics.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { MouseEventHandler } from "react"; -import AnalyticsUtil from "ee/utils/AnalyticsUtil"; - -export const objectCollapseAnalytics: MouseEventHandler = (ev) => { - /* - * Analytics events to be logged whenever user clicks on - * react json viewer's controls to expand or collapse object/array - */ - const targetNode = ev.target as HTMLElement; - - if ( - // collapse/expand icon click, object key click - targetNode.parentElement?.parentElement?.parentElement?.firstElementChild?.classList.contains( - "icon-container", - ) || - // : click - targetNode.parentElement?.parentElement?.firstElementChild?.classList.contains( - "icon-container", - ) || - // { click - targetNode.parentElement?.firstElementChild?.classList.contains( - "icon-container", - ) || - // ellipsis click - targetNode.classList.contains("node-ellipsis") || - // collapse/expand icon - svg path click - targetNode.parentElement?.parentElement?.classList.contains( - "collapsed-icon", - ) || - targetNode.parentElement?.parentElement?.classList.contains("expanded-icon") - ) { - AnalyticsUtil.logEvent("PEEK_OVERLAY_COLLAPSE_EXPAND_CLICK"); - } -}; - -export const textSelectAnalytics = () => { - AnalyticsUtil.logEvent("PEEK_OVERLAY_VALUE_COPIED"); -}; diff --git a/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/PeekOverlayPopup.tsx b/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/PeekOverlayPopup.tsx index c71f8d115e..9b40c04b8e 100644 --- a/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/PeekOverlayPopup.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/PeekOverlayPopup.tsx @@ -1,17 +1,21 @@ -import type { MutableRefObject } from "react"; -import { useState } from "react"; -import React, { useEffect, useRef } from "react"; -import ReactJson from "react-json-view"; -import { JsonWrapper, reactJsonProps } from "./JsonWrapper"; +import React, { + type MutableRefObject, + useCallback, + useMemo, + useRef, +} from "react"; +import { useEventCallback } from "usehooks-ts"; import { componentWillAppendToBody } from "react-append-to-body"; -import _, { debounce } from "lodash"; +import { debounce } from "lodash"; import { zIndexLayers } from "constants/CanvasEditorConstants"; -import { objectCollapseAnalytics, textSelectAnalytics } from "./Analytics"; -import { Divider } from "@appsmith/ads"; import { useSelector } from "react-redux"; import { getConfigTree, getDataTree } from "selectors/dataTreeSelectors"; import { filterInternalProperties } from "utils/FilterInternalProperties"; import { getJSCollections } from "ee/selectors/entitiesSelector"; +import * as Styled from "./styles"; +import { CONTAINER_MAX_HEIGHT_PX, PEEK_OVERLAY_DELAY } from "./constants"; +import { getDataTypeHeader, getPropertyData } from "./utils"; +import { JSONViewer, Size } from "../../JSONViewer"; export interface PeekOverlayStateProps { objectName: string; @@ -31,155 +35,83 @@ export const PeekOverlayPopUp = componentWillAppendToBody( PeekOverlayPopUpContent, ); -export const PEEK_OVERLAY_DELAY = 200; - -const getPropertyData = (src: unknown, propertyPath: string[]) => { - return propertyPath.length > 0 ? _.get(src, propertyPath) : src; -}; - -const getDataTypeHeader = (data: unknown) => { - const dataType = typeof data; - - if (dataType === "object") { - if (Array.isArray(data)) return "array"; - - if (data === null) return "null"; - } - - return dataType; -}; - export function PeekOverlayPopUpContent( props: PeekOverlayStateProps & { hidePeekOverlay: () => void; }, ) { - const CONTAINER_MAX_HEIGHT_PX = 252; + const { hidePeekOverlay, objectName, position, propertyPath } = props; const dataWrapperRef: MutableRefObject = useRef(null); const dataTree = useSelector(getDataTree); const configTree = useSelector(getConfigTree); const jsActions = useSelector(getJSCollections); const filteredData = filterInternalProperties( - props.objectName, - dataTree[props.objectName], + objectName, + dataTree[objectName], jsActions, dataTree, configTree, ); - // Because getPropertyData can return a function - // And we don't want to execute it. - const [jsData] = useState(() => - getPropertyData(filteredData, props.propertyPath), + const [jsData, dataType] = useMemo( + // Because getPropertyData can return a function + // And we don't want to execute it. + () => { + const jsData = getPropertyData(filteredData, propertyPath); + const dataType = getDataTypeHeader(jsData); + + return [jsData, dataType]; + }, + [filteredData, propertyPath], ); - const [dataType] = useState(getDataTypeHeader(jsData)); + const debouncedHide = debounce(hidePeekOverlay, PEEK_OVERLAY_DELAY); - useEffect(() => { - const wheelCallback = () => { - props.hidePeekOverlay(); + const getPositionValues = useCallback(() => { + const positionValues: { $left: string; $bottom?: string; $top?: string } = { + // Always have a minimum of 8px from the left + $left: Math.max(position.right - 300, 8) + "px", }; - window.addEventListener("wheel", wheelCallback); + // if the peek overlay is going to be more than the container height, then show it from the bottom + if (position.top >= CONTAINER_MAX_HEIGHT_PX) { + positionValues.$bottom = `calc(100vh - ${position.top}px)`; + } else { + positionValues.$top = `${position.bottom}px`; + } - return () => { - window.removeEventListener("wheel", wheelCallback); - }; - }, []); + return positionValues; + }, [position]); - useEffect(() => { - if (!dataWrapperRef.current) return; - - dataWrapperRef.current.addEventListener("copy", textSelectAnalytics); - - return () => - dataWrapperRef.current?.removeEventListener("copy", textSelectAnalytics); - }, [dataWrapperRef, dataWrapperRef.current]); - - const debouncedHide = debounce( - () => props.hidePeekOverlay(), - PEEK_OVERLAY_DELAY, - ); - - const getLeftPosition = (position: DOMRect) => { - let left = position.right - 300; - - if (left < 0) left = 8; - - return left; - }; + const onWheel = useEventCallback((ev: React.WheelEvent) => { + ev.stopPropagation(); + hidePeekOverlay(); + }); return ( -
debouncedHide.cancel()} - onMouseLeave={() => debouncedHide()} - onWheel={(ev) => ev.stopPropagation()} - style={{ - minHeight: "46px", - maxHeight: `${CONTAINER_MAX_HEIGHT_PX}px`, - width: "300px", - backgroundColor: "var(--ads-v2-color-bg)", - boxShadow: "0px 0px 10px #0000001A", // color used from designs - borderRadius: "var(--ads-v2-border-radius)", - left: `${getLeftPosition(props.position)}px`, - ...(props.position.top >= CONTAINER_MAX_HEIGHT_PX - ? { - bottom: `calc(100vh - ${props.position.top}px)`, - } - : { - top: `${props.position.bottom}px`, - }), - }} + onMouseEnter={debouncedHide.cancel} + onMouseLeave={debouncedHide} + onWheel={onWheel} + {...getPositionValues()} > -
+ {dataType} -
- -
+ + + {(dataType === "object" || dataType === "array") && jsData !== null && ( - - - + + + )} - {/* TODO: Fix this the next time the file is edited */} - {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} - {dataType === "function" &&
{(jsData as any).toString()}
} - {/* TODO: Fix this the next time the file is edited */} - {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} - {dataType === "boolean" &&
{(jsData as any).toString()}
} - {/* TODO: Fix this the next time the file is edited */} - {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} - {dataType === "string" &&
{(jsData as any).toString()}
} - {/* TODO: Fix this the next time the file is edited */} - {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} - {dataType === "number" &&
{(jsData as any).toString()}
} + {dataType === "function" &&
{jsData.toString()}
} + {dataType === "boolean" &&
{jsData.toString()}
} + {dataType === "string" &&
{jsData.toString()}
} + {dataType === "number" &&
{jsData.toString()}
} {((dataType !== "object" && dataType !== "function" && dataType !== "boolean" && @@ -188,14 +120,12 @@ export function PeekOverlayPopUpContent( dataType !== "number") || jsData === null) && (
- {/* TODO: Fix this the next time the file is edited */} - {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} - {(jsData as any)?.toString() ?? jsData ?? jsData === undefined + {jsData?.toString() ?? jsData ?? jsData === undefined ? "undefined" : "null"}
)} -
-
+ + ); } diff --git a/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/constants.ts b/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/constants.ts new file mode 100644 index 0000000000..63e7dc2cb0 --- /dev/null +++ b/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/constants.ts @@ -0,0 +1,3 @@ +export const CONTAINER_MAX_HEIGHT_PX = 252; + +export const PEEK_OVERLAY_DELAY = 200; diff --git a/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/styles.ts b/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/styles.ts new file mode 100644 index 0000000000..0117cb1a16 --- /dev/null +++ b/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/styles.ts @@ -0,0 +1,43 @@ +import styled from "styled-components"; +import { Divider } from "@appsmith/ads"; + +export const PeekOverlayContainer = styled.div<{ + $left: string; + $top?: string; + $bottom?: string; +}>` + min-height: 46px; + max-height: 252px; + width: 300px; + background-color: var(--ads-v2-color-bg); + box-shadow: 0 0 10px #0000001a; // color used from designs + border-radius: var(--ads-v2-border-radius); + left: ${({ $left }) => $left}; + top: ${({ $top }) => $top}; + bottom: ${({ $bottom }) => $bottom}; +`; + +export const DataType = styled.div` + height: 24px; + color: var(--appsmith-color-black-700); + padding: var(--ads-v2-spaces-2) 0 var(--ads-v2-spaces-2) + var(--ads-v2-spaces-4); + font-size: 10px; +`; + +export const BlockDivider = styled(Divider)` + display: block; +`; + +export const PeekOverlayData = styled.div` + min-height: 20px; + padding: var(--ads-v2-spaces-1) 0 var(--ads-v2-spaces-1) + var(--ads-v2-spaces-4); + font-size: 10px; +`; + +export const JsonWrapper = styled.div` + min-height: 20px; + max-height: 225px; + overflow-y: auto; +`; diff --git a/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/utils.ts b/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/utils.ts new file mode 100644 index 0000000000..b2d4b9cef7 --- /dev/null +++ b/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/utils.ts @@ -0,0 +1,16 @@ +import { get } from "lodash"; + +export const getPropertyData = (src: unknown, propertyPath: string[]) => { + return propertyPath.length > 0 ? get(src, propertyPath) : src; +}; +export const getDataTypeHeader = (data: unknown) => { + const dataType = typeof data; + + if (dataType === "object") { + if (Array.isArray(data)) return "array"; + + if (data === null) return "null"; + } + + return dataType; +}; diff --git a/app/client/src/components/editorComponents/CodeEditor/index.tsx b/app/client/src/components/editorComponents/CodeEditor/index.tsx index 8c9027dc64..b05ccaf9cc 100644 --- a/app/client/src/components/editorComponents/CodeEditor/index.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/index.tsx @@ -128,10 +128,7 @@ import { getEntitiesForNavigation } from "selectors/navigationSelectors"; import history, { NavigationMethod } from "utils/history"; import { CursorPositionOrigin } from "ee/reducers/uiReducers/editorContextReducer"; import type { PeekOverlayStateProps } from "./PeekOverlayPopup/PeekOverlayPopup"; -import { - PeekOverlayPopUp, - PEEK_OVERLAY_DELAY, -} from "./PeekOverlayPopup/PeekOverlayPopup"; +import { PeekOverlayPopUp } from "./PeekOverlayPopup/PeekOverlayPopup"; import ConfigTreeActions from "utils/configTree"; import { getSaveAndAutoIndentKey, @@ -164,6 +161,7 @@ import CodeMirrorTernService from "utils/autocomplete/CodemirrorTernService"; import { getEachEntityInformation } from "ee/utils/autocomplete/EntityDefinitions"; import { getCurrentPageId } from "selectors/editorSelectors"; import { executeCommandAction } from "actions/pluginActionActions"; +import { PEEK_OVERLAY_DELAY } from "./PeekOverlayPopup/constants"; type ReduxStateProps = ReturnType; type ReduxDispatchProps = ReturnType; @@ -202,6 +200,7 @@ export interface EditorStyleProps { popperZIndex?: Indices; blockCompletions?: Array; } + /** * line => Line to which the gutter is added * diff --git a/app/client/src/components/editorComponents/Debugger/StateInspector/StateInspector.test.tsx b/app/client/src/components/editorComponents/Debugger/StateInspector/StateInspector.test.tsx index bdf75dabde..f00a355804 100644 --- a/app/client/src/components/editorComponents/Debugger/StateInspector/StateInspector.test.tsx +++ b/app/client/src/components/editorComponents/Debugger/StateInspector/StateInspector.test.tsx @@ -4,6 +4,8 @@ import "@testing-library/jest-dom"; import { StateInspector } from "./StateInspector"; import { useStateInspectorItems } from "./hooks"; import { filterEntityGroupsBySearchTerm } from "IDE/utils"; +import { lightTheme } from "selectors/themeSelectors"; +import { ThemeProvider } from "styled-components"; jest.mock("./hooks"); jest.mock("IDE/utils"); @@ -31,7 +33,11 @@ describe("StateInspector", () => { ], { key: "value1" }, ]); - render(); + render( + + + , + ); const searchInput = screen.getByPlaceholderText("Search entities"); fireEvent.change(searchInput, { target: { value: "Group 1" } }); @@ -53,7 +59,11 @@ describe("StateInspector", () => { ], { key: "value1" }, ]); - render(); + render( + + + , + ); fireEvent.click(screen.getByText("Item 2")); expect(mockOnClick).toHaveBeenCalled(); @@ -71,7 +81,11 @@ describe("StateInspector", () => { ], { key: "Value1" }, ]); - render(); + render( + + + , + ); expect( screen.getByTestId("t--selected-entity-details").textContent, @@ -84,7 +98,11 @@ describe("StateInspector", () => { it("does not render selected item details when no item is selected", () => { mockedUseStateInspectorItems.mockReturnValue([null, [], null]); - render(); + render( + + + , + ); expect(screen.queryByText("Item 1")).not.toBeInTheDocument(); }); @@ -101,12 +119,20 @@ describe("StateInspector", () => { { key: "value1" }, ]); - render(); + render( + + + , + ); expect(screen.getByText("Group 1")).toBeInTheDocument(); expect(screen.getByText("Group 2")).toBeInTheDocument(); }); it("renders no items when search term does not match any group", () => { - render(); + render( + + + , + ); const searchInput = screen.getByPlaceholderText("Search entities"); fireEvent.change(searchInput, { target: { value: "Nonexistent Group" } }); @@ -116,7 +142,11 @@ describe("StateInspector", () => { it("renders no items when items list is empty", () => { mockedUseStateInspectorItems.mockReturnValue([null, [], null]); - render(); + render( + + + , + ); expect(screen.queryByText("Group 1")).not.toBeInTheDocument(); expect(screen.queryByText("Group 2")).not.toBeInTheDocument(); }); @@ -130,7 +160,11 @@ describe("StateInspector", () => { ], {}, ]); - render(); + render( + + + , + ); expect( screen.getByTestId("t--selected-entity-details").textContent, diff --git a/app/client/src/components/editorComponents/Debugger/StateInspector/StateInspector.tsx b/app/client/src/components/editorComponents/Debugger/StateInspector/StateInspector.tsx index dc1b99d93a..dbedd81a96 100644 --- a/app/client/src/components/editorComponents/Debugger/StateInspector/StateInspector.tsx +++ b/app/client/src/components/editorComponents/Debugger/StateInspector/StateInspector.tsx @@ -1,29 +1,21 @@ import React, { useState } from "react"; -import ReactJson from "react-json-view"; import { EntityGroupsList, Flex, + type FlexProps, type ListItemProps, SearchInput, Text, } from "@appsmith/ads"; +import { JSONViewer, Size } from "components/editorComponents/JSONViewer"; import { filterEntityGroupsBySearchTerm } from "IDE/utils"; import { useStateInspectorItems } from "./hooks"; import * as Styled from "./styles"; -export const reactJsonProps = { - name: null, - enableClipboard: false, - displayDataTypes: false, - displayArrayKey: true, - quotesOnKeys: false, - style: { - fontSize: "12px", - }, - collapsed: 1, - indentWidth: 2, - collapseStringsAfterLength: 30, -}; +const GroupListPadding = { + pl: "spaces-3", + pr: "spaces-3", +} as FlexProps; export const StateInspector = () => { const [selectedItem, items, selectedItemCode] = useStateInspectorItems(); @@ -51,10 +43,7 @@ export const StateInspector = () => { /> { return { groupTitle: item.group, @@ -81,8 +70,8 @@ export const StateInspector = () => { {selectedItem.icon} {selectedItem.title} - - + + ) : null} diff --git a/app/client/src/components/editorComponents/JSONViewer/JSONViewer.tsx b/app/client/src/components/editorComponents/JSONViewer/JSONViewer.tsx new file mode 100644 index 0000000000..19cd2af161 --- /dev/null +++ b/app/client/src/components/editorComponents/JSONViewer/JSONViewer.tsx @@ -0,0 +1,16 @@ +import React from "react"; +import type { JSONViewerProps } from "./types"; +import ReactJson from "react-json-view"; +import * as Styled from "./styles"; +import { FontSize, IconSize, reactJsonProps } from "./constants"; + +export function JSONViewer(props: JSONViewerProps) { + const fontSize = FontSize[props.size]; + const iconSize = IconSize[props.size]; + + return ( + + + + ); +} diff --git a/app/client/src/components/editorComponents/JSONViewer/constants.ts b/app/client/src/components/editorComponents/JSONViewer/constants.ts new file mode 100644 index 0000000000..61b29d3d4f --- /dev/null +++ b/app/client/src/components/editorComponents/JSONViewer/constants.ts @@ -0,0 +1,22 @@ +import { Size } from "./types"; + +export const FontSize = { + [Size.SMALL]: "10px", + [Size.MEDIUM]: "12px", +}; + +export const IconSize = { + [Size.SMALL]: "8px", + [Size.MEDIUM]: "10px", +}; + +export const reactJsonProps = { + name: null, + enableClipboard: false, + displayDataTypes: false, + displayArrayKey: true, + quotesOnKeys: false, + collapsed: 1, + indentWidth: 2, + collapseStringsAfterLength: 30, +}; diff --git a/app/client/src/components/editorComponents/JSONViewer/index.ts b/app/client/src/components/editorComponents/JSONViewer/index.ts new file mode 100644 index 0000000000..7406c3eeae --- /dev/null +++ b/app/client/src/components/editorComponents/JSONViewer/index.ts @@ -0,0 +1,3 @@ +export { JSONViewer } from "./JSONViewer"; +export { Size } from "./types"; +export type { JSONViewerProps } from "./types"; diff --git a/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/JsonWrapper.tsx b/app/client/src/components/editorComponents/JSONViewer/styles.ts similarity index 69% rename from app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/JsonWrapper.tsx rename to app/client/src/components/editorComponents/JSONViewer/styles.ts index f00538b17c..94ee14c40a 100644 --- a/app/client/src/components/editorComponents/CodeEditor/PeekOverlayPopup/JsonWrapper.tsx +++ b/app/client/src/components/editorComponents/JSONViewer/styles.ts @@ -1,33 +1,24 @@ -import styled from "styled-components"; +import styled, { css } from "styled-components"; -export const reactJsonProps = { - name: null, - enableClipboard: false, - displayDataTypes: false, - displayArrayKey: true, - quotesOnKeys: false, - style: { - fontSize: "10px", - }, - collapsed: 1, - indentWidth: 2, - collapseStringsAfterLength: 30, -}; +const ReactJSONViewerOverrider = css<{ $fontSize: string; $iconSize: string }>` + font-size: ${({ $fontSize }) => $fontSize} !important; -export const JsonWrapper = styled.div` // all ellipsis font size + .node-ellipsis, .function-collapsed span:nth-child(2), .string-value span { - font-size: 10px !important; + font-size: ${({ $fontSize }) => $fontSize} !important; } - // disable and hide first object collapser + // disable and hide first object collapse icon + .pretty-json-container > .object-content:first-of-type > .object-key-val:first-of-type > span { pointer-events: none !important; + .icon-container { display: none !important; } @@ -38,28 +29,42 @@ export const JsonWrapper = styled.div` } // collapse icon color change and alignment + .icon-container { - width: 10px !important; - height: 8px !important; + width: ${({ $iconSize }) => $iconSize} !important; + height: ${({ $iconSize }) => $iconSize} !important; + + .expanded-icon { + svg { + vertical-align: middle !important; + padding-left: 0px !important; + width: 0.8em !important; + } + } + svg { color: var(--appsmith-color-black-600) !important; } } // font-sizes and alignments + .pushed-content.object-container { .object-content { padding-left: 4px !important; + .variable-row { padding-top: 0 !important; padding-bottom: 0 !important; border-left: 0 !important; + .variable-value div { - font-size: 10px !important; + font-size: ${({ $fontSize }) => $fontSize} !important; padding-top: 0 !important; padding-bottom: 0 !important; } } + .object-key-val { padding-top: 0 !important; padding-bottom: 0 !important; @@ -70,25 +75,35 @@ export const JsonWrapper = styled.div` } // disabling function collapse and neutral styling + .rjv-function-container { pointer-events: none; font-weight: normal !important; + > span:first-child:before { // In prod build, for some reason react-json-viewer // misses adding this opening braces for function content: "("; } + .function-collapsed { font-weight: normal !important; + span:nth-child(1) { display: none; // hiding extra braces } + span:nth-child(2) { color: #393939 !important; } } } + div:has(.rjv-function-container) { cursor: default !important; } `; + +export const Container = styled.div<{ $fontSize: string; $iconSize: string }>` + ${ReactJSONViewerOverrider} +`; diff --git a/app/client/src/components/editorComponents/JSONViewer/types.ts b/app/client/src/components/editorComponents/JSONViewer/types.ts new file mode 100644 index 0000000000..ec57dcb13e --- /dev/null +++ b/app/client/src/components/editorComponents/JSONViewer/types.ts @@ -0,0 +1,9 @@ +export enum Size { + SMALL = "small", + MEDIUM = "medium", +} + +export interface JSONViewerProps { + src: unknown; + size: Size; +}