@committed/hooks
Advanced tools
Comparing version 0.0.1 to 0.2.0
@@ -5,5 +5,291 @@ 'use strict'; | ||
var react = require('react'); | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var React = require('react'); | ||
var React__default = _interopDefault(React); | ||
/** | ||
* Debounce the update to a value. | ||
* | ||
* The returned value will only update when the useDebounce hook has not been called for the full delay specified. | ||
* | ||
* A set function is also returned so the value can be forced or flushed, say on dismount. | ||
* | ||
* Adapted from <https://usehooks.com/>. | ||
* | ||
* @param value The value to debounce updates for | ||
* @param delay The time to delay updates by (ms) | ||
*/ | ||
function useDebounce(value, delay) { | ||
var _useState = React.useState(value), | ||
debouncedValue = _useState[0], | ||
setDebouncedValue = _useState[1]; | ||
React.useEffect(function () { | ||
if (delay !== null) { | ||
var handler = setTimeout(function () { | ||
setDebouncedValue(value); | ||
}, delay); | ||
return function () { | ||
clearTimeout(handler); | ||
}; | ||
} else { | ||
setDebouncedValue(value); | ||
return; | ||
} | ||
}, [value, delay]); | ||
var flush = function flush() { | ||
return setDebouncedValue(value); | ||
}; | ||
return [debouncedValue, flush]; | ||
} | ||
/** | ||
* useEventListener hook adds an event listener to the given event type and calls the handler when fired. | ||
* The listener is added to the `window` by default or the target element if provided using a ref object. | ||
* It is removed automatically on unmounting. | ||
* | ||
* For event types reference see <https://developer.mozilla.org/en-US/docs/Web/Events>. | ||
* | ||
* (Derived from <https://usehooks-typescript.com/use-event-listener>) | ||
* | ||
* @param eventName the name of the event to listen to | ||
* @param handler the callback function to call on the event firing | ||
* @param element (optional) reference for the element to add the listener too | ||
*/ | ||
function useEventListener(eventName, handler, element) { | ||
var savedHandler = React.useRef(); | ||
React.useEffect(function () { | ||
savedHandler.current = handler; | ||
}, [handler]); | ||
React.useEffect(function () { | ||
var _element$current; | ||
function eventListener(event) { | ||
var current = savedHandler.current; | ||
if (current != null) current(event); | ||
} | ||
var targetElement = (_element$current = element == null ? void 0 : element.current) != null ? _element$current : window; | ||
targetElement.addEventListener(eventName, eventListener); | ||
return function () { | ||
targetElement.removeEventListener(eventName, eventListener); | ||
}; // False positive request for E and T | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [eventName, element]); | ||
} | ||
/** | ||
* useHover tracks the hovered state of the given element. | ||
* | ||
* @param element reference to track hover on | ||
*/ | ||
function useHover(element) { | ||
var _useState = React.useState(false), | ||
hovered = _useState[0], | ||
setHovered = _useState[1]; | ||
var handleMouseOver = function handleMouseOver() { | ||
return setHovered(true); | ||
}; | ||
var handleMouseOut = function handleMouseOut() { | ||
return setHovered(false); | ||
}; | ||
useEventListener('mouseover', handleMouseOver, element); | ||
useEventListener('mouseout', handleMouseOut, element); | ||
return [hovered]; | ||
} | ||
/** | ||
* Call the callback at the given rate. | ||
* | ||
* Based on https://overreacted.io/making-setinterval-declarative-with-react-hooks/ | ||
* | ||
* @param callback the callback | ||
* @param delay the time between calls (ms) | ||
*/ | ||
function useInterval(callback, delay) { | ||
var savedCallback = React.useRef(); // Remember the latest callback. | ||
React.useEffect(function () { | ||
savedCallback.current = callback; | ||
}, [callback]); // Set up the interval. | ||
React.useEffect(function () { | ||
function tick() { | ||
var current = savedCallback.current; | ||
if (current != null) current(); | ||
} | ||
if (delay !== null) { | ||
var id = setInterval(tick, delay); | ||
return function () { | ||
return clearInterval(id); | ||
}; | ||
} else { | ||
return; | ||
} | ||
}, [delay]); | ||
} | ||
/** | ||
* Default function type guard | ||
* @param defaultValue | ||
*/ | ||
function isFunction(defaultValue) { | ||
return typeof defaultValue === 'function'; | ||
} | ||
/** | ||
* useLocalState hook behaves like `React.useState`, returning the state and a function to set the value. | ||
* In addition, the value is put in local storage against the given key and is persisted through page refresh. | ||
*/ | ||
function useLocalState(key, defaultValue, _temp) { | ||
var _ref = _temp === void 0 ? { | ||
serialize: JSON.stringify, | ||
deserialize: JSON.parse | ||
} : _temp, | ||
serialize = _ref.serialize, | ||
deserialize = _ref.deserialize; | ||
var _React$useState = React__default.useState(function () { | ||
var valueInLocalStorage = window.localStorage.getItem(key); | ||
if (valueInLocalStorage != null) { | ||
try { | ||
return deserialize(valueInLocalStorage); | ||
} catch (error) { | ||
window.localStorage.removeItem(key); | ||
} | ||
} | ||
if (isFunction(defaultValue)) { | ||
return defaultValue(); | ||
} else { | ||
return defaultValue; | ||
} | ||
}), | ||
state = _React$useState[0], | ||
setState = _React$useState[1]; | ||
var prevKeyRef = React__default.useRef(key); | ||
React__default.useEffect(function () { | ||
var prevKey = prevKeyRef.current; | ||
if (prevKey !== key) { | ||
window.localStorage.removeItem(prevKey); | ||
} | ||
prevKeyRef.current = key; | ||
if (state === undefined || state === null) { | ||
window.localStorage.removeItem(key); | ||
} else { | ||
window.localStorage.setItem(key, serialize(state)); | ||
} | ||
}, [key, state, serialize]); | ||
var clear = React__default.useCallback(function () { | ||
window.localStorage.removeItem(key); | ||
}, [key]); | ||
return [state, setState, clear]; | ||
} | ||
/** | ||
* Call the callback with a fixed delay (between completions) | ||
* | ||
* The first call will be made immediately. | ||
* | ||
* Based on https://www.aaron-powell.com/posts/2019-09-23-recursive-settimeout-with-react-hooks/ | ||
* | ||
* | ||
* @param callback the callback | ||
* @param delay the time between calls (ms) | ||
*/ | ||
function usePoll(callback, delay) { | ||
var savedCallback = React.useRef(); // Remember the latest callback. | ||
React.useEffect(function () { | ||
savedCallback.current = callback; | ||
}, [callback]); | ||
React.useEffect(function () { | ||
var id = null; | ||
function call() { | ||
var current = savedCallback.current; | ||
var ret = undefined; | ||
if (current != null) { | ||
ret = current(); | ||
} | ||
return ret; | ||
} | ||
function reschedule() { | ||
if (delay !== null) { | ||
id = setTimeout(tick, delay); | ||
} | ||
} | ||
function tick() { | ||
var ret = call(); | ||
if (ret instanceof Promise) { | ||
void ret.then(reschedule); | ||
} else { | ||
reschedule(); | ||
} | ||
} | ||
tick(); | ||
return function () { | ||
id && clearTimeout(id); | ||
id = null; | ||
}; | ||
}, [delay]); | ||
} | ||
/** | ||
* Call the callback after a period of delay. | ||
* | ||
* Based on https://overreacted.io/making-setinterval-declarative-with-react-hooks/ | ||
* | ||
* @param callback the callback | ||
* @param delay the timeout before the call (in ms) | ||
*/ | ||
function useTimeout(callback, delay) { | ||
var savedCallback = React.useRef(); | ||
React.useEffect(function () { | ||
savedCallback.current = callback; | ||
}, [callback]); | ||
React.useEffect(function () { | ||
function tick() { | ||
var current = savedCallback.current; | ||
if (current != null) current(); | ||
} | ||
if (delay !== null) { | ||
var id = setTimeout(tick, delay); | ||
return function () { | ||
return clearTimeout(id); | ||
}; | ||
} else { | ||
return; | ||
} | ||
}, [delay]); | ||
} | ||
/** | ||
* Utility hook for boolean toggle operations | ||
@@ -20,3 +306,3 @@ * | ||
var _useState = react.useState(startState), | ||
var _useState = React.useState(startState), | ||
value = _useState[0], | ||
@@ -32,3 +318,10 @@ setValue = _useState[1]; | ||
exports.useDebounce = useDebounce; | ||
exports.useEventListener = useEventListener; | ||
exports.useHover = useHover; | ||
exports.useInterval = useInterval; | ||
exports.useLocalState = useLocalState; | ||
exports.usePoll = usePoll; | ||
exports.useTimeout = useTimeout; | ||
exports.useToggle = useToggle; | ||
//# sourceMappingURL=hooks.cjs.development.js.map |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");exports.useToggle=function(r){void 0===r&&(r=!1);var t=e.useState(r),u=t[0],o=t[1];return[u,function(){return o(!u)},o]}; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=require("react"),n=(e=t)&&"object"==typeof e&&"default"in e?e.default:e;function r(e,n,r){var u=t.useRef();t.useEffect((function(){u.current=n}),[n]),t.useEffect((function(){var t;function n(e){var t=u.current;null!=t&&t(e)}var o=null!=(t=null==r?void 0:r.current)?t:window;return o.addEventListener(e,n),function(){o.removeEventListener(e,n)}}),[e,r])}exports.useDebounce=function(e,n){var r=t.useState(e),u=r[0],o=r[1];return t.useEffect((function(){if(null!==n){var t=setTimeout((function(){o(e)}),n);return function(){clearTimeout(t)}}o(e)}),[e,n]),[u,function(){return o(e)}]},exports.useEventListener=r,exports.useHover=function(e){var n=t.useState(!1),u=n[0],o=n[1];return r("mouseover",(function(){return o(!0)}),e),r("mouseout",(function(){return o(!1)}),e),[u]},exports.useInterval=function(e,n){var r=t.useRef();t.useEffect((function(){r.current=e}),[e]),t.useEffect((function(){if(null!==n){var e=setInterval((function(){var e=r.current;null!=e&&e()}),n);return function(){return clearInterval(e)}}}),[n])},exports.useLocalState=function(e,t,r){var u=void 0===r?{serialize:JSON.stringify,deserialize:JSON.parse}:r,o=u.serialize,c=u.deserialize,i=n.useState((function(){var n=window.localStorage.getItem(e);if(null!=n)try{return c(n)}catch(t){window.localStorage.removeItem(e)}return function(e){return"function"==typeof e}(t)?t():t})),f=i[0],a=i[1],l=n.useRef(e);n.useEffect((function(){var t=l.current;t!==e&&window.localStorage.removeItem(t),l.current=e,null==f?window.localStorage.removeItem(e):window.localStorage.setItem(e,o(f))}),[e,f,o]);var s=n.useCallback((function(){window.localStorage.removeItem(e)}),[e]);return[f,a,s]},exports.usePoll=function(e,n){var r=t.useRef();t.useEffect((function(){r.current=e}),[e]),t.useEffect((function(){var e=null;function t(){null!==n&&(e=setTimeout(u,n))}function u(){var e=function(){var e=r.current,t=void 0;return null!=e&&(t=e()),t}();e instanceof Promise?e.then(t):t()}return u(),function(){e&&clearTimeout(e),e=null}}),[n])},exports.useTimeout=function(e,n){var r=t.useRef();t.useEffect((function(){r.current=e}),[e]),t.useEffect((function(){if(null!==n){var e=setTimeout((function(){var e=r.current;null!=e&&e()}),n);return function(){return clearTimeout(e)}}}),[n])},exports.useToggle=function(e){void 0===e&&(e=!1);var n=t.useState(e),r=n[0],u=n[1];return[r,function(){return u(!r)},u]}; | ||
//# sourceMappingURL=hooks.cjs.production.min.js.map |
@@ -1,4 +0,287 @@ | ||
import { useState } from 'react'; | ||
import React, { useState, useEffect, useRef } from 'react'; | ||
/** | ||
* Debounce the update to a value. | ||
* | ||
* The returned value will only update when the useDebounce hook has not been called for the full delay specified. | ||
* | ||
* A set function is also returned so the value can be forced or flushed, say on dismount. | ||
* | ||
* Adapted from <https://usehooks.com/>. | ||
* | ||
* @param value The value to debounce updates for | ||
* @param delay The time to delay updates by (ms) | ||
*/ | ||
function useDebounce(value, delay) { | ||
var _useState = useState(value), | ||
debouncedValue = _useState[0], | ||
setDebouncedValue = _useState[1]; | ||
useEffect(function () { | ||
if (delay !== null) { | ||
var handler = setTimeout(function () { | ||
setDebouncedValue(value); | ||
}, delay); | ||
return function () { | ||
clearTimeout(handler); | ||
}; | ||
} else { | ||
setDebouncedValue(value); | ||
return; | ||
} | ||
}, [value, delay]); | ||
var flush = function flush() { | ||
return setDebouncedValue(value); | ||
}; | ||
return [debouncedValue, flush]; | ||
} | ||
/** | ||
* useEventListener hook adds an event listener to the given event type and calls the handler when fired. | ||
* The listener is added to the `window` by default or the target element if provided using a ref object. | ||
* It is removed automatically on unmounting. | ||
* | ||
* For event types reference see <https://developer.mozilla.org/en-US/docs/Web/Events>. | ||
* | ||
* (Derived from <https://usehooks-typescript.com/use-event-listener>) | ||
* | ||
* @param eventName the name of the event to listen to | ||
* @param handler the callback function to call on the event firing | ||
* @param element (optional) reference for the element to add the listener too | ||
*/ | ||
function useEventListener(eventName, handler, element) { | ||
var savedHandler = useRef(); | ||
useEffect(function () { | ||
savedHandler.current = handler; | ||
}, [handler]); | ||
useEffect(function () { | ||
var _element$current; | ||
function eventListener(event) { | ||
var current = savedHandler.current; | ||
if (current != null) current(event); | ||
} | ||
var targetElement = (_element$current = element == null ? void 0 : element.current) != null ? _element$current : window; | ||
targetElement.addEventListener(eventName, eventListener); | ||
return function () { | ||
targetElement.removeEventListener(eventName, eventListener); | ||
}; // False positive request for E and T | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [eventName, element]); | ||
} | ||
/** | ||
* useHover tracks the hovered state of the given element. | ||
* | ||
* @param element reference to track hover on | ||
*/ | ||
function useHover(element) { | ||
var _useState = useState(false), | ||
hovered = _useState[0], | ||
setHovered = _useState[1]; | ||
var handleMouseOver = function handleMouseOver() { | ||
return setHovered(true); | ||
}; | ||
var handleMouseOut = function handleMouseOut() { | ||
return setHovered(false); | ||
}; | ||
useEventListener('mouseover', handleMouseOver, element); | ||
useEventListener('mouseout', handleMouseOut, element); | ||
return [hovered]; | ||
} | ||
/** | ||
* Call the callback at the given rate. | ||
* | ||
* Based on https://overreacted.io/making-setinterval-declarative-with-react-hooks/ | ||
* | ||
* @param callback the callback | ||
* @param delay the time between calls (ms) | ||
*/ | ||
function useInterval(callback, delay) { | ||
var savedCallback = useRef(); // Remember the latest callback. | ||
useEffect(function () { | ||
savedCallback.current = callback; | ||
}, [callback]); // Set up the interval. | ||
useEffect(function () { | ||
function tick() { | ||
var current = savedCallback.current; | ||
if (current != null) current(); | ||
} | ||
if (delay !== null) { | ||
var id = setInterval(tick, delay); | ||
return function () { | ||
return clearInterval(id); | ||
}; | ||
} else { | ||
return; | ||
} | ||
}, [delay]); | ||
} | ||
/** | ||
* Default function type guard | ||
* @param defaultValue | ||
*/ | ||
function isFunction(defaultValue) { | ||
return typeof defaultValue === 'function'; | ||
} | ||
/** | ||
* useLocalState hook behaves like `React.useState`, returning the state and a function to set the value. | ||
* In addition, the value is put in local storage against the given key and is persisted through page refresh. | ||
*/ | ||
function useLocalState(key, defaultValue, _temp) { | ||
var _ref = _temp === void 0 ? { | ||
serialize: JSON.stringify, | ||
deserialize: JSON.parse | ||
} : _temp, | ||
serialize = _ref.serialize, | ||
deserialize = _ref.deserialize; | ||
var _React$useState = React.useState(function () { | ||
var valueInLocalStorage = window.localStorage.getItem(key); | ||
if (valueInLocalStorage != null) { | ||
try { | ||
return deserialize(valueInLocalStorage); | ||
} catch (error) { | ||
window.localStorage.removeItem(key); | ||
} | ||
} | ||
if (isFunction(defaultValue)) { | ||
return defaultValue(); | ||
} else { | ||
return defaultValue; | ||
} | ||
}), | ||
state = _React$useState[0], | ||
setState = _React$useState[1]; | ||
var prevKeyRef = React.useRef(key); | ||
React.useEffect(function () { | ||
var prevKey = prevKeyRef.current; | ||
if (prevKey !== key) { | ||
window.localStorage.removeItem(prevKey); | ||
} | ||
prevKeyRef.current = key; | ||
if (state === undefined || state === null) { | ||
window.localStorage.removeItem(key); | ||
} else { | ||
window.localStorage.setItem(key, serialize(state)); | ||
} | ||
}, [key, state, serialize]); | ||
var clear = React.useCallback(function () { | ||
window.localStorage.removeItem(key); | ||
}, [key]); | ||
return [state, setState, clear]; | ||
} | ||
/** | ||
* Call the callback with a fixed delay (between completions) | ||
* | ||
* The first call will be made immediately. | ||
* | ||
* Based on https://www.aaron-powell.com/posts/2019-09-23-recursive-settimeout-with-react-hooks/ | ||
* | ||
* | ||
* @param callback the callback | ||
* @param delay the time between calls (ms) | ||
*/ | ||
function usePoll(callback, delay) { | ||
var savedCallback = useRef(); // Remember the latest callback. | ||
useEffect(function () { | ||
savedCallback.current = callback; | ||
}, [callback]); | ||
useEffect(function () { | ||
var id = null; | ||
function call() { | ||
var current = savedCallback.current; | ||
var ret = undefined; | ||
if (current != null) { | ||
ret = current(); | ||
} | ||
return ret; | ||
} | ||
function reschedule() { | ||
if (delay !== null) { | ||
id = setTimeout(tick, delay); | ||
} | ||
} | ||
function tick() { | ||
var ret = call(); | ||
if (ret instanceof Promise) { | ||
void ret.then(reschedule); | ||
} else { | ||
reschedule(); | ||
} | ||
} | ||
tick(); | ||
return function () { | ||
id && clearTimeout(id); | ||
id = null; | ||
}; | ||
}, [delay]); | ||
} | ||
/** | ||
* Call the callback after a period of delay. | ||
* | ||
* Based on https://overreacted.io/making-setinterval-declarative-with-react-hooks/ | ||
* | ||
* @param callback the callback | ||
* @param delay the timeout before the call (in ms) | ||
*/ | ||
function useTimeout(callback, delay) { | ||
var savedCallback = useRef(); | ||
useEffect(function () { | ||
savedCallback.current = callback; | ||
}, [callback]); | ||
useEffect(function () { | ||
function tick() { | ||
var current = savedCallback.current; | ||
if (current != null) current(); | ||
} | ||
if (delay !== null) { | ||
var id = setTimeout(tick, delay); | ||
return function () { | ||
return clearTimeout(id); | ||
}; | ||
} else { | ||
return; | ||
} | ||
}, [delay]); | ||
} | ||
/** | ||
* Utility hook for boolean toggle operations | ||
@@ -26,3 +309,3 @@ * | ||
export { useToggle }; | ||
export { useDebounce, useEventListener, useHover, useInterval, useLocalState, usePoll, useTimeout, useToggle }; | ||
//# sourceMappingURL=hooks.esm.js.map |
@@ -1,1 +0,8 @@ | ||
export * from './hooks'; | ||
export * from './useDebounce'; | ||
export * from './useEventListener'; | ||
export * from './useHover'; | ||
export * from './useInterval'; | ||
export * from './useLocalState'; | ||
export * from './usePoll'; | ||
export * from './useTimeout'; | ||
export * from './useToggle'; |
{ | ||
"version": "0.0.1", | ||
"version": "0.2.0", | ||
"name": "@committed/hooks", | ||
@@ -30,4 +30,4 @@ "description": "Committed hooks library", | ||
"storybook": "start-storybook -p 6006", | ||
"build-storybook": "build-storybook", | ||
"format": "prettier --write '**/{src,test,stories}/**/{*.js,*.ts,*.tsx,*.json,*.md,*.mdx}' example/index.tsx", | ||
"build-storybook": "build-storybook --no-dll", | ||
"format": "prettier --write '**/{src,test,stories}/**/{*.js,*.ts,*.tsx,*.json,*.md,*.mdx}'", | ||
"deploy-storybook": "storybook-to-ghpages", | ||
@@ -61,3 +61,3 @@ "generate": "plop --plopfile ./generators/plopfile.js" | ||
"jest": { | ||
"testEnvironment": "node", | ||
"testEnvironment": "jsdom", | ||
"collectCoverage": true, | ||
@@ -79,4 +79,4 @@ "testResultsProcessor": "jest-sonar-reporter", | ||
"@size-limit/preset-small-lib": "^4.6.2", | ||
"@storybook/addon-essentials": "^6.0.27", | ||
"@storybook/react": "^6.0.27", | ||
"@storybook/addon-essentials": "^6.0.28", | ||
"@storybook/react": "^6.0.28", | ||
"@storybook/storybook-deployer": "^2.8.7", | ||
@@ -107,2 +107,3 @@ "@testing-library/jest-dom": "^5.11.5", | ||
"size-limit": "^4.6.2", | ||
"swr": "^0.3.8", | ||
"tsdx": "^0.14.1", | ||
@@ -109,0 +110,0 @@ "tslib": "^2.0.3", |
@@ -29,2 +29,4 @@ <h1 align="center">Committed Hooks</h1> | ||
import { useHook } from '@committed/hooks' | ||
// Or | ||
// import { useHook } from '@committed/hooks/useHook' | ||
@@ -104,17 +106,8 @@ const Example = (props) => { | ||
- `main` which installs deps w/ cache, lints, tests, and builds on all pushes against a Node and OS matrix | ||
- `build` which installs deps w/ cache, lints, tests, and builds. | ||
- `release` triggered on release with (commented) options to publish and deploy storybook | ||
- `size` which comments cost comparison of your library on every pull request using [size-limit](https://github.com/ai/size-limit) | ||
### Drone | ||
Example drone configuration with steps for | ||
- **npm authentication** for later publication with npm | ||
- **build** the main library | ||
- **publish** to npm | ||
- **code-analysis** with sonar | ||
- **announce** with slack | ||
## License | ||
[MIT](/LICENSE) - © Committed Software 2020 https://committed.io |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
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
73189
28
670
37
3
112
1