-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
index.ts
72 lines (60 loc) · 1.34 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import type { Ref } from 'vue-demi'
import { computed, shallowRef } from 'vue-demi'
export interface UseCycleListOptions<T> {
/**
* The initial value of the state.
* A ref can be provided to reuse.
*/
initialValue?: T
/**
* The default index when
*/
fallbackIndex?: number
/**
* Custom function to get the index of the current value.
*/
getIndexOf?: (value: T, list: T[]) => number
}
/**
* Cycle through a list of items
*
* @see https://vueuse.org/useCycleList
*/
export function useCycleList<T>(list: T[], options?: UseCycleListOptions<T>) {
const state = shallowRef(options?.initialValue ?? list[0]) as Ref<T>
const index = computed<number>({
get() {
let index = options?.getIndexOf
? options.getIndexOf(state.value, list)
: list.indexOf(state.value)
if (index < 0)
index = options?.fallbackIndex ?? 0
return index
},
set(v) {
set(v)
},
})
function set(i: number) {
const length = list.length
const index = (i % length + length) % length
const value = list[index]
state.value = value
return value
}
function shift(delta = 1) {
return set(index.value + delta)
}
function next(n = 1) {
return shift(n)
}
function prev(n = 1) {
return shift(-n)
}
return {
state,
index,
next,
prev,
}
}