skeleton icon indicating copy to clipboard operation
skeleton copied to clipboard

NEXT: Automated Documentation

Open endigo9740 opened this issue 1 year ago • 2 comments

This will act as a hub to centralize this information.

Goal

We need to determine a framework-agnostic solution to retrieve and document props, events, and children within each component. This will replace our Svelte-only option used in previous versions of Skeleton, called Sveld.

Solutions

Svelte:

React:

Not Used:

  • [x] vite-plugin-type-to-schema
  • [x] https://www.npmjs.com/package/espree
  • [x] https://typedoc.org/
  • [x] https://github.com/ghostdevv/extractinator
  • [x] https://github.com/HiDeoo/starlight-typedoc

Todo

  • [x] Create a prototype using Astro and a simple test component and type
  • [ ] Create a reusable doc component to scaffold an API block on demand
  • [ ] Test implementation with the Avatar component
  • [ ] Update contribution instructions

Feedback

If you have additional updates or requests for this feature, please do so in the comments section below.

endigo9740 avatar Jan 03 '24 18:01 endigo9740

Sharing this for future reference. @Hugos68 implemented a programmatic way to generate schema via a custom Node script using vega/ts-json-schema-generator. Which is a more modern fork than we're using atm. While super cool, this is probably overkill for the time being. It's also blocked by this PR, which is preventing Windows users at the moment.

import glob from "fast-glob";
import { join } from "path";
import { createGenerator } from "ts-json-schema-generator";
import { promises as fs } from "fs";
import { performance } from "perf_hooks";

/**
 *    Generate schema for a ts file
 * @param {string} path
 * @returns {ReturnType<ReturnType<typeof createGenerator>['createSchema']>}
 */
function generate_schema(path) {
    /** @type {import('ts-json-schema-generator/dist/src/Config').Config} */
    const config = {
        path,
        type: "*",
        skipTypeCheck: true,
    };
    const generator = createGenerator(config);
    const schema = generator.createSchema(config.type);
    return schema;
}

/**
 * @param configuration Configuration object
 * @param configuration.matcher The glob pattern to match the files.
 * @param configuration.output_name The name of the output schema file.
 */
async function main({ matcher, output_name }) {
    /**
     * @type {Array<Promise<void>>}
     */
    const promises = [];
    const files = await glob(matcher);
    for (const file of files) {
        const promise = new Promise((resolve) => {
            const start = performance.now();
            const file_path = join(import.meta.dirname, file);
            const schema_path = file_path.replace("types.ts", output_name);
            const schema = generate_schema(file_path);
            fs.writeFile(schema_path, JSON.stringify(schema, null, 2)).then(() => {
                const end = performance.now();
                console.log(`Schema generated for: "${file_path}"
Schema saved at: "${schema_path}"
Time taken: ${(end - start).toFixed("2")}ms
`);
                resolve();
            });
        });
        promises.push(promise);
    }
    await Promise.all(promises);
}

await main({
    matcher: "**/src/components/**/types.ts",
    output_name: "schema.json",
});

endigo9740 avatar May 16 '24 18:05 endigo9740

Just a quick update for this...

We've now implemented support for React component auto-docs via: https://github.com/YousefED/typescript-json-schema?tab=readme-ov-file

This allows for everything but automatically fetching the default value. A new table component has been introduced to display the schema information per all existing component pages.

In the future, we'll revisit this to handle Svelte 5, likely using: https://github.com/ghostdevv/extractinator

We'll also look at migrating React to following tool, or whatever solution allows us to populate the default values: https://github.com/vega/ts-json-schema-generator

This tool operates in a similar manner, but is a more recent "fork" with some improvements.

endigo9740 avatar May 17 '24 20:05 endigo9740

Noting this idea for later...

Consider using the Vite ?raw feature to display the raw type files in a code block. This would be simple, light weight, and uniform between frameworks.

At least until a proper cross-framework parsing tool can be located and implemented!

endigo9740 avatar Nov 01 '24 19:11 endigo9740

I've recently had the pleasure to work a lot with AST's typescript and all sorts of fun stuff to manipulate and extract stuff from typescript files. I don't think our own custom but lightweight (meaning only features we need) implementation isn't out of reach. Let me know what your thoughts are one this. This could ensure parity between all frameworks with a single tool.

Hugos68 avatar Nov 01 '24 19:11 Hugos68

@Hugos68 biggest priority is speed. I'm trying to close out all remaining milestone issues between now and end of year. So I'm leaning towards a low-tech and simple solution to get things off the ground. Then revisiting post-launch to implement something more robust.

endigo9740 avatar Nov 01 '24 20:11 endigo9740

Do you mind me working on this, I have some time this weekend I can maybe cook up a solution that works for atleast the initial launch

Hugos68 avatar Nov 02 '24 18:11 Hugos68

@Hugos68 go for it! Not sure if you want to keep the tooling we have now and try to get it working with Svelte, start from scratch, or try to find a unique solution per framework. But if you do opt to keep the current tool, then we should probably make that change you suggested. Move the "generation" process to the Docs project rather than the React package.

I'll jump on Discord if you have any questions.

endigo9740 avatar Nov 02 '24 18:11 endigo9740

The framework agnostic solution from Hugo has now shipped!

  • https://github.com/skeletonlabs/skeleton/pull/2928

endigo9740 avatar Nov 08 '24 23:11 endigo9740