zent
Version:
一套前端设计语言和基于React的实现
120 lines (110 loc) • 2.59 kB
text/typescript
import Decimal from 'big.js';
import { INumberInputDecimalProps } from './NumberInput';
import { trimLeadingPlus } from './utils';
export const EMPTY_DECIMAL = new Decimal(0);
export function isPotentialValue(value: string) {
return value === '' || value === '.' || value === '-' || value === '+';
}
export function isDecimal(value: string): boolean {
return /^[-+]?\d*\.?\d*$/.test(value);
}
export function getDelta(decimal: number, step?: number): Decimal {
if (Number.isFinite(step)) {
return new Decimal(step);
}
return new Decimal(1).div(Math.pow(10, decimal));
}
function fromPotential(v: number | string | undefined): Decimal | null {
v = String(v);
if (isDecimal(v)) {
return new Decimal(trimLeadingPlus(v));
}
return null;
}
export function normalizeMinMax(props: INumberInputDecimalProps) {
const min = fromPotential(props.min);
const max = fromPotential(props.max);
return {
min,
max,
};
}
export function normalizeValue(
value: string | number | undefined,
min: Decimal | null,
max: Decimal | null,
decimalPlaces: number,
showTooltip?: boolean
): {
input: string;
value: Decimal;
pop?: { visible: boolean; text: string; type: string };
} {
let pop;
if (value === undefined || value === null) {
return {
input: '',
value: EMPTY_DECIMAL,
};
}
value = String(value);
if (isPotentialValue(value) || !isDecimal(value)) {
return {
input: '',
value: EMPTY_DECIMAL,
};
}
if (value === '' || isPotentialValue(value)) {
return {
input: value,
value: EMPTY_DECIMAL,
};
}
let decimal = new Decimal(trimLeadingPlus(value));
if (min !== null) {
if (min.cmp(decimal) === 1) {
decimal = min;
showTooltip &&
(pop = {
visible: true,
text: String(min),
type: 'min',
});
}
}
if (max !== null) {
if (max.cmp(decimal) === -1) {
decimal = max;
showTooltip &&
(pop = {
visible: true,
text: String(max),
type: 'max',
});
}
}
const popState = pop && showTooltip ? { pop } : {};
return {
input: decimal.toFixed(decimalPlaces),
value: decimal,
...popState,
};
}
export function calculateLimit(
value: Decimal,
min: Decimal | null,
max: Decimal | null
): { canInc: boolean; canDec: boolean } {
let canDec = true;
let canInc = true;
if (min !== null) {
canDec = min.cmp(value) === -1;
}
if (max !== null) {
canInc = max.cmp(value) === 1;
}
return {
canDec,
canInc,
};
}