From ac748c8cfbfe0801dd26800884346b43179983c8 Mon Sep 17 00:00:00 2001 From: ae_atrofimov Date: Thu, 3 Oct 2024 17:49:53 +0200 Subject: [PATCH 1/3] feat(ref): added rpc-parser component to linea ref pages --- .../linea/json-rpc-methods/eth_accounts.mdx | 43 ++------ .../json-rpc-methods/eth_blocknumber.mdx | 43 ++------ .../linea/json-rpc-methods/eth_chainid.mdx | 43 ++------ .../linea/json-rpc-methods/eth_gasprice.mdx | 43 ++------ .../eth_maxpriorityfeepergas.mdx | 43 ++------ .../linea/json-rpc-methods/eth_syncing.mdx | 43 ++------ .../ParserOpenRPC/DetailsBox/MDContent.tsx | 62 ++++++----- .../ParserOpenRPC/DetailsBox/RenderParams.tsx | 8 ++ .../ParserOpenRPC/DetailsBox/index.tsx | 11 +- .../ProjectsBox/styles.module.scss | 13 ++- .../ParserOpenRPC/RequestBox/index.tsx | 15 +-- .../RequestBox/styles.module.css | 25 +++++ src/components/ParserOpenRPC/index.tsx | 101 ++++++++++++------ src/css/custom.css | 4 + 14 files changed, 217 insertions(+), 280 deletions(-) diff --git a/services/reference/linea/json-rpc-methods/eth_accounts.mdx b/services/reference/linea/json-rpc-methods/eth_accounts.mdx index 0dafbcb738..529e7f38fb 100644 --- a/services/reference/linea/json-rpc-methods/eth_accounts.mdx +++ b/services/reference/linea/json-rpc-methods/eth_accounts.mdx @@ -1,40 +1,13 @@ --- title: "eth_accounts" +hide_title: true +hide_table_of_contents: true --- -import Tabs from "@theme/Tabs" -import TabItem from "@theme/TabItem" +import ParserOpenRPC from "@site/src/components/ParserOpenRPC" +import { NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc" -import Description from "/services/reference/_partials/_eth_accounts-description.mdx" - - - -## Parameters - -import Params from "/services/reference/_partials/_eth_accounts-parameters.mdx" - - - -## Returns - -import Returns from "/services/reference/_partials/_eth_accounts-returns.mdx" - - - -## Example - -import Example from "/services/reference/_partials/_eth_accounts-example.mdx" - - - -### Request - -import Request from "./_eth_accounts-request.mdx" - - - -### Response - -import Response from "/services/reference/_partials/_eth_accounts-response.mdx" - - + diff --git a/services/reference/linea/json-rpc-methods/eth_blocknumber.mdx b/services/reference/linea/json-rpc-methods/eth_blocknumber.mdx index 076b45d83c..9c02f2a533 100644 --- a/services/reference/linea/json-rpc-methods/eth_blocknumber.mdx +++ b/services/reference/linea/json-rpc-methods/eth_blocknumber.mdx @@ -1,40 +1,13 @@ --- title: "eth_blockNumber" +hide_title: true +hide_table_of_contents: true --- -import Tabs from "@theme/Tabs" -import TabItem from "@theme/TabItem" +import ParserOpenRPC from "@site/src/components/ParserOpenRPC" +import { NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc" -import Description from "/services/reference/_partials/_eth_blocknumber-description.mdx" - - - -## Parameters - -import Params from "/services/reference/_partials/_eth_blocknumber-parameters.mdx" - - - -## Returns - -import Returns from "/services/reference/_partials/_eth_blocknumber-returns.mdx" - - - -## Example - -import Example from "/services/reference/_partials/_eth_blocknumber-example.mdx" - - - -### Request - -import Request from "./_eth_blocknumber-request.mdx" - - - -### Response - -import Response from "/services/reference/_partials/_eth_blocknumber-response.mdx" - - + diff --git a/services/reference/linea/json-rpc-methods/eth_chainid.mdx b/services/reference/linea/json-rpc-methods/eth_chainid.mdx index a6f446ad26..f0dd180f23 100644 --- a/services/reference/linea/json-rpc-methods/eth_chainid.mdx +++ b/services/reference/linea/json-rpc-methods/eth_chainid.mdx @@ -1,40 +1,13 @@ --- title: "eth_chainId" +hide_title: true +hide_table_of_contents: true --- -import Tabs from "@theme/Tabs" -import TabItem from "@theme/TabItem" +import ParserOpenRPC from "@site/src/components/ParserOpenRPC" +import { NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc" -import Description from "/services/reference/_partials/_eth_chainid-description.mdx" - - - -## Parameters - -import Params from "/services/reference/_partials/_eth_chainid-parameters.mdx" - - - -## Returns - -import Returns from "/services/reference/_partials/_eth_chainid-returns.mdx" - - - -## Example - -import Example from "/services/reference/_partials/_eth_chainid-example.mdx" - - - -### Request - -import Request from "./_eth_chainid-request.mdx" - - - -### Response - -import Response from "/services/reference/_partials/_eth_chainid-response.mdx" - - + diff --git a/services/reference/linea/json-rpc-methods/eth_gasprice.mdx b/services/reference/linea/json-rpc-methods/eth_gasprice.mdx index 8980dcc8a3..abe151ba1a 100644 --- a/services/reference/linea/json-rpc-methods/eth_gasprice.mdx +++ b/services/reference/linea/json-rpc-methods/eth_gasprice.mdx @@ -1,40 +1,13 @@ --- title: "eth_gasPrice" +hide_title: true +hide_table_of_contents: true --- -import Tabs from "@theme/Tabs" -import TabItem from "@theme/TabItem" +import ParserOpenRPC from "@site/src/components/ParserOpenRPC" +import { NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc" -import Description from "/services/reference/_partials/_eth_gasprice-description.mdx" - - - -## Parameters - -import Params from "/services/reference/_partials/_eth_gasprice-parameters.mdx" - - - -## Returns - -import Returns from "/services/reference/_partials/_eth_gasprice-returns.mdx" - - - -## Example - -import Example from "/services/reference/_partials/_eth_gasprice-example.mdx" - - - -### Request - -import Request from "./_eth_gasprice-request.mdx" - - - -### Response - -import Response from "/services/reference/_partials/_eth_gasprice-response.mdx" - - + diff --git a/services/reference/linea/json-rpc-methods/eth_maxpriorityfeepergas.mdx b/services/reference/linea/json-rpc-methods/eth_maxpriorityfeepergas.mdx index 6f818052ae..58cede5ca0 100644 --- a/services/reference/linea/json-rpc-methods/eth_maxpriorityfeepergas.mdx +++ b/services/reference/linea/json-rpc-methods/eth_maxpriorityfeepergas.mdx @@ -1,40 +1,13 @@ --- title: "eth_maxPriorityFeePerGas" +hide_title: true +hide_table_of_contents: true --- -import Tabs from "@theme/Tabs" -import TabItem from "@theme/TabItem" +import ParserOpenRPC from "@site/src/components/ParserOpenRPC" +import { NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc" -import Description from "/services/reference/_partials/_eth_maxpriorityfeepergas-description.mdx" - - - -## Parameters - -import Params from "/services/reference/_partials/_eth_maxpriorityfeepergas-parameters.mdx" - - - -## Returns - -import Returns from "/services/reference/_partials/_eth_maxpriorityfeepergas-returns.mdx" - - - -## Example - -import Example from "/services/reference/_partials/_eth_maxpriorityfeepergas-example.mdx" - - - -### Request - -import Request from "./_eth_maxpriorityfeepergas-request.mdx" - - - -### Response - -import Response from "/services/reference/_partials/_eth_maxpriorityfeepergas-response.mdx" - - + diff --git a/services/reference/linea/json-rpc-methods/eth_syncing.mdx b/services/reference/linea/json-rpc-methods/eth_syncing.mdx index 7ffbcd4456..0abb7fd5cf 100644 --- a/services/reference/linea/json-rpc-methods/eth_syncing.mdx +++ b/services/reference/linea/json-rpc-methods/eth_syncing.mdx @@ -1,40 +1,13 @@ --- title: "eth_syncing" +hide_title: true +hide_table_of_contents: true --- -import Tabs from "@theme/Tabs" -import TabItem from "@theme/TabItem" +import ParserOpenRPC from "@site/src/components/ParserOpenRPC" +import { NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc" -import Description from "/services/reference/_partials/_eth_syncing-description.mdx" - - - -## Parameters - -import Params from "/services/reference/_partials/_eth_syncing-parameters.mdx" - - - -## Returns - -import Returns from "/services/reference/_partials/_eth_syncing-returns.mdx" - - - -## Example - -import Example from "/services/reference/_partials/_eth_syncing-example.mdx" - - - -### Request - -import Request from "./_eth_syncing-request.mdx" - - - -### Response - -import Response from "/services/reference/_partials/_eth_syncing-response.mdx" - - + diff --git a/src/components/ParserOpenRPC/DetailsBox/MDContent.tsx b/src/components/ParserOpenRPC/DetailsBox/MDContent.tsx index fcd8e3eeba..1cc4bc463e 100644 --- a/src/components/ParserOpenRPC/DetailsBox/MDContent.tsx +++ b/src/components/ParserOpenRPC/DetailsBox/MDContent.tsx @@ -1,43 +1,48 @@ import React from "react"; -const parseLists = (content: string) => { - const lines = content.split('\n'); +const parseLists = (text: string) => { + const lines = text.split('\n'); let result = ''; - let isFirstLevelOpen = false; - let isSecondLevelOpen = false; + let inList = false; + let inSubList = false; + lines.forEach((line) => { - if (line.match(/^ {2}-\s+/)) { - if (!isSecondLevelOpen) { - result += '
    '; - isSecondLevelOpen = true; - } - result += `
  • ${line.trim().substring(4)}
  • `; - } else if (line.match(/^ -\s+/)) { - if (isSecondLevelOpen) { - result += '
'; - isSecondLevelOpen = false; + const trimmed = line.trim(); + const isListItem = trimmed.startsWith('- '); + const isSubListItem = line.startsWith(' - '); + + if (isListItem && !isSubListItem) { + if (!inList) { + result += '
    \n'; + inList = true; + } else if (inSubList) { + result += '
\n'; + inSubList = false; } - if (!isFirstLevelOpen) { - result += '
    '; - isFirstLevelOpen = true; + result += `
  • ${trimmed.slice(2).trim()}
  • \n`; + } else if (isSubListItem) { + if (!inSubList) { + result = result.replace(/<\/li>\n$/, ''); + result += '
      \n'; + inSubList = true; } - result += `
    • ${line.trim().substring(2)}
    • `; + result += `
    • ${trimmed.slice(4).trim()}
    • \n`; } else { - if (isSecondLevelOpen) { - result += '
    '; - isSecondLevelOpen = false; + if (inSubList) { + result += '
\n'; + inSubList = false; } - if (isFirstLevelOpen) { - result += ''; - isFirstLevelOpen = false; + if (inList) { + result += '\n'; + inList = false; } - result += line; + result += `${line}\n`; } }); - if (isSecondLevelOpen) result += ''; - if (isFirstLevelOpen) result += ''; + if (inSubList) result += '\n'; + if (inList) result += '\n'; return result; -}; +} const parseMarkdown = (content: string) => { return parseLists( @@ -45,6 +50,7 @@ const parseMarkdown = (content: string) => { .replace(/\[(.*?)\]\((.*?)\)/g, '$1') .replace(/`(.*?)`/g, '$1') .replace(/\*\*(.*?)\*\*/g, '$1') + .replace(/\*(.*?)\*/g, '$1') ); }; diff --git a/src/components/ParserOpenRPC/DetailsBox/RenderParams.tsx b/src/components/ParserOpenRPC/DetailsBox/RenderParams.tsx index 887b977a4f..79444a968a 100644 --- a/src/components/ParserOpenRPC/DetailsBox/RenderParams.tsx +++ b/src/components/ParserOpenRPC/DetailsBox/RenderParams.tsx @@ -96,6 +96,10 @@ const renderSchema = (schemaItem, schemas, name) => { ); + if (schemaItem?.schema?.oneOf) return renderCombinations(schemaItem.schema, name, "oneOf"); + if (schemaItem?.schema?.allOf) return renderCombinations(schemaItem.schema, name, "allOf"); + if (schemaItem?.schema?.anyOf) return renderCombinations(schemaItem.schema, name, "anyOf"); + if (schemaItem.oneOf) return renderCombinations(schemaItem, name, "oneOf"); if (schemaItem.allOf) return renderCombinations(schemaItem, name, "allOf"); if (schemaItem.anyOf) return renderCombinations(schemaItem, name, "anyOf"); @@ -184,5 +188,9 @@ export const renderParamSchemas = (inputSchema, schemas) => { }; export const renderResultSchemas = (inputSchema, schemas) => { + const customResult = inputSchema?.schema?.maxPriorityFeePerGas; + if (customResult) { + return <>{renderSchema(customResult, schemas, inputSchema.name)} + } return <>{renderSchema(inputSchema, schemas, inputSchema.name)}; }; diff --git a/src/components/ParserOpenRPC/DetailsBox/index.tsx b/src/components/ParserOpenRPC/DetailsBox/index.tsx index 912b1640e9..e72022c881 100644 --- a/src/components/ParserOpenRPC/DetailsBox/index.tsx +++ b/src/components/ParserOpenRPC/DetailsBox/index.tsx @@ -18,6 +18,7 @@ interface TagItem { interface DetailsBoxProps { method: string; description: string | null; + summary: string | null; params: MethodParam[]; components: SchemaComponents; result: any; @@ -28,6 +29,7 @@ interface DetailsBoxProps { export default function DetailsBox({ method, description, + summary, params, components, result, @@ -46,7 +48,14 @@ export default function DetailsBox({ )} {method} - + {summary !== null && ( +

+ +

+ )} + {description !== null && ( + + )} {extraContent &&
{extraContent}
} void; + requestURL: string; + isLoading: boolean; } export default function RequestBox({ @@ -32,6 +33,8 @@ export default function RequestBox({ isMetamaskNetwork = false, defExampleResponse, resetResponseHandle, + requestURL = "", + isLoading, }: RequestBoxProps) { const { userAPIKey } = useContext(MetamaskProviderContext); const exampleRequest = useMemo(() => { @@ -41,7 +44,7 @@ export default function RequestBox({ if (isMetamaskNetwork) { return `await window.ethereum.request({\n "method": "${method}",\n "params": ${preparedParams.replace(/"([^"]+)":/g, '$1:')},\n});`; } - return `curl ${LINEA_REQUEST_URL}/v3/${API_KEY} \\\n -X POST \\\n -H "Content-Type: application/json" \\\n -d '{\n "jsonrpc": "2.0",\n "method": "${method}",\n "params": ${preparedShellParams},\n "id": 1\n }'`; + return `curl ${requestURL}${API_KEY} \\\n -X POST \\\n -H "Content-Type: application/json" \\\n -d '{\n "jsonrpc": "2.0",\n "method": "${method}",\n "params": ${preparedShellParams},\n "id": 1\n }'`; }, [userAPIKey, method, paramsData]); const exampleResponse = useMemo(() => { @@ -59,18 +62,18 @@ export default function RequestBox({ }, [response, defExampleResponse]); const methodsWithRequiredWalletConnection = ["eth_accounts", "eth_sendTransaction", "personal_sign", "eth_signTypedData_v4"]; - const isRunAndCustomizeRequestDisabled = methodsWithRequiredWalletConnection.includes(method) ? + const isRunAndCustomizeRequestDisabled = isMetamaskNetwork && methodsWithRequiredWalletConnection.includes(method) ? !isMetamaskInstalled : false; const runRequestButton = ( ); diff --git a/src/components/ParserOpenRPC/RequestBox/styles.module.css b/src/components/ParserOpenRPC/RequestBox/styles.module.css index 78f14a484a..0ded51e680 100644 --- a/src/components/ParserOpenRPC/RequestBox/styles.module.css +++ b/src/components/ParserOpenRPC/RequestBox/styles.module.css @@ -40,3 +40,28 @@ background: none; border: 0; } + +.runBtnWrap { + display: flex; + justify-content: center; + min-width: 109px; +} + +.loader { + width: 16px; + height: 16px; + border: 2px solid #FFF; + border-bottom-color: transparent; + border-radius: 50%; + display: inline-block; + animation: rotation 1s linear infinite; +} + +@keyframes rotation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/src/components/ParserOpenRPC/index.tsx b/src/components/ParserOpenRPC/index.tsx index 9f39881622..935e66ab95 100644 --- a/src/components/ParserOpenRPC/index.tsx +++ b/src/components/ParserOpenRPC/index.tsx @@ -6,7 +6,6 @@ import React, { useEffect, } from "react"; import { usePluginData } from "@docusaurus/useGlobalData"; -import { useLocation } from "@docusaurus/router"; import { ResponseItem, NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc"; import DetailsBox from "@site/src/components/ParserOpenRPC/DetailsBox"; import InteractiveBox from "@site/src/components/ParserOpenRPC/InteractiveBox"; @@ -24,7 +23,7 @@ import { import { AuthBox } from "@site/src/components/ParserOpenRPC/AuthBox"; import { MetamaskProviderContext } from "@site/src/theme/Root"; import ProjectsBox from "@site/src/components/ParserOpenRPC/ProjectsBox"; -import { LINEA_REQUEST_URL, REF_PATH } from "@site/src/lib/constants"; +import { LINEA_REQUEST_URL } from "@site/src/lib/constants"; interface ParserProps { network: NETWORK_NAMES; @@ -49,8 +48,6 @@ export default function ParserOpenRPC({ extraContent, }: ParserProps) { if (!method || !network) return null; - const location = useLocation(); - const { pathname } = location; const [isModalOpen, setModalOpen] = useState(false); const [reqResult, setReqResult] = useState(undefined); const [paramsData, setParamsData] = useState([]); @@ -59,6 +56,7 @@ export default function ParserOpenRPC({ const [isComplexTypeView, setIsComplexTypeView] = useState(false); const { metaMaskAccount, metaMaskProvider, userAPIKey } = useContext(MetamaskProviderContext); const [defExampleResponse, setDefExampleResponse] = useState(undefined); + const [isLoading, setIsLoading] = useState(false); const { colorMode } = useColorMode(); const trackAnalyticsForRequest = (response) => { trackClickForSegment({ @@ -124,7 +122,8 @@ export default function ParserOpenRPC({ ); return { - description: currentMethod.description || currentMethod.summary || null, + description: currentMethod.description || null, + summary: currentMethod.summary || null, params: currentMethod.params || [], result: currentMethod.result || null, components: currentNetwork.data.components || null, @@ -132,6 +131,7 @@ export default function ParserOpenRPC({ paramStructure: currentMethod?.paramStructure || null, errors, tags, + servers: currentNetwork.data?.servers?.[0]?.url || null }; }, [currentNetwork, method]); @@ -187,39 +187,71 @@ export default function ParserOpenRPC({ setParamsData(Object.values(data)); }; - const onSubmitRequestHandle = async () => { - if (isMetamaskNetwork) { - if (!metaMaskProvider) return - try { - const response = await metaMaskProvider?.request({ - method: method, - params: paramsData - }) - setReqResult(response); - trackAnalyticsForRequest(response); - } catch (e) { - setReqResult(e); - } + const handleMetaMaskRequest = async () => { + if (!metaMaskProvider) return; + setIsLoading(true); + try { + const response = await metaMaskProvider.request({ + method, + params: paramsData, + }); + setReqResult(response); + trackAnalyticsForRequest(response); + } catch (e) { + setReqResult(e); + } finally { + setIsLoading(false); + } + }; + + const getInfuraUrl = (url: string) => { + if (process.env.VERCEL_ENV === "production") { + return url; } else { - const URL = `${LINEA_REQUEST_URL}/v3/${userAPIKey}`; - let params = { - method: "POST", + return url.replace("infura.io", "dev.infura.org"); + } + } + + const INIT_URL = currentMethodData.servers !== null ? getInfuraUrl(currentMethodData.servers) : `${LINEA_REQUEST_URL}/v3/`; + + const handleServiceRequest = async () => { + const URL = `${INIT_URL}${userAPIKey}`; + const params = { + method: "POST", + headers: { "Content-Type": "application/json", - body: JSON.stringify({ - jsonrpc: "2.0", - method, - params: paramsData, - id: 1, - }), - }; + }, + body: JSON.stringify({ + jsonrpc: "2.0", + method, + params: paramsData, + id: 1, + }), + }; + setIsLoading(true); + try { const res = await fetch(URL, params); if (res.ok) { const response = await res.json(); - setReqResult(response.result); - trackAnalyticsForRequest(response.result); + setReqResult(response); + trackAnalyticsForRequest(response); } else { - console.error("error"); + const errorText = await res.text(); + const errorState = JSON.parse(errorText); + setReqResult(`Request failed. Status: ${res.status}. ${errorState}`); } + } catch (e) { + setReqResult(`${e}`); + } finally { + setIsLoading(false); + } + }; + + const onSubmitRequestHandle = async () => { + if (isMetamaskNetwork) { + await handleMetaMaskRequest(); + } else { + await handleServiceRequest(); } }; @@ -250,6 +282,7 @@ export default function ParserOpenRPC({
- {pathname.startsWith(REF_PATH) && } - {!pathname.startsWith(REF_PATH) && !metaMaskAccount && ( + {!isMetamaskNetwork && } + {isMetamaskNetwork && !metaMaskAccount && ( )}
diff --git a/src/css/custom.css b/src/css/custom.css index 637fe43655..20d51c594d 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -359,6 +359,10 @@ button:hover { color: #ffffff; } +[data-theme="light"] .react-dropdown-select-dropdown-handle { + color: #24272A; +} + @media (width <= 1200px) { .navbar__item, .navbar__link { From cf602757899239f6cd0588d49233eb25ad550d7b Mon Sep 17 00:00:00 2001 From: ae_atrofimov Date: Thu, 3 Oct 2024 18:21:08 +0200 Subject: [PATCH 2/3] feat(ref): added minor style fix --- src/components/ParserOpenRPC/ProjectsBox/styles.module.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/ParserOpenRPC/ProjectsBox/styles.module.scss b/src/components/ParserOpenRPC/ProjectsBox/styles.module.scss index 0f4a1a4160..67fbf06734 100644 --- a/src/components/ParserOpenRPC/ProjectsBox/styles.module.scss +++ b/src/components/ParserOpenRPC/ProjectsBox/styles.module.scss @@ -3,6 +3,7 @@ --select-value-color: #BBC0C5; --select-label-color: #fff; --select-item-hover: #000; + --select-color-title: #fff; } :root[data-theme="light"] { @@ -10,6 +11,7 @@ --select-value-color: #24272A; --select-label-color: #24272A; --select-item-hover: #BBC0C5; + --select-color-title: #24272A; } .selectWrapper { @@ -33,7 +35,7 @@ justify-content: center; align-items: center; background-color: var(--select-bg); - color: #ffffff; + color: var(--select-color-title); } .selectDropdown { From f9ddecbe67ae78cc1d6962e41f5ebbab9ca8874b Mon Sep 17 00:00:00 2001 From: ae_atrofimov Date: Fri, 4 Oct 2024 11:23:08 +0200 Subject: [PATCH 3/3] feat(ref): fix for init collapse state --- .../ParserOpenRPC/CollapseBox/CollapseBox.tsx | 10 ++++------ .../ParserOpenRPC/DetailsBox/RenderParams.tsx | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/ParserOpenRPC/CollapseBox/CollapseBox.tsx b/src/components/ParserOpenRPC/CollapseBox/CollapseBox.tsx index 0cb4a1e776..556d927c72 100644 --- a/src/components/ParserOpenRPC/CollapseBox/CollapseBox.tsx +++ b/src/components/ParserOpenRPC/CollapseBox/CollapseBox.tsx @@ -14,14 +14,12 @@ interface CollapseBoxProps { export const CollapseBox = ({ children, - isInitCollapsed = false, + isInitCollapsed = true, }: CollapseBoxProps) => { - const { collapsed, toggleCollapsed } = useCollapsible({ initialState: true }); + const { collapsed, setCollapsed } = useCollapsible({ initialState: isInitCollapsed }); const { colorMode } = useColorMode(); useEffect(() => { - if (isInitCollapsed) { - toggleCollapsed(); - } + setCollapsed(isInitCollapsed); }, [isInitCollapsed]); return (
setCollapsed((expanded) => !expanded)} > {collapsed ? "Show child attributes" : "Hide child attributes"}
{ description={item.description || item.title || ""} />
- + <> {Object.entries(item.properties).map(([key, value]) => (