Skip to content

Commit 65e07b9

Browse files
committed
fix(select): remove teleport option due to SSR issues and bad API/implementation
need to be re-worked entirely with a great API and avoid SSR issues such as with VitePress
1 parent f57c98c commit 65e07b9

File tree

3 files changed

+42
-87
lines changed

3 files changed

+42
-87
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
- 🎨 Great styling out-of-the-box, customization with CSS variables & Vue `:deep`
4040
- ✅ Single & multi-select support
4141
- 🖌️ Infinite customization with `<slot>`s
42-
- 🪄 `<Teleport />` menu where you want
4342
- 📦 Extremely light, **0 dependencies** (4.4kb gzip)
4443

4544
## Installation

docs/props.md

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -159,18 +159,6 @@ Whether the first option should be focused when the dropdown is opened. If set t
159159

160160
Whether the dropdown should close after an option is selected.
161161

162-
## teleport
163-
164-
**Type**: `string`
165-
166-
**Default**: `undefined`
167-
168-
Teleport the menu outside of the component DOM tree. You can pass a valid string according to the official Vue 3 Teleport documentation (e.g. `teleport="body"` will teleport the menu into the `<body>` tree). This can be used in case you are having `z-index` issues within your DOM tree structure.
169-
170-
::: info
171-
Top and left properties are calculated using a ref on the `.vue-select` with a `container.getBoundingClientRect()`.
172-
:::
173-
174162
## inputId
175163

176164
**Type**: `string`

src/Select.vue

Lines changed: 42 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,6 @@ const props = withDefaults(
5959
* When set to true, clear the search input when an option is selected.
6060
*/
6161
closeOnSelect?: boolean;
62-
/**
63-
* Teleport the menu to another part of the DOM with higher priority such as `body`.
64-
* This way, you can avoid z-index issues. Menu position will be calculated using
65-
* JavaScript, instead of using CSS absolute & relative positioning.
66-
*/
67-
teleport?: string;
6862
/**
6963
* The ID of the input element. This is useful for accessibility or forms.
7064
*/
@@ -110,7 +104,6 @@ const props = withDefaults(
110104
isMenuOpen: undefined,
111105
shouldAutofocusOption: true,
112106
closeOnSelect: true,
113-
teleport: undefined,
114107
inputId: undefined,
115108
aria: undefined,
116109
filterBy: (option: GenericOption, label: string, search: string) => label.toLowerCase().includes(search.toLowerCase()),
@@ -363,21 +356,6 @@ const handleClickOutside = (event: MouseEvent) => {
363356
}
364357
};
365358
366-
const calculateMenuPosition = () => {
367-
if (container.value) {
368-
const rect = container.value.getBoundingClientRect();
369-
370-
return {
371-
left: `${rect.x}px`,
372-
top: `${rect.y + rect.height}px`,
373-
};
374-
}
375-
376-
console.warn("Unable to calculate dynamic menu position because of missing internal DOM reference.");
377-
378-
return { top: "0px", left: "0px" };
379-
};
380-
381359
watch(
382360
() => search.value,
383361
() => {
@@ -516,64 +494,53 @@ onBeforeUnmount(() => {
516494
</div>
517495
</div>
518496

519-
<Teleport
520-
:to="teleport"
521-
:disabled="!teleport"
522-
:defer="true"
497+
<div
498+
v-if="menuOpen"
499+
ref="menu"
500+
class="menu"
501+
role="listbox"
502+
:aria-label="aria?.labelledby"
503+
:aria-multiselectable="isMulti"
523504
>
524-
<div
525-
v-if="menuOpen"
526-
ref="menu"
527-
class="menu"
528-
role="listbox"
529-
:aria-label="aria?.labelledby"
530-
:aria-multiselectable="isMulti"
531-
:style="{
532-
width: props.teleport ? `${container?.getBoundingClientRect().width}px` : '100%',
533-
top: props.teleport ? calculateMenuPosition().top : 'unset',
534-
left: props.teleport ? calculateMenuPosition().left : 'unset',
535-
}"
505+
<slot name="menu-header" />
506+
507+
<MenuOption
508+
v-for="(option, i) in availableOptions"
509+
:key="i"
510+
type="button"
511+
class="menu-option"
512+
:class="{ focused: focusedOption === i, selected: option.value === selected }"
513+
:menu="menu"
514+
:index="i"
515+
:is-focused="focusedOption === i"
516+
:is-selected="option.value === selected"
517+
:is-disabled="option.disabled || false"
518+
@select="setOption(option)"
536519
>
537-
<slot name="menu-header" />
538-
539-
<MenuOption
540-
v-for="(option, i) in availableOptions"
541-
:key="i"
542-
type="button"
543-
class="menu-option"
544-
:class="{ focused: focusedOption === i, selected: option.value === selected }"
545-
:menu="menu"
546-
:index="i"
547-
:is-focused="focusedOption === i"
548-
:is-selected="option.value === selected"
549-
:is-disabled="option.disabled || false"
550-
@select="setOption(option)"
551-
>
552-
<slot name="option" :option="option">
553-
{{ getOptionLabel(option) }}
554-
</slot>
555-
</MenuOption>
520+
<slot name="option" :option="option">
521+
{{ getOptionLabel(option) }}
522+
</slot>
523+
</MenuOption>
556524

557-
<div v-if="!isTaggable && availableOptions.length === 0" class="no-results">
558-
<slot name="no-options">
559-
No results found
560-
</slot>
561-
</div>
525+
<div v-if="!isTaggable && availableOptions.length === 0" class="no-results">
526+
<slot name="no-options">
527+
No results found
528+
</slot>
529+
</div>
562530

563-
<div
564-
v-if="isTaggable && search"
565-
class="taggable-no-options"
566-
@click="createOption"
531+
<div
532+
v-if="isTaggable && search"
533+
class="taggable-no-options"
534+
@click="createOption"
535+
>
536+
<slot
537+
name="taggable-no-options"
538+
:option="search"
567539
>
568-
<slot
569-
name="taggable-no-options"
570-
:option="search"
571-
>
572-
Press enter to add {{ search }} option
573-
</slot>
574-
</div>
540+
Press enter to add {{ search }} option
541+
</slot>
575542
</div>
576-
</Teleport>
543+
</div>
577544
</div>
578545
</template>
579546

@@ -788,6 +755,7 @@ onBeforeUnmount(() => {
788755
right: 0;
789756
padding: var(--vs-menu-padding);
790757
margin-top: var(--vs-menu-offset-top);
758+
width: 100%;
791759
max-height: var(--vs-menu-height);
792760
overflow-y: auto;
793761
border: var(--vs-menu-border);

0 commit comments

Comments
 (0)