@douglasneuroinformatics/libui 2.9.3 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"NumberFieldInput.d.ts","sourceRoot":"","sources":["../../../../src/components/Form/NumberField/NumberFieldInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAM1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAC1C,uBAAuB,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,eAAe,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CACjF,CAAC;AAEF,eAAO,MAAM,gBAAgB,6EAU1B,qBAAqB,sBA2BvB,CAAC"}
1
+ {"version":3,"file":"NumberFieldInput.d.ts","sourceRoot":"","sources":["../../../../src/components/Form/NumberField/NumberFieldInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAGhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAM1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAC1C,uBAAuB,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,eAAe,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CACjF,CAAC;AAEF,eAAO,MAAM,gBAAgB,6EAU1B,qBAAqB,sBAqCvB,CAAC"}
@@ -1,22 +1,30 @@
1
- import React from 'react';
1
+ import React, { useRef, useState } from 'react';
2
2
  import { parseNumber } from '@douglasneuroinformatics/libjs';
3
3
  import { Input } from '../../Input/Input.js';
4
4
  import { Label } from '../../Label/Label.js';
5
5
  import { FieldGroup } from '../FieldGroup/FieldGroup.js';
6
6
  export const NumberFieldInput = ({ description, error, label, max = Number.MAX_SAFE_INTEGER, min = Number.MIN_SAFE_INTEGER, name, readOnly, setValue, value }) => {
7
+ const inputValueRef = useRef(value?.toString() ?? '');
8
+ const [inputKey, setInputKey] = useState(0);
7
9
  const handleChange = (event) => {
8
- const newValue = parseNumber(event.target.value);
9
- if (Number.isNaN(newValue)) {
10
- setValue(undefined);
10
+ let newValue = value;
11
+ if (/^[+-]?$/.test(event.target.value)) {
12
+ newValue = undefined;
13
+ inputValueRef.current = event.target.value;
11
14
  }
12
- else if (newValue >= min && newValue <= max) {
13
- setValue(newValue);
15
+ else {
16
+ const parsedValue = parseNumber(event.target.value);
17
+ if (parsedValue >= min && parsedValue <= max) {
18
+ newValue = parsedValue;
19
+ inputValueRef.current = event.target.value;
20
+ }
14
21
  }
22
+ value === newValue ? setInputKey(inputKey + 1) : setValue(newValue);
15
23
  };
16
24
  return (React.createElement(FieldGroup, null,
17
25
  React.createElement(FieldGroup.Row, null,
18
26
  React.createElement(Label, null, label),
19
27
  React.createElement(FieldGroup.Description, { description: description })),
20
- React.createElement(Input, { disabled: readOnly, max: max, min: min, name: name, type: "text", value: value ?? '', onChange: handleChange }),
28
+ React.createElement(Input, { disabled: readOnly, max: max, min: min, name: name, type: "text", value: inputValueRef.current, onChange: handleChange }),
21
29
  React.createElement(FieldGroup.Error, { error: error })));
22
30
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@douglasneuroinformatics/libui",
3
3
  "type": "module",
4
- "version": "2.9.3",
4
+ "version": "2.10.0",
5
5
  "packageManager": "pnpm@9.3.0",
6
6
  "description": "Generic UI components for DNP projects, built using React and Tailwind CSS",
7
7
  "author": "Joshua Unrau",
@@ -362,3 +362,25 @@ export const ReadOnly: StoryObj<typeof Form<ExampleFormSchemaType>> = {
362
362
  validationSchema: $ExampleFormData
363
363
  }
364
364
  };
365
+
366
+ export const WithInitialValue: StoryObj<typeof Form> = {
367
+ args: {
368
+ content: {
369
+ numberInput: {
370
+ kind: 'number',
371
+ label: 'Number Input',
372
+ variant: 'input'
373
+ }
374
+ },
375
+ initialValues: {
376
+ numberInput: 44
377
+ },
378
+ onSubmit: (data) => {
379
+ alert(JSON.stringify(data, null, 2));
380
+ },
381
+ preventResetValuesOnReset: true,
382
+ validationSchema: z.object({
383
+ numberInput: z.number()
384
+ })
385
+ }
386
+ };
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useRef, useState } from 'react';
2
2
 
3
3
  import { parseNumber } from '@douglasneuroinformatics/libjs';
4
4
  import type { NumberFormField } from '@douglasneuroinformatics/libui-form-types';
@@ -25,14 +25,24 @@ export const NumberFieldInput = ({
25
25
  setValue,
26
26
  value
27
27
  }: NumberFieldInputProps) => {
28
+ const inputValueRef = useRef(value?.toString() ?? '');
29
+ const [inputKey, setInputKey] = useState(0);
30
+
28
31
  const handleChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
29
- const newValue = parseNumber(event.target.value);
30
- if (Number.isNaN(newValue)) {
31
- setValue(undefined);
32
- } else if (newValue >= min && newValue <= max) {
33
- setValue(newValue);
32
+ let newValue: number | undefined = value;
33
+ if (/^[+-]?$/.test(event.target.value)) {
34
+ newValue = undefined;
35
+ inputValueRef.current = event.target.value;
36
+ } else {
37
+ const parsedValue = parseNumber(event.target.value);
38
+ if (parsedValue >= min && parsedValue <= max) {
39
+ newValue = parsedValue;
40
+ inputValueRef.current = event.target.value;
41
+ }
34
42
  }
43
+ value === newValue ? setInputKey(inputKey + 1) : setValue(newValue);
35
44
  };
45
+
36
46
  return (
37
47
  <FieldGroup>
38
48
  <FieldGroup.Row>
@@ -45,7 +55,7 @@ export const NumberFieldInput = ({
45
55
  min={min}
46
56
  name={name}
47
57
  type="text"
48
- value={value ?? ''}
58
+ value={inputValueRef.current}
49
59
  onChange={handleChange}
50
60
  />
51
61
  <FieldGroup.Error error={error} />