shikijs / twoslash

You take some Shiki, add a hint of TypeScript compiler, and šŸŽ‰ incredible static code samples
https://shikijs.github.io/twoslash/
MIT License
1.08k stars 54 forks source link

[remark-shiki-twoslash] passing multiple themes produces code wrapped by undefined tag #108

Closed zoubingwu closed 3 years ago

zoubingwu commented 3 years ago

just change transpile option in test/mdx.test.ts to multiple themes

- const transpile = async (str: string, opts: UserConfigSettings = { theme: "dark-plus" }) => {
+ const transpile = async (str: string, opts: UserConfigSettings = { themes: ["dark-plus", "light-plus"] }) => {
  const jsx = await mdx(str, {
    filepath: "file/path/file.mdx",
    remarkPlugins: [[remarkShikiTwoslash, opts]],
  })
  return jsx
}

try log one of the result and re-run test

const res = await transpile(content)
+ console.log(res)

the output:

const layoutProps = {

};
const MDXLayout = "wrapper"
export default function MDXContent({
  components,
  ...props
}) {
  return <MDXLayout {...layoutProps} {...props} components={components} mdxType="MDXLayout">
    <h1>{`Hello, world!`}</h1>
    <undefined><pre {...{
      "className": "shiki dark-plus twoslash lsp",
      "style": {
        "backgroundColor": "#1E1E1E",
        "color": "#D4D4D4"
      }
    }}><div parentName="pre" {...{
      "className": "language-id"
    }}>{`ts`}</div><div parentName="pre" {...{
      "className": "code-container"
    }}><code parentName="div"><div parentName="code" {...{
      "className": "line"
    }}><span parentName="div" {...{
      "style": {
        "color": "#569CD6"
      }
    }}>{`const`}</span><span parentName="div" {...{
      "style": {
        "color": "#D4D4D4"
      }
    }}>{` `}</span><span parentName="div" {...{
      "style": {
        "color": "#4FC1FF"
      }
    }}><data-lsp parentName="span" {...{
      "lsp": "const a: \"123\""
    }}>{`a`}</data-lsp></span><span parentName="div" {...{
      "style": {
        "color": "#D4D4D4"
      }
    }}>{` = `}</span><span parentName="div" {...{
      "style": {
        "color": "#CE9178"
      }
    }}>{`'123'`}</span></div></code></div></pre>
      <pre {...{
        "className": "shiki light-plus twoslash lsp",
        "style": {
          "backgroundColor": "#FFFFFF",
          "color": "#000000"
        }
      }}><div parentName="pre" {...{
        "className": "language-id"
      }}>{`ts`}</div><div parentName="pre" {...{
        "className": "code-container"
      }}><code parentName="div"><div parentName="code" {...{
        "className": "line"
      }}><span parentName="div" {...{
        "style": {
          "color": "#0000FF"
        }
      }}>{`const`}</span><span parentName="div" {...{
        "style": {
          "color": "#000000"
        }
      }}>{` `}</span><span parentName="div" {...{
        "style": {
          "color": "#0070C1"
        }
      }}><data-lsp parentName="span" {...{
        "lsp": "const a: \"123\""
      }}>{`a`}</data-lsp></span><span parentName="div" {...{
        "style": {
          "color": "#000000"
        }
      }}>{` = `}</span><span parentName="div" {...{
        "style": {
          "color": "#A31515"
        }
      }}>{`'123'`}</span></div></code></div></pre></undefined>
  </MDXLayout>;
}

;
MDXContent.isMDXComponent = true;

you can find that those content in two themes wrapped by pre tag are inside an undefined tag, it won't cause any problem affecting the user but react dev tool will throw an error about The tag <undefined> is unrecognized in this browser

frencojobs commented 3 years ago

Thanks for the extensive explanation.

For rendering in MDX, use the wrapFragments option which will use <div class="shiki-twoslash-fragment"> as wrapper instead of undefined. You can then set your renderer to replace that div with a React.Fragment during runtime if you will. It is, in fact, how it's done in the Docusaurus plugin. The tests are fine, but yes I agree we might want to add that to the documentation.

zoubingwu commented 3 years ago

@frencojobs

Cool! Yeah didn't see any docs about wrapFragments option until now šŸ˜‚šŸ˜‚šŸ˜‚ should have checked the typing of options at first but indeed it would be better to add it in documentation.

Thanks for your quick reply! I'll leave this issue here in case any one else having the same problem but feel free to close it as my problem already solved.