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]: Shadcn vue MultiSelect Dropdown Misalignment Issue in Custom Component #988

Open
2 tasks
aakashbashyal21 opened this issue Jan 5, 2025 · 0 comments
Open
2 tasks
Labels
bug Something isn't working

Comments

@aakashbashyal21
Copy link

aakashbashyal21 commented Jan 5, 2025

Reproduction

https://stackblitz.com/edit/tdkd3r-rvzugw?file=src%2Fcomponents%2FMultiSelect.vue

Describe the bug

I'm implementing a shadcn/ui Multiselect component in vue 3 for a form. https://www.shadcn-vue.com/docs/components/tags-input

But I'm encountering an issue with the dropdown menu's alignment. The dropdown appears misaligned relative to the input field.

When the dropdown opens, it does not align properly with the input field (or anchor). Instead, it either shifts too far to the left, right, or appears outside the expected container.

Component Details:

Form Usage:

<FormField v-slot="{ componentField }" name="roles">
  <FormItem>
    <FormLabel>Role</FormLabel>
    <FormControl>
      <MultiSelect
        v-bind="componentField"
        :options="frameworksList"
        :onValueChange="componentField.onChange"
        :defaultValue="componentField.modelValue"
        placeholder="Select options"
        variant="inverted"
        :animation="2"
        :maxCount="10"
      />
    </FormControl>
    <FormMessage />
  </FormItem>
</FormField>

Custom MultiSelect Implementation:

I use Radix Vue's Combobox for dropdown positioning. Here's a simplified version of the implementation:

<template>
  <TagsInput class="px-0 gap-0 w-full" :model-value="modelValue">
    <div class="flex gap-2 flex-wrap items-center px-3">
      <TagsInputItem
        v-for="item in selectedValues"
        :key="item"
        :value="item"
        as-child
      >
        <Badge :key="item">
          {{ getOption(item)?.label || item }}
          <XCircle
            class="ml-2 h-4 w-4 cursor-pointer"
            @click.stop="toggleOption(item)"
          />
        </Badge>
      </TagsInputItem>
    </div>
    <ComboboxRoot
      v-model="modelValue"
      v-model:open="open"
      v-model:search-term="searchTerm"
      class="w-full"
    >
      <ComboboxAnchor as-child>
        <ComboboxInput placeholder="Framework..." as-child>
          <TagsInputInput
            class="w-full px-3"
            :class="modelValue.length > 0 ? 'mt-2' : ''"
            @keydown.enter.prevent
            @focus="open = true"
          />
        </ComboboxInput>
      </ComboboxAnchor>
      <ComboboxPortal>
        <ComboboxContent as-child>
          <CommandList
            position="popper"
            class="w-[--radix-popper-anchor-width] rounded-md mt-2 border bg-popover text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
          >
            <CommandEmpty>No results found</CommandEmpty>
            <CommandGroup>
              <CommandItem
                v-for="framework in filteredFrameworks"
                :key="framework.value"
                :value="framework.value"
                @select="toggleOption(framework.value)"
              >
                {{ framework.label }}
                <CheckIcon
                  v-if="selectedValues.includes(framework.value)"
                  class="ml-auto h-4 w-4"
                />
              </CommandItem>
            </CommandGroup>
          </CommandList>
        </ComboboxContent>
      </ComboboxPortal>
    </ComboboxRoot>
  </TagsInput>
</template>

The dropdown menu (ComboboxContent) should align directly below the input field. Instead, it appears offset (either horizontally or vertically). Adjusting CSS such as margin or padding hasn’t resolved the issue.

Here is the stackblitz example: https://stackblitz.com/edit/tdkd3r-rvzugw

How can I fix the dropdown alignment issue for the MultiSelect component It is a issue with a class being not properly used but I am not sure what class have been affecting positioning?

image

System Info

System:
    OS: Windows 10 10.0.19045
    CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
    Memory: 19.91 GB / 31.86 GB
  Binaries:
    Node: 22.12.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.9.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (131.0.2903.86)
    Internet Explorer: 11.0.19041.4355

Contributes

  • I am willing to submit a PR to fix this issue
  • I am willing to submit a PR with failing tests
@aakashbashyal21 aakashbashyal21 added the bug Something isn't working label Jan 5, 2025
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

No branches or pull requests

1 participant