Skip to content

Commit 0726ecc

Browse files
committed
feat(slots): improve placeholder slot
1 parent 384a1c6 commit 0726ecc

File tree

7 files changed

+62
-6
lines changed

7 files changed

+62
-6
lines changed

docs/slots.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,22 @@ Customize the rendered template for the clear icon. Please note that the slot is
168168
</template>
169169
```
170170

171+
## placeholder
172+
173+
**Type**: `slotProps: { text: string }`
174+
175+
Customize the rendered template for the placeholder.
176+
177+
```vue
178+
<template>
179+
<VueSelect v-model="option" :options="options">
180+
<template #placeholder>
181+
<span>Custom placeholder</span>
182+
</template>
183+
</VueSelect>
184+
</template>
185+
```
186+
171187
## loading
172188

173189
**Type**: `slotProps: {}`

playground/PlaygroundLayout.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const links = [
88
{ value: "/single-select", label: "Single Select" },
99
{ value: "/multi-select", label: "Multi Select" },
1010
{ value: "/multi-select-taggable", label: "Multi Select Taggable" },
11+
{ value: "/custom-placeholder", label: "Custom Placeholder" },
1112
{ value: "/custom-menu-container", label: "Custom Menu Container" },
1213
{ value: "/custom-menu-option", label: "Custom Menu Option" },
1314
{ value: "/custom-option-label-value", label: "Custom Option Label/Value" },
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script setup lang="ts">
2+
import type { Option } from "../../src";
3+
import { ref } from "vue";
4+
import VueSelect from "../../src";
5+
6+
const selected = ref<string | null>(null);
7+
8+
const options: Option<string>[] = [
9+
{ label: "Alice's Adventures in Wonderland", value: "alice" },
10+
{ label: "A Wizard of Earthsea", value: "wizard" },
11+
{ label: "Harry Potter and the Philosopher's Stone", value: "harry_potter_1" },
12+
{ label: "Harry Potter and the Chamber of Secrets", value: "harry_potter_2" },
13+
];
14+
</script>
15+
16+
<template>
17+
<VueSelect
18+
v-model="selected"
19+
:options="options"
20+
:is-multi="false"
21+
placeholder="Pick a book"
22+
>
23+
<template #placeholder>
24+
<span>Custom placeholder</span>
25+
</template>
26+
</VueSelect>
27+
28+
<p class="selected-value">
29+
Selected book value: {{ selected || "none" }}
30+
</p>
31+
</template>

playground/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import ControlledMenu from "./demos/ControlledMenu.vue";
55
import CustomMenuContainer from "./demos/CustomMenuContainer.vue";
66
import CustomMenuOption from "./demos/CustomMenuOption.vue";
77
import CustomOptionLabelValue from "./demos/CustomOptionLabelValue.vue";
8+
import CustomPlaceholder from "./demos/CustomPlaceholder.vue";
89
import CustomSearchFilter from "./demos/CustomSearchFilter.vue";
910
import InfiniteScroll from "./demos/InfiniteScroll.vue";
1011
import MenuHeader from "./demos/MenuHeader.vue";
@@ -22,6 +23,7 @@ const router = createRouter({
2223
{ path: "/single-select", component: SingleSelect },
2324
{ path: "/multi-select", component: MultiSelect },
2425
{ path: "/multi-select-taggable", component: MultiSelectTaggable },
26+
{ path: "/custom-placeholder", component: CustomPlaceholder },
2527
{ path: "/custom-menu-container", component: CustomMenuContainer },
2628
{ path: "/custom-menu-option", component: CustomMenuOption },
2729
{ path: "/custom-option-label-value", component: CustomOptionLabelValue },

src/Placeholder.vue

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1-
<script setup lang="ts">
1+
<script setup lang="ts" generic="GenericOption extends Option<OptionValue>, OptionValue = string">
2+
import type { Option } from "./types/option";
3+
import type { Slots } from "./types/slots";
4+
25
defineProps<{
36
text: string;
7+
placeholderSlot?: Slots<GenericOption, OptionValue>["placeholder"];
48
}>();
59
</script>
610

711
<template>
812
<div class="input-placeholder">
9-
{{ text }}
13+
<component :is="placeholderSlot" v-if="placeholderSlot" />
14+
15+
<template v-else>
16+
{{ text }}
17+
</template>
1018
</div>
1119
</template>
1220

src/Select.vue

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -316,13 +316,10 @@ watch(
316316
>
317317
<template v-if="!selectedOptions[0] && !search.length">
318318
<Placeholder
319-
v-if="!$slots.placeholder"
320319
:text="placeholder"
320+
:placeholder-slot="slots.placeholder"
321321
:class="props.classes?.placeholder"
322322
/>
323-
<div v-else>
324-
<slot name="placeholder"></slot>
325-
</div>
326323
</template>
327324

328325
<div

src/types/slots.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export type Slots<GenericOption extends Option<OptionValue>, OptionValue> = {
1212
"clear"?: () => any;
1313
"dropdown"?: () => any;
1414
"loading"?: () => any;
15+
"placeholder"?: () => any;
1516
"menu-header"?: () => any;
1617
"menu-container"?: (props: { defaultContent: JSX.Element }) => any;
1718
"option"?: (props: { option: GenericOption; index: number; isFocused: boolean; isSelected: boolean; isDisabled: boolean }) => any;

0 commit comments

Comments
 (0)