jd-solanki / anu

Anu - DX focused utility based vue component library built on top of UnoCSS & VueUse ⚑️πŸ”₯
https://anu-vue.netlify.app/
MIT License
1.03k stars 56 forks source link

πŸ€ΉπŸ»β€β™‚οΈ Framework stability in Vue Ecosystem & my vision #222

Open jd-solanki opened 7 months ago

jd-solanki commented 7 months ago

Hi πŸ‘‹πŸ»

I have something to share and I guess you are related to this thing as well.

I'm JD, Author of Vue UI framework Anu. You can read why I created Anu here. After Nuxt UI get released (it was nice lib and can fulfill what I was trying to do with Anu) and due to full time job burden I wasn't able to work on Anu as expected at the start.

I'm writing this because I recently realized few stuff I written below and anu reached the 970+ stars which I thought it won't after taking a break from it.

We don't need 10 frameworks that does the same thing differently but 1 framework that does things accurately

The Problems

  1. After doing some wild work I found still Vue UI frameworks are not satisfying to me. Every UI framework has its pros and cons. For example,

    • Vuetify there's regular breaking changes and not enough (easy) customization options compared to new options like radix & nuxt UI.
    • Nuxt UI is nice with flexbility but still you don't have flexibility with how content gets rendered in DOM. E.g. You can't have custom structure for alert component you just pass the props and DOM structure will get rendered. In some case if you want to add badge after title then I guess there's no slot and even if they provide it's practically impossible to provide slot for each customization stuff like before-title, after title, etc.
    • Shadc Vue this is next level but still it has low level code where for just alert with title & desc I have to write 6-7 lines of code as I attached in image image
  2. UI frameworks are not stable with their API because we don't have any guidelines on how we should name our props and what slots we should provide as a framework. This makes framework to introduce new API changes as they evolve and author's mind/vision changes. E.g. Vuetify calls alert detail prop "text" where nuxt UI call it "description" etc. Vuetify made data-table slot name changes recently that broke our existing app and had to rename slots everywhere.

  3. (it might look similar to 2nd point) Years passes and framework changes but project stays the same. After project get finished and you wish to upgrade deps to latest after a year or two, framework that project relies on changes few stuff making framework not future proof and we have to carefully upgrade to latest version using release notes.

The Solutions

  1. I would like to work on high level UI lib that is based on radix vue that provides API like nuxt UI for building quick interfaces but still allow accessing low level components of radix vue. For example, for regular alert user will pass prop title & desc just like nuxt UI but if someone wants the more flexibility like rendering badge after title then user can use low level components like shadcn AlertTitle & AlertDescription. This way, user will have full flexibility with style & structure.
  2. We'll create framework guidelines on how framework should be designed and we'll follow it for our UI framework. Similar to Vue Style Guide but for frameworks
    • naming props, slots, etc. For example, boolean props should prefix with is, should, etc.
    • what props and slots should be provided by framework's specific component
  3. As we follow the framework guidelines we'll keep the prop names consistent across the releases and introduce soft deprecations if necessary to make framework as stable as possible and timeless.

The Conclusion


Edit:

  1. Readers of this issue might be interested in this new repo, Check README.
zernonia commented 7 months ago

This is a good proposal @jd-solanki ! πŸ’š I couldn't agree more with the 3 problems you stated above.

Although shadcn-vue provides a good low level way of constructing a component, however I find it difficult for beginner dev or anyone to "just use" the component with props/event/slot ready.

I had a similar idea in mind to create a UI library that handle this exact problem, which is to provide high level components, and at the same time low level (Radix Vue) component with a consistent theming capabilities.

And with your suggestion of framework guidelines with consistent naming convention, I believe that would reduce the fear of updating major version. πŸ’š

I do however foresee some challenges regarding implementing a framework guidelines that would be adopt by every framework, but we can definitely start somewhere!

sadeghbarati commented 7 months ago

Hi, Thanks for the write, I agree with most of the things you mentioned here but one "Mix low-level and high-level API/props"

https://mui.com/material-ui/react-alert/

Component Per Node is the way βœ…

https://github.com/mui/material-ui/discussions/41085






Mixed props and low-level components ❌

<script setup lang="ts">
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
</script>

<template>
    <!-- how can I change font-size of description without touching the actual component -->
    <Alert title="Heads up!" description="..." />

    <!-- this will cause confusion -->
    <Alert title="Heads up!" description="...">
        <AlertTitle>Heads up!</AlertTitle>
        <AlertDescription>...</AlertDescription>
    </Alert> 
</template>

Slots this is not the way

<script setup lang="ts">
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
</script>

<template>
    <Alert :classes="{ root: { class: 'text-red-900' }, title: { class: 'text-red-800' } }">
        <template #title>
            Heads up!
        </template>

        <template #description>
            ...
        </template>

        <template #icon>...</template>
    </Alert>

    <Alert>
        <template #icon>...</template>
        <AlertTitle class="text-red-800">Heads up!</AlertTitle>
        <AlertDescription class="bg-green-600">...</AlertDescription>
    </Alert> 
</template>

We don't need 10 frameworks that does the same thing differently but 1 framework that does things accurately

I can relate to that quote.

Also every UI framework has its own way of doing the code

Although defineProps doesn't support node_modules external extended complex types and I'm not fan of defineEmits, for UI frameworks/libs it's better to stick to the Vue script setup syntax cause it is more friendly syntax for beginner dev

jd-solanki commented 6 months ago

Today, I had another thought πŸ’­

I'll address these issues in framework guidelines/solutions

jd-solanki commented 6 months ago

Readers of this issue might be interested in this new repo, Check README.

SoCuul commented 1 month ago

@jd-solanki I'd recommend putting a node at the top of the official docs and GitHub repo to tell people about the state of the ui framework, so they don't start a brand new project with it.

sohaha commented 1 month ago

Every upgrade to the current front-end project, be it a UI library or tool chain, is a disaster