-
Notifications
You must be signed in to change notification settings - Fork 103
Expand file tree
/
Copy pathnumber.component.tsx
More file actions
114 lines (103 loc) · 3.92 KB
/
number.component.tsx
File metadata and controls
114 lines (103 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import React, { useCallback, useMemo, useState } from 'react';
import { Layer, NumberInput } from '@carbon/react';
import classNames from 'classnames';
import { isTrue } from '../../../utils/boolean-utils';
import { shouldUseInlineLayout } from '../../../utils/form-helper';
import FieldValueView from '../../value/view/field-value-view.component';
import { type FormFieldInputProps } from '../../../types';
import styles from './number.scss';
import { useTranslation } from 'react-i18next';
import { useFormProviderContext } from '../../../provider/form-provider';
import FieldLabel from '../../field-label/field-label.component';
import { isEmpty } from '../../../validators/form-validator';
import { Concept } from '@openmrs/esm-framework';
const extractFieldUnitsAndRange = (concept?: Concept): string => {
if (!concept) {
return '';
}
const { hiAbsolute, lowAbsolute, units } = concept;
const displayUnits = units ? ` ${units}` : '';
const hasLowerLimit = lowAbsolute != null;
const hasUpperLimit = hiAbsolute != null;
if (hasLowerLimit && hasUpperLimit) {
return `(${lowAbsolute} - ${hiAbsolute}${displayUnits})`;
} else if (hasUpperLimit) {
return `(<= ${hiAbsolute}${displayUnits})`;
} else if (hasLowerLimit) {
return `(>= ${lowAbsolute}${displayUnits})`;
}
return units ? `(${units})` : '';
};
const NumberField: React.FC<FormFieldInputProps> = ({ field, value, errors, warnings, setFieldValue }) => {
const { t } = useTranslation();
const [lastBlurredValue, setLastBlurredValue] = useState(value);
const { layoutType, sessionMode, workspaceLayout } = useFormProviderContext();
const numberValue = useMemo(() => {
if (isNaN(value)) {
return '';
}
return value ?? '';
}, [value]);
const onBlur = (event) => {
event.preventDefault();
if (lastBlurredValue != value) {
setLastBlurredValue(value);
}
};
const handleChange = useCallback(
(event) => {
const parsedValue = isEmpty(event.target.value) ? undefined : Number(event.target.value);
setFieldValue(isNaN(parsedValue) ? undefined : parsedValue);
},
[setFieldValue],
);
const isInline = useMemo(() => {
if (['view', 'embedded-view'].includes(sessionMode) || isTrue(field.readonly)) {
return shouldUseInlineLayout(field.inlineRendering, layoutType, workspaceLayout, sessionMode);
}
return false;
}, [sessionMode, field.readonly, field.inlineRendering, layoutType, workspaceLayout]);
return sessionMode == 'view' || sessionMode == 'embedded-view' ? (
<div className={styles.formField}>
<FieldValueView
label={t(field.label)}
value={value}
conceptName={field.meta?.concept?.display}
isInline={isInline}
/>
</div>
) : (
!field.isHidden && (
<Layer>
<NumberInput
id={field.id}
invalid={errors.length > 0}
invalidText={errors[0]?.message}
label={<FieldLabel field={field} customLabel={t('{{fieldDescription}} {{unitsAndRange}}',
{
fieldDescription: t(field.label),
unitsAndRange: extractFieldUnitsAndRange(field.meta?.concept),
interpolation: { escapeValue: false }
})}/>}
max={Number(field.questionOptions.max) || undefined}
min={Number(field.questionOptions.min) || undefined}
name={field.id}
value={numberValue}
onChange={handleChange}
onBlur={onBlur}
allowEmpty={true}
size="lg"
hideSteppers={field.hideSteppers ?? false}
onWheel={(e) => e.target.blur()}
disabled={field.isDisabled}
readOnly={isTrue(field.readonly)}
className={classNames(styles.controlWidthConstrained, styles.boldedLabel)}
warn={warnings.length > 0}
warnText={warnings[0]?.message}
step={field.questionOptions.step ?? 0.01}
/>
</Layer>
)
);
};
export default NumberField;