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

[Feature] Combine guides with API content #24

Open
semicolin opened this issue Mar 3, 2023 · 9 comments
Open

[Feature] Combine guides with API content #24

semicolin opened this issue Mar 3, 2023 · 9 comments
Assignees
Labels
Type: Enhancement New feature or request

Comments

@semicolin
Copy link

Description

When I write a guide for one of my library's components, I want to include API documentation for that component's class (inputs, outputs, properties, methods, jsdoc comments) alongside the guide's markdown and demos so readers can find all relevant documentation for a component in one place (like the Angular Material docs for example). Currently, API and Guide are separate pages and I don't see any way to combine them, aside from adding a link to the corresponding API page.

Proposed solution

Maybe add methods to NgDocActions for rendering the API documentation (or pieces of the API documentation)? For example:

  NgDocActions.apiPage("MyComponent")
or
  NgDocActions.apiDescription("MyComponent")
  NgDocActions.apiConstructor("MyComponent")
  NgDocActions.apiProperties("MyComponent")
  NgDocActions.apiMethods("MyComponent")

Maybe this could be accomplished with existing functionality by doing something like

  NgDocActions.demo("NgDocPageComponent")

but I haven't figured out how to wire that up, if it's even possible.

Alternatives considered

If you are planning to do #21 maybe you could add a Guide tab on the API page that pulls its content from a page with corresponding NgDocPage.api property (or something like that). Then render that API page (including Guide tab) in place of the guide page.

@semicolin semicolin added the Type: Enhancement New feature or request label Mar 3, 2023
@skoropadas
Copy link
Member

Well, I've had some experience with what you're suggesting. Before I created this library, I had another private version of it in which this feature was available, i.e. it was possible to render the API directly in the guides, I thought just like you that it could be convenient for users, but after collecting the metric, it became clear that users, first of all, look at the demo and various examples and they look at the API of components only as a last resort when they have not found a suitable example or if there are problems with it, in other cases, they are not very interested in it.

Moreover, some guides may contain examples of using combinations of components, for example, the Menu component guide in Angular Material displays the API for several entities - MatMenu, MatMenuTrigger, MatMenuItem, MatMenuContent, along with sets of variables, interfaces, etc. All of this can create confusion and make it difficult for users to navigate (in my opinion, of course 🙂). One solution could be to separate the main guide from the API using tabs, as seen in the Angular Material documentation, but then another problem arises - it becomes inconvenient to move between the guide and the API because of scrolling, to the point where it's easier to open a second browser window with the API and look at the guide and API simultaneously.

Please understand me correctly, this is a relatively simple feature and it can easily be done. I just don't want to create controversial solutions. I mean that API pages will be improved over time to give users more information, structure it, and show all the necessary connections between entities. Displaying the same thing in the guide would be excessive, and displaying only part of the API sounds questionable and strange.

I liked the approach of MUI, which I would like to suggest you consider. They also write guides showing the various possibilities of their component library and at the end of such guides, they provide links to API pages.

Meanwhile, I wouldn't close this ticket and see what other users might say in the future.

@semicolin
Copy link
Author

Yes, I see your point. My dilemma is that I don't know whether to put the content in the guides or the jsdoc comments. As you point out, users will look at the guide first so I want the guide to have a good description of the component and its inputs/outputs, but I would prefer for that content to live in the jsdoc so that it is also accessible within the IDE and for other devs on my project who are reading the source code. For now I will just put up with a bit of duplication and add links in both directions.

@skoropadas
Copy link
Member

Yes, I understand that documentation for a component library is the most ambiguous because almost every element of the library requires visual examples, but at the same time, it would be desirable to document them in the code using comments.

In this case, I think that the documentation should be strictly divided into two types:

  • The first type is the documentation for entities that have a visual representation or that in some way affect the template. For them, you can create a guide with demos or code examples. In this case, in the JSDoc documentation, you can simply provide a link to the page with examples and just describe what this entity does in general terms because a person who reads the documentation from the source code will not see them otherwise.
  • The second type is documentation only in JSDoc without a guide. This is more suitable for entities that do not have a visual representation, such as functions, services, etc. In this case, you can describe usage examples directly in JSDoc using markdown, since live demos are not particularly important here.

@skoropadas
Copy link
Member

@semicolin Hey, I decided to revisit this ticket, and I think I have a new idea on how it could be implemented:

I could add a new type of guide, which is a combination of an API and NgDocPage. Let's call it an "API Guide" that could be created for any entity. Your configuration for such a page could look like this:

export interface NgDocApiPage extends NgDocPage {
  /**
   * Any declaration that should be used to show the API.
   */
  declaration: any;
}

Here, you can see that the interface inherits from NgDocPage, which means you would have the ability to create demos, playgrounds, etc., just like you do now. However, you would need to specify the declaration for which the API should be generated.

In the end, NgDoc could generate and display a similar header as it does on the API page, with selectors for the declaration name automatically. The content you write in index.md and the API could be separated below using tabs.

It's important to note that if this type of guide is used, the specified declaration will NOT be displayed in the API List. Otherwise, it would cause conflicts with keywords. What do you think about this?

@semicolin
Copy link
Author

That's an interesting idea, but removing the declaration from the API List is not ideal. Could the API List link to the API Guide?

@skoropadas
Copy link
Member

I think yes that's possible!
But I haven't figured out yet what should be included in the declaration to generate the API, but most likely it will be one of the following options:

  • A relative path to the file with the name specified - "../../my-class.ts#MyClass"
  • An absolute path to the file - "libs/my-lib/my-class.ts#MyClass"

Initially, I was thinking about importing and assigning a class, for example:

import { MyClass } from 'my-lib';

export const page = {
  declaration: MyClass
}

export default page;

But there might be situations where someone wants to create a similar page for an interface or another type of declaration that doesn't exist at runtime. However, in theory, I could try combining these two options.

@DaveMBush
Copy link

I wanted to chime in here.🛎️ I came here looking for this feature. 👀

I'm writing tutorial-like documentation, and I generally start with the API description and then dive into the usage. The API documentation is written in jsdoc already. It seems redundant to repeat it 🔁, yet sending people off to API land to read it seems like a poor user experience☹️.

For now, I will have to choose redundancy over poor user experience.

BTW, I love what you have here. Once it is set up, it is pretty easy to use.🚀

@skoropadas
Copy link
Member

@DaveMBush Thank you! But yeah totally agree, I'm gonna start working on this after SSR support

@skoropadas
Copy link
Member

I've been refactoring the core part of the engine for quite some time, and finally, I've started implementing this feature. I've come up with a new idea that seems more flexible to me, and it departs from the initial proposal:

  1. Allow passing an array of paths to markdown files instead of a single path when describing the page metadata:
const MyPage: NgDocPage = {
  title: `My Page`,
  mdFile: ['./index.md', './api.md'],
};

In this case, each markdown file will be considered a separate page, displayed as individual tabs.

  1. Add support for YAML Front Matter metadata for each markdown file, so you can describe tab title, route, icon, and other parameters:
api.md
---
title: API
icon: button-icon
route: api
---
  1. Rendering the API on the markdown file page will occur using the NgDocActions.api method. This way, users can decide how to render the API, either on a separate page or within the current index.md file:
api.md
---
title: API
icon: button-icon
route: api
---

{{ NgDocActions.api('libs/ui-kit/components/button.ts#ButtonComponent') }}
index.md
# ButtonComponent

## API

{{ NgDocActions.api('libs/ui-kit/components/button.ts#ButtonComponent') }}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants