add OTP + fix field
This commit is contained in:
parent
86551c1ba8
commit
f54e3c683c
|
|
@ -135,7 +135,7 @@ export const FieldInput: FC<{
|
||||||
{prefix && prefix !== "" ? (
|
{prefix && prefix !== "" ? (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
"c-px-2 c-flex c-flex-row c-items-center",
|
"c-pl-2 c-flex c-flex-row c-items-center",
|
||||||
css`
|
css`
|
||||||
color: gray;
|
color: gray;
|
||||||
`
|
`
|
||||||
|
|
@ -200,7 +200,7 @@ export const FieldInput: FC<{
|
||||||
{suffix && suffix !== "" ? (
|
{suffix && suffix !== "" ? (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
"c-px-2 c-flex c-flex-row c-items-center",
|
"c-pr-2 c-flex c-flex-row c-items-center",
|
||||||
css`
|
css`
|
||||||
color: gray;
|
color: gray;
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import { FieldRichText } from "./TypeRichText";
|
||||||
import { FieldUpload } from "./TypeUpload";
|
import { FieldUpload } from "./TypeUpload";
|
||||||
import { KeyValue } from "./KeyValue";
|
import { KeyValue } from "./KeyValue";
|
||||||
import { InputMask, format } from "@react-input/mask";
|
import { InputMask, format } from "@react-input/mask";
|
||||||
|
import { FieldOTP } from "./TypeOTP";
|
||||||
|
|
||||||
export type PropTypeInput = {
|
export type PropTypeInput = {
|
||||||
type: "input";
|
type: "input";
|
||||||
|
|
@ -32,7 +33,8 @@ export type PropTypeInput = {
|
||||||
| "monthly"
|
| "monthly"
|
||||||
| "key-value"
|
| "key-value"
|
||||||
| "mask"
|
| "mask"
|
||||||
| "phone";
|
| "phone"
|
||||||
|
| "otp";
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
onFocus?: (e: FocusEvent<HTMLDivElement>) => void;
|
onFocus?: (e: FocusEvent<HTMLDivElement>) => void;
|
||||||
onBlur?: (e: FocusEvent<HTMLDivElement>) => void;
|
onBlur?: (e: FocusEvent<HTMLDivElement>) => void;
|
||||||
|
|
@ -110,6 +112,7 @@ export const FieldTypeInput: FC<{
|
||||||
|
|
||||||
const disabled =
|
const disabled =
|
||||||
typeof field.disabled === "function" ? field.disabled() : field.disabled;
|
typeof field.disabled === "function" ? field.disabled() : field.disabled;
|
||||||
|
|
||||||
switch (type_field) {
|
switch (type_field) {
|
||||||
case "toggle":
|
case "toggle":
|
||||||
return (
|
return (
|
||||||
|
|
@ -198,6 +201,8 @@ export const FieldTypeInput: FC<{
|
||||||
<FieldMoney field={field} fm={fm} prop={prop} arg={arg} />
|
<FieldMoney field={field} fm={fm} prop={prop} arg={arg} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
case "otp":
|
||||||
|
return <FieldOTP field={field} fm={fm} prop={prop} arg={arg} digit={4} />;
|
||||||
case "rich-text":
|
case "rich-text":
|
||||||
return <FieldRichText field={field} fm={fm} prop={prop} />;
|
return <FieldRichText field={field} fm={fm} prop={prop} />;
|
||||||
case "date": {
|
case "date": {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
import { useLocal } from "lib/utils/use-local";
|
||||||
|
import { FC } from "react";
|
||||||
|
import { FieldLocal, FieldProp, FMLocal } from "../../typings";
|
||||||
|
import { PropTypeInput } from "./TypeInput";
|
||||||
|
|
||||||
|
export const FieldOTP: FC<{
|
||||||
|
digit: number;
|
||||||
|
field: FieldLocal;
|
||||||
|
fm: FMLocal;
|
||||||
|
prop: PropTypeInput;
|
||||||
|
arg: FieldProp;
|
||||||
|
}> = ({ digit, fm, field }) => {
|
||||||
|
const local = useLocal({
|
||||||
|
otp: [] as string[],
|
||||||
|
ref: [] as HTMLInputElement[],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (local.otp.length === 0 && digit) {
|
||||||
|
for (let i = 0; i < digit; i++) {
|
||||||
|
local.otp.push("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="c-flex-1 c-flex c-justify-center c-items-center">
|
||||||
|
{local.otp.map((item, idx) => (
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
key={idx}
|
||||||
|
className={cx(
|
||||||
|
"c-rounded-md c-text-center",
|
||||||
|
css`
|
||||||
|
margin: 3px;
|
||||||
|
font-size: 3em;
|
||||||
|
padding: 0px 10px;
|
||||||
|
width: 60px;
|
||||||
|
height: 100px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
background: white;
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
onChange={() => {}}
|
||||||
|
value={item}
|
||||||
|
ref={(ref) => {
|
||||||
|
if (ref) local.ref[idx] = ref;
|
||||||
|
}}
|
||||||
|
onPaste={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var clipboardData =
|
||||||
|
e.clipboardData || (window as any).clipboardData;
|
||||||
|
var pastedData = clipboardData.getData("text");
|
||||||
|
for (let i = 0; i < pastedData.length; i++) {
|
||||||
|
if (i >= local.otp.length) break;
|
||||||
|
local.otp[i] = pastedData[i];
|
||||||
|
}
|
||||||
|
local.render();
|
||||||
|
}}
|
||||||
|
onKeyDown={async (e) => {
|
||||||
|
if (e.key === "Backspace") {
|
||||||
|
local.otp[idx] = "";
|
||||||
|
local.render();
|
||||||
|
const ref = local.ref[idx - 1];
|
||||||
|
if (ref) {
|
||||||
|
ref.focus();
|
||||||
|
}
|
||||||
|
} else if (parseInt(e.key) || e.key === "0") {
|
||||||
|
local.otp[idx] = e.key;
|
||||||
|
local.render();
|
||||||
|
const ref = local.ref[idx + 1];
|
||||||
|
if (ref) {
|
||||||
|
ref.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const otp = local.otp.join("");
|
||||||
|
if (otp.length === digit) {
|
||||||
|
fm.data[field.name] = otp;
|
||||||
|
fm.render();
|
||||||
|
}
|
||||||
|
local.render();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue