@ones-design/utils
Advanced tools
Comparing version 1.10.1-rc.1 to 1.10.1-rc.2
import { isEqual as isEqual$1 } from '@senojs/lodash'; | ||
import { Children, Fragment, isValidElement, cloneElement as cloneElement$1, useCallback, useRef, useLayoutEffect as useLayoutEffect$1, useEffect, useState } from 'react'; | ||
import { Children, Fragment, isValidElement, cloneElement as cloneElement$1, useCallback, useRef, useState, useEffect } from 'react'; | ||
@@ -233,41 +233,2 @@ /** | ||
function useEvent(callback) { | ||
const fnRef = useRef(); | ||
fnRef.current = callback; | ||
const memoFn = useCallback((...args) => { | ||
var _fnRef$current; | ||
return (_fnRef$current = fnRef.current) === null || _fnRef$current === void 0 ? void 0 : _fnRef$current.call(fnRef, ...args); | ||
}, []); | ||
return memoFn; | ||
} | ||
function canUseDom() { | ||
return !!(typeof window !== 'undefined' && window.document && window.document.createElement); | ||
} | ||
/** | ||
* Wrap `useLayoutEffect` which will not throw warning message in test env | ||
* 判断环境,只有浏览器环境下可以使用 useLayoutEffect | ||
* useLayoutEffect: value change -> layoutEffect -> re-render | ||
*/ | ||
const useInternalLayoutEffect = process.env.NODE_ENV !== 'test' && canUseDom() ? useLayoutEffect$1 : useEffect; | ||
const useLayoutUpdateEffect = (callback, deps) => { | ||
const firstMountRef = useRef(true); | ||
useInternalLayoutEffect(() => { | ||
if (!firstMountRef.current) { | ||
return callback(); | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, deps); | ||
// We tell react that first mount has passed | ||
useInternalLayoutEffect(() => { | ||
firstMountRef.current = false; | ||
return () => { | ||
firstMountRef.current = true; | ||
}; | ||
}, []); | ||
}; | ||
const useLayoutEffect = useInternalLayoutEffect; | ||
const defaultShouldUpdate = (prev, next) => { | ||
@@ -303,79 +264,2 @@ if (Array.isArray(prev) && Array.isArray(next)) { | ||
var Source = /*#__PURE__*/function (Source) { | ||
Source[Source["INNER"] = 0] = "INNER"; | ||
Source[Source["PROP"] = 1] = "PROP"; | ||
return Source; | ||
}(Source || {}); // props 传入的值 | ||
/** We only think `undefined` is empty */ | ||
function hasValue(value) { | ||
return value !== undefined; | ||
} | ||
/** | ||
* Similar to `useState` but will use props value if provided. | ||
* Note that internal use rc-util `useState` hook. | ||
* 和 useState 类似,如果该参数由 props 提供,优先使用 props 内的参数 | ||
* 保证当 value 在非空值和 undefined 之间切换时可以自动切换受控和非受控模式 | ||
*/ | ||
function useMergedState(defaultStateValue, option) { | ||
const { | ||
defaultValue, | ||
value, | ||
onChange, | ||
postState | ||
} = option || {}; | ||
// ======================= Init ======================= | ||
const [mergedValue, setMergedValue] = useState(() => { | ||
let finalValue; | ||
let source; | ||
if (hasValue(value)) { | ||
finalValue = value; | ||
source = Source.PROP; | ||
} else if (hasValue(defaultValue)) { | ||
finalValue = typeof defaultValue === 'function' ? defaultValue() : defaultValue; | ||
source = Source.PROP; | ||
} else { | ||
// value 是 undefined,表示未传入 props,可以直接使用内部值 | ||
finalValue = typeof defaultStateValue === 'function' ? defaultStateValue() : defaultStateValue; | ||
source = Source.INNER; | ||
} | ||
return [finalValue, source, finalValue]; | ||
}); | ||
const chosenValue = hasValue(value) ? value : mergedValue[0]; | ||
const postMergedValue = postState ? postState(chosenValue) : chosenValue; | ||
// ======================= Sync ======================= | ||
useLayoutUpdateEffect(() => { | ||
setMergedValue(([prevValue]) => [value, Source.PROP, prevValue]); | ||
}, [value]); | ||
// ====================== Update ====================== | ||
const changeEventPrevRef = useRef(); | ||
const triggerChange = useEvent(updater => { | ||
setMergedValue(prev => { | ||
const [prevValue, prevSource, prevPrevValue] = prev; | ||
const nextValue = typeof updater === 'function' ? updater(prevValue) : updater; | ||
// Do nothing if value not change | ||
if (nextValue === prevValue) { | ||
return prev; | ||
} | ||
const overridePrevValue = prevSource === Source.INNER && changeEventPrevRef.current !== prevPrevValue ? prevPrevValue : prevValue; | ||
return [nextValue, Source.INNER, overridePrevValue]; | ||
}); | ||
}); | ||
// ====================== Change ====================== | ||
const onChangeFn = useEvent(onChange); | ||
useLayoutEffect(() => { | ||
const [current, source, prev] = mergedValue; | ||
if (current !== prev && source === Source.INNER) { | ||
onChangeFn(current, prev); | ||
changeEventPrevRef.current = prev; | ||
} | ||
}, [mergedValue, onChangeFn]); | ||
return [postMergedValue, triggerChange]; | ||
} | ||
function useIntersectionObserver(elementRef, { | ||
@@ -409,2 +293,2 @@ threshold = 0, | ||
export { cloneElement, hasParent, isEqual, isFragment, isSubArrayFromStart, isValidChildren, replaceMessage, tip, toArray, useCombineRefs, useEvent, useIntersectionObserver, useLayoutEffect, useMemo, useMergedState, warn }; | ||
export { cloneElement, hasParent, isEqual, isFragment, isSubArrayFromStart, isValidChildren, replaceMessage, tip, toArray, useCombineRefs, useIntersectionObserver, useMemo, warn }; |
import { isEqual as isEqual$1 } from '@senojs/lodash'; | ||
import { Children, Fragment, isValidElement, cloneElement as cloneElement$1, useCallback, useRef, useLayoutEffect as useLayoutEffect$1, useEffect, useState } from 'react'; | ||
import { Children, Fragment, isValidElement, cloneElement as cloneElement$1, useCallback, useRef, useState, useEffect } from 'react'; | ||
@@ -233,41 +233,2 @@ /** | ||
function useEvent(callback) { | ||
const fnRef = useRef(); | ||
fnRef.current = callback; | ||
const memoFn = useCallback((...args) => { | ||
var _fnRef$current; | ||
return (_fnRef$current = fnRef.current) === null || _fnRef$current === void 0 ? void 0 : _fnRef$current.call(fnRef, ...args); | ||
}, []); | ||
return memoFn; | ||
} | ||
function canUseDom() { | ||
return !!(typeof window !== 'undefined' && window.document && window.document.createElement); | ||
} | ||
/** | ||
* Wrap `useLayoutEffect` which will not throw warning message in test env | ||
* 判断环境,只有浏览器环境下可以使用 useLayoutEffect | ||
* useLayoutEffect: value change -> layoutEffect -> re-render | ||
*/ | ||
const useInternalLayoutEffect = process.env.NODE_ENV !== 'test' && canUseDom() ? useLayoutEffect$1 : useEffect; | ||
const useLayoutUpdateEffect = (callback, deps) => { | ||
const firstMountRef = useRef(true); | ||
useInternalLayoutEffect(() => { | ||
if (!firstMountRef.current) { | ||
return callback(); | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, deps); | ||
// We tell react that first mount has passed | ||
useInternalLayoutEffect(() => { | ||
firstMountRef.current = false; | ||
return () => { | ||
firstMountRef.current = true; | ||
}; | ||
}, []); | ||
}; | ||
const useLayoutEffect = useInternalLayoutEffect; | ||
const defaultShouldUpdate = (prev, next) => { | ||
@@ -303,79 +264,2 @@ if (Array.isArray(prev) && Array.isArray(next)) { | ||
var Source = /*#__PURE__*/function (Source) { | ||
Source[Source["INNER"] = 0] = "INNER"; | ||
Source[Source["PROP"] = 1] = "PROP"; | ||
return Source; | ||
}(Source || {}); // props 传入的值 | ||
/** We only think `undefined` is empty */ | ||
function hasValue(value) { | ||
return value !== undefined; | ||
} | ||
/** | ||
* Similar to `useState` but will use props value if provided. | ||
* Note that internal use rc-util `useState` hook. | ||
* 和 useState 类似,如果该参数由 props 提供,优先使用 props 内的参数 | ||
* 保证当 value 在非空值和 undefined 之间切换时可以自动切换受控和非受控模式 | ||
*/ | ||
function useMergedState(defaultStateValue, option) { | ||
const { | ||
defaultValue, | ||
value, | ||
onChange, | ||
postState | ||
} = option || {}; | ||
// ======================= Init ======================= | ||
const [mergedValue, setMergedValue] = useState(() => { | ||
let finalValue; | ||
let source; | ||
if (hasValue(value)) { | ||
finalValue = value; | ||
source = Source.PROP; | ||
} else if (hasValue(defaultValue)) { | ||
finalValue = typeof defaultValue === 'function' ? defaultValue() : defaultValue; | ||
source = Source.PROP; | ||
} else { | ||
// value 是 undefined,表示未传入 props,可以直接使用内部值 | ||
finalValue = typeof defaultStateValue === 'function' ? defaultStateValue() : defaultStateValue; | ||
source = Source.INNER; | ||
} | ||
return [finalValue, source, finalValue]; | ||
}); | ||
const chosenValue = hasValue(value) ? value : mergedValue[0]; | ||
const postMergedValue = postState ? postState(chosenValue) : chosenValue; | ||
// ======================= Sync ======================= | ||
useLayoutUpdateEffect(() => { | ||
setMergedValue(([prevValue]) => [value, Source.PROP, prevValue]); | ||
}, [value]); | ||
// ====================== Update ====================== | ||
const changeEventPrevRef = useRef(); | ||
const triggerChange = useEvent(updater => { | ||
setMergedValue(prev => { | ||
const [prevValue, prevSource, prevPrevValue] = prev; | ||
const nextValue = typeof updater === 'function' ? updater(prevValue) : updater; | ||
// Do nothing if value not change | ||
if (nextValue === prevValue) { | ||
return prev; | ||
} | ||
const overridePrevValue = prevSource === Source.INNER && changeEventPrevRef.current !== prevPrevValue ? prevPrevValue : prevValue; | ||
return [nextValue, Source.INNER, overridePrevValue]; | ||
}); | ||
}); | ||
// ====================== Change ====================== | ||
const onChangeFn = useEvent(onChange); | ||
useLayoutEffect(() => { | ||
const [current, source, prev] = mergedValue; | ||
if (current !== prev && source === Source.INNER) { | ||
onChangeFn(current, prev); | ||
changeEventPrevRef.current = prev; | ||
} | ||
}, [mergedValue, onChangeFn]); | ||
return [postMergedValue, triggerChange]; | ||
} | ||
function useIntersectionObserver(elementRef, { | ||
@@ -409,2 +293,2 @@ threshold = 0, | ||
export { cloneElement, hasParent, isEqual, isFragment, isSubArrayFromStart, isValidChildren, replaceMessage, tip, toArray, useCombineRefs, useEvent, useIntersectionObserver, useLayoutEffect, useMemo, useMergedState, warn }; | ||
export { cloneElement, hasParent, isEqual, isFragment, isSubArrayFromStart, isValidChildren, replaceMessage, tip, toArray, useCombineRefs, useIntersectionObserver, useMemo, warn }; |
import useCombineRefs from './useCombineRefs'; | ||
import useEvent from './useEvent'; | ||
import useLayoutEffect from './useLayoutEffect'; | ||
import useMemo from './useMemo'; | ||
import useMergedState from './useMergedState'; | ||
export { useEvent, useLayoutEffect, useMergedState, useMemo, useCombineRefs }; | ||
export { useMemo, useCombineRefs }; |
@@ -6,4 +6,4 @@ export { isSubArrayFromStart } from './array'; | ||
export { replaceMessage } from './common'; | ||
export { useEvent, useLayoutEffect, useMergedState, useMemo, useCombineRefs } from './hooks'; | ||
export { useMemo, useCombineRefs } from './hooks'; | ||
export { useIntersectionObserver } from './observer'; | ||
export { warn, tip } from './warn'; |
{ | ||
"name": "@ones-design/utils", | ||
"version": "1.10.1-rc.1", | ||
"version": "1.10.1-rc.2", | ||
"description": "ONES Design", | ||
@@ -57,3 +57,3 @@ "type": "module", | ||
}, | ||
"gitHead": "61b8e314345711030bd3078ad2e34ad2b96b690d" | ||
"gitHead": "c6dd275fd0c6c0fd7ee83d63b45e73bfbc387f88" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
4
57761
15
652