Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Markdown Generation, Types, UI/UX Overhaul #210

Open
sean-perkins opened this issue Aug 25, 2022 · 11 comments
Open

Proposal: Markdown Generation, Types, UI/UX Overhaul #210

sean-perkins opened this issue Aug 25, 2022 · 11 comments

Comments

@sean-perkins
Copy link
Contributor

I have a couple different changes I think could benefit this project. Let me know if you would be open to these changes and I'd be happy to do the work of submitting PRs around them.

1. Refactor markdown generation to JSX

Currently the generation of markdown is handled through a custom utility defined in docusaurus-plugin-openapi. The implementation uses these to generate the independent sections, such as: createParamsTable, createStatusCodesTable, etc.

I'd like to propose refactoring these to render with React directly, to eliminate the declarative pattern of:

create("thead", {
  children: create("tr", {
    children: create("th", {
      style: { textAlign: "left" },
      children: `${
        type.charAt(0).toUpperCase() + type.slice(1)
      } Parameters`,
    }),
  }),
}),

and moving to:

return (
  <thead>
    <tr>
      <th style={textAlign: 'left' }>
        {type.chartAt(0).toUpperCase() + type.slice(1)} Parameters
      </th>
    </tr>
  </thead>
);

When docusaurus builds, the SSR behavior will still output the contents as HTML.

The benefits here are:

  1. Removes internal utils for DOM creation
  2. Standardizes on HTML/JSX
  3. Allows for more complex UI implementations that the existing utilities would not easily satisfy

2. Move markdown sections to docusaurus-theme-openapi

By moving the markdown section components (params table, status table, etc.) to the theme and exporting from that library, developers can more easily build custom ApiItem/ApiPage implementations, while reusing more of the internal sections.

For example, in my project I have a custom apiItemComponent defined & then need to manage recreating the UI if I want to customize the ApiContent section. Ideally I could reference all the existing sections and render a custom implementation for a specific section (e.g.: createStatusCodesTable).

3. Expose OpenAPI types

Continuing on the 2nd point, I would like to expose the OpenAPI types declared here: https://github.com/cloud-annotations/docusaurus-openapi/blob/main/packages/docusaurus-plugin-openapi/src/types.ts to the entry point of the module. This would allow custom implementations that are building custom section replacements, to leverage the existing types.

4. UI/UX Overhaul

I am unsure if the current design is based off any thing specific. The project that I am migrating to docusaurus currently is hosted in Readme.io. Their UI design has some nice improvements that I think would enhance this plugin: https://sample-threes.readme.io/reference/authentication-1

If approved, I would like to merge this work into a "next" branch, and split up the individual migrations. We wouldn't need to match the design 1:1, but there are a few immediate differences that I think would benefit this project:

  • Color coded request methods & combining the request method and server url into a single area

Screen Shot 2022-08-24 at 9 04 00 PM

  • Move the inputs for path params/request body in the same area as their API description (also clicking the path parameter focuses the input)

Screen Shot 2022-08-24 at 9 04 44 PM

  • Click a response opens a dialog with the shape of the response:

Screen Shot 2022-08-24 at 9 05 32 PM

  • Users can click predefined response examples

Screen Shot 2022-08-24 at 9 06 12 PM

  • The language options can handle many options, without clipping off the screen.

Screen Shot 2022-08-24 at 9 06 41 PM

@sean-perkins
Copy link
Contributor Author

Here is an example of what a redesign of the middle pane in the OpenAPI docs could look like for this plugin:

Kapture.2022-08-25.at.22.03.35.mp4

In addition to upgraded visuals, we can also accomplish the same type of response previewing that you can see in the Readme example.

With this section upgraded, you can see how some of the information in the right pane becomes obsolete. This allows us to maximize the real estate for the example code snippets (arguably the more important information).

@semoal
Copy link

semoal commented Aug 27, 2022

Just for adding context to this proposal, from my side didn't used yet this plugin because didn't match well the requirements I find relevant for my API clients. With the new design proposal will be perfectly FIT everything we need. Clean, informative and easy to try the API.
For me +100 to all the proposals @sean-perkins proposed here! gj

@bourdakos1
Copy link
Member

This all sounds great to me 😁

@arrigolupori
Copy link

@sean-perkins @bourdakos1 I'm also on board with the proposed changes and can contribute to smaller tasks with Sean if it would be of help. I want to use Docusaurus but want to ensure great support for the OpenAPI spec. This would tick all the points!

@sean-perkins
Copy link
Contributor Author

That would be awesome, thanks @arrigolupori. I should have a few PRs up by this weekend to tackle the higher level UI refactors. I am going to leave the form control UI alone at first, but will migrate that once the new main container UI is in place.

One thing that I am unaware of how to best solve for, is when moving the rendering into JSX, we lose the ability of rendering the OpenAPI spec information that contains markdown formatted contents. My first PRs will avoid this scenario, as I will still be rendering the <ApiContent /> component:

for most of the sections, but if anyone has ideas let me know 👍

For example, if my OpenAPI endpoint description was:

  description: "This is a description. :::tip Try it out ::: **This should be bolded**"

We want to continue to render that output as formatted markdown & admonitions. We could pass the contents through a plugin like react markdown again, but this will only format standard markdown into HTML. I would assume there is a docusaurus utility or internal function that helps solve for this.

I am unsure why the <ApiContent /> approach does not have this problem and renders the markdown correctly.

@bourdakos1
Copy link
Member

A little background, when we first wrote this we used JSX to render everything. However, we ran into a handful of issues with the approach. The way we had it working was to save each piece of openapi content that could be formatted with markdown as a markdown file that Docusaurus would ingest, but this didn’t scale very well, it was a lot of piping and a lot of files generated. What we do now is basically turn a page of the spec into a single markdown file, that’s what the “ApiContent” component is. This approach has been working pretty well so far and has the added benefit of the generated markdown being reusable outside of Docusaurus.

I’ll dig around and see if there were any other big reasons for why we switched to this new markdown generation approach.

I’m happy to switch back to JSX, but I’d like to hear more about your plan first

@bourdakos1
Copy link
Member

Here’s the PR where we made the change for reference #65

@sean-perkins
Copy link
Contributor Author

@bourdakos1 thank you for the added context, this helps a lot!

After reviewing other plugins, that PR and the overall challenge, I think we should adjust the goals here. I think we should still move as much of the rendering responsibility to JSX as possible. What this would look like is encapsulating the different sections in a JSX component, but continue to render it with the create utility function that renders the markdown contents as a string. It would just render our custom components vs. a table or div directly.

The benefits here, if possible, is that developers can swizzle the shared JSX components to customize the design as possible, but the plugin will still compose the markdown as a single result through <ApiContent />. I will need to confirm if this possible. This should persist the behavior of markdown contents being rendered correctly when defined in the OpenAPI spec file.

I'll adjust my approach based on this and try to get a PR up for an isolated section that represents what this would look like.

@bourdakos1
Copy link
Member

Sounds good to me 😁 We had this idea at one point, but at the time of implementation MDX didn’t support JSX components with markdown content. However, I believe this might be a possibility with MDX2

@sean-perkins
Copy link
Contributor Author

@bourdakos1 is there anything I can do to help with the open pull requests (add additional documentation, tests, etc.)?

I have one more larger PR that I am working on (refactoring the status codes table UI), that I should have in later this week.

So far the assumptions around leaving the responsibility of rendering the inner markdown formatted contents to the openapi plugin, has been working great. This has allowed the higher order UI to be in JSX/React and the formatted markdown to be written with the create/guard/etc. utilities.

@bourdakos1
Copy link
Member

Hey sorry I've been on vacation and haven't had a chance to take a look at them yet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants