epicmaxco / vuestic-ui

Free and Open Source UI Library for Vue 3 🤘
https://vuestic.dev
MIT License
3.3k stars 320 forks source link

Research components as composables #4195

Open m0ksem opened 1 month ago

m0ksem commented 1 month ago

Take a look on shadcn examples: https://www.shadcn-vue.com/docs/components/select.html

The cool part of it is that we can pass anything anywhere we want and actually components stored in our codebase.

Reason #1:

There are a lot of cases when user asks us for update and must wait until we release new version:

For example, aria-label-by attribute caused hydration mismatch because we were using incorrect way to handle component ID. (see https://github.com/epicmaxco/vuestic-ui/commit/cc0da4d65ccb92a86b44814711b1e15de1c567ce)

In case if components are owned by the user they can fix this issue manually.

Reason #2:

In case if my app is using VaSelect, but don't use virtual-scroller I should be able to drop virtual-scroller functionality from output bundle.

Reason #3:

Slots might be not flexible enough sometimes. In VaCarousel we need to add new prop "how much slides visible at once in viewport" to show 3 slides at the same time. image

We don't have this functionality for now. If we had composables to make carousel user can manually make this type of component to show 3 slides at once. (Also, this way he can drop some extra animations, hover listeners, etc reason #2)

Example with DataTable

I needed to have Vuetify Table once with Resize feature. I made a composable which turn any table into resizable one. It is using standard DOM api, appendChild for resizers, etc. No framework specific. And I also needed to visually customize Vuetify table, so it was easier to make standard HTML table, apply this composable and fully control table layout. If we had this composable in Vuestic I think it would be nice. I can make some tables resizable, sortable, searchable, etc.

Example with Calendar

We have composable which generates days for VaDatePicker. This can be reused to make a Calendar. It also can be reused for advanced Day pickers with multiple range, etc.

Feature chaining

We need to research do we even need this composables, is it possible to make, how to chain features (For example, in select: trackBy, valueBy, textBy feature, search feature, v-model feature).

Components approach

Maybe, instead of composables we can have components and abuse provide/inject to register features.

<VuSelect #default="{ selectValue }"> // Vuestic cUstom
   <VuSelectTrigger>
      <VuSelectText #default="{ text }">
        <VuInputField v-model="text.ref" />
      </VuSelectText>
   </VuSelectTrigger>

   <VuSelectDropdownCotent>
      <VuList keys="textBy, valueBy, iconBy" :list="options" #list-item="{ text, value, icon }"> // notice this keys from keys without By.
          <p @click="selectValue(value)">
             <VaIcon name="icon" />
             {{ text }}
          </p>
      </VuList>
   </VuSelectDropdownContent>
</VuSelect>

Goal of task

We need to find what's best for the user here. I think we can implement almost anything (even if we don't, we'll do a rollup plugin for codegen or whatever).

The goal of this issue is to research and propose to be API for user to make customizable components and allow them to own their components.

When this task is complete

We have a plan how to give user full control over components (preferred) OR We decided this idea is impossible to implement and we drop it.

m0ksem commented 1 month ago

What we need for now is: opinion, ideas (good&bad) and later we'll think about implementation.