Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: DropdownMenu(Trigger) will be slow to display when there's a lot of render elements #296

Open
frankchen211 opened this issue Jan 21, 2024 · 4 comments · May be fixed by #334
Open
Labels
bug Something isn't working

Comments

@frankchen211
Copy link

Environment

Shadcn Vue version: 0.8.7
Vue version: 3.4.15

Link to minimal reproduction

https://github.com/frankchen211/shadcn-vue/tree/draft/blue-violet

Steps to reproduce

For task page example,

  1. Make more data like 1000 rows
  2. Set pageSize to 1000
  3. click View button to open the dropdown menu, it will take a while to display(remove any functions from TanStack Table).
const columns = ['col1', 'col2', 'col3']
<DropdownMenuCheckboxItem
        v-for="column in columns"
        :key="column"
        class="capitalize"
        :checked="true"
>
        {{ column }}
</DropdownMenuCheckboxItem>
  1. click and compare with the FacetedFilter(using Popover) which is faster.

Describe the bug

For task page example, if you have large dataset to display at one page,
like 1000 per/page, then click View button to open the dropdown menu, it will take a while to display, but the FacetedFilter(using Popover) is faster.

Expected behavior

Faster

Conext & Screenshots (if applicable)

No response

@frankchen211 frankchen211 added the bug Something isn't working label Jan 21, 2024
@hrynevychroman
Copy link
Collaborator

@sadeghbarati I can get this issue to working process, ok?

@sadeghbarati
Copy link
Collaborator

@romanhrynevych absolutely 💯 ❤️

@hrynevychroman
Copy link
Collaborator

hrynevychroman commented Feb 9, 2024

First of all we need to clarify that amount of elements 1000 is a big number, so I think you need to use vue-virtual-scroller

This package only renders some elements near your scroll position, not all, I think that this might fix your error at all.

I tried to make a demo and received some errors with table elements and library, but will send you link when something will happens 🙂

Don't think that this issue is legit for this package, maybe we will add one more example of BigData scroll after successful implementation 😁

@jamesallan93
Copy link

I followed @hrynevychroman advice about vue-virtual-scroller.
My dropdown was taking a few seconds to open, due the dynamic items being loaded, so thx @hrynevychroman.

Things i want to point out first:

The virtual scroller docs are poorly written, so you might get into some issues.
So i will share how used it.
I added a search bar in my dropdown to filter items, and had an issue, on keydown it was focusing on dropdown item, and to fix it, i did this recommendation to stop it: radix-ui/primitives#2193 (comment)

Also another issue was about virtual scroller bad docs, and found this solution: Akryum/vue-virtual-scroller#865

image

the final result is this:

<ClientOnly>
        <div class="mb-16 flex flex-wrap items-baseline">
          <DropdownMenu>
            <DropdownMenuTrigger>Country</DropdownMenuTrigger>
            <DropdownMenuContent
              :avoidCollisions="true"
              side="bottom"
              align="start"
            >
              <DropdownMenuLabel>
                <div @keydown="($event) => $event.stopPropagation()">
                  <JInput
                    v-model="searchQuery"
                    placeholder="Search country"
                    class="w-full"
                    id="query-country"
                    name="search"
                  >
                    <template #icon>
                      <component
                        :is="SearchIcon"
                        class="size-4 text-muted-foreground ml-1.5"
                      />
                    </template>
                  </JInput>
                </div>
              </DropdownMenuLabel>
              <DropdownMenuSeparator />
              <div class="flex py-2 flex-col">
                <div class="flex px-2 items-center">
                  <Map class="size-4" />
                  <div class="ml-4">Current Location</div>
                </div>
                <DropdownMenuItem>{{ getSelected }}</DropdownMenuItem>
              </div>
              <DropdownMenuSeparator />
              <DynamicScroller
                :items="filteredCountries"
                :min-item-size="10"
                class="max-h-48 overflow-y-auto"
                key-field="country_code"
              >
                <template v-slot="{ item, index, active }">
                  <DynamicScrollerItem
                    :item="item"
                    :active="active"
                    :size-dependencies="[item.name]"
                    :data-index="index"
                    :index="index"
                    :key="item.country_code"
                  >
                    <DropdownMenuItem
                      :key="`${item.country_code}-${index}`"
                      @click="selected_country = item.country_code"
                    >
                      {{ item.name }}
                    </DropdownMenuItem>
                  </DynamicScrollerItem>
                </template>
              </DynamicScroller>
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
</ClientOnly>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants