crap
This commit is contained in:
3
src/components/PlusMinusInput/PlusMinusInput.module.css
Normal file
3
src/components/PlusMinusInput/PlusMinusInput.module.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.number-input {
|
||||
width: rem(50);
|
||||
}
|
||||
97
src/components/PlusMinusInput/PlusMinusInput.tsx
Normal file
97
src/components/PlusMinusInput/PlusMinusInput.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import {ActionIcon, Flex, NumberInput, rem} from "@mantine/core";
|
||||
import {IconMinus, IconPlus} from "@tabler/icons-react";
|
||||
import styles from './PlusMinusInput.module.css';
|
||||
import {FC, useEffect, useState} from "react";
|
||||
|
||||
type ControlledValueProps = {
|
||||
value: number;
|
||||
onChange: (value: number) => void;
|
||||
}
|
||||
|
||||
type RestProps = {
|
||||
defaultValue?: number;
|
||||
onChange: (value: number) => void;
|
||||
}
|
||||
|
||||
type Props = RestProps & Partial<ControlledValueProps>;
|
||||
|
||||
const PlusMinusInput: FC<Props> = (props: Props) => {
|
||||
const isControlled = props.value !== undefined;
|
||||
const [internalValue, setInternalValue] = useState(props.defaultValue || 0);
|
||||
|
||||
const value = isControlled ? props.value : internalValue;
|
||||
|
||||
const onMinusClick = () => {
|
||||
|
||||
const newValue = (value || 0) - 1;
|
||||
if (newValue < 0) {
|
||||
return;
|
||||
}
|
||||
if (isControlled) {
|
||||
props.onChange(newValue);
|
||||
} else {
|
||||
setInternalValue(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
const onPlusClick = () => {
|
||||
const newValue = (value || 0) + 1;
|
||||
if (isControlled) {
|
||||
props.onChange(newValue);
|
||||
} else {
|
||||
setInternalValue(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
const handleInputChange = (event: number | string) => {
|
||||
let newValue = typeof event === "string" ? 0 : event;
|
||||
if (isNaN(newValue) || newValue < 0) {
|
||||
newValue = 0;
|
||||
}
|
||||
if (isControlled) {
|
||||
props.onChange(newValue);
|
||||
} else {
|
||||
setInternalValue(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!isControlled) {
|
||||
props.onChange(internalValue);
|
||||
}
|
||||
}, [internalValue]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
align={"center"}
|
||||
gap={rem(10)}
|
||||
>
|
||||
<ActionIcon
|
||||
disabled={value === 0}
|
||||
onClick={onMinusClick}
|
||||
variant={"default"}>
|
||||
<IconMinus/>
|
||||
</ActionIcon>
|
||||
<NumberInput
|
||||
min={0}
|
||||
styles={{
|
||||
input: {
|
||||
textAlign: "center"
|
||||
}
|
||||
}}
|
||||
allowNegative={false}
|
||||
hideControls
|
||||
value={value}
|
||||
className={styles['number-input']}
|
||||
onChange={(event) => handleInputChange(event)}
|
||||
/>
|
||||
<ActionIcon
|
||||
onClick={onPlusClick}
|
||||
variant={"default"}>
|
||||
<IconPlus/>
|
||||
</ActionIcon>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
export default PlusMinusInput;
|
||||
Reference in New Issue
Block a user