@cdoublev/react-utils v0.10.4
React Utils
About
This package contains common hooks and components to use in a React application.
Installation
npm i @cdoublev/react-utils
@cdoublev/react-utils
is built to run in the current version of NodeJS, which means it should be transpiled with your application using its own targets.
API
Hooks
useAnimate
useAnimate
abstracts using Element.animate()
from the Web Animation API (MDN).
useAnimate :: Ref -> Animate
Ref
should be a React reference object containing an Element
, ie. Ref => { current: Element }
.
Animate
is a Function
that has the following signature: Animate :: (Keyframes -> Options?|Number?) -> Animation
.
Animation
(W3C) will be cancelled if it's still running when the component unmounts.
Example: CodePen
useAnimateCustom
useAnimateCustom
abstracts using animate()
, a lightweight alternative to Element.animate()
or its official polyfill, with some extra features.
Note: this hook relies on @cdoublev/animate
as an optional dependency to install manually.
useAnimateCustom :: Ref -> Animate
Ref
should be a React reference object containing an Element
, ie. Ref => { current: Element }
.
Animate
is a Function
that has the following signature: Animate :: (Keyframes|MotionPath -> Options?|Number?) -> Animation
.
Animation
conforms to the native Animation
(W3C). It will be cancelled if it's still running when the component unmouts.
Example: CodePen
Related:
useIntersectionObserver
useIntersectionObserver
abstracts using an IntersectionObserver
to execute a function when an Element
intersects an ancestor, ie. when it enters in or exits from its viewport.
useIntersectionObserver :: Configuration -> [CallbackRef, Identifier -> CallbackRef, Ref]
The first CallbackRef
should be used to define root
, ie. an ancestor containing the Element
s to observe, defined with the second callback ref obtained by executing the higher order function with an Identifier
(String|Number|Symbol
) for each Element
to observe.
Both should be used. root
will default to null
(ie. document
) when the corresponding callback ref is executed without an argument. null
can't be used to set root
to document
because React will execute the callback ref with null
before unmount, if it's used as a ref prop.
Ref
is a React object ref containing the current IntersectionObserver
. It can be used eg. to manually unobserve a target after a first intersection.
Each observed Element
will be unobserved before unmount, and the current IntersectionObserver
will be disconnected before root
unmounts, except if root
corresponds to document
, as it could be shared with other components. Only one IntersectionObserver
will be created for each unique set of intersection options.
Example: CodePen
Configuration:
rootMargin
andthreshold
are two of the threeIntersectionObserver
options (W3C), the third beingroot
onEnter
andonExit
are optional callbacks executed with the arguments received from theIntersectionObserver
callback when anElement
enters in or exits from the viewport of its ancestor
Note: make sure to use a memoized value for threshold
if it's an Array
, as well as for onEnter
and onExit
.
useInterval
Credit: Dan Abramov.
useInterval
abstracts using setInterval()
and clearInterval()
to schedule and repeat the execution of a function over time, without worrying about cancelling the timer to avoid a memory leak such as a React state update on an unmounted component.
useInterval :: [Function, Number] -> void
It will stop executing Function
if:
- the component unmounts
- the reference to
Function
has changed - the delay (
Number
) has changed
useGatherMemo
useGatherMemo
abstracts gathering (merging) and/or picking (destructuring) properties from object(s) while memoizing the result to avoid unneeded updates in the component and its children.
It's a low level hook that can be usefull eg. when you want to merge options or props received in a hook or a component with a large default options object, instead of listing each option argument with a default value and/or listing each one as a dependency of a hook.
useGatherMemo :: (Object -> ...String|Symbol) -> [x, Object]
Example:
const options = { color: 'red', size: 'large' }
/**
* 1. Pick prop(s) and gather the rest
*
* Both constants will be defined with a memoized value/reference, if `options`
* shallow equals its previous render value
*/
// Write this:
const [color, subOptions] = useGatherMemo(options, 'color')
// Instead of this:
const { color, ...subOptions } = options
/**
* 2. Gather properties
*
* `allOptions` will be defined with a memoized reference, if `subOptions`
* shallow equals its previous render value.
*/
// Write this:
const allOptions = useGatherMemo({ ...subOptions, display: 'fullscreen' })
// Instead of this:
const allOptions = { ...subOptions, display: 'fullscreen' }
Warning: don't over use it, ie. use it only with large objects, otherwise it will negatively impact performances by increasing the call stack as well as the amount of data stored in memory.
useLazyStateUpdate
useLazyStateUpdate
abstracts delaying a state update.
Give it a state value and a delay (default to 100
ms) and it will update the component and return the corresponding state when delay
is over.
It could be used eg. to delay the render of an error notice after validating an input value updated on each user input.
useLazyStateUpdate :: [a, Number] -> a
useMediaQuery
useMediaQuery
abstracts using windows.matchMedia()
to observe a match against a query, eg. (min-width: 50em)
.
useMediaQuery :: String -> Boolean
useScrollIntoView
useScrollIntoView
abstracts using Element.scrollIntoView()
when a scroll
event is emitted.
Depending on the scroll direction, it prevents the default scroll behavior and scrolls into view the next or previous Element
, on:
- ✅ touch (finger or stylus) move
- ✅ wheel (rolling)
- ❌ wheel (button)
useScrollIntoView :: Configuration -> [CallbackRef, Identifier -> CallbackRef, Ref]
The first CallbackRef
should be used to define root
, ie. an ancestor containing the Element
s to scroll into view, defined with the second callback ref, obtained by executing the higher order function with a unique Identifier
(String|Number|Symbol
) for each Element
.
Both should be used. To set document
as root
, the corresponding callback ref should be executed without an argument. See useIntersectionObserver
to know why, since this hook is used to set the previous/next Element
to scroll into view when an Element
enters in the viewport of root
.
Ref
is a React object ref containing the current IntersectionObserver
.
Example:
Configuration:
beforeScroll
is an optional callback executed before scrolling, that can be used to set theElement
to scroll into view (by returning its index value intargets
) or eg. to set a CSS transition classname before scrolling, and receiving as arguments (1) the index of the target that will be scrolled into view, (2) the current target index and (3) the scrolling direction (up
,down
,left
, orright
)delay
(default to200
ms) is a timeout value before scrollingdirections
(default toboth
) is the scroll direction to listen on (x
,y
, orboth
)wait
(default to1000
ms) is a timeout value between two authorized scroll eventsmode
(default toauto
) is the scrolling behavioronEnter
andonExit
are optional callbacks defined inuseIntersectionObserver
touchSensitivity
(default to150
) is a distance in pixels that the finger or stylus should move to be handled as a scroll event
useSVGMousePosition
useSVGMousePosition
abstracts translating the position of the mouse relative to an <svg>
in document
, into a position relative to its viewBox
.
It could be used eg. to animate the position of a child SVGElement
(paths, filters, clips, masks, gradients, etc...).
useSVGMousePosition :: Configuration -> [Position, CallbackRef, CallbackRef]
Position
are the coordinates of the mouse: Position => { x: Float, y: Float }
.
The first CallbackRef
should be used to define the <svg>
. Using both callbacks is usefull to listen mousemove
events in an ancestor Element
containing the <svg>
and animate the position of a child SVGElement
outside of the <svg>
.
Note: the <svg>
should preserve its aspect ratio, otherwise Position
will be incorrect, as the current implementation is using Element.getBoundingClientRect()
to compute its dimensions.
Example: CodePen
Configuration:
hasRoot
(default tofalse
) is an optional boolean to make sure that themouseover
event listener will be registered only when the<svg>
is mounted, eg. if it's conditionally rendered in itsroot
componentinitial
(default to{ x: 0, y: 0 }
) is an optional initial positionisFixed
(default tofalse
) is an optionalBoolean
to flag thetarget
as having a fixed position in the viewport ofdocument
, ie. inwindow
precision
(default to2
) is an optional number to roundPosition
values
useTimeout
useTimeout
abstracts using setTimeout()
and clearTimeout()
to schedule the execution of a Function
, without worrying about cancelling the timer to avoid a memory leak such as a React state update on an unmounted component.
useTimeout :: [Function, Number] -> void
It will stop executing Function
if:
- the component unmounts
- the reference to
Function
has changed - the delay (
Number
) has changed
useTransition
useTransition
abstracts scheduling multiple state updates over time using different delays and durations.
It will always return the current state as a collection, which can be conceptualized as a box whose values are entering and exiting in and out over time. It can be used eg. to transition between CSS classnames when a component did mount or before unmouting.
useTransition :: { transitions: [Transition], onExit?: Transition } -> [[x], Restart, Exit?, Boolean?, Enter?]
A Transition
([x, Number, Number?]
) is a collection of a state value (x
) and one or two Number
s: the first value is the delay before applying the given state, and the second value is the duration during which it should be applied, except for the Transition
defined on onExit
, defined only with a duration.
Note: transitions
should be memoized, otherwhise the inital state will always be applied.
Exit
, Enter
, and the Boolean
are returned only when onExit
is provided. Exit
is a Function
to execute the Transition
defined on onExit
before toggling the Boolean
value to false
, indicating that the component can be considered as unmounted. Enter
is a Function
to toggle this value back to true
.
Demo: CodePen.
Related packages:
useValidation
useValidation
abstracts using the Constraint Validation API (MDN) to validate a form field on blur (default) or on change.
useValidation :: { onChange?: Function, onBlur?: Function, validateOnChange?: Boolean } -> [String, Props]
It returns any error message from the Constraint Validation API, and a collection of component properties such as onChange
and onBlur
event handlers, to assign to an <input>
, <select>
or <textarea>
. Each of those handlers will be composed with a corresponding handler given as argument.
Components
Filter
<Filter>
provides common filter effects to use in a SVGElement
.
Usage for a single filter effect:
<svg viewBox='0 0 100 100'>
<Filter id='glow-large' name='glow' blur='10' spread='3' opacity='0.3' />
<Filter id='glow-small' name='glow' blur='5' spread='2' opacity='0.7' />
<circle filter='url(#glow-large)' cx='25' cy='25' r='25'>
<circle filter='url(#glow-small)' cx='75' cy='75' r='25'>
</svg>
When used alone, <Filter>
should not have a in
or result
and it will automatically be wrapped in a <filter>
with the following default prop values:
'colorInterpolation'
(for thecolor-interpolation-filter
attribute):'sRGB'
'id'
:'name'
'width'
and'height'
: based on'name'
'x'
and'y'
: based on'width'
and'height'
'width'
, 'height'
, 'x'
, 'y'
should be provided as percentage values.
All effect's names are listed further below.
Usage for composing filter effects:
<svg viewBox='0 0 100 100'>
<filter id='glow-noise' x='-100%' y='-100%' height='300%' width='300%'>
<Filter name='glow' blur='10' spread='3' />
<Filter name='noise' in='glow' opacity='0.2' frequency='0.2' />
</filter>
<circle filter='url(#glow-noise)' cx='50' cy='50' r='25'>
</svg>
When composed, <Filter>
s should have a in
and eventually a result
prop (defaults to name
and not required for the last <Filter>
in the composition).
Effect name
s and props:
Name | Props |
---|---|
color-correction | lightness, opacity, saturation |
glow | blur, spread, lightness, opacity |
glow-inset | blur, threshold, lightness, opacity |
gooey | tolerance |
noise | frequency, blend, color, lightness, opacity |
shadow | color, offsetX, offsetY, blur, spread, threshold, opacity, saturation |
shadow-inset | color, offsetX, offsetY, blur, spread, threshold, opacity, saturation |
Default values:
- color:
'black'
- lightness:
1
- opacity:
0.5
- offsetX:
0
- offsetY:
0
- saturation:
1
- spread:
0
- threshold:
0
All props require a number, except blend
(CSS blend mode) and color
(CSS color).
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago