interactivethings / catalog

Create living style guides using Markdown or React
https://www.catalog.style/
BSD 3-Clause "New" or "Revised" License
1.6k stars 145 forks source link

Documenting Function-as-Child components #427

Open nicolaslohrer opened 6 years ago

nicolaslohrer commented 6 years ago

Hey guys,

I was wondering if you have any experience with documenting components which use the function-as-child / render props pattern. I'm trying to come up with a way to do so but the function that contains most of the meat of the implementation doesn't show up in the source code examples.

Here's how my page looks like:

export default () => markdown`
  ${(
    <ReactSpecimen>
      <TableProvider initialSortState={{ sortBy: "colB", order: "ASC" }}>
        {({ Table, THead, TBody, Tr, Th, Td, sort, sortState }) => (
          <React.Fragment>
            <Table>
              <THead>
                <Tr>
                  <Th name={"colA"}>Column A</Th>
                  <Th name={"colB"}>Column B</Th>
                </Tr>
              </THead>
              <TBody>
                <Tr>
                  <Td>test</Td>
                  <Td>test</Td>
                </Tr>
                <Tr>
                  <Td>test</Td>
                  <Td>test</Td>
                </Tr>
              </TBody>
            </Table>
          </React.Fragment>
        )}
      </TableProvider>
    </ReactSpecimen>
  )}
`;

However, all that actually shows up in the source code example is this:

<TableProvider initialSortState={{"sortBy":"colB","order":"ASC"}}>

</TableProvider>

I could somehow get it to work by following the advice from @herrstucki in #261 and putting the entire <TableProvider /> into a string like this:

export default () => markdown`
  ${(
    <ReactSpecimen>
      {` // that's where the string begins ...
        <TableProvider initialSortState={{ sortBy: "colB", order: "ASC" }}>
          {({ Table, THead, TBody, Tr, Th, Td, sort, sortState }) => (
            <React.Fragment>
              ...
            </React.Fragment>
          )}
        </TableProvider>
      `}
    </ReactSpecimen>
  )}
`;

That does exactly what I'm looking for: the component is rendered and I can see the entire code. However, that solution seems like it comes with sacrificing syntax highlighting, prettier's auto-formatting, IntelliSense, autocomplete, and TypeScript's static type checks. And I suppose the builds would no longer break when there's a bug within the stringified code.

After a bit of research this doesn't seem like an easy one to me. But maybe you guys have some ideas I haven't considered yet? :)

All this aside, I'm really impressed by Catalog! I've been trying Storybook and Styleguidist these last days, but Catalog is starting to become my favorite. Thanks a lot!

Nicolas

jstcki commented 6 years ago

Hi! You can set the sourceText prop on ReactSpecimen to control what’s displayed as source. Or use the catalog/babel Babel preset which does that automatically for you.

nicolaslohrer commented 6 years ago

Huh, I didn’t know about that, thanks! Just to be sure I get this: Using sourceText would require copying the code into a string and passing it to ReactSpecimen, right? I guess the babel preset would be the more elegant solution then. I’m using create-react-app with react-scripts-ts which doesn’t allow modifying the babel config. So my options are a custom react setup or manually copying code into sourceText, right?