From addfd95bf2a34f976b013ecb26657874fcaa6846 Mon Sep 17 00:00:00 2001 From: lmhcoding <13265878974@163.com> Date: Sat, 19 Sep 2020 21:02:33 +0800 Subject: [PATCH] feat: add useToogle & useBoolean --- docs/useToggle.md | 0 src/index.ts | 2 + src/useBoolean.ts | 20 ++++++ src/useScroll.ts | 2 +- src/useScrollRef.ts | 2 +- src/useToggle.ts | 56 +++++++++++++++++ tests/useBoolean.test.ts | 45 ++++++++++++++ tests/useToggle.test.ts | 131 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 256 insertions(+), 2 deletions(-) create mode 100644 docs/useToggle.md create mode 100644 src/useBoolean.ts create mode 100644 src/useToggle.ts create mode 100644 tests/useBoolean.test.ts create mode 100644 tests/useToggle.test.ts diff --git a/docs/useToggle.md b/docs/useToggle.md new file mode 100644 index 0000000..e69de29 diff --git a/src/index.ts b/src/index.ts index 2c82b70..8397e09 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,3 +5,5 @@ export * from './useScroll' export * from './useScrollRef' export * from './useWindowScroll' export * from './useEventRef' +export * from './useToggle' +export * from './useBoolean' diff --git a/src/useBoolean.ts b/src/useBoolean.ts new file mode 100644 index 0000000..f3d47f5 --- /dev/null +++ b/src/useBoolean.ts @@ -0,0 +1,20 @@ +import { Ref } from 'vue' +import { useToggle } from './useToggle' + +interface IBoolean { + state: Ref + 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) + } +} diff --git a/src/useScroll.ts b/src/useScroll.ts index 5518ca3..1c51f24 100644 --- a/src/useScroll.ts +++ b/src/useScroll.ts @@ -12,7 +12,7 @@ export function useScroll(target: Target): ScrollState { } const state = reactive({ x: 0, - y: 0, + y: 0 }) const eventTarget = useEvent( 'scroll', diff --git a/src/useScrollRef.ts b/src/useScrollRef.ts index 712267c..6afe0f4 100644 --- a/src/useScrollRef.ts +++ b/src/useScrollRef.ts @@ -10,6 +10,6 @@ export function useScrollRef(): IScrollState { const state = useScroll(target) return { target, - ...state, + ...state } } diff --git a/src/useToggle.ts b/src/useToggle.ts new file mode 100644 index 0000000..c0ed795 --- /dev/null +++ b/src/useToggle.ts @@ -0,0 +1,56 @@ +import { ref, Ref } from 'vue' + +export type ToggleParamType = string | number | boolean | undefined | null + +export interface ToggleReturn { + state: Ref + toggle: (next?: boolean) => void + setDefault: () => void + setRight: () => void +} + +export interface ITwoType + extends Omit, 'state' | 'toggle'> { + state: Ref + toggle: (next?: T | U) => void +} + +export interface IToggle { + (): ToggleReturn + (defaultValue: T): ToggleReturn + ( + defaultValue: T, + resetValue?: U + ): ITwoType +} + +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 + 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 + } +} diff --git a/tests/useBoolean.test.ts b/tests/useBoolean.test.ts new file mode 100644 index 0000000..1894a48 --- /dev/null +++ b/tests/useBoolean.test.ts @@ -0,0 +1,45 @@ +import { Ref } from 'vue' +import { useBoolean } from '../src/useBoolean' + +describe('test useBoolean', () => { + let state: Ref + 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) + }) +}) diff --git a/tests/useToggle.test.ts b/tests/useToggle.test.ts new file mode 100644 index 0000000..49ae366 --- /dev/null +++ b/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 + 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 + 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') + }) +})