Skip to content

Commit 4b2b0d1

Browse files
committed
feat(docs): update docs, add typescript section
1 parent c797c0d commit 4b2b0d1

File tree

5 files changed

+160
-6
lines changed

5 files changed

+160
-6
lines changed

docs/.vitepress/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export default defineConfig({
3131
{ text: "Slots", link: "/slots" },
3232
{ text: "Events", link: "/events" },
3333
{ text: "Styling", link: "/styling" },
34+
{ text: "TypeScript", link: "/typescript" },
3435
],
3536
},
3637
{

docs/demo/multiple-select.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ title: 'Multiple Select'
77
The following example demonstrates how to use the `VueSelect` component to create a multiple select dropdown.
88

99
::: warning
10-
Setting `is-multi` to `true` will change the `v-model` to become an array of strings `string[]`. Make sure to update your `v-model` accordingly.
10+
Setting `is-multi` to `true` will change the `v-model` to become an array of any `any[]`. Make sure to update your `v-model` accordingly.
1111
:::
1212

1313
<script setup>

docs/dropdown-options.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ When using the `options` prop, you can pass an array of objects to the component
1414
</template>
1515
```
1616

17+
::: info
18+
If you are using TypeScript, make sure to read the [TypeScript usage](/typescript) section to leverage proper type-safety.
19+
:::
20+
1721
## Passing extra properties
1822

1923
You can pass extra properties to the options object. The component will ignore them but you will be able to manipulate those extra properties using some props and slots.
@@ -26,3 +30,7 @@ You can pass extra properties to the options object. The component will ignore t
2630
/>
2731
</template>
2832
```
33+
34+
::: info
35+
If you are using TypeScript, make sure to read the [TypeScript usage](/typescript) section to leverage proper type-safety.
36+
:::

docs/props.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@ This component is **ready to be used in production**. However, if there is a fea
1010

1111
## v-model
1212

13-
**Type**: `string | string[]`
13+
**Type**: `any | any[]`
1414

1515
**Required**: `true`
1616

17-
The value of the select. If `isMulti` is `true`, the `v-model` should be an array of string `string[]`.
17+
The value of the select. If `isMulti` is `true`, the `v-model` should be an array of any `any[]`.
18+
19+
::: info
20+
If using TypeScript, you can leverage proper type-safety between `option.value` & `v-model`. By doing this, you don't have an `any` type. Read more about [TypeScript usage](/typescript).
21+
:::
1822

1923
## options
2024

@@ -27,17 +31,20 @@ A list of options to choose from. Each option should have a `label` and a `value
2731
**Type interface**:
2832

2933
```ts
30-
type Option = {
34+
type Option<T> = {
3135
label: string;
32-
value: string;
33-
[key: string]: any;
36+
value: T;
3437
};
3538
```
3639

3740
::: tip
3841
This type is exported from the component and can be imported in your application.
3942
:::
4043

44+
::: info
45+
If you are using TypeScript, you can leverage proper type-safety between `option.value` & `v-model`. Read more about [TypeScript usage](/typescript).
46+
:::
47+
4148
## autoscroll
4249

4350
**Type**: `boolean`

docs/typescript.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
title: 'TypeScript'
3+
---
4+
5+
# TypeScript
6+
7+
In order to provide flexibility with TypeScript, Vue 3 Select Component has been written in TypeScript. This means that you can take advantage of TypeScript's type checking and autocompletion features.
8+
9+
## About generics in TypeScript & Vue
10+
11+
Vue 3 Select Component uses a feature that has been released on Vue 3.3 called [**Generics**](https://vuejs.org/api/sfc-script-setup.html#generics).
12+
13+
Generics allow you to define a type that can be used in multiple places with different types. This is useful when you want to create a component that can be used with different types of data.
14+
15+
A common type you'll see is the `Option` type, which is used to define the options of the select component.
16+
17+
```typescript
18+
type Option<T> = {
19+
label: string;
20+
value: T;
21+
};
22+
```
23+
24+
## Custom option value
25+
26+
::: info
27+
Ensure you are familiar with the [`:options` prop](/props#options) before reading this section.
28+
:::
29+
30+
By default, the `value` property of the option object is a `string`. However, it is possible to use a custom type, such as a `number` or a complex object.
31+
32+
```vue
33+
<script setup lang="ts">
34+
import { ref } from "vue";
35+
import VueSelect, { type Option } from "vue3-select-component";
36+
37+
// Define a custom type for the option value.
38+
// It takes a generic type that defines the type of the `value` property.
39+
// In this case, the `value` property is a `number`.
40+
type UserOption = Option<number>;
41+
42+
const selectedUser = ref<number>();
43+
44+
const userOptions: UserOption[] = [
45+
{ label: "Alice", value: 1 },
46+
{ label: "Bob", value: 2 },
47+
{ label: "Charlie", value: 3 },
48+
// ❌ - This will cause a type error because `value` is not a number
49+
{ label: "David", value: "a string" },
50+
];
51+
</script>
52+
53+
<template>
54+
<VueSelect
55+
v-model="selectedUser"
56+
:options="userOptions"
57+
placeholder="Pick a user"
58+
/>
59+
</template>
60+
```
61+
62+
## Custom option properties
63+
64+
It is possible to **add properties** to the options passed inside the `:options` prop, while still being type-safe.
65+
66+
Let's say you want to add a `username` property to the option object.
67+
68+
This `username` property will be available on **all available props and slots** that receive the `option` object.
69+
70+
```vue
71+
<script setup lang="ts">
72+
import { ref } from "vue";
73+
import VueSelect, { type Option } from "vue3-select-component";
74+
75+
type UserOption = Option<number> & { username: string };
76+
77+
const selectedUser = ref<number>();
78+
79+
const userOptions: UserOption[] = [
80+
{ label: "Alice", value: 1, username: "alice15" },
81+
{ label: "Bob", value: 2, username: "bob01" },
82+
{ label: "Charlie", value: 3, username: "charlie20" },
83+
{ label: "David", value: 4, username: "david30" },
84+
];
85+
</script>
86+
87+
<template>
88+
<!-- The username property will be available on functions inside the VueSelect component. -->
89+
<VueSelect
90+
v-model="selectedUser"
91+
:options="userOptions"
92+
:get-option-label="option => `${option.label} (${option.username})`"
93+
placeholder="Pick a user"
94+
>
95+
<!-- The username property is also available on slots that receive an option object. -->
96+
<template #option="{ option }">
97+
<span>{{ option.label }} - {{ option.username }}</span>
98+
</template>
99+
</VueSelect>
100+
</template>
101+
```
102+
103+
## Type-safe relationship between `option.value` & `v-model`
104+
105+
Vue 3 Select Component creates a type-safe relationship between the `option.value` and the `v-model` prop.
106+
107+
This means that if you have a custom type for the `value` property of the option object, the `v-model` prop will also be type-safe.
108+
109+
```vue
110+
<script setup lang="ts">
111+
import { ref } from "vue";
112+
import VueSelect, { type Option } from "vue3-select-component";
113+
114+
type UserOption = Option<number>;
115+
116+
// This `ref()` type implementation is incorrect, as it should
117+
// be `ref<number>()`.
118+
const selectedUser = ref<string>();
119+
120+
const userOptions: UserOption[] = [
121+
{ label: "Alice", value: 1 },
122+
{ label: "Bob", value: 2 },
123+
{ label: "Charlie", value: 3 },
124+
];
125+
</script>
126+
127+
<template>
128+
<!--
129+
Our v-model will cause a type error because `ref<string>()`
130+
cannot be assigned to `Option.value<number>`.
131+
-->
132+
<VueSelect
133+
v-model="selectedUser"
134+
:options="userOptions"
135+
placeholder="Pick a user"
136+
/>
137+
</template>
138+
```

0 commit comments

Comments
 (0)