Storybook: Addon-controls: JSON Editor/Treeview for Object Properties

Created on 28 Sep 2020  路  11Comments  路  Source: storybookjs/storybook

Is your feature request related to a problem? Please describe
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

  • I have some object properties that are long/nested/hard to read when displayed as unformatted text using the current "textbox" in storybook.
  • I'd like to have a more organized way to navigate my JSON properties as an option. (It doesn't need to replace the existing text option, it would just be good to have 1 more choice).

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

  • Pretty-printing the JSON string prior to putting it into the textbox so it isn't all squashed onto 1 line
  • Instead of implementing something custom, using an existing JsonEditor component

Are you able to assist to bring the feature to reality?
no | yes, I can...

  • I can help with testing, or possibly implementation with some pointers about what region of code to modify, assuming that this new control is something that matches Storybook's goals.

Additional context
Add any other context or screenshots about the feature request here.

PN controls feature request

Most helpful comment

@hydrosquall i think the JSON editor will be strictly better than the text field, and if it's not we should work on it until it is. in that case a full replacement would be the way to go!

All 11 comments

This looks fantastic! Would love a PR for it, and it would probably be a pretty isolated change here:

https://github.com/storybookjs/storybook/blob/next/lib/components/src/controls/Object.tsx

If you'd like to take it on, we'd be happy to help you get set up to do it in Discord https://discord.gg/UUt2PJb

I love the Cosmos implementation, but what if for a quick win to achieve proper formatting we just pretty printed the JSON prior to adding it to the textarea value?

Change Line 9 from Object.tsx

const format = (value: any) => (value ? JSON.stringify(value) : '');

to

const format = (value: any) => (value ? JSON.stringify(value, null, 4) : '');

Thoughts? I can submit a PR to get this working if so (I also would like to have this!)

Edit: I have this working on my fork of Storybook:
Screen Shot 2020-09-29 at 3 31 01 PM

Functional video:
https://www.dropbox.com/s/26b9r1dfdtdfjjq/Screen%20Recording%202020-09-29%20at%203.35.47%20PM.mov?dl=0

@shilman I took a look at the ecosystem of react tree viewer components, and ruled out these two options that seemed focus on read-only views of trees data structures

Read-only trees

  • react-json-tree here is extracted from Redux Devtools, but it doesn't seem to have a clear "onChange" prop that I can hook into, despite the fact that redux devtools features an editable JSON tree. Note the README happens to point to other peer read-only tree viewer projects in the NPM ecosystem.
  • react-treebeard here is in the storybook ecosystem already, but it doesn't seem to lend itself to editable text fields.

Short of reusing the Cosmos TreeView directly, I came down to three final options for standalone trees that could be plugged into

Editable Trees

  • react-json-view: https://mac-s-g.github.io/react-json-view/demo/dist/, weighs 36 KB gzipped, last updated August 2018
  • react-editable-json-tree, https://oxyno-zeta.github.io/react-editable-json-tree/ weighs 18.6 KB gzipped , last updated May 2019
  • jsoneditor-react, https://github.com/vankop/jsoneditor-react weighs 226 KB gzipped (the react wrapper alone's stats are misleading since this the heaviest part of the dependency comes from the jsoneditor package itself, active project and last updated 6 days ago (September 2020).

This is why I think any of these could work, on a Goldilocks-style small/medium/large scale, depending on Storybook's goals / adding 3rd-party dependencies policy.

  • react-editable-json-tree if we just want something simple and reusable without a theme
  • react-json-view if we want a fancier theming capabilities with a bit more weight, and fancier styling on the various additional buttons (copy to clipboard, add more keys, etc)
  • jsoneditor-react if we aren't concerned about bundle weight and want to have full tree power (e.g. searching, filtering, export to file etc) for the JSON property. (My opinion is that this is a lot more complicated than what we need for a knob.

While react-editable-json-tree weighs the least and offers all the capabilities that we need, react-json-view offers the option of a few nice UX bonuses (copy to clipboard, show key datatype, collapse strings after a certain length, and fancier styling) that could be worth the extra bundle weight.

Let me know if you have a preference or any additional questions - otherwise, I'll take a pass at opening a PR with react-json-view or react-editable-json-tree later this week.

@hydrosquall thanks for doing the research on this. react-json-view looks pretty great.

@yannbf didn't you look at this at one point?

Hey @shilman I did! The drawback of using it was that react-json-view itself is not optimised so it adds quite some weight into the addon. The maintainer said he was busy but would review code from contributors, if they'd ever want to help optimise it. If I remember correctly, the themes add quite some weight, so if we could somehow strip them down and tree shake it, that would help reduce the end size of the package.

Here's the example of my POC, I really liked it:

@yannbf do you have a branch open with your POC? It sounds like you've already done what I was planning to.

Tree-shaking unused themes seems useful but I'm not sure that it's blocking concern for me. 36 kB gzipped ( https://bundlephobia.com/[email protected] ) seems reasonable in the scheme of a bundle that currently weighs 615 kb gzipped, a ~5% increase.

https://bundlephobia.com/result?p=@storybook/components@6.0.22

Hey @hydrosquall that's a preeetty old code but I will try to dig it up from my stash graveyard. Will let you know! We can definitely work on this together if you'd like!

Ok that was easier than expected. Here you go!

Quick tip for you!
Start with yarn bootstrap then install stuff and build core, that's the first step.

Then on terminal 1, build the addons you want on watch mode:

yarn build addon-knobs addon-controls --watch

On examples/official-storybook/main.ts, set a glob only to the stories that actually matter and you load them way faster:

module.exports = {
  stories: [
    './stories/**/with-knobs.stories.@(js|ts|tsx|mdx)',
    './stories/**/addon-controls.stories.@(js|ts|tsx|mdx)',
  ],
  ....
}

On terminal 2, start the official react storybook:

yarn start

Then have fun 馃拑

Tree-shaking unused themes seems useful but I'm not sure that it's blocking concern for me. 36 kB gzipped ( bundlephobia.com/[email protected] ) seems reasonable in the scheme of a bundle that currently weighs 615 kb gzipped, a ~5% increase.

We're actively working on performance these days and will be doing our best to slim this down. Adding another biggish dependency just creates more work for whoever is doing this optimization. that said, it's 175k unpacked, which isn't too bad compared to a bunch of our deps so i agree it's not a huge deal.

We're actively working on performance these days and will be doing our best to slim this down

Yea, I think this is good to aim for too. I don't have much experience with rewriting code so that it can be tree shaken, but perhaps that is a task we can look into as a follow-up once the initial tree control is added.

Regarding how the feature is actually implemented - would we want to replace the text-field based control completely, or do we want to provide the "tree" option just as an alternative? I don't want to break anybody's current workflow unexpectedly (but I think that this tree-based control is likely going to be a more useful default for many users).

@hydrosquall i think the JSON editor will be strictly better than the text field, and if it's not we should work on it until it is. in that case a full replacement would be the way to go!

Was this page helpful?
0 / 5 - 0 ratings