Updates
This commit is contained in:
parent
358bfed988
commit
9f8527fc4d
@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import Row from "../../layout/Row";
|
import Row from "../../layout/Row";
|
||||||
import { Info, Minus, Plus } from "lucide-react";
|
import { Info, Minus, Plus } from "lucide-react";
|
||||||
import twuiNumberfy from "../../utils/numberfy";
|
import twuiNumberfy from "../../utils/numberfy";
|
||||||
@ -7,10 +7,10 @@ import { InputProps } from ".";
|
|||||||
let pressInterval: any;
|
let pressInterval: any;
|
||||||
let pressTimeout: any;
|
let pressTimeout: any;
|
||||||
|
|
||||||
type Props = Pick<InputProps<any>, "min" | "max" | "step"> & {
|
type Props = Pick<InputProps<any>, "min" | "max" | "step" | "decimal"> & {
|
||||||
|
value: string;
|
||||||
setValue: React.Dispatch<React.SetStateAction<string>>;
|
setValue: React.Dispatch<React.SetStateAction<string>>;
|
||||||
getNormalizedValue: (v: string) => void;
|
buttonDownRef: React.RefObject<boolean>;
|
||||||
buttonDownRef: React.MutableRefObject<boolean>;
|
|
||||||
inputRef: React.RefObject<HTMLInputElement | null>;
|
inputRef: React.RefObject<HTMLInputElement | null>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -18,21 +18,50 @@ type Props = Pick<InputProps<any>, "min" | "max" | "step"> & {
|
|||||||
* # Input Number Text Buttons
|
* # Input Number Text Buttons
|
||||||
*/
|
*/
|
||||||
export default function NumberInputButtons({
|
export default function NumberInputButtons({
|
||||||
getNormalizedValue,
|
value,
|
||||||
setValue,
|
setValue,
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
step,
|
step,
|
||||||
buttonDownRef,
|
buttonDownRef,
|
||||||
inputRef,
|
inputRef,
|
||||||
|
decimal,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const PRESS_TRIGGER_TIMEOUT = 200;
|
const PRESS_TRIGGER_TIMEOUT = 200;
|
||||||
const DEFAULT_STEP = 1;
|
const DEFAULT_STEP = 1;
|
||||||
|
|
||||||
|
const [buttonDown, setButtonDown] = useState(false);
|
||||||
|
|
||||||
|
// function getNormalizedValue(value: string) {
|
||||||
|
// if (numberText) {
|
||||||
|
// if (props.max && twuiNumberfy(value) > twuiNumberfy(props.max))
|
||||||
|
// return getFinalValue(props.max);
|
||||||
|
|
||||||
|
// if (props.min && twuiNumberfy(value) < twuiNumberfy(props.min))
|
||||||
|
// return getFinalValue(props.min);
|
||||||
|
|
||||||
|
// return getFinalValue(value);
|
||||||
|
// } else {
|
||||||
|
// return value;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
buttonDownRef.current = buttonDown;
|
||||||
|
if (buttonDown) {
|
||||||
|
setValue(inputRef.current?.value || "");
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
setValue(inputRef.current?.value || "");
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
}, [buttonDown]);
|
||||||
|
|
||||||
function incrementDownPress() {
|
function incrementDownPress() {
|
||||||
window.clearTimeout(pressTimeout);
|
window.clearTimeout(pressTimeout);
|
||||||
|
setButtonDown(true);
|
||||||
|
|
||||||
pressTimeout = setTimeout(() => {
|
pressTimeout = setTimeout(() => {
|
||||||
buttonDownRef.current = true;
|
|
||||||
pressInterval = setInterval(() => {
|
pressInterval = setInterval(() => {
|
||||||
increment();
|
increment();
|
||||||
}, 50);
|
}, 50);
|
||||||
@ -40,14 +69,15 @@ export default function NumberInputButtons({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function incrementDownCancel() {
|
function incrementDownCancel() {
|
||||||
buttonDownRef.current = false;
|
setButtonDown(false);
|
||||||
window.clearTimeout(pressTimeout);
|
window.clearTimeout(pressTimeout);
|
||||||
window.clearInterval(pressInterval);
|
window.clearInterval(pressInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
function decrementDownPress() {
|
function decrementDownPress() {
|
||||||
|
setButtonDown(true);
|
||||||
|
|
||||||
pressTimeout = setTimeout(() => {
|
pressTimeout = setTimeout(() => {
|
||||||
buttonDownRef.current = true;
|
|
||||||
pressInterval = setInterval(() => {
|
pressInterval = setInterval(() => {
|
||||||
decrement();
|
decrement();
|
||||||
}, 50);
|
}, 50);
|
||||||
@ -55,41 +85,51 @@ export default function NumberInputButtons({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function decrementDownCancel() {
|
function decrementDownCancel() {
|
||||||
buttonDownRef.current = false;
|
setButtonDown(false);
|
||||||
window.clearTimeout(pressTimeout);
|
window.clearTimeout(pressTimeout);
|
||||||
window.clearInterval(pressInterval);
|
window.clearInterval(pressInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
function increment() {
|
function increment() {
|
||||||
const existingValue = inputRef.current?.value;
|
if (!inputRef.current) return;
|
||||||
const existingNumberValue = twuiNumberfy(existingValue);
|
|
||||||
|
|
||||||
if (max && existingNumberValue >= twuiNumberfy(max)) {
|
const existingValue = inputRef.current.value;
|
||||||
return setValue(String(max));
|
const existingNumberValue = twuiNumberfy(existingValue, decimal);
|
||||||
} else if (min && existingNumberValue < twuiNumberfy(min)) {
|
|
||||||
return setValue(String(min));
|
let new_value = "";
|
||||||
|
|
||||||
|
if (max && existingNumberValue >= twuiNumberfy(max, decimal)) {
|
||||||
|
new_value = twuiNumberfy(max, decimal).toLocaleString();
|
||||||
|
} else if (min && existingNumberValue < twuiNumberfy(min, decimal)) {
|
||||||
|
new_value = twuiNumberfy(min, decimal).toLocaleString();
|
||||||
} else {
|
} else {
|
||||||
setValue(
|
new_value = (
|
||||||
String(
|
existingNumberValue +
|
||||||
existingNumberValue + twuiNumberfy(step || DEFAULT_STEP),
|
twuiNumberfy(step || DEFAULT_STEP, decimal)
|
||||||
),
|
).toLocaleString();
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inputRef.current.value = new_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decrement() {
|
function decrement() {
|
||||||
const existingValue = inputRef.current?.value;
|
if (!inputRef.current) return;
|
||||||
const existingNumberValue = twuiNumberfy(existingValue);
|
|
||||||
|
|
||||||
if (min && existingNumberValue <= twuiNumberfy(min)) {
|
const existingValue = inputRef.current?.value;
|
||||||
setValue(String(min));
|
const existingNumberValue = twuiNumberfy(existingValue, decimal);
|
||||||
|
|
||||||
|
let new_value = "";
|
||||||
|
|
||||||
|
if (min && existingNumberValue <= twuiNumberfy(min, decimal)) {
|
||||||
|
new_value = twuiNumberfy(min, decimal).toLocaleString();
|
||||||
} else {
|
} else {
|
||||||
setValue(
|
new_value = (
|
||||||
String(
|
existingNumberValue -
|
||||||
existingNumberValue - twuiNumberfy(step || DEFAULT_STEP),
|
twuiNumberfy(step || DEFAULT_STEP, decimal)
|
||||||
),
|
).toLocaleString();
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inputRef.current.value = new_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -6,27 +6,21 @@ import React, {
|
|||||||
ReactNode,
|
ReactNode,
|
||||||
RefObject,
|
RefObject,
|
||||||
TextareaHTMLAttributes,
|
TextareaHTMLAttributes,
|
||||||
|
useRef,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
import Span from "../../layout/Span";
|
import Span from "../../layout/Span";
|
||||||
import Button from "../../layout/Button";
|
|
||||||
import { Eye, EyeOff, Info, InfoIcon, X } from "lucide-react";
|
import { Eye, EyeOff, Info, InfoIcon, X } from "lucide-react";
|
||||||
import { AutocompleteOptions } from "../../types";
|
import { AutocompleteOptions } from "../../types";
|
||||||
import twuiNumberfy from "../../utils/numberfy";
|
import twuiNumberfy from "../../utils/numberfy";
|
||||||
import Dropdown from "../../elements/Dropdown";
|
import Dropdown from "../../elements/Dropdown";
|
||||||
import Card from "../../elements/Card";
|
|
||||||
import Stack from "../../layout/Stack";
|
import Stack from "../../layout/Stack";
|
||||||
import NumberInputButtons from "./NumberInputButtons";
|
import NumberInputButtons from "./NumberInputButtons";
|
||||||
import twuiSlugToNormalText from "../../utils/slug-to-normal-text";
|
import twuiSlugToNormalText from "../../utils/slug-to-normal-text";
|
||||||
import twuiUseReady from "../../hooks/useReady";
|
|
||||||
import Row from "../../layout/Row";
|
import Row from "../../layout/Row";
|
||||||
import Paper from "../../elements/Paper";
|
import Paper from "../../elements/Paper";
|
||||||
import { TWUISelectValidityObject } from "../Select";
|
import { TWUISelectValidityObject } from "../Select";
|
||||||
|
|
||||||
let timeout: any;
|
|
||||||
let validationFnTimeout: any;
|
|
||||||
let externalValueChangeTimeout: any;
|
|
||||||
|
|
||||||
export type InputProps<KeyType extends string> = Omit<
|
export type InputProps<KeyType extends string> = Omit<
|
||||||
DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,
|
DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,
|
||||||
"prefix" | "suffix"
|
"prefix" | "suffix"
|
||||||
@ -80,6 +74,7 @@ export type InputProps<KeyType extends string> = Omit<
|
|||||||
React.HTMLAttributes<HTMLDivElement>,
|
React.HTMLAttributes<HTMLDivElement>,
|
||||||
HTMLDivElement
|
HTMLDivElement
|
||||||
>;
|
>;
|
||||||
|
// refreshDefaultValue?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
let refreshes = 0;
|
let refreshes = 0;
|
||||||
@ -121,9 +116,18 @@ export default function Input<KeyType extends string>(
|
|||||||
validity: existingValidity,
|
validity: existingValidity,
|
||||||
clearInputProps,
|
clearInputProps,
|
||||||
rawNumber,
|
rawNumber,
|
||||||
|
// refreshDefaultValue,
|
||||||
...props
|
...props
|
||||||
} = inputProps;
|
} = inputProps;
|
||||||
|
|
||||||
|
const componentRefreshesRef = useRef(0);
|
||||||
|
let timeoutRef = useRef<any>(null);
|
||||||
|
let validationFnTimeoutRef = useRef<any>(null);
|
||||||
|
let externalValueChangeTimeoutRef = useRef<any>(null);
|
||||||
|
|
||||||
|
refreshes++;
|
||||||
|
componentRefreshesRef.current++;
|
||||||
|
|
||||||
function getFinalValue(v: any) {
|
function getFinalValue(v: any) {
|
||||||
if (rawNumber) return twuiNumberfy(v);
|
if (rawNumber) return twuiNumberfy(v);
|
||||||
if (numberText) {
|
if (numberText) {
|
||||||
@ -167,21 +171,8 @@ export default function Input<KeyType extends string>(
|
|||||||
props.placeholder ||
|
props.placeholder ||
|
||||||
(props.name ? twuiSlugToNormalText(props.name) : undefined);
|
(props.name ? twuiSlugToNormalText(props.name) : undefined);
|
||||||
|
|
||||||
function getNormalizedValue(value: string) {
|
|
||||||
if (numberText) {
|
|
||||||
if (props.max && twuiNumberfy(value) > twuiNumberfy(props.max))
|
|
||||||
return getFinalValue(props.max);
|
|
||||||
|
|
||||||
if (props.min && twuiNumberfy(value) < twuiNumberfy(props.min))
|
|
||||||
return getFinalValue(props.min);
|
|
||||||
|
|
||||||
return getFinalValue(value);
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
// if (!existingReady) return;
|
||||||
if (!existingValidity) return;
|
if (!existingValidity) return;
|
||||||
setValidity(existingValidity);
|
setValidity(existingValidity);
|
||||||
}, [existingValidity]);
|
}, [existingValidity]);
|
||||||
@ -190,8 +181,8 @@ export default function Input<KeyType extends string>(
|
|||||||
if (buttonDownRef.current) return;
|
if (buttonDownRef.current) return;
|
||||||
|
|
||||||
if (changeHandler) {
|
if (changeHandler) {
|
||||||
window.clearTimeout(externalValueChangeTimeout);
|
window.clearTimeout(externalValueChangeTimeoutRef.current);
|
||||||
externalValueChangeTimeout = setTimeout(() => {
|
externalValueChangeTimeoutRef.current = setTimeout(() => {
|
||||||
changeHandler(val);
|
changeHandler(val);
|
||||||
}, finalDebounce);
|
}, finalDebounce);
|
||||||
}
|
}
|
||||||
@ -208,10 +199,10 @@ export default function Input<KeyType extends string>(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.clearTimeout(timeout);
|
window.clearTimeout(timeoutRef.current);
|
||||||
|
|
||||||
if (validationRegex) {
|
if (validationRegex) {
|
||||||
timeout = setTimeout(() => {
|
timeoutRef.current = setTimeout(() => {
|
||||||
setValidity({
|
setValidity({
|
||||||
isValid: validationRegex.test(val),
|
isValid: validationRegex.test(val),
|
||||||
msg: "Value mismatch",
|
msg: "Value mismatch",
|
||||||
@ -220,9 +211,9 @@ export default function Input<KeyType extends string>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (validationFunction) {
|
if (validationFunction) {
|
||||||
window.clearTimeout(validationFnTimeout);
|
window.clearTimeout(validationFnTimeoutRef.current);
|
||||||
|
|
||||||
validationFnTimeout = setTimeout(() => {
|
validationFnTimeoutRef.current = setTimeout(() => {
|
||||||
if (validationRegex && !validationRegex.test(val)) {
|
if (validationRegex && !validationRegex.test(val)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -235,11 +226,20 @@ export default function Input<KeyType extends string>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
// if (!existingReady) return;
|
||||||
if (typeof props.value !== "string" || !props.value.match(/./)) return;
|
if (typeof props.value !== "string" || !props.value.match(/./)) return;
|
||||||
setValue(String(props.value));
|
setValue(String(props.value));
|
||||||
}, [props.value]);
|
}, [props.value]);
|
||||||
|
|
||||||
|
// React.useEffect(() => {
|
||||||
|
// if (!refreshDefaultValue) return;
|
||||||
|
// console.log("Name:", props.title || props.name);
|
||||||
|
// console.log("props.defaultValue", props.defaultValue);
|
||||||
|
// // setValue(String(props.defaultValue || ""));
|
||||||
|
// }, [refreshDefaultValue]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
// if (!existingReady) return;
|
||||||
if (istextarea && textAreaRef.current) {
|
if (istextarea && textAreaRef.current) {
|
||||||
} else if (inputRef?.current) {
|
} else if (inputRef?.current) {
|
||||||
inputRef.current.value = getFinalValue(value);
|
inputRef.current.value = getFinalValue(value);
|
||||||
@ -452,11 +452,12 @@ export default function Input<KeyType extends string>(
|
|||||||
<NumberInputButtons
|
<NumberInputButtons
|
||||||
setValue={setValue}
|
setValue={setValue}
|
||||||
inputRef={inputRef}
|
inputRef={inputRef}
|
||||||
getNormalizedValue={getNormalizedValue}
|
value={value}
|
||||||
max={props.max}
|
max={props.max}
|
||||||
min={props.min}
|
min={props.min}
|
||||||
step={props.step}
|
step={props.step}
|
||||||
buttonDownRef={buttonDownRef}
|
buttonDownRef={buttonDownRef}
|
||||||
|
decimal={decimal}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user