Skip to content

Commit d2b629c

Browse files
Add InputNumber to V11 (#8206)
* feat: New Component: InputNumber * feat: add inputnumber demo * feat: updates for useInputNumber hook * feat: Enhancements for InputNumber usage with buttons
1 parent 70f5a2b commit d2b629c

31 files changed

Lines changed: 2211 additions & 0 deletions
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { useInputNumber } from '@primereact/headless/inputnumber';
2+
import type { InputNumberInstance, useInputNumberValueChangeEvent } from '@primereact/types/shared/inputnumber';
3+
import { Button } from 'primereact/button';
4+
import { IconField } from 'primereact/iconfield';
5+
import { InputGroup } from 'primereact/inputgroup';
6+
import { InputNumber } from 'primereact/inputnumber';
7+
import { Label } from 'primereact/label';
8+
import * as React from 'react';
9+
10+
export default function ButtonsDemo() {
11+
const [value1, setValue1] = React.useState(20);
12+
const [value2, setValue2] = React.useState(25);
13+
const [value3, setValue3] = React.useState(10.25);
14+
15+
const inputRef1 = React.useRef<InputNumberInstance>(null);
16+
const inputRef2 = React.useRef<InputNumberInstance>(null);
17+
const inputRef3 = React.useRef<InputNumberInstance>(null);
18+
19+
const inputNumber1 = useInputNumber({
20+
target: inputRef1,
21+
value: value1,
22+
mode: 'currency',
23+
currency: 'USD',
24+
onValueChange: (e: useInputNumberValueChangeEvent) => setValue1(e.value)
25+
});
26+
27+
const inputNumber2 = useInputNumber({
28+
target: inputRef2,
29+
value: value2,
30+
onValueChange: (e: useInputNumberValueChangeEvent) => setValue2(e.value)
31+
});
32+
33+
const inputNumber3 = useInputNumber({
34+
target: inputRef3,
35+
value: value3,
36+
mode: 'currency',
37+
currency: 'EUR',
38+
onValueChange: (e: useInputNumberValueChangeEvent) => setValue3(e.value)
39+
});
40+
41+
return (
42+
<div className="card flex flex-wrap gap-4">
43+
<div className="flex-auto">
44+
<Label htmlFor="stacked-buttons" className="font-bold block mb-2">
45+
Stacked
46+
</Label>
47+
<InputGroup>
48+
<InputNumber ref={inputRef1} value={value1} inputId="stacked-buttons" mode="currency" currency="USD" fluid onValueChange={inputNumber1?.onValueChange} />
49+
<InputGroup.Addon className="flex-col">
50+
<Button severity="secondary" onPointerDown={(e: React.PointerEvent<HTMLButtonElement>) => inputRef1.current?.increment(e, 1)} onPointerUp={inputRef1.current?.stopSpin} className="py-0 text-[.5rem]">
51+
<i className="pi pi-angle-up" />
52+
</Button>
53+
<Button severity="secondary" onPointerDown={(e: React.PointerEvent<HTMLButtonElement>) => inputRef1.current?.decrement(e, -1)} onPointerUp={inputRef1.current?.stopSpin} className="py-0 text-[.5rem]">
54+
<i className="pi pi-angle-down" />
55+
</Button>
56+
</InputGroup.Addon>
57+
</InputGroup>
58+
</div>
59+
60+
<div className="flex-auto">
61+
<Label htmlFor="minmax-buttons" className="font-bold block mb-2">
62+
Min-Max
63+
</Label>
64+
<InputGroup>
65+
<InputGroup.Addon as={Button} severity="secondary" iconOnly disabled={value2 === 100} onPointerDown={(e: React.PointerEvent<HTMLButtonElement>) => inputRef2.current?.increment(e, 1)} onPointerUp={inputRef2.current?.stopSpin}>
66+
<i className="pi pi-plus"></i>
67+
</InputGroup.Addon>
68+
<InputNumber ref={inputRef2} value={value2} inputId="minmax-buttons" fluid min={0} max={100} onValueChange={inputNumber2?.onValueChange} />
69+
<InputGroup.Addon as={Button} severity="secondary" iconOnly disabled={value2 === 0} onPointerDown={(e: React.PointerEvent<HTMLButtonElement>) => inputRef2.current?.decrement(e, -1)} onPointerUp={inputRef2.current?.stopSpin}>
70+
<i className="pi pi-minus"></i>
71+
</InputGroup.Addon>
72+
</InputGroup>
73+
</div>
74+
75+
<div className="flex-auto">
76+
<Label htmlFor="horizontal-buttons" className="font-bold block mb-2">
77+
Horizontal with Step
78+
</Label>
79+
<IconField>
80+
<IconField.Icon onPointerDown={(e: React.PointerEvent<HTMLButtonElement>) => inputRef3.current?.increment(e, 0.25)} onPointerUp={inputRef3.current?.stopSpin}>
81+
<i className="pi pi-plus"></i>
82+
</IconField.Icon>
83+
<InputNumber ref={inputRef3} value={value3} inputId="horizontal-buttons" fluid mode="currency" currency="EUR" onValueChange={inputNumber3?.onValueChange} />
84+
<IconField.Icon onPointerDown={(e: React.PointerEvent<HTMLButtonElement>) => inputRef3.current?.decrement(e, -0.25)} onPointerUp={inputRef3.current?.stopSpin}>
85+
<i className="pi pi-minus"></i>
86+
</IconField.Icon>
87+
</IconField>
88+
</div>
89+
</div>
90+
);
91+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { InputNumber } from 'primereact/inputnumber';
2+
import { Label } from 'primereact/label';
3+
4+
export default function CurrencyDemo() {
5+
return (
6+
<div className="card flex flex-wrap gap-4">
7+
<div className="flex-auto">
8+
<Label htmlFor="currency-us" className="font-bold block mb-2">
9+
United States
10+
</Label>
11+
<InputNumber defaultValue={1500} inputId="currency-us" mode="currency" currency="USD" locale="en-US" fluid />
12+
</div>
13+
<div className="flex-auto">
14+
<Label htmlFor="currency-germany" className="font-bold block mb-2">
15+
Germany
16+
</Label>
17+
<InputNumber defaultValue={2500} inputId="currency-germany" mode="currency" currency="EUR" locale="de-DE" fluid />
18+
</div>
19+
<div className="flex-auto">
20+
<Label htmlFor="currency-india" className="font-bold block mb-2">
21+
India
22+
</Label>
23+
<InputNumber defaultValue={4250} inputId="currency-india" mode="currency" currency="INR" currencyDisplay="code" locale="en-IN" fluid />
24+
</div>
25+
<div className="flex-auto">
26+
<Label htmlFor="currency-japan" className="font-bold block mb-2">
27+
Japan
28+
</Label>
29+
<InputNumber defaultValue={5002} inputId="currency-japan" mode="currency" currency="JPY" locale="jp-JP" fluid />
30+
</div>
31+
</div>
32+
);
33+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { InputNumber } from 'primereact/inputnumber';
2+
3+
export default function DisabledDemo() {
4+
return (
5+
<div className="card flex justify-center">
6+
<InputNumber defaultValue={50} disabled prefix="%" />
7+
</div>
8+
);
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { InputNumber } from 'primereact/inputnumber';
2+
3+
export default function FilledDemo() {
4+
return (
5+
<div className="card flex justify-center">
6+
<InputNumber variant="filled" />
7+
</div>
8+
);
9+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { InputNumberValueChangeEvent } from '@primereact/types/shared/inputnumber';
2+
import { InputNumber } from 'primereact/inputnumber';
3+
import { Label } from 'primereact/label';
4+
import * as React from 'react';
5+
6+
export default function FloatLabelDemo() {
7+
const [value1, setValue1] = React.useState<number | null>(null);
8+
const [value2, setValue2] = React.useState<number | null>(null);
9+
const [value3, setValue3] = React.useState<number | null>(null);
10+
11+
return (
12+
<div className="card flex flex-wrap justify-center items-end gap-4">
13+
<Label.Float>
14+
<InputNumber value={value1} onValueChange={(e: InputNumberValueChangeEvent) => setValue1(e.value)} inputId="over_label" mode="currency" currency="USD" locale="en-US" />
15+
<Label htmlFor="over_label">Over Label</Label>
16+
</Label.Float>
17+
18+
<Label.Float variant="in">
19+
<InputNumber value={value2} onValueChange={(e: InputNumberValueChangeEvent) => setValue2(e.value)} inputId="in_label" mode="currency" currency="USD" locale="en-US" variant="filled" />
20+
<Label htmlFor="in_label">In Label</Label>
21+
</Label.Float>
22+
23+
<Label.Float variant="on">
24+
<InputNumber value={value3} onValueChange={(e: InputNumberValueChangeEvent) => setValue3(e.value)} inputId="on_label" mode="currency" currency="USD" locale="en-US" />
25+
<Label htmlFor="on_label">On Label</Label>
26+
</Label.Float>
27+
</div>
28+
);
29+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { InputNumber } from 'primereact/inputnumber';
2+
import { Label } from 'primereact/label';
3+
4+
export default function IftaLabelDemo() {
5+
return (
6+
<div className="card flex justify-center">
7+
<Label.Ifta>
8+
<InputNumber defaultValue={1} inputId="price_input" mode="currency" currency="USD" locale="en-US" variant="filled" />
9+
<Label htmlFor="price_input">Price</Label>
10+
</Label.Ifta>
11+
</div>
12+
);
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { InputNumber } from 'primereact/inputnumber';
2+
3+
export default function InputNumberPTDemo() {
4+
return <InputNumber defaultValue={50}></InputNumber>;
5+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { InputNumberValueChangeEvent } from '@primereact/types/shared/inputnumber';
2+
import { InputNumber } from 'primereact/inputnumber';
3+
import * as React from 'react';
4+
5+
export default function InvalidDemo() {
6+
const [value1, setValue1] = React.useState<number | null>(null);
7+
const [value2, setValue2] = React.useState<number | null>(null);
8+
9+
return (
10+
<div className="card flex flex-wrap justify-center gap-4">
11+
<InputNumber value={value1} onValueChange={(e: InputNumberValueChangeEvent) => setValue1(e.value)} invalid={value1 === null} mode="decimal" minFractionDigits={2} placeholder="Amount" />
12+
<InputNumber value={value2} onValueChange={(e: InputNumberValueChangeEvent) => setValue2(e.value)} invalid={value2 === null} mode="decimal" minFractionDigits={2} variant="filled" placeholder="Amount" />
13+
</div>
14+
);
15+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { InputNumber } from 'primereact/inputnumber';
2+
import { Label } from 'primereact/label';
3+
4+
export default function LocaleDemo() {
5+
return (
6+
<div className="card flex flex-wrap gap-4">
7+
<div className="flex-auto">
8+
<Label htmlFor="locale-user" className="font-bold block mb-2">
9+
User Locale
10+
</Label>
11+
<InputNumber defaultValue={151351} inputId="locale-user" minFractionDigits={2} fluid />
12+
</div>
13+
<div className="flex-auto">
14+
<Label htmlFor="locale-us" className="font-bold block mb-2">
15+
United States Locale
16+
</Label>
17+
<InputNumber defaultValue={115744} inputId="locale-us" locale="en-US" minFractionDigits={2} fluid />
18+
</div>
19+
<div className="flex-auto">
20+
<Label htmlFor="locale-german" className="font-bold block mb-2">
21+
German Locale
22+
</Label>
23+
<InputNumber defaultValue={635524} inputId="locale-german" locale="de-DE" minFractionDigits={2} fluid />
24+
</div>
25+
<div className="flex-auto">
26+
<Label htmlFor="locale-indian" className="font-bold block mb-2">
27+
Indian Locale
28+
</Label>
29+
<InputNumber defaultValue={732762} inputId="locale-indian" locale="en-IN" minFractionDigits={2} fluid />
30+
</div>
31+
</div>
32+
);
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { InputNumber } from 'primereact/inputnumber';
2+
import { Label } from 'primereact/label';
3+
4+
export default function NumeralsDemo() {
5+
return (
6+
<div className="card flex flex-wrap gap-4">
7+
<div className="flex-auto">
8+
<Label htmlFor="integeronly" className="font-bold block mb-2">
9+
Integer Only
10+
</Label>
11+
<InputNumber defaultValue={42723} inputId="integeronly" fluid />
12+
</div>
13+
<div className="flex-auto">
14+
<Label htmlFor="withoutgrouping" className="font-bold block mb-2">
15+
Without Grouping
16+
</Label>
17+
<InputNumber defaultValue={58151} inputId="withoutgrouping" useGrouping={false} fluid />
18+
</div>
19+
<div className="flex-auto">
20+
<Label htmlFor="minmaxfraction" className="font-bold block mb-2">
21+
Min-Max Fraction Digits
22+
</Label>
23+
<InputNumber defaultValue={2351.35} inputId="minmaxfraction" minFractionDigits={2} maxFractionDigits={5} fluid />
24+
</div>
25+
<div className="flex-auto">
26+
<Label htmlFor="minmax" className="font-bold block mb-2">
27+
Min-Max Boundaries
28+
</Label>
29+
<InputNumber defaultValue={50} inputId="minmax" min={0} max={100} fluid />
30+
</div>
31+
</div>
32+
);
33+
}

0 commit comments

Comments
 (0)