@craft-code/react-helper-utils
v0.4.3
Published
react utility functions / hooks / components
Downloads
172
Readme
CraftCode React Helpers
this package containes the following:
- conetext:
helpers-context
- hooks:
useHelpers
useDebounce
useThrottle
useIntersectionObserver
useCRUDState
useOutsideClick
useDialog
useMediaQuery
- components:
CollapsibleWrapper
InfinteListWrapper
RenderIf
HelpersContextProvider
DialogContainer
- other:
helperFunctions
- zustand:
cookieStorage
helpers-context:
this context is used to pass any constant values to the functions / hooks / commponents that need them
it's required for some functions / hooks / commponents to work correctly
HOOKS:
1 - useHelpers
provides the usual colection of helper functions
that are used in most of our projects
and works as a wrapper for helperFunctions
that pass the helpers-context
value to it
| param | type | | ---------- | :--: | | *none* | - |
⚠ must be used inside the
helpers-context
provider to provide the necessary values to the functions
which includes:
fileExtensionToName,
filterFalseValuesFromAnObject,
// random
generateRandomId,
getRandomImageLink,
getImageServerLink,
matchIframeLink,
removeLineBreaksFromString,
// text manipulation
getFlagEmoji,
truncateString,
// html
sanitizeHtml,
// date-time
timeSpanToDate,
// youtube
getYoutubeLinkId,
getYoutubeLinkThumbnail,
generateYoutubeIFrameLink,
// whatsapp
goToWhatsappChat,
forwardMessageToWhatsApp,
// google
generateGooogleMapsUrlFromCords,
// friendly url
getIdFromFriendlyUrl,
generateFriendlyUrlFromId,
// local storage
getFromLocalStorage,
saveToLocalStorage,
2 - useDebounce
| param | type | | --------------- | ------ | | delayInMS* | number |
Usage:
const debounce1s = useDebounce(1000);
const debounce2s = useDebounce(2000);
if (isFulfiled) debounce1s(() => doSomthing(...args)); // debounces for 1s
if (isFulfiled_2) debounce2s(() => doSomthing(...args)); // debounces for 2s
3 - useThrottle
| param | type | | --------------- | ------ | | delayInMS* | number |
Usage:
const throttle1s = useThrottle(1000);
const throttle2s = useThrottle(2000);
if (isFulfiled) throttle1s(() => doSomthing(...args)); // executs only once every 1s
if (isFulfiled_2) throttle2s(() => doSomthing(...args)); // executs only once every 2s
4 - useIntersectionObserver
returns the state of the observed element
| param | type |
| :--------: | :---------------------------------------------------------: |
| elementRef | Element | null
|
| options | IntersectionObserverInit &
{observeOnce: boolean
;}; |
5 - useCRUDState
useState with operation flags and permissions controll
| param | type |
| :------ | :------------------: |
| options | Partial<Params<T
>> |
types
type Action = "ADD" | "EDIT" | "DELETE";
type Params<T> = {
initialData: T;
canAdd: boolean;
canEdit: boolean;
canDelete: boolean;
onActionDenied: (deniedAction: Action) => void;
emptyOnReset?: boolean;
};
Usage:
interface Brand {
name: string;
logoSrc: string;
}
const { dispatch, is, state } = useCrudState<Partial<Brand>>({
canAdd,
canDelete,
canEdit,
});
Note:
Setting
params.emptyOnReset
totrue
when callingdispatch.RESET()
will set state toundefined
while setting
params.emptyOnReset
tofalse
will set state toparams.initialData
6 - useOutsideClick
executes a function when clicking outside / inside of an element(s)
| param | type |
| :------------------ | :----------------------------------------------------------------------------------------------------------: |
| elementRef* | MutableRefObject<Element | null
| undefined
> | MutableRefObject<Element | null
| undefined
>[] |
| outSideClickHandler | () => void
|
| inSideClickHandler | (idx?: number) => void
|
Usage:
const elementRef = useRef<any>();
const button1Ref = useRef<any>();
const button2Ref = useRef<any>();
const button3Ref = useRef<any>();
// single element
useOutsideClick(
elementRef,
() => alert("outside"),
() => alert("inside")
);
// multiple elememts
useOutsideClick(
[button1Ref, button2Ref, button3Ref],
() => alert("outside all buttons"),
(idx) => alert(`inside button #${idx}`)
);
7 - useDialog
enables the use of the new HTML <dialog/>
element in a hook frindly form
must pass a ref to the <dialog/>
element in the root of the app to the Helpers Context
Usage
App root:
import { DialogContainer, HelpersContextProvider } from '@craft-code/react-helper-utils'
const App => () => (
<HelpersContextProvider value={contextValue}>
...
...
<DialogContainer/> {/* <= this is where the content will be placed */}
<HelpersContextProvider/>
)
your component:
import { useDialog } from '@craft-code/react-helper-utils'
const { open, close } = useDialog();
const SomeComponent = () => {
...
return <button onClick={() => open('content')}> Show Dialog </botton>
}
8 - useMediaQuery
creates a reactive value representing the matching of the provided media query
| param | type |
| :----------- | :-------------------------------: |
| query* | string (CSS media query string)
|
| defaultValue | boolean |
8 - useDebounceState
creates a reactive state that returns a 3rd value that updates after a delay
AKA: mix of React's useState
and useDebounce
hook
| param | type |
| :------------- | :----: |
| duration* | number |
| initialValue | T
|
Usage
const [value, setValue, debouncedValue] = useDebounceState<string>(500, "");
COMPONENTS:
1 - CollapsibleWrapper
Litlarly a simple div that collaps and expands verticaly with absolutly no styling
| prop | type | description | | ------------ | ------- | ----------------------------------------------------- | | isOpen* | boolean | controlls the state of the containing div | | fadeOpacity | boolean | fade the opacity of the content through the transtion |
2 - InfinteListWrapper
this component takes @tanstack/react-query
infinite query
and takes care of fetching more data on reaching the end of the container
| prop | type | description |
| ------------------------- | ----------------------------------------- | ---------------------------------------- |
| infiniteQueryResult* | UseInfiniteQueryResult<T
> | result of the infinite query hook |
| loadingComponent | ReactNode | component to show when loading more data |
| noDataComponent | ReactNode | componet to show when there is no data |
| children | (Items: InfiniteData<T>[]) => ReactNode
| control how to render the fetched data |
3 - RenderIf
this component only purpose is CODE READABILITY only, which is good enough 🙂, Realy.
| prop | type | description | | --------------- | --------- | -------------------------------------------------- | | condition* | boolean | switch between main and fallback component | | children | ReactNode | Main component to render conditionaly | | fallback | ReactNode | component to render when the condition is not meet |
Usage:
//before
{ condition ? (
/* main element code
.
.
. */
):( // the line that you keep searching for while coding
/* fallback element code
.
.
. */
)}
// after
<RenderIf condition={condition} fallback={<fallbackComponent />}>
<MainComponent />
</RenderIf>
4 - HelpersContextProvider
this component is the NEW RECOMENDED WAY to use the helpers context
| prop | type | description | | ----------- | ---------------------- | --------------------------------------------------------- | | value* | IHelpesContextProvider | value to be passed to the components / hooks that need it | | children | ReactNode | |
5 - DialogContainer
this component is the container for the content passed to the useDialog
hook
MUST be used inside
<HelpersContextProvider>
& not<HelpersContext.Provider>
otherwise it won't work
OTHER:
1 - helperFunctions
this is the backbone of the useHelpers
hook that let you use them outside react components / hooks,
the hook is just a wrapper to access the HelpersContext
value
ZUSTAND:
1 - cookieStorage
this is a custom storage to use in the zustand persist
middleware that use cookies to save state
please note that cookie size limitations apply (max 4kB afaik).
usage
import { cookieStorage } from '@craft-code/react-helper-utils';
import { persist } from 'zustand/middleware';
const stateCreator = (set,get) => ({...})
const storage = create(persist(stateCreator,{name: 'storage', storage: () => cookieStorage}))
there is a utility function to set expiary time on a cookie called setExpiry
| param | type |
| ---------- | ---------------- |
| cookieName | string |
| date | Date
| string |
usage:
import { setExpiry } from "@craft-code/react-helper-utils";
setExpiry("storage", "1997-08-21");
Releases:
0.4.3
- fixed export point
/native
0.4.2
- added export point for hooks that work with
react-native
0.4.1
- fixed a bug in
useCRUDState
wherestate
andis
values update in seperate renders
0.4.0
- removed
<HelpersContext.Provider/>
component - replaced
useCreateCRUDState
hook withuseCRUDState
- added
useDebounceState
0.3.6
<HelpersContext.Provider/>
will be removed in future releases
please use <HelpersContextProvide/>
insted
- added a custom
cookie storage
storage for zustandpersist
middleware that is used to persist state in cookies - added
<HelpersContextProvider/>
component as the new recommended way of using the context - added
useDialog
hook to show dialogs using the new HTML<dialog/>
element - added
<DialogContainer/>
to show content provided touseDialog()
.open
method - added
useMediaQuery
to provid a reactive state that change according to media queries.matches
state
0.3.5
- fixed
useDebounce
not triggering more than once some times
0.3.4
- removed extra debug info from render from
InfinteListWrapper
0.3.3
- added useThrottle hook
0.3.2
- fixed noDataComponent & loadingComponent components showing up at the same time in
InfinteListWrapper
helperFunctions
doesn't require default config
0.3.1
- add support for multiple elements to useOutsideClick hook
- useOutsideClick hook has
inSideClickHandler
now
0.3.0:
- 🔴 removed NextSEO
- added useOutsideClick hook
- added helperFunctions as a way to use the helper functions outside react components / hooks
0.2.0:
- configured code spliting
- added RenderIf component
0.1.0:
- initial release