Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@committed/hooks

Package Overview
Dependencies
Maintainers
4
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@committed/hooks - npm Package Compare versions

Comparing version 0.6.1 to 0.6.2

dist/hooks.js

828

dist/hooks.esm.js

@@ -1,828 +0,2 @@

import React, { useState, useRef, useEffect, useLayoutEffect, useMemo, useCallback } from 'react';
/**
* Utility hook for boolean state
*
* returns the value, an object containing function for toggle, setTrue and setFalse.
*
* Use with caution, attaching to buttons can cause unintended consequences from double clicks.
* @params startState (optional) starting value
*/
function useBoolean(startState) {
if (startState === void 0) {
startState = false;
}
var _useState = useState(startState),
value = _useState[0],
setValue = _useState[1];
var functions = React.useMemo(function () {
return {
toggle: function toggle() {
return setValue(function (state) {
return !state;
});
},
setTrue: function setTrue() {
return setValue(true);
},
setFalse: function setFalse() {
return setValue(false);
}
};
}, [setValue]);
return [value, functions];
}
/** type guard to check if value or function */
function isValue(arg) {
return typeof arg !== 'function';
}
/** no operation */
// eslint-disable-next-line @typescript-eslint/no-empty-function
function noop() {}
/**
* useControllableState hook for when the state may be controlled or uncontrolled.
*
* Returns as the standard useState hook, but has additional props of a controlled value and a controlled change handler.
* Set these using the components incoming props for the state, if defined they will be used, if not you get the standard useState behaviour.
*
* @param {T | undefined} value The controlled value (of type T) or undefined for an uncontrolled value
* @param {React.Dispatch<React.SetStateAction<T>> | undefined} setValue The dispatch handler for state changes or undefined for when an uncontrolled value, ignored if uncontrolled
* @param {T | (() => T | undefined) | undefined} initialState The initial state value, or state initializer for when uncontrolled, ignored if controlled
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function useControllableState(value, setValue, initialState) {
var _useRef = useRef(value !== undefined),
wasControlled = _useRef.current;
var isControlled = value !== undefined;
var _useState = useState(function () {
if (value === undefined) {
if (initialState !== undefined) {
return isValue(initialState) ? initialState : initialState();
}
}
return undefined;
}),
uncontrolled = _useState[0],
setUncontrolled = _useState[1];
var effect = noop;
if (process.env.NODE_ENV !== 'production') {
effect = function effect() {
if (wasControlled !== isControlled) {
console.warn('Components should not switch from uncontrolled to controlled (or vice versa)');
}
};
}
useEffect(effect, [effect, isControlled]);
return [wasControlled ? value : uncontrolled, wasControlled ? setValue : setUncontrolled];
}
/**
* 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 {T} value The value to debounce updates for
* @param { number | null} 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];
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function changed(previous, current) {
var allKeys = Object.keys(_extends({}, previous, current));
var changed = {};
allKeys.forEach(function (key) {
if (previous["" + key] !== current["" + key]) {
changed["" + key] = {
from: previous["" + key],
to: current["" + key]
};
}
});
return changed;
}
/**
* useDebug hook will log props and state changes to help identify the cause and frequency of component updates, when not in `production`.
*
* @param name the name for this component instance
* @param props the props for the component
* @param state the state for the component
*/
function useDebug(name, props, state) {
if (props === void 0) {
props = {};
}
if (state === void 0) {
state = {};
}
var prevProps = useRef(props);
var prevState = useRef(state);
useEffect(function () {
if (process.env.NODE_ENV === 'production') {
return;
}
var changedProps = changed(prevProps.current, props);
var changedState = changed(prevState.current, state);
if (Object.keys(_extends({}, changedProps, changedState)).length) {
console.log(name + " updated:", 'props', changedProps, 'state', changedState);
}
prevProps.current = props;
prevState.current = state;
});
}
/**
* 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 to
* @param development (optional) mark true to apply only when not in `production`
*/
function useEventListener(eventName, handler, element, development) {
var savedHandler = useRef();
useEffect(function () {
savedHandler.current = handler;
}, [handler]);
useEffect(function () {
var _element$current;
if (development === true && process.env.NODE_ENV === 'production') {
return;
}
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]);
}
var ImageTypes = {
gif: 'image/gif',
ico: 'image/x-icon',
jpeg: 'image/jpeg',
jpg: 'image/jpeg',
png: 'image/png',
svg: 'image/svg+xml'
};
function getFavIcon(document) {
var link = document.querySelector("link[rel*='icon']");
if (link !== null) {
return {
type: link.getAttribute('type'),
href: link.getAttribute('href')
};
} else {
return null;
}
}
function setFavIcon(document, data) {
if (data === null || data.href === null || data.type === null) {
var _document$querySelect;
(_document$querySelect = document.querySelector("link[rel*='icon']")) == null ? void 0 : _document$querySelect.remove();
} else {
var _document$querySelect2;
var link = (_document$querySelect2 = document.querySelector("link[rel*='icon']")) != null ? _document$querySelect2 : document.createElement('link');
link.type = data.type;
link.href = data.href;
link.rel = 'shortcut icon';
document.getElementsByTagName('head')[0].appendChild(link);
}
}
function isImageType(input) {
return input !== undefined && Object.keys(ImageTypes).includes(input);
}
var DEFAULT_OPTIONS = {
retain: false
};
/**
* useFavicon changes (or creates) the favicon for the given href.
*
* @param href The url of the favicon
*/
function useFavicon(href, options) {
if (options === void 0) {
options = {};
}
var originalRef = useRef(getFavIcon(document));
var _options = options,
_options$retain = _options.retain,
retain = _options$retain === void 0 ? DEFAULT_OPTIONS.retain : _options$retain;
useLayoutEffect(function () {
originalRef.current = getFavIcon(document);
if (!retain) {
return function () {
setFavIcon(document, originalRef.current);
};
} else {
return;
}
}, [retain]);
useLayoutEffect(function () {
var imageType = href.toLowerCase().split('.').pop();
if (isImageType(imageType)) {
// eslint-disable-next-line security/detect-object-injection
var type = ImageTypes[imageType];
setFavIcon(document, {
type: type,
href: href
});
} else {
if (process.env.NODE_ENV !== 'production') {
console.warn("Unrecognised image type href: " + href);
}
}
}, [href]);
}
/**
* 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]);
}
var KEYBOARD_MODIFIERS = ['Alt', 'Control', 'Meta', 'OS', 'Shift'];
var MODIFIER_ALIASES = {
alt: 'Alt',
ctrl: 'Control',
control: 'Control',
shift: 'Shift',
meta: 'Meta',
option: 'Alt'
};
var KEY_ALIASES = {
plus: '+',
up: 'ArrowUp',
down: 'ArrowDown',
left: 'ArrowLeft',
right: 'ArrowRight',
space: ' ',
esc: 'Escape'
};
function isKeyFilter(input) {
return typeof input === 'function';
}
function isKeyArray(input) {
return Array.isArray(input);
}
var DEFAULT_KEYBOARD_FILTER_OPTIONS = {
ignoreKey: false,
ignoreRepeat: false
};
function eventLength(e) {
var length = 0;
KEYBOARD_MODIFIERS.forEach(function (modifier) {
if (e.getModifierState(modifier)) {
length++;
}
});
if (!KEYBOARD_MODIFIERS.includes(e.key)) {
length++;
}
return length;
}
function createKeysFilter(keys, options) {
// Convenience code for any key
if (keys === '') {
return function () {
return true;
};
}
return function (e) {
if (options.ignoreRepeat && e.repeat) {
return false;
}
var splitKeys = keys.split('+').filter(function (key) {
return key.length > 0;
});
if (splitKeys.length !== eventLength(e)) {
return false;
}
return splitKeys.every(function (key) {
var _MODIFIER_ALIASES$key;
var modifier = (_MODIFIER_ALIASES$key = MODIFIER_ALIASES[key.toLowerCase()]) != null ? _MODIFIER_ALIASES$key : key;
if (e.getModifierState(modifier)) {
return true;
}
if (e.key === key || e.key === KEY_ALIASES[key.toLowerCase()]) {
return true;
}
if (e.key.length > 1 && e.key.toLowerCase() === key.toLowerCase()) {
return true;
}
if (e.code === key || !options.ignoreKey && e.code === 'Key' + key.toUpperCase()) {
return true;
}
return false;
});
};
}
/**
* useKeyboard hook to add a callback to be called on the use of the keyboard under specified circumstances.
*
*
* @param keys {Keys} The definition of the key filter.
* The basic definition is a string filter separated with the `+` e.g. `'a'` or `'ctrl+a'`
* An array can be provided with alternatives, so matching any filter in the array will call the handler.
* Finally, you can provide your own function `(event: KeyboardEvent) => boolean`
* @param handler {((event: KeyboardEvent) => void) | null} the callback function to call on a key event firing and passing the filter
* @param options options options object
* @param options.element {RefObejct} provide a ref for the element to bind to (defaults to `window`)
* @param options.event {keyup | keydown} a ref for the element to bind to (defaults to `keydown`)
* @param options.ignoreKey {boolean} set `true` to turn off the `KeyCode` test no other match (defaults to `false`)
* @param options.ignoreRepeat {boolean} set `true` to ignore repeat events (defaults to `false`)
* @param options.development {boolean} set `true` to remove in production, using `process.env.NODE_ENV` (defaults to `false`)
*/
function useKeyboard(keys, handler, options) {
if (options === void 0) {
options = {};
}
var savedHandler = useRef();
useEffect(function () {
savedHandler.current = handler;
}, [handler]);
var _options = options,
element = _options.element,
_options$event = _options.event,
event = _options$event === void 0 ? 'keydown' : _options$event,
development = _options.development;
var _options2 = options,
_options2$ignoreKey = _options2.ignoreKey,
ignoreKey = _options2$ignoreKey === void 0 ? DEFAULT_KEYBOARD_FILTER_OPTIONS.ignoreKey : _options2$ignoreKey,
_options2$ignoreRepea = _options2.ignoreRepeat,
ignoreRepeat = _options2$ignoreRepea === void 0 ? DEFAULT_KEYBOARD_FILTER_OPTIONS.ignoreRepeat : _options2$ignoreRepea;
var keyFilter = useMemo(function () {
var filterOptions = {
ignoreKey: ignoreKey,
ignoreRepeat: ignoreRepeat
};
if (isKeyFilter(keys)) {
return keys;
}
if (isKeyArray(keys)) {
return function (e) {
return keys.map(function (key) {
return createKeysFilter(key, filterOptions);
}).some(function (filter) {
return filter(e);
});
};
} else {
return createKeysFilter(keys, filterOptions);
}
}, [keys, ignoreKey, ignoreRepeat]);
var keyHandler = useCallback(function (e) {
if (savedHandler.current == null) {
return;
}
if (keyFilter(e)) {
savedHandler.current(e);
}
}, [keyFilter]);
useEventListener(event, keyHandler, element, development);
}
/**
* 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]);
}
var DEFAULT_OPTIONS$1 = {
append: false,
retain: false,
separator: ''
};
/**
* useTitle hook allows you to control the document title from your component.
*
* @param title The string to set the title to or to be appended.
* @param options The options to configure the useTitle
* @param options.append Set true to append the given string to the current title
* @param options.retain Set true to keep the title even after the component has unmounted
* @param options.separator The separator to use when appending
*/
function useTitle(title, options) {
if (options === void 0) {
options = {};
}
var _options = options,
_options$append = _options.append,
append = _options$append === void 0 ? DEFAULT_OPTIONS$1.append : _options$append,
_options$retain = _options.retain,
retain = _options$retain === void 0 ? DEFAULT_OPTIONS$1.retain : _options$retain,
_options$separator = _options.separator,
separator = _options$separator === void 0 ? DEFAULT_OPTIONS$1.separator : _options$separator;
var titleRef = useRef(document.title);
useLayoutEffect(function () {
titleRef.current = document.title;
if (!retain) {
return function () {
document.title = titleRef.current;
};
} else {
return;
}
}, [retain]);
useLayoutEffect(function () {
if (append) {
document.title = titleRef.current + separator + title;
} else {
document.title = title;
}
}, [title, separator, append]);
}
function isInitializer(candidate) {
return typeof candidate === 'function';
}
function isModifier(candidate) {
return typeof candidate === 'function';
}
/**
* useTrackedState hook provides the standard `[value, setValue]` array with an additional object providing
* `undo` and `redo` functions with convenience `boolean`s for `canUndo` and `canRedo`.
*
* @param initialState (optional) starting state or function to provide starting state
*/
function useTrackedState(initialState) {
var _useState = useState({
current: isInitializer(initialState) ? initialState() : initialState,
undoStack: [],
redoStack: []
}),
tracked = _useState[0],
setTracked = _useState[1];
var undo = useCallback(function () {
setTracked(function (currentTracked) {
if (currentTracked.undoStack.length === 0) {
return currentTracked;
}
var current = currentTracked.current,
undoStack = currentTracked.undoStack,
redoStack = currentTracked.redoStack;
return {
current: undoStack[undoStack.length - 1],
undoStack: undoStack.slice(0, undoStack.length - 1),
redoStack: [].concat(redoStack, [current])
};
});
}, []);
var redo = useCallback(function () {
setTracked(function (currentTracked) {
if (currentTracked.redoStack.length === 0) {
return currentTracked;
}
var current = currentTracked.current,
undoStack = currentTracked.undoStack,
redoStack = currentTracked.redoStack;
return {
current: redoStack[redoStack.length - 1],
undoStack: [].concat(undoStack, [current]),
redoStack: redoStack.slice(0, redoStack.length - 1)
};
});
}, []);
var setValue = useCallback(function (setState) {
setTracked(function (_ref) {
var current = _ref.current,
undoStack = _ref.undoStack;
return {
current: isModifier(setState) ? setState(current) : setState,
undoStack: [].concat(undoStack, [current]),
redoStack: []
};
}); // Incorrectly suggests adding T
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return [tracked.current, setValue, {
undo: undo,
redo: redo,
canUndo: tracked.undoStack.length > 0,
canRedo: tracked.redoStack.length > 0
}];
}
export { KEYBOARD_MODIFIERS, useBoolean, useControllableState, useDebounce, useDebug, useEventListener, useFavicon, useHover, useInterval, useKeyboard, useLocalState, usePoll, useTimeout, useTitle, useTrackedState };
import n,{useState as t,useRef as e,useEffect as r,useLayoutEffect as o,useMemo as u,useCallback as c}from"react";function i(e){void 0===e&&(e=!1);var r=t(e),o=r[1];return[r[0],n.useMemo(function(){return{toggle:function(){return o(function(n){return!n})},setTrue:function(){return o(!0)},setFalse:function(){return o(!1)}}},[o])]}function a(){}function l(n,o,u){var c=e(void 0!==n).current,i=void 0!==n,l=t(function(){if(void 0===n&&void 0!==u)return"function"!=typeof u?u:u()}),f=l[0],v=l[1],d=a;return"production"!==process.env.NODE_ENV&&(d=function(){c!==i&&console.warn("Components should not switch from uncontrolled to controlled (or vice versa)")}),r(d,[d,i]),[c?n:f,c?o:v]}function f(n,e){var o=t(n),u=o[0],c=o[1];return r(function(){if(null!==e){var t=setTimeout(function(){c(n)},e);return function(){clearTimeout(t)}}c(n)},[n,e]),[u,function(){return c(n)}]}function v(){return v=Object.assign||function(n){for(var t=1;t<arguments.length;t++){var e=arguments[t];for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r])}return n},v.apply(this,arguments)}function d(n,t){var e=Object.keys(v({},n,t)),r={};return e.forEach(function(e){n[""+e]!==t[""+e]&&(r[""+e]={from:n[""+e],to:t[""+e]})}),r}function s(n,t,o){void 0===t&&(t={}),void 0===o&&(o={});var u=e(t),c=e(o);r(function(){if("production"!==process.env.NODE_ENV){var e=d(u.current,t),r=d(c.current,o);Object.keys(v({},e,r)).length&&console.log(n+" updated:","props",e,"state",r),u.current=t,c.current=o}})}function p(n,t,o,u){var c=e();r(function(){c.current=t},[t]),r(function(){var t;if(!0!==u||"production"!==process.env.NODE_ENV){var e=null!=(t=null==o?void 0:o.current)?t:window;return e.addEventListener(n,r),function(){e.removeEventListener(n,r)}}function r(n){var t=c.current;null!=t&&t(n)}},[n,o])}var g={gif:"image/gif",ico:"image/x-icon",jpeg:"image/jpeg",jpg:"image/jpeg",png:"image/png",svg:"image/svg+xml"};function m(n){var t=n.querySelector("link[rel*='icon']");return null!==t?{type:t.getAttribute("type"),href:t.getAttribute("href")}:null}function y(n,t){if(null===t||null===t.href||null===t.type){var e;null==(e=n.querySelector("link[rel*='icon']"))||e.remove()}else{var r,o=null!=(r=n.querySelector("link[rel*='icon']"))?r:n.createElement("link");o.type=t.type,o.href=t.href,o.rel="shortcut icon",n.getElementsByTagName("head")[0].appendChild(o)}}function h(n,t){void 0===t&&(t={});var r=e(m(document)),u=t.retain,c=void 0!==u&&u;o(function(){return r.current=m(document),c?void 0:function(){y(document,r.current)}},[c]),o(function(){var t,e=n.toLowerCase().split(".").pop();void 0!==(t=e)&&Object.keys(g).includes(t)?y(document,{type:g[e],href:n}):"production"!==process.env.NODE_ENV&&console.warn("Unrecognised image type href: "+n)},[n])}function S(n){var e=t(!1),r=e[0],o=e[1];return p("mouseover",function(){return o(!0)},n),p("mouseout",function(){return o(!1)},n),[r]}function k(n,t){var o=e();r(function(){o.current=n},[n]),r(function(){if(null!==t){var n=setInterval(function(){var n=o.current;null!=n&&n()},t);return function(){return clearInterval(n)}}},[t])}var w=["Alt","Control","Meta","OS","Shift"],E={alt:"Alt",ctrl:"Control",control:"Control",shift:"Shift",meta:"Meta",option:"Alt"},O={plus:"+",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",space:" ",esc:"Escape"};function C(n,t){return""===n?function(){return!0}:function(e){if(t.ignoreRepeat&&e.repeat)return!1;var r=n.split("+").filter(function(n){return n.length>0});return r.length===function(n){var t=0;return w.forEach(function(e){n.getModifierState(e)&&t++}),w.includes(n.key)||t++,t}(e)&&r.every(function(n){var r,o=null!=(r=E[n.toLowerCase()])?r:n;return!!e.getModifierState(o)||e.key===n||e.key===O[n.toLowerCase()]||e.key.length>1&&e.key.toLowerCase()===n.toLowerCase()||e.code===n||!t.ignoreKey&&e.code==="Key"+n.toUpperCase()})}}function A(n,t,o){void 0===o&&(o={});var i=e();r(function(){i.current=t},[t]);var a=o.element,l=o.event,f=void 0===l?"keydown":l,v=o.development,d=o.ignoreKey,s=void 0!==d&&d,g=o.ignoreRepeat,m=void 0!==g&&g,y=u(function(){var t={ignoreKey:s,ignoreRepeat:m};return"function"==typeof n?n:Array.isArray(n)?function(e){return n.map(function(n){return C(n,t)}).some(function(n){return n(e)})}:C(n,t)},[n,s,m]);p(f,c(function(n){null!=i.current&&y(n)&&i.current(n)},[y]),a,v)}function N(t,e,r){var o=void 0===r?{serialize:JSON.stringify,deserialize:JSON.parse}:r,u=o.serialize,c=o.deserialize,i=n.useState(function(){var n=window.localStorage.getItem(t);if(null!=n)try{return c(n)}catch(n){window.localStorage.removeItem(t)}return function(n){return"function"==typeof n}(e)?e():e}),a=i[0],l=i[1],f=n.useRef(t);n.useEffect(function(){var n=f.current;n!==t&&window.localStorage.removeItem(n),f.current=t,null==a?window.localStorage.removeItem(t):window.localStorage.setItem(t,u(a))},[t,a,u]);var v=n.useCallback(function(){window.localStorage.removeItem(t)},[t]);return[a,l,v]}function j(n){void 0===n&&(n=!1);var t=i(n),e=t[1];return[t[0],e.setTrue,e.setFalse]}function T(n,t){var o=e();r(function(){o.current=n},[n]),r(function(){var n=null;function e(){null!==t&&(n=setTimeout(r,t))}function r(){var n=function(){var n=o.current,t=void 0;return null!=n&&(t=n()),t}();n instanceof Promise?n.then(e):e()}return r(),function(){n&&clearTimeout(n),n=null}},[t])}function b(n,t){var o=e();r(function(){o.current=n},[n]),r(function(){if(null!==t){var n=setTimeout(function(){var n=o.current;null!=n&&n()},t);return function(){return clearTimeout(n)}}},[t])}function I(n,t){void 0===t&&(t={});var r=t.append,u=void 0!==r&&r,c=t.retain,i=void 0!==c&&c,a=t.separator,l=void 0===a?"":a,f=e(document.title);o(function(){return f.current=document.title,i?void 0:function(){document.title=f.current}},[i]),o(function(){document.title=u?f.current+l+n:n},[n,l,u])}function L(n){return"function"==typeof n}function R(n){var e,r=t({current:(e=n,"function"==typeof e?n():n),undoStack:[],redoStack:[]}),o=r[0],u=r[1],i=c(function(){u(function(n){if(0===n.undoStack.length)return n;var t=n.current,e=n.undoStack,r=n.redoStack;return{current:e[e.length-1],undoStack:e.slice(0,e.length-1),redoStack:[].concat(r,[t])}})},[]),a=c(function(){u(function(n){if(0===n.redoStack.length)return n;var t=n.redoStack;return{current:t[t.length-1],undoStack:[].concat(n.undoStack,[n.current]),redoStack:t.slice(0,t.length-1)}})},[]),l=c(function(n){u(function(t){var e=t.current,r=t.undoStack;return{current:L(n)?n(e):n,undoStack:[].concat(r,[e]),redoStack:[]}})},[]);return[o.current,l,{undo:i,redo:a,canUndo:o.undoStack.length>0,canRedo:o.redoStack.length>0}]}export{w as KEYBOARD_MODIFIERS,i as useBoolean,l as useControllableState,f as useDebounce,s as useDebug,p as useEventListener,h as useFavicon,S as useHover,k as useInterval,A as useKeyboard,N as useLocalState,j as useModal,T as usePoll,b as useTimeout,I as useTitle,R as useTrackedState};
//# sourceMappingURL=hooks.esm.js.map

@@ -11,2 +11,3 @@ export * from './useBoolean';

export * from './useLocalState';
export * from './useModal';
export * from './usePoll';

@@ -13,0 +14,0 @@ export * from './useTimeout';

@@ -9,6 +9,9 @@ /**

*/
export declare function useBoolean(startState?: boolean): [boolean, {
toggle: () => void;
setTrue: () => void;
setFalse: () => void;
}];
export declare function useBoolean(startState?: boolean): [
boolean,
{
toggle: () => void;
setTrue: () => void;
setFalse: () => void;
}
];

@@ -6,8 +6,12 @@ /// <reference types="react" />

*/
export declare function useTrackedState<T = undefined>(): [T | undefined, React.Dispatch<React.SetStateAction<T | undefined>>, {
undo: () => void;
redo: () => void;
canUndo: boolean;
canRedo: boolean;
}];
export declare function useTrackedState<T = undefined>(): [
T | undefined,
React.Dispatch<React.SetStateAction<T | undefined>>,
{
undo: () => void;
redo: () => void;
canUndo: boolean;
canRedo: boolean;
}
];
/**

@@ -19,7 +23,11 @@ * useTrackedState hook provides the standard `[value, setValue]` array with an additional object providing

*/
export declare function useTrackedState<T>(initialState: T | (() => T)): [T, React.Dispatch<React.SetStateAction<T>>, {
undo: () => void;
redo: () => void;
canUndo: boolean;
canRedo: boolean;
}];
export declare function useTrackedState<T>(initialState: T | (() => T)): [
T,
React.Dispatch<React.SetStateAction<T>>,
{
undo: () => void;
redo: () => void;
canUndo: boolean;
canRedo: boolean;
}
];
{
"version": "0.6.1",
"version": "0.6.2",
"name": "@committed/hooks",

@@ -9,3 +9,6 @@ "description": "Committed hooks library",

"repository": "git://github.com/commitd/hooks.git",
"main": "dist/index.js",
"source": "src/index.ts",
"main": "dist/hooks.js",
"umd:main": "dist/hooks.umd.js",
"module": "dist/hooks.esm.js",
"typings": "dist/index.d.ts",

@@ -24,4 +27,4 @@ "publishConfig": {

"commit": "cz",
"start": "tsdx watch",
"build": "tsdx build",
"start": "microbundle watch",
"build": "yarn clean ; microbundle",
"test": "tsdx test",

@@ -37,3 +40,3 @@ "lint": "tsdx lint",

"generate": "plop --plopfile ./generators/plopfile.js",
"prepare": "husky install && tsdx build",
"postinstall": "husky install",
"semantic-release": "semantic-release"

@@ -54,6 +57,5 @@ },

},
"module": "dist/hooks.esm.js",
"size-limit": [
{
"path": "dist/hooks.cjs.production.min.js",
"path": "dist/hooks.js",
"limit": "10 KB"

@@ -126,2 +128,3 @@ },

"jest-sonar-reporter": "^2.0.0",
"microbundle": "^0.15.0",
"plop": "^2.7.4",

@@ -140,6 +143,6 @@ "prettier": "^2.1.2",

"tsdx": "^0.14.1",
"tslib": "^2.3.1",
"typescript": "^4.6.3"
"tslib": "^2.4.0",
"typescript": "^4.6.4"
},
"dependencies": {}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc