jakearchibald / svgomg

Web GUI for SVGO
https://jakearchibald.github.io/svgomg/
MIT License
5.73k stars 469 forks source link

Next major version plan #431

Open jakearchibald opened 8 months ago

jakearchibald commented 8 months ago

I'm going to try and find some time to work on this. Here's what I'm planning:

I would like to work with SVGO so that plugin definitions have enough metadata so this site can automatically generate the required UI. That will make it easier to stay in sync with SVGO, because there won't be a process of checking all the plugins looking for changes.

SethFalco commented 8 months ago

This all sounds good!

I would like to work with SVGO so that plugin definitions have enough metadata so this site can automatically generate the required UI.

I'm happy to help with this where I can. If you have any ideas in mind, please let me know. I'd hope something can be worked out with our type definitions, but that'd probably be really messy.

Reference: https://github.com/svg/svgo/blob/main/plugins/plugins-types.d.ts#L279C6-L279C19

I'd imagine the most flexible solution is for us to expose a JSON Schema for SVGO's config somehow. Then clients can project the parts they want and work with it.

jakearchibald commented 8 months ago

Yeah, I think it'd need to be more than just TypeScript, since types don't express number ranges, or floats vs ints.

SethFalco commented 7 months ago

I've been giving this some thought, and I think I know how we can approach it.

We'll export a schema property in each plugin, the same way we already export name, description, and fn. The schema property will store the equivalent of a JSON Schema for the params that it accepts, types, enums/ranges, etc.

I'm mostly stealing the idea from ESLint, which does this to define the config for custom ESLint rules:

Rules may specify a schema property, which is a JSON Schema format description of a rule’s options which will be used by ESLint to validate configuration options and prevent invalid or unexpected inputs before they are passed to the rule in context.options.

// Possibly trying to validate ["error", { someOptionalProperty: true }]
// but when the rule is enabled, config will always fail validation because the options are an > array which doesn't match "object"
module.exports = {
    meta: {
        schema: {
            type: "object",
            properties: {
                someOptionalProperty: {
                    type: "boolean"
                }
            },
            additionalProperties: false
        }
    }
}

https://eslint.org/docs/latest/extend/custom-rules#options-schemas

Both CLI and Node.js applications would be able to pull this information out, by accessing the respective plugins schema property or equivilent help command. Would you be happy to work with an interface like this?

jakearchibald commented 7 months ago

Does that give enough information to build a UI? Eg "number" is not enough info if the valid values are integers in a particular range, as I'd like to provide a slider that can only select the valid values. I guess number values like precision don't have a literal maximum, but values stop making meaningful difference beyond a particular value. Also, if it's an array of strings, does the order matter?

I think, ideally, each plugin needs:

Then each plugin parameter needs:

I've started setting up the build system for the next version, using Vite. Once that's done I'll start getting the components together.

SethFalco commented 7 months ago

Does that give enough information to build a UI?

Yeah it should, in fact, there are even libraries for building a UI from a JSON Schema.

https://github.com/rjsf-team/react-jsonschema-form

JSON Schema supports min, max, multipleOf etc, for numbers for example, and various other properties for other types.

Then each plugin parameter needs:

JSON Schema can provide all of those. 👍🏽

jakearchibald commented 7 months ago

Amazing, sounds like a good option then!

jakearchibald commented 7 months ago

I'm working in https://github.com/jakearchibald/svgomg/tree/next if anyone wants to follow along.

I've set up a modern Vite, Preact, & TypeScript-based development environment & build system, with static rendering and hydration. Next up: start building up the UI, modernising as I go along.

jakearchibald commented 6 months ago

About to start developing the main UI.

Anyone here with any UI design skills? I'm a little unsure how to tackle the sub-options for each transform.

Screenshot 2024-01-16 at 08 57 35

My current thought is to put an arrow on the right-hand side of the feature option, which toggles the expand/collapse of the sub-options.

Sub-options will all be hidden by default, given you an overview of the features.

The site is currently based on material design, and it doesn't seem like there's a pattern for a 'thing' that has a toggle but also further options. All the examples I've seen make you go to a different page for options.

jakearchibald commented 6 months ago

@SethFalco I'm approaching the point where I'm going to start needing the schema stuff in SVGO. Is there any progress there? If not, can you give me a hint of where you'd like it to live, and I can start getting a PR together.

SethFalco commented 6 months ago

I'd started on it locally, but haven't pushed yet. I'll finish it up tonight and open a PR in SVGO (I'll mention you in the PR!) so you can give it a peek and note if you think there are any issues with it.

If I don't get it done, I'll open a draft PR with the progress so you can at least see what I have in mind which should be enough to review and get started on your end.

jakearchibald commented 6 months ago

Perfect, thanks!

SethFalco commented 6 months ago

I've opened the pull request for it now with my work:

This isn't complete, but you're welcome to review the direction it's going already. I'm hoping it's in a state you act more or less continue development too.