Skip to content

Commit

Permalink
Allow useCycleList to receive ref list and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hjJunior committed Mar 13, 2023
1 parent 6aaa66e commit f7e58ef
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 11 deletions.
5 changes: 3 additions & 2 deletions packages/core/useCycleList/demo.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script setup lang="ts">
import { useCycleList } from '@vueuse/core'
import { ref } from 'vue'
const list = [
const list = ref([
'Dog',
'Cat',
'Lizard',
Expand All @@ -10,7 +11,7 @@ const list = [
'Dolphin',
'Octopus',
'Seal',
]
])
const { state, next, prev } = useCycleList(list)
</script>
Expand Down
3 changes: 2 additions & 1 deletion packages/core/useCycleList/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Cycle through a list of items.
```ts
import { useCycleList } from '@vueuse/core'

const { state, next, prev } = useCycleList([
const list = ref([
'Dog',
'Cat',
'Lizard',
Expand All @@ -23,6 +23,7 @@ const { state, next, prev } = useCycleList([
'Octopus',
'Seal',
])
const { state, next, prev } = useCycleList(list)

console.log(state.value) // 'Dog'

Expand Down
74 changes: 74 additions & 0 deletions packages/core/useCycleList/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { ref } from 'vue-demi'
import { useCycleList } from '.'

describe('useCycleList', () => {
it('should work with array', () => {
const { state, next, prev, index } = useCycleList(['foo', 'bar', 'fooBar'])

expect(state.value).toBe('foo')
expect(index.value).toBe(0)

next()

expect(state.value).toBe('bar')
expect(index.value).toBe(1)

prev()

expect(state.value).toBe('foo')
expect(index.value).toBe(0)

index.value = 2

expect(state.value).toBe('fooBar')
expect(index.value).toBe(2)

state.value = 'foo'

expect(state.value).toBe('foo')
expect(index.value).toBe(0)
})

it('should work with ref', () => {
const list = ref(['foo', 'bar', 'fooBar'])

const { state, next, prev, index } = useCycleList(list)

expect(state.value).toBe('foo')
expect(index.value).toBe(0)

next()

expect(state.value).toBe('bar')
expect(index.value).toBe(1)

prev()

expect(state.value).toBe('foo')
expect(index.value).toBe(0)

index.value = 2

expect(state.value).toBe('fooBar')
expect(index.value).toBe(2)

state.value = 'foo'

expect(state.value).toBe('foo')
expect(index.value).toBe(0)
})

describe('when list empty', () => {
it('returns the correctly data', () => {
const list = ref(['foo', 'bar', 'fooBar'])

const { state, index } = useCycleList(list)

list.value = []
index.value = 2

expect(state.value).toBeUndefined()
expect(index.value).toBe(0)
})
})
})
25 changes: 17 additions & 8 deletions packages/core/useCycleList/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type Ref, computed, shallowRef } from 'vue-demi'
import { type MaybeRef } from '@vueuse/shared'
import { type Ref, computed, shallowRef, watch } from 'vue-demi'
import { type MaybeRef, resolveUnref } from '@vueuse/shared'

export interface UseCycleListOptions<T> {
/**
Expand All @@ -24,14 +24,16 @@ export interface UseCycleListOptions<T> {
*
* @see https://vueuse.org/useCycleList
*/
export function useCycleList<T>(list: T[], options?: UseCycleListOptions<T>): UseCycleListReturn<T> {
const state = shallowRef(options?.initialValue ?? list[0]) as Ref<T>
export function useCycleList<T>(list: MaybeRef<T[]>, options?: UseCycleListOptions<T>): UseCycleListReturn<T> {
const state = shallowRef(getInitialValue()) as Ref<T>

const index = computed<number>({
get() {
const targetList = resolveUnref<T[]>(list)

let index = options?.getIndexOf
? options.getIndexOf(state.value, list)
: list.indexOf(state.value)
? options.getIndexOf(state.value, targetList)
: targetList.indexOf(state.value)

if (index < 0)
index = options?.fallbackIndex ?? 0
Expand All @@ -44,9 +46,10 @@ export function useCycleList<T>(list: T[], options?: UseCycleListOptions<T>): Us
})

function set(i: number) {
const length = list.length
const targetList = resolveUnref<T[]>(list)
const length = targetList.length
const index = (i % length + length) % length
const value = list[index]
const value = targetList[index]
state.value = value
return value
}
Expand All @@ -63,6 +66,12 @@ export function useCycleList<T>(list: T[], options?: UseCycleListOptions<T>): Us
return shift(-n)
}

function getInitialValue() {
return resolveUnref(options?.initialValue ?? resolveUnref<T[]>(list)[0]) ?? undefined
}

watch(shallowRef(list), () => set(index.value))

return {
state,
index,
Expand Down

0 comments on commit f7e58ef

Please sign in to comment.