koumoul-dev / vuetify-jsonschema-form

Create beautiful and low-effort forms that output valid data. Published on npm as @koumoul/vjsf.
https://koumoul-dev.github.io/vuetify-jsonschema-form/latest/
MIT License
538 stars 154 forks source link

imagining the next major version v3 #409

Open albanm opened 1 year ago

albanm commented 1 year ago

What comes next ?

I think a few things converge toward rethinking and rewriting large parts of vjsf.

Next are a few ideas about how things could look on the next major version. Some of these ideas are already detailed in issues, but I like having a more complete view of the future in a single document.

Target is Q2 or Q3 2023. In the meantime only bug fixes and small pull requests will be included in v2.

Development frameworks and tools

Do we keep building a dist ? I suspect most people use a toolchain that can load the lib from source code and build it inside their app.

Do we get back to using templates instead of render functions ? I think maybe the limitations we tried to circumvent are not so true anymore or not so important in the new architecture. If we do this we might clarify components import and improve overall maintainability.

Vocabulary / expressivity

Improved composition

The massive use of mixins works for now but we can do better. Explore the composition API of Vue 3.

I think the multi-root components have the potential for making many things simpler (for example an object rendered as a flat section can be rendered in a component without adding intermediate structure).

More generic/meta injection of custom components, slots, props, etc so that many use cases are covered without documenting tens of options.

Decoupling of core and lib components

The following is an initial proposition. It needs more thinking and testing.

The core:

The components lib:

Ideally the core and the components lib would be sufficiently decoupled to allow for creating alternate component libs for other frameworks than vuetify. Maybe this project should even be separated into 'vue-json-schema-form' and 'vuetify-json-schema-form'. This is not a top priority and should not be done if it compromises maintenability.

Reactivity and performance

If we manage to implement a saner reactivity system and by leveraging the separation between the root component and vjsf-property component I think we can solve the annoying issue of external schema/data change and have more predictable behaviors in general.

Better responsive design

Similar logic to the usual responsive breakpoints (xs, sm, etc.), but based on the actual size available to the form (and invidually to each of its children). This should be solved in the core vjsf-property component so that when given to the lib component it has a single value to apply.

Do we keep using a 12 columns grid system like vuetify or do we use more generic percent based values ?

Do we implement responsive layout with flexbox directly in the core vjsf-property component or do we delegate this to the lib component ?

The responsive breakpoint should be usable at the lowest level possible to define the width of each property or at the highest level possible to define a totally different layout (change order, hide an avanced section, use expansion panels instead of tabs, etc.).

Also different layouts might be provided for editable and readOnly mode.

Schema validation

I really want to check if a very strong ajv integration could solve all our schema validation needs.

The core component vjsf-property would apply ajv on all its intermediate models. At an object level either a child already displays an error (we can know that using inject/provide mechanism) or the error is displayed on the current level.

We should look info ajv-errors and ajv-i18n and see if we can get error messages good enough for our users directly from ajv validation.

The validator could also be used to validate the internal vocabularies (cf section "Vocabulary / expressivity").

The validator could also be used detect the current item of a select based on oneOf/anyOf which would allow for a more permissive convention than the strict convention of a property with const value. Also we should have a look at the discriminator keyword for this question.

If we use ajv specifically then we could also use more functionality like Modifying data during validation. Initialization of the model from the schema inside the recursive rendering of vjsf has long been a source of complexity (we render recursively and immediately bubble up some changes that trigger re-renders, it is a circular mess). Using ajv to fill default values before rendering components might solve this issue at least partially.

With strong validation integration the tagline "Create beautiful and low-effort forms that output valid data" would become a hard reality instead of a moving target where we strive to cover more cases as we go.

Support JTD ?

See here for a discussion of JTD vs JSON schema. In my mind the most important case for JTD is the code generation capabilities (https://github.com/jsontypedef/json-typedef-codegen). Not only do you ensure validity at input validation, you can also ensure the safety of the code that manipulates the data afterward.

A strong integration of Ajv and the decoupling of layout vs schema might make supporting both specifications possible without too much hassle. In this case should the project be renamed (vue-json-form) ?

Warning : I am not sure yet that JTD has enough expressivity to support a good implicit layout generation.

Retro-compatibility

The core should manage retro-compatibility of schema annotations and at least some options. It should emit warnings for options that are no longer supported. Technical compatibility is not as much of a priority (props, slots, etc) as long as the functionality can be preserved with reasonable work from developers.

Compilation and tree-shaking

Ok, this one is not obvious but it could be a game-changer to extend legitimate uses of vjsf. In its current state I tend to use vjsf only when schemas are dynamically provided (by some sort of plugin system) or when I know that the application has broad usage of it. But if I have a small form in a standalone page I will not be using vjsf because I am too aware of the cost in source size, init time, etc. The idea to solve this is to introduce a compilation mode that would take a schema and options at build time and do these tasks:

This way we can achieve a much lighter integration:

This compilation could also include some other tools like json-schema-to-typescript so that the built component could have typed data bindings.

What I don't think I will do : compile the actual UI code for the schema, vue components will still be generic components, simply they won't be loaded if they are not used.

This approach would probably require a small script based integration at first, then I could work on a closer integration with build systems (a webpack loader ?).

albanm commented 1 year ago

I have been having a debate with myself about this draft these last few days. When I put all ideas together the scope becomes kind of scary, basically I would be building something very similar to jsonforms but even more ambitious. As I have always been wary of excessive layering it got me thinking. I mean stacking abstractions, creating new standards, building large collaborative organizations, etc, it's all good. But personally I am more of the type that gets things done with what is at hand, and do it fast if possible. By creating a monorepo it might be possible to strongly decouple some stuff without creating an organizational nightmare at each new functionality, but still I must strive to keep things simple and not forget that a good deal of power and simplicity comes from assuming some level of coupling.

Therefore I think I will skip on the creation of an external layout schema. Edition would not be very user-friendly and managing coherence with the schema and the data would be complex. I will stick with being very json schema first and using annotations. But I do intend to rethink these annotations : bring some new power and genericity to the syntax, and write a JSON schema vocabulary for them. I will also stick with strong vuejs coupling. I will try to decouple some core components from vuetify implementations, but as a way to better structure the code and facilitate extensibility and not to open the door to compatible implementations with other frameworks (not in this version anyway).

Other ideas like the strong ajv integration, better responsive layout, better reactivity, etc are still a go. JTD support could simply be documented by linking to the schema2td tool I am writing in another repo.

isedwards commented 1 year ago

@albanm - do you list anywhere the advantages of vjsf over jsonforms? Are there some capabilities in vjsf that don't exist in jsonforms?

albanm commented 1 year ago

No, I don't have the full picture in mind and I don't perfectly know the capabilities of jsonforms so I don't want to be too affirmative on the topic. But sill I would say that vjsf is a less ambitious project in term of scope but has more detailed stuff (nested array validation, external data fetch, vuetify slots, props, etc). Things are not perfect but vjsf aims at providing a schema first approach that doesn't let you get stuck once you need to get into more details of customization of the form.

I would also add that vjsf is currently in a low maintenance mode (sorry for the pending PRs), but it is temporary and the project is definitely not dead at all. Actively used professionally at my company and no plan to switch to another tool anytime soon.

isedwards commented 1 year ago

@albanm is the plan to release an initial Vuetify 3 version before Vue 2 reaches end of life on on December 31st, 2023?

albanm commented 1 year ago

Yes, for sure.

RemiC2care commented 1 year ago

Hi @albanm,

We use your vue2 vjsf ( and a pleasure to use ) and we are currently switching to vue3.

Is there a chance to have an update of vjsf in a near future?

Thanks a lot

albanm commented 1 year ago

Hello,

Vjsf 3 won't be ready soon (best-case scenario is somewhere around august or september). But it is more than a port to vue 3, it is a rethink of many things and a complete rewrite. I don't have the time to work on this major version and on a simpler compatibility version of vjsf 2 for vue 3. If someone wants to work on this and bring it to completion I am willing to accept pull requests (or add a link to a fork).

RemiC2care commented 1 year ago

Hello,

Thank you for you quick answer, keep the good work. Bye

ocostello commented 10 months ago

Hi, is there any update to the expected date of a release supporting Vue 3?

albanm commented 10 months ago

I am working on it. Hard to evaluate the necessary time, but end of year is the last deadline with a alpha available probably in a month from now.

Same as before : I am working on a full rewrite with a pretty ambitious target that comes with some level of uncertainty. But I would be ok with linking to a fork with a more minimalist port of vjsf 2 to vue 3 if someone wants to work on it.

MaciejDybowski commented 8 months ago

@albanm is there a chance for a beta version for 3 to appear this month?

albanm commented 8 months ago

Yes, maybe more an alpha than a beta, but it is coming soon.

The latest documentation contains a recent version of the work in progress https://koumoul-dev.github.io/vuetify-jsonschema-form/master/ . Not usable yet, but it shows that many things are starting to take shape.

Most of the work is done in the new project json-layout.

albanm commented 8 months ago

fyi https://github.com/koumoul-dev/vuetify-jsonschema-form/issues/420