feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { act, renderHook } from '@testing-library/react-hooks';
|
||||
import useToggle from '../index';
|
||||
|
||||
describe('useToggle', () => {
|
||||
it('toggle values', () => {
|
||||
const hook = renderHook(() => useToggle());
|
||||
expect(hook.result.current.state).toBeFalsy();
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle();
|
||||
});
|
||||
expect(hook.result.current.state).toBeTruthy();
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle();
|
||||
});
|
||||
expect(hook.result.current.state).toBeFalsy();
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle(false);
|
||||
});
|
||||
expect(hook.result.current.state).toBeFalsy();
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle(true);
|
||||
});
|
||||
expect(hook.result.current.state).toBeTruthy();
|
||||
});
|
||||
|
||||
it('default value', () => {
|
||||
const hook = renderHook(() => useToggle(true));
|
||||
expect(hook.result.current.state).toBeTruthy();
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle();
|
||||
});
|
||||
expect(hook.result.current.state).toBeFalsy();
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle();
|
||||
});
|
||||
expect(hook.result.current.state).toBeTruthy();
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle(true);
|
||||
});
|
||||
expect(hook.result.current.state).toBeTruthy();
|
||||
});
|
||||
|
||||
it('default non-boolean value', () => {
|
||||
const defaultValue = {};
|
||||
const hook = renderHook(() => useToggle(defaultValue));
|
||||
expect(hook.result.current.state).toBe(defaultValue);
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle();
|
||||
});
|
||||
expect(hook.result.current.state).toBe(false);
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle();
|
||||
});
|
||||
expect(hook.result.current.state).toBe(defaultValue);
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle(defaultValue);
|
||||
});
|
||||
expect(hook.result.current.state).toBe(defaultValue);
|
||||
});
|
||||
|
||||
it('default non-boolean values', () => {
|
||||
enum Theme {
|
||||
Light = 0,
|
||||
Dark,
|
||||
}
|
||||
|
||||
const hook = renderHook(() => useToggle<Theme>(Theme.Light, Theme.Dark));
|
||||
expect(hook.result.current.state).toBe(Theme.Light);
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle();
|
||||
});
|
||||
expect(hook.result.current.state).toBe(Theme.Dark);
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle();
|
||||
});
|
||||
expect(hook.result.current.state).toBe(Theme.Light);
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle(Theme.Light);
|
||||
});
|
||||
expect(hook.result.current.state).toBe(Theme.Light);
|
||||
|
||||
act(() => {
|
||||
hook.result.current.toggle(Theme.Dark);
|
||||
});
|
||||
expect(hook.result.current.state).toBe(Theme.Dark);
|
||||
});
|
||||
});
|
||||
62
frontend/packages/arch/hooks/src/use-toggle/index.ts
Normal file
62
frontend/packages/arch/hooks/src/use-toggle/index.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useState, useMemo } from 'react'
|
||||
|
||||
type State = any
|
||||
|
||||
export interface ReturnValue<T = State> {
|
||||
state: T;
|
||||
toggle: (value?: T) => void;
|
||||
}
|
||||
|
||||
function useToggle<T = boolean>(): ReturnValue<T>
|
||||
|
||||
function useToggle<T = State>(defaultValue: T): ReturnValue<T>
|
||||
|
||||
function useToggle<T = State, U = State>(
|
||||
defaultValue: T,
|
||||
reverseValue: U,
|
||||
): ReturnValue<T | U>
|
||||
|
||||
function useToggle<D extends State = State, R extends State = State>(
|
||||
defaultValue: D = false as D,
|
||||
reverseValue?: R,
|
||||
) {
|
||||
const [state, setState] = useState<D | R>(defaultValue)
|
||||
|
||||
const actions = useMemo(() => {
|
||||
const reverseValueOrigin = (reverseValue === undefined ? !defaultValue : reverseValue) as D | R
|
||||
|
||||
const toggle = (value?: D | R) => {
|
||||
if (value !== undefined) {
|
||||
setState(value)
|
||||
return
|
||||
}
|
||||
setState((s) => (s === defaultValue ? reverseValueOrigin : defaultValue))
|
||||
}
|
||||
return {
|
||||
toggle,
|
||||
}
|
||||
}, [defaultValue, reverseValue])
|
||||
|
||||
return {
|
||||
state,
|
||||
...actions,
|
||||
}
|
||||
}
|
||||
|
||||
export default useToggle
|
||||
Reference in New Issue
Block a user