Skip to content

Commit c8d132a

Browse files
committed
feat(web-core): create useMapper composable
1 parent 7fd4528 commit c8d132a

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# `useMapper` composable
2+
3+
This composable maps values from one type to another using a mapping record. It takes a source value, a mapping object, and a default value to use when the source value is undefined or not found in the mapping.
4+
5+
## Usage
6+
7+
```ts
8+
const mappedValue = useMapper(sourceValue, mapping, defaultValue)
9+
```
10+
11+
| | Required | Type | Default | |
12+
| -------------- | :------: | ------------------------- | ------- | --------------------------------------------------------------------------------- |
13+
| `sourceValue` || `MaybeRefOrGetter<TFrom>` | | The source value to be mapped. Can be a ref, a getter function, or a raw value |
14+
| `mapping` || `Record<TFrom, TTo>` | | An object mapping source values to destination values |
15+
| `defaultValue` || `MaybeRefOrGetter<TTo>` | | The default value to use when the source is undefined or not found in the mapping |
16+
17+
## Return value
18+
19+
| | Type | |
20+
| ------------- | ------------------ | ------------------------------------------------ |
21+
| `mappedValue` | `ComputedRef<TTo>` | A computed reference containing the mapped value |
22+
23+
## Example
24+
25+
```vue
26+
<template>
27+
<div>
28+
<p>Selected car color: {{ carColor }}</p>
29+
<p>Recommended wall color: {{ wallColor }}</p>
30+
31+
<button @click="carColor = 'red'">Red Car</button>
32+
<button @click="carColor = 'blue'">Blue Car</button>
33+
<button @click="carColor = 'black'">Black Car</button>
34+
<button @click="carColor = 'green'">Green Car</button>
35+
<button @click="carColor = 'silver'">Silver Car</button>
36+
<button @click="carColor = undefined">No Car</button>
37+
</div>
38+
</template>
39+
40+
<script lang="ts" setup>
41+
import { useMapper } from '@/composables/mapper'
42+
import { ref } from 'vue'
43+
44+
// Source type
45+
type CarColor = 'red' | 'blue' | 'black' | 'green' | 'silver'
46+
47+
// Destination type
48+
type WallColor = 'beige' | 'lightGray' | 'cream' | 'white'
49+
50+
// Create a ref for the source value
51+
const carColor = ref<CarColor | undefined>(undefined)
52+
53+
// Create a computed property that maps car color to wall color
54+
const wallColor = useMapper<CarColor, WallColor>(
55+
carColor,
56+
{
57+
red: 'beige',
58+
blue: 'lightGray',
59+
black: 'cream',
60+
green: 'beige',
61+
silver: 'lightGray',
62+
},
63+
'white'
64+
)
65+
</script>
66+
```
67+
68+
In this example:
69+
70+
- When `carColor.value` is `'red'` or `'green'`, `wallColor.value` will be `'beige'`
71+
- When `carColor.value` is `'blue'` or `'silver'`, `wallColor.value` will be `'lightGray'`
72+
- When `carColor.value` is `'black'`, `wallColor.value` will be `'cream'`
73+
- When `carColor.value` is `undefined` or any value not in the mapping, `wallColor.value` will be
74+
`'white'` (the default value)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { computed, type ComputedRef, type MaybeRefOrGetter, toValue } from 'vue'
2+
3+
export function useMapper<TFrom extends string | number, TTo>(
4+
_source: MaybeRefOrGetter<TFrom | undefined>,
5+
mapping: Record<TFrom, TTo>,
6+
_defaultValue: MaybeRefOrGetter<TTo>
7+
): ComputedRef<TTo> {
8+
return computed(() => {
9+
const source = toValue(_source)
10+
const defaultValue = toValue(_defaultValue)
11+
12+
if (source === undefined) {
13+
return defaultValue
14+
}
15+
16+
return Object.prototype.hasOwnProperty.call(mapping, source) ? mapping[source] : defaultValue
17+
})
18+
}

0 commit comments

Comments
 (0)