OneGraph/graphiql-code-exporter

Support for file generation

Opened this issue · 10 comments

Currently this library supports generating snippets which can be copy/pasted. It would be good to open up the "methods" of code exporting to allow things like exporting straight to file.

I would like to introduce an additional opt-in button that when clicked would allow a function passed via a prop to be called. A consuming library can therefore implement this however they please (writing the file to disk, etc), but benefits by allowing this library to render the snippets as usual.

What do you think to this?

This is a great idea! If the end-developer provides a onCodeExported prop then we can render another button for export, that'll provide the final generated code to the callback, and the developer can do with it what they like. Would that work for you?

Brilliant I'll get a PR together in due course. Thanks @sgrove. Is there any chance I can ask for a "new file" svg, equivalent to the copy icon?

What are your thoughts on an input for a filename?

Yeah, I'll get an svg icon for you.

I suspect that the snippets should probably return an array of objects:

[{
  path: "src/client.js"
  content: "..."
},
{
  path: "src/components.js"
  content: "..."
}
]

They should render the files in the same view, but exporting should give the caller the chance to write multiple files all at once. This is helpful for setting up e.g. ApolloClient.js, etc.

They should render the files in the same view, but exporting should give the caller the chance to write multiple files all at once. This is helpful for setting up e.g. ApolloClient.js, etc.

That's an interesting approach. In my use case, I have several distinct snippets that the user can choose and exporting only needs to create a single file. However the name is variable, so I can't just go with src/client.js, I need the user to provide a name of a snippet i.e "SearchBox" which we can then generate a file: src/SearchBox.jsx

pieh commented

Even for usage in Gatsby, having ability to generate multiple snippets might be valuable:

In the case of snippet that we skipped for initial integration ( in gatsbyjs/gatsby#17120 ), we were generating single snippet for gatsby-node.js file, but if we look at workflow that user might be interested in doing - there would be benefit in supporting multiple snippets (so generate snippet that creates pages in gatsby-node.js and then snippet for each page template that is referenced there) - this way user wouldn't have to generate those snippets as separate steps - instead entire flow would be packed in single code generation step. We will have some problems to solve in our custom code for that (because we would need to manipulate queries a bit for each snippet), but this isn't concern of this package ;)

Dialing back talk about gatsby usage - I'm wondering if instead of trying to add this new button in graphiql-code-exporter that is focused in this specific use case - maybe there could be slots that user can add custom piecies of UI? Similar to how graphiql allow you to control toolbar with <GraphiQL.Toolbar>? And allow using render prop (or something like this) so those UI pieces get access to generated snippets etc?

instead entire flow would be packed in single code generation step

That's a pretty decent approach. If it wasn't obvious already, I was trying to lay the groundwork here for Gatsby 😄 , perhaps supporting an array would be useful in this library even if initial, simple consumer implementations don't support multi-generation.

maybe there could be slots that user can add custom piecies of UI

I'm interested to see how that would play out. Sometimes being overly generic can lead to a clunky UI. My best suggestion at the moment is to:

  1. Open up the options fields to accept inputs, this has it's advantages anyway as boolean's only work for some use cases
  2. Allow programmatic options generation, currently the options are hardcoded to the snippet. If we want the above to work with inputs we could parse the query and generate the correct number of inputs
pieh commented

I'm interested to see how that would play out. Sometimes being overly generic can lead to a clunky UI.

For sure - all approaches come with their own pros and cons (both for users and maintainers). I just think it's helpful to at least consider potential options. At this point going for generic solutions might not be best course of action but worth thinking if this would be ultimate goal (some time in the future) - and if so, how would potential migration path look like.

My best suggestion at the moment is to:

  1. Open up the options fields to accept inputs, this has it's advantages anyway as boolean's only work for some use cases
  2. Allow programmatic options generation, currently the options are hardcoded to the snippet. If we want the above to work with inputs we could parse the query and generate the correct number of inputs

Yup, I arrived at very similar conclusions when I was experimenting/hacking around some time ago (please don't judge my UI :D):
Screenshot 2019-09-04 at 18 09 02

Yup, I arrived at very similar conclusions when I was experimenting/hacking around some time ago

That's good to hear, @sgrove how do you feel about this solution? If you're happy, I can start putting a PR together and we can have a conversation over it

Yeah, I think making the header panel controls configurable for a snippet makes sense!