Skip to content

Instantly share code, notes, and snippets.

@UrbanChrisy
Last active June 15, 2023 15:01
Show Gist options
  • Save UrbanChrisy/df5e700fb4203b44ff3d01a7bfe5a013 to your computer and use it in GitHub Desktop.
Save UrbanChrisy/df5e700fb4203b44ff3d01a7bfe5a013 to your computer and use it in GitHub Desktop.
/**
*
* ▬▬ι═══════ﺤ -═══════ι▬▬
* Created by Chris on 16/04/20.
* ▬▬ι═══════ﺤ -═══════ι▬▬
*
*/
import CleaveJs from "cleave.js";
// eslint-disable-next-line import/no-unresolved
import { CleaveOptions } from "cleave.js/options";
import isEqual from "lodash/isEqual";
import React, { Ref, useEffect, useRef, useState } from "react";
function usePrevious<T = any>(props: T): T {
const ref = useRef(props);
useEffect(() => {
ref.current = props;
});
return ref.current;
}
export interface ChangeEvent<T> extends React.ChangeEvent<T> {
target: { rawValue: string } & EventTarget & T;
}
export type CleaveProps = {
id?: string;
name?: string;
options: CleaveOptions;
inputRef?: Ref<HTMLInputElement>;
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
value?: string;
defaultValue?: string;
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "defaultValue" | "onChange">;
export default function Cleave(props: CleaveProps) {
const { options, inputRef, value, type, onChange, defaultValue, ...otherProps } = props;
const [,setCleaveInstance] = useState<CleaveJs | null>(null);
const input = useRef<HTMLInputElement>(null);
const prevOptions = usePrevious(options);
useEffect(() => {
const newCleaveInstance = new CleaveJs(input?.current!, {
...options,
initValue: value,
onValueChanged: onChange,
});
newCleaveInstance.setRawValue(value || defaultValue || "");
setCleaveInstance(newCleaveInstance);
}, [!isEqual(options, prevOptions)]);
return (
<input {...otherProps} ref={input} />
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment