Skip to content

Commit

Permalink
feat: add useToogle & useBoolean
Browse files Browse the repository at this point in the history
  • Loading branch information
lmhcoding committed Sep 19, 2020
1 parent 66477dd commit addfd95
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 2 deletions.
Empty file added docs/useToggle.md
Empty file.
2 changes: 2 additions & 0 deletions src/index.ts
Expand Up @@ -5,3 +5,5 @@ export * from './useScroll'
export * from './useScrollRef'
export * from './useWindowScroll'
export * from './useEventRef'
export * from './useToggle'
export * from './useBoolean'
20 changes: 20 additions & 0 deletions src/useBoolean.ts
@@ -0,0 +1,20 @@
import { Ref } from 'vue'
import { useToggle } from './useToggle'

interface IBoolean {
state: Ref<boolean>
setTrue: () => void
setFalse: () => void
toggle: (next?: boolean) => void
}

export function useBoolean(defaultValue: boolean = false): IBoolean {
const { state, toggle } = useToggle(defaultValue)

return {
state,
toggle,
setTrue: () => toggle(true),
setFalse: () => toggle(false)
}
}
2 changes: 1 addition & 1 deletion src/useScroll.ts
Expand Up @@ -12,7 +12,7 @@ export function useScroll(target: Target): ScrollState {
}
const state = reactive({
x: 0,
y: 0,
y: 0
})
const eventTarget = useEvent(
'scroll',
Expand Down
2 changes: 1 addition & 1 deletion src/useScrollRef.ts
Expand Up @@ -10,6 +10,6 @@ export function useScrollRef(): IScrollState {
const state = useScroll(target)
return {
target,
...state,
...state
}
}
56 changes: 56 additions & 0 deletions src/useToggle.ts
@@ -0,0 +1,56 @@
import { ref, Ref } from 'vue'

export type ToggleParamType = string | number | boolean | undefined | null

export interface ToggleReturn<T extends ToggleParamType = ToggleParamType> {
state: Ref<T>
toggle: (next?: boolean) => void
setDefault: () => void
setRight: () => void
}

export interface ITwoType<T extends ToggleParamType = ToggleParamType, U extends ToggleParamType = ToggleParamType>
extends Omit<ToggleReturn<T>, 'state' | 'toggle'> {
state: Ref<T | U>
toggle: (next?: T | U) => void
}

export interface IToggle {
(): ToggleReturn<boolean>
<T extends ToggleParamType = ToggleParamType>(defaultValue: T): ToggleReturn<T>
<T extends ToggleParamType = ToggleParamType, U extends ToggleParamType = ToggleParamType>(
defaultValue: T,
resetValue?: U
): ITwoType<T, U>
}

export const useToggle: IToggle = <
T extends ToggleParamType = ToggleParamType,
U extends ToggleParamType = ToggleParamType
>(
defaultValue: T = false as T,
reverseValue?: U
) => {
const state = ref(defaultValue) as Ref<T | U>
const reverseTo = (reverseValue === undefined ? !defaultValue : reverseValue) as T | U

const toggle = (next?: T | U) => {
if (next !== undefined) {
state.value = next
} else {
state.value = state.value === defaultValue ? reverseTo : defaultValue
}
}
const setDefault = () => {
state.value = defaultValue
}
const setRight = () => {
state.value = reverseTo
}
return {
state,
setDefault,
setRight,
toggle
}
}
45 changes: 45 additions & 0 deletions tests/useBoolean.test.ts
@@ -0,0 +1,45 @@
import { Ref } from 'vue'
import { useBoolean } from '../src/useBoolean'

describe('test useBoolean', () => {
let state: Ref<boolean>
let toggle: (next?: boolean) => void
let setTrue: () => void
let setFalse: () => void
beforeEach(() => {
const result = useBoolean()
state = result.state
toggle = result.toggle
setTrue = result.setTrue
setFalse = result.setFalse
})

test('init State should be false', () => {
expect(state.value).toBe(false)
})

test('state.value should be toggled after invoking toggle with none params', () => {
expect(state.value).toBe(false)
toggle()
expect(state.value).toBe(true)
toggle()
expect(state.value).toBe(false)
})
test('state.value should be set to specify value after invoking toggle with one parameter', () => {
expect(state.value).toBe(false)
toggle(true)
expect(state.value).toBe(true)
toggle(false)
expect(state.value).toBe(false)
})
test('state.value should be true after invoking setTrue', () => {
setTrue()
expect(state.value).toBe(true)
})
test('state.value should be false after invoking setFalse', () => {
toggle(true)
expect(state.value).toBe(true)
setFalse()
expect(state.value).toBe(false)
})
})
131 changes: 131 additions & 0 deletions tests/useToggle.test.ts
@@ -0,0 +1,131 @@
import { Ref } from 'vue'
import { useToggle } from '../src/useToggle'

describe('test useToggle with none params', () => {
let state: Ref<boolean>
let toggle: (next?: boolean) => void
let setDefault: () => void
let setRight: () => void
beforeEach(() => {
const result = useToggle()
state = result.state
toggle = result.toggle
setDefault = result.setDefault
setRight = result.setRight
})

test('init State should be false', () => {
expect(state.value).toBe(false)
})

test('state.value should be toggled after invoking toggle with none params', () => {
expect(state.value).toBe(false)
toggle()
expect(state.value).toBe(true)
toggle()
expect(state.value).toBe(false)
})
test('state.value should be set to specify value after invoking toggle with one parameter', () => {
expect(state.value).toBe(false)
toggle(true)
expect(state.value).toBe(true)
toggle(false)
expect(state.value).toBe(false)
})
test('state.value should be false after invoking setDefault', () => {
toggle(true)
expect(state.value).toBe(true)
setDefault()
expect(state.value).toBe(false)
})
test('state.value should be true after invoking setRight', () => {
setRight()
expect(state.value).toBe(true)
})
})

describe('test useToggle with one parameter', () => {
let state: Ref<boolean>
let toggle: (next?: boolean) => void
let setDefault: () => void
let setRight: () => void
beforeEach(() => {
const result = useToggle(true)
state = result.state
toggle = result.toggle
setDefault = result.setDefault
setRight = result.setRight
})

test('init State should be true', () => {
expect(state.value).toBe(true)
})

test('state.value should be toggled after invoking toggle with none params', () => {
expect(state.value).toBe(true)
toggle()
expect(state.value).toBe(false)
toggle()
expect(state.value).toBe(true)
})
test('state.value should be set to specify value after invoking toggle with one parameter', () => {
expect(state.value).toBe(true)
toggle(false)
expect(state.value).toBe(false)
toggle(true)
expect(state.value).toBe(true)
})
test('state.value should be true after invoking setDefault', () => {
toggle(false)
expect(state.value).toBe(false)
setDefault()
expect(state.value).toBe(true)
})
test('state.value should be false after invoking setRight', () => {
setRight()
expect(state.value).toBe(false)
})
})

describe('test useToggle with two parameters', () => {
let state: Ref<'abc' | 'cde'>
let toggle: (next?: 'abc' | 'cde') => void
let setDefault: () => void
let setRight: () => void
beforeEach(() => {
const result = useToggle('abc', 'cde')
state = result.state
toggle = result.toggle
setDefault = result.setDefault
setRight = result.setRight
})

test('init State should be abc', () => {
expect(state.value).toBe('abc')
})

test('state.value should be toggled after invoking toggle with none params', () => {
expect(state.value).toBe('abc')
toggle()
expect(state.value).toBe('cde')
toggle()
expect(state.value).toBe('abc')
})
test('state.value should be set to specify value after invoking toggle with one parameter', () => {
expect(state.value).toBe('abc')
toggle('cde')
expect(state.value).toBe('cde')
toggle('abc')
expect(state.value).toBe('abc')
})
test('state.value should be abc after invoking setDefault', () => {
toggle('cde')
expect(state.value).toBe('cde')
setDefault()
expect(state.value).toBe('abc')
})
test('state.value should be cde after invoking setRight', () => {
setRight()
expect(state.value).toBe('cde')
})
})

0 comments on commit addfd95

Please sign in to comment.