doczjs / docz

✍ It has never been so easy to document your things!
https://docz.site
MIT License
23.66k stars 1.46k forks source link

Use types and interfaces inside Playground #904

Closed nicolasbouffard closed 5 years ago

nicolasbouffard commented 5 years ago

Question

Description

Say I have the following working MDX :

<Playground>
  {() => {
    const person = {
      name: "John Doe"
    };

    return <div>{person.name}</div>
  }}
</Playground>

If I want to use TypeScript to write a type definition for the Person, I can't. The simple fact of adding a type or interface yields a SyntaxError: Unexpected token, expected ";" message :

<Playground>
  {() => {
    type Name = string;

    interface Person {
      name: Name;
    }

    const person: Person = {
      name: "John Doe"
    };

    return <div>{person.name}</div>
  }}
</Playground>

I can't add return types to functions either (same error message) :

<Playground>
  {() => {
    // This does not work :
    // const getHelloWorldMessage = (): string => "Hello world !"

    // But this does :
    const getHelloWorldMessage = () => "Hello world !"

    return <div>{getHelloWorldMessage()}</div>
  }}
</Playground>

I can import typed elements from outside the MDX and it works fine though :

// utils.tsx
export const getHelloWorldMessage = (): string => "Hello world !"
import { getHelloWorldMessage } from "./utils"

<Playground>
  {() => {
    return <div>{getHelloWorldMessage()}</div>
  }}
</Playground>

How can we do that ?

Edit : Just found out that we can't use the rest operator when destructuring props inside the playground either :

<Playground>
  {() => {
    const HelloWorld = ({
      message,
      ...rest
    }) => {
      console.log(rest)
      return <div>{message}</div>
    };

    return <HelloWorld message="Hello world !" otherProp="Some other prop"/>
  }}
</Playground>

This yields (LiveProvider, in Resizable (created by Playground)) TypeError: Cannot read property 'offsetWidth' of undefined. Adding this to the previous use cases makes it very hard to use the Playground for anything a bit more complicated than very basic components (buttons, alerts, etc.). Am I missing something ? Pretty much all the examples I have found only do that, but I feel like Docz can be used to provide a clean documentation for so much more complex components, if it wasn't for these issues...

nicolasbouffard commented 5 years ago

Since it doesn't seem possible for the time being to do what I want natively in the Playground, I had to use an alternative, which required some changes to the docz-theme-default and docz packages. I shared those modifications in the following PRs :

Those two PRs have been merged in the master branch on my fork if anybody is interested in trying this.

mgallagher commented 5 years ago

Hmmmm, I feel like TypeScript support should be more of a concern with React Live or Bublé rather than building a workaround into Playground.

One way you could maybe get around this is with the LiveProvider's transformCode prop + Babel. Check out this issue comment over on react-live. Assuming an approach like that works, you'd be able to write TS within the Playground like you were originally trying to do.

dreyks commented 5 years ago

So is there a workaround I can use with docz? I understand that I can pass transformCode prop to LiveProvider but there's no way for me to pass a custom transformCode when I use it as Playground