Closed lognaturel closed 7 months ago
Per discussion with @sadiqkhoja on Friday, we'd also like to take this opportunity to split the @odk/web-forms
package into at least two packages (I'm not suggesting any naming here, but it'd be good to discuss):
A view-only package, essentially represented by what's currently in packages/odk-web-forms/src/components
. As I understand it, this is the aspect we're most motivated to migrate.
An engine-only package, essentially represented by what's currently in packages/odk-web-forms/src/lib
. A small chunk of the engine currently uses some of Solid's reactivity APIs (and a small set of other third-party abstractions around those) to implement certain aspects of engine state. It's unclear to me if migrating these aspects to Vue is in scope for this issue, or a priority. And @sadiqkhoja, to clarify since we discussed but left it unanswered Friday: my understanding is that yes, Vue's reactivity API is also designed so it can be used independent of view rendering.
And while we're here... I'm excited to get used to distinguishing the Vue/view homonyms out loud all the time 🙃
Another consideration for the view package, which @sadiqkhoja and I discussed a bit on Friday but also left open: currently we're using the SUID material UI with Solid. A quick search for a Vue equivalent reveals:
Of these, Vuetify stands out to me as probably an easier transition. I'm cautious about the Bootstrap option, and about Sass to the extent any of them expose that as part of the development workflow. I'm also sort of surprised how little (if at all) I see any of them reference back to the official MUI React library in terms of documentation, concepts, APIs, etc.
For Material 2, Vuetify looks fine.
But if we are targeting Material 3 then can we consider Material Web? Not all components are implemented though, one that stands out is date / time picker.
For Material 2, Vuetify looks fine.
It looks to me like the Material 3 blueprint is mature: https://vuetifyjs.com/en/features/blueprints/#white-label-concept
I’ve only briefly looked at the blueprint approach but it feels powerful and maybe an answer to the question of how we could keep web forms looking modern while honoring a user’s branding. That said, more dependency layers add risk.
consider Material Web
That’s not Vue-specific, right?
Many components of Vuetify are using v1 or v2 specification of material design, for example Button (if you click on button it will take to you to m2)
Searching on their git repo, I couldn't find a single component with a m3 spec.
M2 website does mention vuetify as an additional open source implementation, but M3 doesn't.
I couldn't find a single component with a m3 spec.
That's too bad.
@alyblenkin do you think we absolutely need a material 3 base? From the recent updates to Collect, I think the most distinctive things are the rounded buttons, rounded dialogs, and filled text boxes (e.g. Vuetify's default). We don't have aspirations to use any of the "Material You" stuff.
I'd like us to also consider https://quasar.dev which I've been following since we had some conversation about leveraging a component library for Central. It's broader than a component library and has some features that could be interesting when we get into PWA or native app territory. It apparently is good to work with in VSCode. The website is not visually appealing but I think the components look good and are very complete (e.g. https://quasar.dev/vue-components/rating). The flexbox support looks like it would make grid view straightforward to implement (likely all libs have this).
@alyblenkin do you think we absolutely need a material 3 base?
We don't need to use an M3 base! I agree; the biggest differences with M3 are the rounded edges for buttons and dialogs, and the typography. Google might also be embracing flat design again with only a slight elevation.
Using an M2 base will not look vastly different from Collect. Most people probably won't notice! I'm pretty sure google forms stills uses M2 🌶️
How easy is making small customizations, like adjusting the radius on buttons with Vuetify?
How easy is making small customizations, like adjusting the radius on buttons with Vuetify?
Trivial in all of the frameworks we're considering, as far as I can tell. I'm somewhat less sure about the corner radius of the dialog itself but I imagine it's possible to customize.
Vue Material: top hit on Google (for me at least)
I think this one should be out because it doesn't support Vue 3. The goal in using Vue is consistency with Central and Vue 2 and 3 are quite different.
I just noticed that SUID uses Material 2 so we're not losing anything when compared to what's currently there by picking a library that is Material 2 focused.
Here are the some criteria I see:
One criterion I am thinking of is authors/sponsor of the library. Material Web is being developed by Google, so I am inclined to trust it more than Vuetify and Quasar for quality and compliance with the specs. Currently, it doesn't include all the components we need like datepicker, cards, etc but they are in the roadmap. Since it's a library of "Web Components", its usage in vue is super simple:
<template>
<label>
Material 3
<md-checkbox checked></md-checkbox>
</label>
<md-outlined-button>Back</md-outlined-button>
<md-filled-button>Next</md-filled-button>
</template>
<script setup>
import '@material/web/button/filled-button.js';
import '@material/web/button/outlined-button.js';
import '@material/web/checkbox/checkbox.js';
const primaryColor = 'magenta';
</script>
<style scoped lang="scss">
md-checkbox, md-outlined-button, md-filled-button {
--md-sys-color-primary: v-bind(primaryColor);;
}
</style>
For the missing components, we can pick them individually from vuetify/quasar or other npm packages until they are available in Material Web
So here's my preference:
1 - Material Web 2 - Quasar (for it has more components including timepicker) 3- Vuetify
is being developed by Google
Would that be the makers of Google Meet, the enterprise Google Chat, previously Duo, which replaced Allo, the replacement for Hangouts, the rebrand of +Hangouts, which replaced Talk and Voice? 😬 I'm sad to say this, but my trust in Google actually completing and supporting software is pretty low these days. The quality of the Google Material library for Android feels pretty low and they implement components very slowly.
With Material Web we'd have to add our own theming layer, right? I know we've talked about keeping theming fairly tightly scoped but I think there could be benefit to being able to leverage a well-considered theming approach even if we don't expose all of it at once.
we can pick them individually from vuetify/quasar or other npm packages until they are available
Are there page weight configurations for this or not really because we'd be able to dynamically request only what's needed for a given form?
I haven't deeply thought about this but I suspect that switching component implementations (e.g switching from one date picker to another) will be more difficult than it seems. There'll probably be subtle behavior in one that we then have to replicate in another. It'll probably be around something like localization.
This world has gotten a lot more complicated with a lot more decision points since I last looked around. Here are some things I've found potentially interesting:
Based on there's zero corporate support I would like to drop Material Web from the consideration completely. I was the one who was advocating for it the most with the assumption that it is an official implementation by Google of the specs so it ought to be 100% compliant and good in quality but I was wrong.
All components should have automated tests
Maybe I'm being overly pedantic, but I suspect this would be overkill if taken literally? We should absolutely have more rigorous client-UI testing than what exists for Solid components, but I don't know if we want to have tests for e.g. something which is purely declarative and not a likely regression risk.
As encouraged by @getodk/central for easier switching between projects.
Acceptance Criteria:
Not in scope - separate issues