@linzjs/step-ag-grid
Version:
[](https://github.com/semantic-release/semantic-release) > Reusable [ag-grid](https://www.ag-grid.com/) component for LINZ / Toitū te whenua.
84 lines (77 loc) • 2.59 kB
text/typescript
import { ReactElement } from 'react';
import { GridBaseRow } from '../components/Grid';
import { isFloat, stringByteLengthIsInvalid } from './util';
export interface TextInputValidatorProps<TData extends GridBaseRow> {
required?: boolean;
maxLength?: number;
maxBytes?: number;
invalid?: (value: string, data: TData, context: any) => ReactElement | string | null;
numberFormat?: {
precision?: number;
scale?: number;
gtMin?: number;
geMin?: number;
ltMax?: number;
leMax?: number;
notZero?: boolean;
};
}
export const TextInputValidator = <TData extends GridBaseRow>(
props: TextInputValidatorProps<TData>,
value: string | null,
data: TData,
context: any,
) => {
if (value == null) return null;
// This can happen because subcomponent is invoked without type safety
if (typeof value !== 'string') {
return 'Value is not a string';
}
if (props.required && value.trim() == '') {
return 'Must not be empty';
}
if (props.maxLength && value.length > props.maxLength) {
return `Must be no longer than ${props.maxLength} characters`;
}
if (props.maxBytes && stringByteLengthIsInvalid(value, props.maxBytes)) {
return `Must be no longer than ${props.maxBytes} bytes`;
}
const nf = props.numberFormat;
if (nf) {
if (value != '' && !isFloat(value)) {
return `Must be a valid number`;
}
if (value != '') {
const number = parseFloat(value);
if (nf.notZero && number === 0) {
return `Must not be 0`;
}
if (nf.gtMin != null && number <= nf.gtMin) {
return `Must be greater than ${nf.gtMin.toLocaleString()}`;
}
if (nf.geMin != null && number < nf.geMin) {
return `Must not be less than ${nf.geMin.toLocaleString()}`;
}
if (nf.ltMax != null && number >= nf.ltMax) {
return `Must be less than ${nf.ltMax.toLocaleString()}`;
}
if (nf.leMax != null && number > nf.leMax) {
return `Must not be greater than ${nf.leMax.toLocaleString()}`;
}
if (nf.precision != null && value != '') {
if (parseFloat(number.toPrecision(nf.precision)) != number) {
return `Must have no more than ${nf.precision} digits precision`;
}
}
if (nf.scale != null && value != '') {
if (parseFloat(number.toFixed(nf.scale)) != number) {
return nf.scale == 0 ? `Must be a whole number` : `Must have no more than ${nf.scale} decimal places`;
}
}
}
}
if (props.invalid) {
return props.invalid(value, data, context);
}
return null;
};