Commit 6cc198bf authored by Sangjune Bae's avatar Sangjune Bae
Browse files

first commit

parent 81c6da4b
import { useState } from 'react';
/**
* A convenience hook around `useState` designed to be paired with
* the component [callback ref](https://reactjs.org/docs/refs-and-the-dom.html#callback-refs) api.
* Callback refs are useful over `useRef()` when you need to respond to the ref being set
* instead of lazily accessing it in an effect.
*
* ```ts
* const [element, attachRef] = useCallbackRef<HTMLDivElement>()
*
* useEffect(() => {
* if (!element) return
*
* const calendar = new FullCalendar.Calendar(element)
*
* return () => {
* calendar.destroy()
* }
* }, [element])
*
* return <div ref={attachRef} />
* ```
*
* @category refs
*/
export default function useCallbackRef() {
return useState(null);
}
\ No newline at end of file
/// <reference types="react" />
/**
* Creates a `Ref` whose value is updated in an effect, ensuring the most recent
* value is the one rendered with. Generally only required for Concurrent mode usage
* where previous work in `render()` may be discarded befor being used.
*
* This is safe to access in an event handler.
*
* @param value The `Ref` value
*/
declare function useCommittedRef<TValue>(value: TValue): React.MutableRefObject<TValue>;
export default useCommittedRef;
import { useEffect, useRef } from 'react';
/**
* Creates a `Ref` whose value is updated in an effect, ensuring the most recent
* value is the one rendered with. Generally only required for Concurrent mode usage
* where previous work in `render()` may be discarded befor being used.
*
* This is safe to access in an event handler.
*
* @param value The `Ref` value
*/
function useCommittedRef(value) {
var ref = useRef(value);
useEffect(function () {
ref.current = value;
}, [value]);
return ref;
}
export default useCommittedRef;
\ No newline at end of file
import { DependencyList, EffectCallback } from 'react';
export declare type EffectHook = (effect: EffectCallback, deps?: DependencyList) => void;
export declare type IsEqual<TDeps extends DependencyList> = (nextDeps: TDeps, prevDeps: TDeps) => boolean;
export declare type CustomEffectOptions<TDeps extends DependencyList> = {
isEqual: IsEqual<TDeps>;
effectHook?: EffectHook;
};
/**
* a useEffect() hook with customized depedency comparision
*
* @param effect The effect callback
* @param dependencies A list of dependencies
* @param isEqual A function comparing the next and previous dependencyLists
*/
declare function useCustomEffect<TDeps extends DependencyList = DependencyList>(effect: EffectCallback, dependencies: TDeps, isEqual: IsEqual<TDeps>): void;
/**
* a useEffect() hook with customized depedency comparision
*
* @param effect The effect callback
* @param dependencies A list of dependencies
* @param options
* @param options.isEqual A function comparing the next and previous dependencyLists
* @param options.effectHook the underlying effect hook used, defaults to useEffect
*/
declare function useCustomEffect<TDeps extends DependencyList = DependencyList>(effect: EffectCallback, dependencies: TDeps, options: CustomEffectOptions<TDeps>): void;
export default useCustomEffect;
import { useRef, useEffect, useDebugValue } from 'react';
import useMounted from './useMounted';
function useCustomEffect(effect, dependencies, isEqualOrOptions) {
var isMounted = useMounted();
var _ref = typeof isEqualOrOptions === 'function' ? {
isEqual: isEqualOrOptions
} : isEqualOrOptions,
isEqual = _ref.isEqual,
_ref$effectHook = _ref.effectHook,
effectHook = _ref$effectHook === void 0 ? useEffect : _ref$effectHook;
var dependenciesRef = useRef();
dependenciesRef.current = dependencies;
var cleanupRef = useRef(null);
effectHook(function () {
// If the ref the is `null` it's either the first effect or the last effect
// ran and was cleared, meaning _this_ update should run, b/c the equality
// check failed on in the cleanup of the last effect.
if (cleanupRef.current === null) {
var cleanup = effect();
cleanupRef.current = function () {
if (isMounted() && isEqual(dependenciesRef.current, dependencies)) {
return;
}
cleanupRef.current = null;
if (cleanup) cleanup();
};
}
return cleanupRef.current;
});
useDebugValue(effect);
}
export default useCustomEffect;
\ No newline at end of file
export default function useEventCallback<TCallback extends (...args: any[]) => any>(fn?: TCallback | null): TCallback;
import { useCallback } from 'react';
import useCommittedRef from './useCommittedRef';
export default function useEventCallback(fn) {
var ref = useCommittedRef(fn);
return useCallback(function () {
return ref.current && ref.current.apply(ref, arguments);
}, [ref]);
}
\ No newline at end of file
declare type EventHandler<T, K extends keyof DocumentEventMap> = (this: T, ev: DocumentEventMap[K]) => any;
/**
* Attaches an event handler outside directly to specified DOM element
* bypassing the react synthetic event system.
*
* @param element The target to listen for events on
* @param event The DOM event name
* @param handler An event handler
* @param capture Whether or not to listen during the capture event phase
*/
export default function useEventListener<T extends Element | Document | Window, K extends keyof DocumentEventMap>(eventTarget: T | (() => T), event: K, listener: EventHandler<T, K>, capture?: boolean | AddEventListenerOptions): void;
export {};
import { useEffect } from 'react';
import useEventCallback from './useEventCallback';
/**
* Attaches an event handler outside directly to specified DOM element
* bypassing the react synthetic event system.
*
* @param element The target to listen for events on
* @param event The DOM event name
* @param handler An event handler
* @param capture Whether or not to listen during the capture event phase
*/
export default function useEventListener(eventTarget, event, listener, capture) {
if (capture === void 0) {
capture = false;
}
var handler = useEventCallback(listener);
useEffect(function () {
var target = typeof eventTarget === 'function' ? eventTarget() : eventTarget;
target.addEventListener(event, handler, capture);
return function () {
return target.removeEventListener(event, handler, capture);
};
}, [eventTarget]);
}
\ No newline at end of file
/// <reference types="react" />
export interface FocusManagerOptions {
/**
* A callback fired when focus shifts. returning `false` will prevent
* handling the focus event
*/
willHandle?(focused: boolean, event: React.FocusEvent): boolean | void;
/**
* A callback fired after focus is handled but before onChange is called
*/
didHandle?(focused: boolean, event: React.FocusEvent): void;
/**
* A callback fired after focus has changed
*/
onChange?(focused: boolean, event: React.FocusEvent): void;
/**
* When true, the event handlers will not report focus changes
*/
isDisabled: () => boolean;
}
export interface FocusController {
onBlur: (event: any) => void;
onFocus: (event: any) => void;
}
/**
* useFocusManager provides a way to track and manage focus as it moves around
* a container element. An `onChange` is fired when focus enters or leaves the
* element, but not when it moves around inside the element, similar to
* `pointerenter` and `pointerleave` DOM events.
*
* ```tsx
* const [focused, setFocusState] = useState(false)
*
* const { onBlur, onFocus } = useFocusManager({
* onChange: nextFocused => setFocusState(nextFocused)
* })
*
* return (
* <div tabIndex="-1" onFocus={onFocus} onBlur={onBlur}>
* {String(focused)}
* <input />
* <input />
*
* <button>A button</button>
* </div>
* ```
*
*/
export default function useFocusManager(opts: FocusManagerOptions): FocusController;
import { useCallback, useRef } from 'react';
import useEventCallback from './useEventCallback';
import useMounted from './useMounted';
/**
* useFocusManager provides a way to track and manage focus as it moves around
* a container element. An `onChange` is fired when focus enters or leaves the
* element, but not when it moves around inside the element, similar to
* `pointerenter` and `pointerleave` DOM events.
*
* ```tsx
* const [focused, setFocusState] = useState(false)
*
* const { onBlur, onFocus } = useFocusManager({
* onChange: nextFocused => setFocusState(nextFocused)
* })
*
* return (
* <div tabIndex="-1" onFocus={onFocus} onBlur={onBlur}>
* {String(focused)}
* <input />
* <input />
*
* <button>A button</button>
* </div>
* ```
*
*/
export default function useFocusManager(opts) {
var isMounted = useMounted();
var lastFocused = useRef();
var handle = useRef();
var willHandle = useEventCallback(opts.willHandle);
var didHandle = useEventCallback(opts.didHandle);
var onChange = useEventCallback(opts.onChange);
var isDisabled = useEventCallback(opts.isDisabled);
var handleFocusChange = useCallback(function (focused, event) {
if (event && event.persist) event.persist();
if (willHandle && willHandle(focused, event) === false) return;
clearTimeout(handle.current);
handle.current = setTimeout(function () {
if (focused !== lastFocused.current) {
if (didHandle) didHandle(focused, event); // only fire a change when unmounted if its a blur
if (isMounted() || !focused) {
lastFocused.current = focused;
onChange && onChange(focused, event);
}
}
});
}, [isMounted, willHandle, didHandle, onChange, lastFocused]);
var handleBlur = useCallback(function (event) {
if (!isDisabled()) handleFocusChange(false, event);
}, [handleFocusChange, isDisabled]);
var handleFocus = useCallback(function (event) {
if (!isDisabled()) handleFocusChange(true, event);
}, [handleFocusChange, isDisabled]);
return {
onBlur: handleBlur,
onFocus: handleFocus
};
}
\ No newline at end of file
/**
* Returns a function that triggers a component update. the hook equivalent to
* `this.forceUpdate()` in a class component. In most cases using a state value directly
* is preferable but may be required in some advanced usages of refs for interop or
* when direct DOM manipulation is required.
*
* ```ts
* const forceUpdate = useForceUpdate();
*
* const updateOnClick = useCallback(() => {
* forceUpdate()
* }, [forceUpdate])
*
* return <button type="button" onClick={updateOnClick}>Hi there</button>
* ```
*/
export default function useForceUpdate(): () => void;
import { useReducer } from 'react';
/**
* Returns a function that triggers a component update. the hook equivalent to
* `this.forceUpdate()` in a class component. In most cases using a state value directly
* is preferable but may be required in some advanced usages of refs for interop or
* when direct DOM manipulation is required.
*
* ```ts
* const forceUpdate = useForceUpdate();
*
* const updateOnClick = useCallback(() => {
* forceUpdate()
* }, [forceUpdate])
*
* return <button type="button" onClick={updateOnClick}>Hi there</button>
* ```
*/
export default function useForceUpdate() {
// The toggling state value is designed to defeat React optimizations for skipping
// updates when they are stricting equal to the last state value
var _useReducer = useReducer(function (state) {
return !state;
}, false),
dispatch = _useReducer[1];
return dispatch;
}
\ No newline at end of file
declare type DocumentEventHandler<K extends keyof DocumentEventMap> = (this: Document, ev: DocumentEventMap[K]) => any;
/**
* Attaches an event handler outside directly to the `document`,
* bypassing the react synthetic event system.
*
* ```ts
* useGlobalListener('keydown', (event) => {
* console.log(event.key)
* })
* ```
*
* @param event The DOM event name
* @param handler An event handler
* @param capture Whether or not to listen during the capture event phase
*/
export default function useGlobalListener<K extends keyof DocumentEventMap>(event: K, handler: DocumentEventHandler<K>, capture?: boolean | AddEventListenerOptions): void;
export {};
import useEventListener from './useEventListener';
import { useCallback } from 'react';
/**
* Attaches an event handler outside directly to the `document`,
* bypassing the react synthetic event system.
*
* ```ts
* useGlobalListener('keydown', (event) => {
* console.log(event.key)
* })
* ```
*
* @param event The DOM event name
* @param handler An event handler
* @param capture Whether or not to listen during the capture event phase
*/
export default function useGlobalListener(event, handler, capture) {
if (capture === void 0) {
capture = false;
}
var documentTarget = useCallback(function () {
return document;
}, []);
return useEventListener(documentTarget, event, handler, capture);
}
\ No newline at end of file
declare type State = {
image: HTMLImageElement | null;
error: unknown | null;
};
/**
* Fetch and load an image for programatic use such as in a `<canvas>` element.
*
* @param imageOrUrl The `HtmlImageElement` or image url to load
* @param crossOrigin The `crossorigin` attribute to set
*
* ```ts
* const { image, error } = useImage('/static/kittens.png')
* const ref = useRef<HTMLCanvasElement>()
*
* useEffect(() => {
* const ctx = ref.current.getContext('2d')
*
* if (image) {
* ctx.drawImage(image, 0, 0)
* }
* }, [ref, image])
*
* return (
* <>
* {error && "there was a problem loading the image"}
* <canvas ref={ref} />
* </>
* ```
*/
export default function useImage(imageOrUrl?: string | HTMLImageElement | null | undefined, crossOrigin?: 'anonymous' | 'use-credentials' | string): State;
export {};
import { useState, useEffect } from 'react';
/**
* Fetch and load an image for programatic use such as in a `<canvas>` element.
*
* @param imageOrUrl The `HtmlImageElement` or image url to load
* @param crossOrigin The `crossorigin` attribute to set
*
* ```ts
* const { image, error } = useImage('/static/kittens.png')
* const ref = useRef<HTMLCanvasElement>()
*
* useEffect(() => {
* const ctx = ref.current.getContext('2d')
*
* if (image) {
* ctx.drawImage(image, 0, 0)
* }
* }, [ref, image])
*
* return (
* <>
* {error && "there was a problem loading the image"}
* <canvas ref={ref} />
* </>
* ```
*/
export default function useImage(imageOrUrl, crossOrigin) {
var _useState = useState({
image: null,
error: null
}),
state = _useState[0],
setState = _useState[1];
useEffect(function () {
if (!imageOrUrl) return undefined;
var image;
if (typeof imageOrUrl === 'string') {
image = new Image();
if (crossOrigin) image.crossOrigin = crossOrigin;
image.src = imageOrUrl;
} else {
image = imageOrUrl;
if (image.complete && image.naturalHeight > 0) {
setState({
image: image,
error: null
});
return;
}
}
function onLoad() {
setState({
image: image,
error: null
});
}
function onError(error) {
setState({
image: image,
error: error
});
}
image.addEventListener('load', onLoad);
image.addEventListener('error', onError);
return function () {
image.removeEventListener('load', onLoad);
image.removeEventListener('error', onError);
};
}, [imageOrUrl, crossOrigin]);
return state;
}
\ No newline at end of file
import { DependencyList, EffectCallback } from 'react';
/**
* An _immediate_ effect that runs an effect callback when its dependency array
* changes. This is helpful for updates should must run during render, most
* commonly state derived from props; a more ergonomic version of https://reactjs.org/docs/hooks-faq.html#how-do-i-implement-getderivedstatefromprops
*
* ```ts
* function Example({ value }) {
* const [intermediaryValue, setValue] = useState(value);
*
* useImmediateUpdateEffect(() => {
* setValue(value)
* }, [value])
* ```
*
* @category effects
*/
declare function useImmediateUpdateEffect(effect: EffectCallback, deps: DependencyList): void;
export default useImmediateUpdateEffect;
import { useRef } from 'react';
import useStableMemo from './useStableMemo';
import useWillUnmount from './useWillUnmount';
/**
* An _immediate_ effect that runs an effect callback when its dependency array
* changes. This is helpful for updates should must run during render, most
* commonly state derived from props; a more ergonomic version of https://reactjs.org/docs/hooks-faq.html#how-do-i-implement-getderivedstatefromprops
*
* ```ts
* function Example({ value }) {
* const [intermediaryValue, setValue] = useState(value);
*
* useImmediateUpdateEffect(() => {
* setValue(value)
* }, [value])
* ```
*
* @category effects
*/
function useImmediateUpdateEffect(effect, deps) {
var firstRef = useRef(true);
var tearDown = useRef();
useWillUnmount(function () {
if (tearDown.current) tearDown.current();
});
useStableMemo(function () {
if (firstRef.current) {
firstRef.current = false;
return;
}
if (tearDown.current) tearDown.current();
tearDown.current = effect();
}, deps);
}
export default useImmediateUpdateEffect;
\ No newline at end of file
/**
* Setup an [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) on
* a DOM Element.
*
* @param element The DOM element to observe
* @param init IntersectionObserver options
*/
export default function useIntersectionObserver<TElement extends Element>(element: TElement | null | undefined, { threshold, root, rootMargin }?: IntersectionObserverInit): IntersectionObserverEntry[];
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment