@rc-component/mini-decimal
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -1,63 +0,6 @@ | ||
export declare type ValueType = string | number; | ||
export interface DecimalClass { | ||
add: (value: ValueType) => DecimalClass; | ||
isEmpty: () => boolean; | ||
isNaN: () => boolean; | ||
isInvalidate: () => boolean; | ||
toNumber: () => number; | ||
/** | ||
* Parse value as string. Will return empty string if `isInvalidate`. | ||
* You can set `safe=false` to get origin string content. | ||
*/ | ||
toString: (safe?: boolean) => string; | ||
equals: (target: DecimalClass) => boolean; | ||
lessEquals: (target: DecimalClass) => boolean; | ||
negate: () => DecimalClass; | ||
} | ||
/** | ||
* We can remove this when IE not support anymore | ||
*/ | ||
export declare class NumberDecimal implements DecimalClass { | ||
origin: string; | ||
number: number; | ||
empty: boolean; | ||
constructor(value: ValueType); | ||
negate(): NumberDecimal; | ||
add(value: ValueType): NumberDecimal; | ||
isEmpty(): boolean; | ||
isNaN(): boolean; | ||
isInvalidate(): boolean; | ||
equals(target: DecimalClass): boolean; | ||
lessEquals(target: DecimalClass): boolean; | ||
toNumber(): number; | ||
toString(safe?: boolean): string; | ||
} | ||
export declare class BigIntDecimal implements DecimalClass { | ||
origin: string; | ||
negative: boolean; | ||
integer: bigint; | ||
decimal: bigint; | ||
/** BigInt will convert `0009` to `9`. We need record the len of decimal */ | ||
decimalLen: number; | ||
empty: boolean; | ||
nan: boolean; | ||
constructor(value: string | number); | ||
private getMark; | ||
private getIntegerStr; | ||
private getDecimalStr; | ||
/** | ||
* Align BigIntDecimal with same decimal length. e.g. 12.3 + 5 = 1230000 | ||
* This is used for add function only. | ||
*/ | ||
private alignDecimal; | ||
negate(): BigIntDecimal; | ||
add(value: ValueType): BigIntDecimal; | ||
isEmpty(): boolean; | ||
isNaN(): boolean; | ||
isInvalidate(): boolean; | ||
equals(target: DecimalClass): boolean; | ||
lessEquals(target: DecimalClass): boolean; | ||
toNumber(): number; | ||
toString(safe?: boolean): string; | ||
} | ||
import BigIntDecimal from './BigIntDecimal'; | ||
import NumberDecimal from './NumberDecimal'; | ||
import type { DecimalClass, ValueType } from './interface'; | ||
export { NumberDecimal, BigIntDecimal }; | ||
export type { DecimalClass, ValueType }; | ||
export default function getMiniDecimal(value: ValueType): DecimalClass; | ||
@@ -64,0 +7,0 @@ /** |
@@ -1,278 +0,10 @@ | ||
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck"; | ||
import _createClass from "@babel/runtime/helpers/esm/createClass"; | ||
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
/* eslint-disable max-classes-per-file */ | ||
/* eslint-disable max-classes-per-file */ | ||
import { getNumberPrecision, isE, num2str, trimNumber, validateNumber } from "./numberUtil"; | ||
import BigIntDecimal from "./BigIntDecimal"; | ||
import NumberDecimal from "./NumberDecimal"; | ||
import { trimNumber } from "./numberUtil"; | ||
import { supportBigInt } from "./supportUtil"; | ||
function isEmpty(value) { | ||
return !value && value !== 0 && !Number.isNaN(value) || !String(value).trim(); | ||
} | ||
/** | ||
* We can remove this when IE not support anymore | ||
*/ | ||
export var NumberDecimal = /*#__PURE__*/function () { | ||
function NumberDecimal(value) { | ||
_classCallCheck(this, NumberDecimal); | ||
_defineProperty(this, "origin", ''); | ||
_defineProperty(this, "number", void 0); | ||
_defineProperty(this, "empty", void 0); | ||
if (isEmpty(value)) { | ||
this.empty = true; | ||
return; | ||
} | ||
this.origin = String(value); | ||
this.number = Number(value); | ||
} | ||
_createClass(NumberDecimal, [{ | ||
key: "negate", | ||
value: function negate() { | ||
return new NumberDecimal(-this.toNumber()); | ||
} | ||
}, { | ||
key: "add", | ||
value: function add(value) { | ||
if (this.isInvalidate()) { | ||
return new NumberDecimal(value); | ||
} | ||
var target = Number(value); | ||
if (Number.isNaN(target)) { | ||
return this; | ||
} | ||
var number = this.number + target; // [Legacy] Back to safe integer | ||
if (number > Number.MAX_SAFE_INTEGER) { | ||
return new NumberDecimal(Number.MAX_SAFE_INTEGER); | ||
} | ||
if (number < Number.MIN_SAFE_INTEGER) { | ||
return new NumberDecimal(Number.MIN_SAFE_INTEGER); | ||
} | ||
var maxPrecision = Math.max(getNumberPrecision(this.number), getNumberPrecision(target)); | ||
return new NumberDecimal(number.toFixed(maxPrecision)); | ||
} | ||
}, { | ||
key: "isEmpty", | ||
value: function isEmpty() { | ||
return this.empty; | ||
} | ||
}, { | ||
key: "isNaN", | ||
value: function isNaN() { | ||
return Number.isNaN(this.number); | ||
} | ||
}, { | ||
key: "isInvalidate", | ||
value: function isInvalidate() { | ||
return this.isEmpty() || this.isNaN(); | ||
} | ||
}, { | ||
key: "equals", | ||
value: function equals(target) { | ||
return this.toNumber() === (target === null || target === void 0 ? void 0 : target.toNumber()); | ||
} | ||
}, { | ||
key: "lessEquals", | ||
value: function lessEquals(target) { | ||
return this.add(target.negate().toString()).toNumber() <= 0; | ||
} | ||
}, { | ||
key: "toNumber", | ||
value: function toNumber() { | ||
return this.number; | ||
} | ||
}, { | ||
key: "toString", | ||
value: function toString() { | ||
var safe = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; | ||
if (!safe) { | ||
return this.origin; | ||
} | ||
if (this.isInvalidate()) { | ||
return ''; | ||
} | ||
return num2str(this.number); | ||
} | ||
}]); | ||
return NumberDecimal; | ||
}(); | ||
export var BigIntDecimal = /*#__PURE__*/function () { | ||
/** BigInt will convert `0009` to `9`. We need record the len of decimal */ | ||
function BigIntDecimal(value) { | ||
_classCallCheck(this, BigIntDecimal); | ||
_defineProperty(this, "origin", ''); | ||
_defineProperty(this, "negative", void 0); | ||
_defineProperty(this, "integer", void 0); | ||
_defineProperty(this, "decimal", void 0); | ||
_defineProperty(this, "decimalLen", void 0); | ||
_defineProperty(this, "empty", void 0); | ||
_defineProperty(this, "nan", void 0); | ||
if (isEmpty(value)) { | ||
this.empty = true; | ||
return; | ||
} | ||
this.origin = String(value); // Act like Number convert | ||
if (value === '-' || Number.isNaN(value)) { | ||
this.nan = true; | ||
return; | ||
} | ||
var mergedValue = value; // We need convert back to Number since it require `toFixed` to handle this | ||
if (isE(mergedValue)) { | ||
mergedValue = Number(mergedValue); | ||
} | ||
mergedValue = typeof mergedValue === 'string' ? mergedValue : num2str(mergedValue); | ||
if (validateNumber(mergedValue)) { | ||
var trimRet = trimNumber(mergedValue); | ||
this.negative = trimRet.negative; | ||
var numbers = trimRet.trimStr.split('.'); | ||
this.integer = BigInt(numbers[0]); | ||
var decimalStr = numbers[1] || '0'; | ||
this.decimal = BigInt(decimalStr); | ||
this.decimalLen = decimalStr.length; | ||
} else { | ||
this.nan = true; | ||
} | ||
} | ||
_createClass(BigIntDecimal, [{ | ||
key: "getMark", | ||
value: function getMark() { | ||
return this.negative ? '-' : ''; | ||
} | ||
}, { | ||
key: "getIntegerStr", | ||
value: function getIntegerStr() { | ||
return this.integer.toString(); | ||
} | ||
}, { | ||
key: "getDecimalStr", | ||
value: function getDecimalStr() { | ||
return this.decimal.toString().padStart(this.decimalLen, '0'); | ||
} | ||
/** | ||
* Align BigIntDecimal with same decimal length. e.g. 12.3 + 5 = 1230000 | ||
* This is used for add function only. | ||
*/ | ||
}, { | ||
key: "alignDecimal", | ||
value: function alignDecimal(decimalLength) { | ||
var str = "".concat(this.getMark()).concat(this.getIntegerStr()).concat(this.getDecimalStr().padEnd(decimalLength, '0')); | ||
return BigInt(str); | ||
} | ||
}, { | ||
key: "negate", | ||
value: function negate() { | ||
var clone = new BigIntDecimal(this.toString()); | ||
clone.negative = !clone.negative; | ||
return clone; | ||
} | ||
}, { | ||
key: "add", | ||
value: function add(value) { | ||
if (this.isInvalidate()) { | ||
return new BigIntDecimal(value); | ||
} | ||
var offset = new BigIntDecimal(value); | ||
if (offset.isInvalidate()) { | ||
return this; | ||
} | ||
var maxDecimalLength = Math.max(this.getDecimalStr().length, offset.getDecimalStr().length); | ||
var myAlignedDecimal = this.alignDecimal(maxDecimalLength); | ||
var offsetAlignedDecimal = offset.alignDecimal(maxDecimalLength); | ||
var valueStr = (myAlignedDecimal + offsetAlignedDecimal).toString(); // We need fill string length back to `maxDecimalLength` to avoid parser failed | ||
var _trimNumber = trimNumber(valueStr), | ||
negativeStr = _trimNumber.negativeStr, | ||
trimStr = _trimNumber.trimStr; | ||
var hydrateValueStr = "".concat(negativeStr).concat(trimStr.padStart(maxDecimalLength + 1, '0')); | ||
return new BigIntDecimal("".concat(hydrateValueStr.slice(0, -maxDecimalLength), ".").concat(hydrateValueStr.slice(-maxDecimalLength))); | ||
} | ||
}, { | ||
key: "isEmpty", | ||
value: function isEmpty() { | ||
return this.empty; | ||
} | ||
}, { | ||
key: "isNaN", | ||
value: function isNaN() { | ||
return this.nan; | ||
} | ||
}, { | ||
key: "isInvalidate", | ||
value: function isInvalidate() { | ||
return this.isEmpty() || this.isNaN(); | ||
} | ||
}, { | ||
key: "equals", | ||
value: function equals(target) { | ||
return this.toString() === (target === null || target === void 0 ? void 0 : target.toString()); | ||
} | ||
}, { | ||
key: "lessEquals", | ||
value: function lessEquals(target) { | ||
return this.add(target.negate().toString()).toNumber() <= 0; | ||
} | ||
}, { | ||
key: "toNumber", | ||
value: function toNumber() { | ||
if (this.isNaN()) { | ||
return NaN; | ||
} | ||
return Number(this.toString()); | ||
} | ||
}, { | ||
key: "toString", | ||
value: function toString() { | ||
var safe = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; | ||
if (!safe) { | ||
return this.origin; | ||
} | ||
if (this.isInvalidate()) { | ||
return ''; | ||
} | ||
return trimNumber("".concat(this.getMark()).concat(this.getIntegerStr(), ".").concat(this.getDecimalStr())).fullStr; | ||
} | ||
}]); | ||
return BigIntDecimal; | ||
}(); | ||
// Still support origin export | ||
export { NumberDecimal, BigIntDecimal }; | ||
export default function getMiniDecimal(value) { | ||
@@ -284,5 +16,5 @@ // We use BigInt here. | ||
} | ||
return new NumberDecimal(value); | ||
} | ||
/** | ||
@@ -292,22 +24,16 @@ * Align the logic of toFixed to around like 1.5 => 2. | ||
*/ | ||
export function toFixed(numStr, separatorStr, precision) { | ||
var cutOnly = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; | ||
if (numStr === '') { | ||
return ''; | ||
} | ||
var _trimNumber2 = trimNumber(numStr), | ||
negativeStr = _trimNumber2.negativeStr, | ||
integerStr = _trimNumber2.integerStr, | ||
decimalStr = _trimNumber2.decimalStr; | ||
var _trimNumber = trimNumber(numStr), | ||
negativeStr = _trimNumber.negativeStr, | ||
integerStr = _trimNumber.integerStr, | ||
decimalStr = _trimNumber.decimalStr; | ||
var precisionDecimalStr = "".concat(separatorStr).concat(decimalStr); | ||
var numberWithoutDecimal = "".concat(negativeStr).concat(integerStr); | ||
if (precision >= 0) { | ||
// We will get last + 1 number to check if need advanced number | ||
var advancedNum = Number(decimalStr[precision]); | ||
if (advancedNum >= 5 && !cutOnly) { | ||
@@ -317,15 +43,11 @@ var advancedDecimal = getMiniDecimal(numStr).add("".concat(negativeStr, "0.").concat('0'.repeat(precision)).concat(10 - advancedNum)); | ||
} | ||
if (precision === 0) { | ||
return numberWithoutDecimal; | ||
} | ||
return "".concat(numberWithoutDecimal).concat(separatorStr).concat(decimalStr.padEnd(precision, '0').slice(0, precision)); | ||
} | ||
if (precisionDecimalStr === '.0') { | ||
return numberWithoutDecimal; | ||
} | ||
return "".concat(numberWithoutDecimal).concat(precisionDecimalStr); | ||
} |
@@ -0,1 +1,3 @@ | ||
import type { ValueType } from './interface'; | ||
export declare function isEmpty(value: ValueType): boolean; | ||
/** | ||
@@ -2,0 +4,0 @@ * Format string number to readable number |
import { supportBigInt } from "./supportUtil"; | ||
export function isEmpty(value) { | ||
return !value && value !== 0 && !Number.isNaN(value) || !String(value).trim(); | ||
} | ||
/** | ||
* Format string number to readable number | ||
*/ | ||
export function trimNumber(numStr) { | ||
var str = numStr.trim(); | ||
var negative = str.startsWith('-'); | ||
if (negative) { | ||
str = str.slice(1); | ||
} | ||
str = str // Remove decimal 0. `1.000` => `1.`, `1.100` => `1.1` | ||
.replace(/(\.\d*[^0])0*$/, '$1') // Remove useless decimal. `1.` => `1` | ||
.replace(/\.0*$/, '') // Remove integer 0. `0001` => `1`, 000.1' => `.1` | ||
str = str | ||
// Remove decimal 0. `1.000` => `1.`, `1.100` => `1.1` | ||
.replace(/(\.\d*[^0])0*$/, '$1') | ||
// Remove useless decimal. `1.` => `1` | ||
.replace(/\.0*$/, '') | ||
// Remove integer 0. `0001` => `1`, 000.1' => `.1` | ||
.replace(/^0+/, ''); | ||
if (str.startsWith('.')) { | ||
str = "0".concat(str); | ||
} | ||
var trimStr = str || '0'; | ||
@@ -27,7 +29,5 @@ var splitNumber = trimStr.split('.'); | ||
var decimalStr = splitNumber[1] || '0'; | ||
if (integerStr === '0' && decimalStr === '0') { | ||
negative = false; | ||
} | ||
var negativeStr = negative ? '-' : ''; | ||
@@ -47,2 +47,3 @@ return { | ||
} | ||
/** | ||
@@ -52,26 +53,20 @@ * [Legacy] Convert 1e-9 to 0.000000001. | ||
*/ | ||
export function getNumberPrecision(number) { | ||
var numStr = String(number); | ||
if (isE(number)) { | ||
var precision = Number(numStr.slice(numStr.indexOf('e-') + 2)); | ||
var decimalMatch = numStr.match(/\.(\d+)/); | ||
if (decimalMatch !== null && decimalMatch !== void 0 && decimalMatch[1]) { | ||
precision += decimalMatch[1].length; | ||
} | ||
return precision; | ||
} | ||
return numStr.includes('.') && validateNumber(numStr) ? numStr.length - numStr.indexOf('.') - 1 : 0; | ||
} | ||
/** | ||
* Convert number (includes scientific notation) to -xxx.yyy format | ||
*/ | ||
export function num2str(number) { | ||
var numStr = String(number); | ||
if (isE(number)) { | ||
@@ -81,10 +76,7 @@ if (number > Number.MAX_SAFE_INTEGER) { | ||
} | ||
if (number < Number.MIN_SAFE_INTEGER) { | ||
return String(supportBigInt() ? BigInt(number).toString() : Number.MIN_SAFE_INTEGER); | ||
} | ||
numStr = number.toFixed(getNumberPrecision(numStr)); | ||
} | ||
return trimNumber(numStr).fullStr; | ||
@@ -95,14 +87,16 @@ } | ||
return !Number.isNaN(num); | ||
} // Empty | ||
} | ||
// Empty | ||
if (!num) { | ||
return false; | ||
} | ||
return (// Normal type: 11.28 | ||
/^\s*-?\d+(\.\d+)?\s*$/.test(num) || // Pre-number: 1. | ||
/^\s*-?\d+\.\s*$/.test(num) || // Post-number: .1 | ||
return ( | ||
// Normal type: 11.28 | ||
/^\s*-?\d+(\.\d+)?\s*$/.test(num) || | ||
// Pre-number: 1. | ||
/^\s*-?\d+\.\s*$/.test(num) || | ||
// Post-number: .1 | ||
/^\s*-?\.\d+\s*$/.test(num) | ||
); | ||
} |
"use strict"; | ||
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -39,5 +38,3 @@ value: true | ||
}); | ||
var _MiniDecimal = _interopRequireWildcard(require("./MiniDecimal")); | ||
Object.keys(_MiniDecimal).forEach(function (key) { | ||
@@ -54,6 +51,4 @@ if (key === "default" || key === "__esModule") return; | ||
}); | ||
var _numberUtil = require("./numberUtil"); | ||
var _default = _MiniDecimal.default; | ||
exports.default = _default; |
@@ -1,63 +0,6 @@ | ||
export declare type ValueType = string | number; | ||
export interface DecimalClass { | ||
add: (value: ValueType) => DecimalClass; | ||
isEmpty: () => boolean; | ||
isNaN: () => boolean; | ||
isInvalidate: () => boolean; | ||
toNumber: () => number; | ||
/** | ||
* Parse value as string. Will return empty string if `isInvalidate`. | ||
* You can set `safe=false` to get origin string content. | ||
*/ | ||
toString: (safe?: boolean) => string; | ||
equals: (target: DecimalClass) => boolean; | ||
lessEquals: (target: DecimalClass) => boolean; | ||
negate: () => DecimalClass; | ||
} | ||
/** | ||
* We can remove this when IE not support anymore | ||
*/ | ||
export declare class NumberDecimal implements DecimalClass { | ||
origin: string; | ||
number: number; | ||
empty: boolean; | ||
constructor(value: ValueType); | ||
negate(): NumberDecimal; | ||
add(value: ValueType): NumberDecimal; | ||
isEmpty(): boolean; | ||
isNaN(): boolean; | ||
isInvalidate(): boolean; | ||
equals(target: DecimalClass): boolean; | ||
lessEquals(target: DecimalClass): boolean; | ||
toNumber(): number; | ||
toString(safe?: boolean): string; | ||
} | ||
export declare class BigIntDecimal implements DecimalClass { | ||
origin: string; | ||
negative: boolean; | ||
integer: bigint; | ||
decimal: bigint; | ||
/** BigInt will convert `0009` to `9`. We need record the len of decimal */ | ||
decimalLen: number; | ||
empty: boolean; | ||
nan: boolean; | ||
constructor(value: string | number); | ||
private getMark; | ||
private getIntegerStr; | ||
private getDecimalStr; | ||
/** | ||
* Align BigIntDecimal with same decimal length. e.g. 12.3 + 5 = 1230000 | ||
* This is used for add function only. | ||
*/ | ||
private alignDecimal; | ||
negate(): BigIntDecimal; | ||
add(value: ValueType): BigIntDecimal; | ||
isEmpty(): boolean; | ||
isNaN(): boolean; | ||
isInvalidate(): boolean; | ||
equals(target: DecimalClass): boolean; | ||
lessEquals(target: DecimalClass): boolean; | ||
toNumber(): number; | ||
toString(safe?: boolean): string; | ||
} | ||
import BigIntDecimal from './BigIntDecimal'; | ||
import NumberDecimal from './NumberDecimal'; | ||
import type { DecimalClass, ValueType } from './interface'; | ||
export { NumberDecimal, BigIntDecimal }; | ||
export type { DecimalClass, ValueType }; | ||
export default function getMiniDecimal(value: ValueType): DecimalClass; | ||
@@ -64,0 +7,0 @@ /** |
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.NumberDecimal = exports.BigIntDecimal = void 0; | ||
Object.defineProperty(exports, "BigIntDecimal", { | ||
enumerable: true, | ||
get: function get() { | ||
return _BigIntDecimal.default; | ||
} | ||
}); | ||
Object.defineProperty(exports, "NumberDecimal", { | ||
enumerable: true, | ||
get: function get() { | ||
return _NumberDecimal.default; | ||
} | ||
}); | ||
exports.default = getMiniDecimal; | ||
exports.toFixed = toFixed; | ||
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); | ||
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); | ||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); | ||
var _BigIntDecimal = _interopRequireDefault(require("./BigIntDecimal")); | ||
var _NumberDecimal = _interopRequireDefault(require("./NumberDecimal")); | ||
var _numberUtil = require("./numberUtil"); | ||
var _supportUtil = require("./supportUtil"); | ||
/* eslint-disable max-classes-per-file */ | ||
function isEmpty(value) { | ||
return !value && value !== 0 && !Number.isNaN(value) || !String(value).trim(); | ||
} | ||
/** | ||
* We can remove this when IE not support anymore | ||
*/ | ||
var NumberDecimal = /*#__PURE__*/function () { | ||
function NumberDecimal(value) { | ||
(0, _classCallCheck2.default)(this, NumberDecimal); | ||
(0, _defineProperty2.default)(this, "origin", ''); | ||
(0, _defineProperty2.default)(this, "number", void 0); | ||
(0, _defineProperty2.default)(this, "empty", void 0); | ||
// Still support origin export | ||
if (isEmpty(value)) { | ||
this.empty = true; | ||
return; | ||
} | ||
this.origin = String(value); | ||
this.number = Number(value); | ||
} | ||
(0, _createClass2.default)(NumberDecimal, [{ | ||
key: "negate", | ||
value: function negate() { | ||
return new NumberDecimal(-this.toNumber()); | ||
} | ||
}, { | ||
key: "add", | ||
value: function add(value) { | ||
if (this.isInvalidate()) { | ||
return new NumberDecimal(value); | ||
} | ||
var target = Number(value); | ||
if (Number.isNaN(target)) { | ||
return this; | ||
} | ||
var number = this.number + target; // [Legacy] Back to safe integer | ||
if (number > Number.MAX_SAFE_INTEGER) { | ||
return new NumberDecimal(Number.MAX_SAFE_INTEGER); | ||
} | ||
if (number < Number.MIN_SAFE_INTEGER) { | ||
return new NumberDecimal(Number.MIN_SAFE_INTEGER); | ||
} | ||
var maxPrecision = Math.max((0, _numberUtil.getNumberPrecision)(this.number), (0, _numberUtil.getNumberPrecision)(target)); | ||
return new NumberDecimal(number.toFixed(maxPrecision)); | ||
} | ||
}, { | ||
key: "isEmpty", | ||
value: function isEmpty() { | ||
return this.empty; | ||
} | ||
}, { | ||
key: "isNaN", | ||
value: function isNaN() { | ||
return Number.isNaN(this.number); | ||
} | ||
}, { | ||
key: "isInvalidate", | ||
value: function isInvalidate() { | ||
return this.isEmpty() || this.isNaN(); | ||
} | ||
}, { | ||
key: "equals", | ||
value: function equals(target) { | ||
return this.toNumber() === (target === null || target === void 0 ? void 0 : target.toNumber()); | ||
} | ||
}, { | ||
key: "lessEquals", | ||
value: function lessEquals(target) { | ||
return this.add(target.negate().toString()).toNumber() <= 0; | ||
} | ||
}, { | ||
key: "toNumber", | ||
value: function toNumber() { | ||
return this.number; | ||
} | ||
}, { | ||
key: "toString", | ||
value: function toString() { | ||
var safe = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; | ||
if (!safe) { | ||
return this.origin; | ||
} | ||
if (this.isInvalidate()) { | ||
return ''; | ||
} | ||
return (0, _numberUtil.num2str)(this.number); | ||
} | ||
}]); | ||
return NumberDecimal; | ||
}(); | ||
exports.NumberDecimal = NumberDecimal; | ||
var BigIntDecimal = /*#__PURE__*/function () { | ||
/** BigInt will convert `0009` to `9`. We need record the len of decimal */ | ||
function BigIntDecimal(value) { | ||
(0, _classCallCheck2.default)(this, BigIntDecimal); | ||
(0, _defineProperty2.default)(this, "origin", ''); | ||
(0, _defineProperty2.default)(this, "negative", void 0); | ||
(0, _defineProperty2.default)(this, "integer", void 0); | ||
(0, _defineProperty2.default)(this, "decimal", void 0); | ||
(0, _defineProperty2.default)(this, "decimalLen", void 0); | ||
(0, _defineProperty2.default)(this, "empty", void 0); | ||
(0, _defineProperty2.default)(this, "nan", void 0); | ||
if (isEmpty(value)) { | ||
this.empty = true; | ||
return; | ||
} | ||
this.origin = String(value); // Act like Number convert | ||
if (value === '-' || Number.isNaN(value)) { | ||
this.nan = true; | ||
return; | ||
} | ||
var mergedValue = value; // We need convert back to Number since it require `toFixed` to handle this | ||
if ((0, _numberUtil.isE)(mergedValue)) { | ||
mergedValue = Number(mergedValue); | ||
} | ||
mergedValue = typeof mergedValue === 'string' ? mergedValue : (0, _numberUtil.num2str)(mergedValue); | ||
if ((0, _numberUtil.validateNumber)(mergedValue)) { | ||
var trimRet = (0, _numberUtil.trimNumber)(mergedValue); | ||
this.negative = trimRet.negative; | ||
var numbers = trimRet.trimStr.split('.'); | ||
this.integer = BigInt(numbers[0]); | ||
var decimalStr = numbers[1] || '0'; | ||
this.decimal = BigInt(decimalStr); | ||
this.decimalLen = decimalStr.length; | ||
} else { | ||
this.nan = true; | ||
} | ||
} | ||
(0, _createClass2.default)(BigIntDecimal, [{ | ||
key: "getMark", | ||
value: function getMark() { | ||
return this.negative ? '-' : ''; | ||
} | ||
}, { | ||
key: "getIntegerStr", | ||
value: function getIntegerStr() { | ||
return this.integer.toString(); | ||
} | ||
}, { | ||
key: "getDecimalStr", | ||
value: function getDecimalStr() { | ||
return this.decimal.toString().padStart(this.decimalLen, '0'); | ||
} | ||
/** | ||
* Align BigIntDecimal with same decimal length. e.g. 12.3 + 5 = 1230000 | ||
* This is used for add function only. | ||
*/ | ||
}, { | ||
key: "alignDecimal", | ||
value: function alignDecimal(decimalLength) { | ||
var str = "".concat(this.getMark()).concat(this.getIntegerStr()).concat(this.getDecimalStr().padEnd(decimalLength, '0')); | ||
return BigInt(str); | ||
} | ||
}, { | ||
key: "negate", | ||
value: function negate() { | ||
var clone = new BigIntDecimal(this.toString()); | ||
clone.negative = !clone.negative; | ||
return clone; | ||
} | ||
}, { | ||
key: "add", | ||
value: function add(value) { | ||
if (this.isInvalidate()) { | ||
return new BigIntDecimal(value); | ||
} | ||
var offset = new BigIntDecimal(value); | ||
if (offset.isInvalidate()) { | ||
return this; | ||
} | ||
var maxDecimalLength = Math.max(this.getDecimalStr().length, offset.getDecimalStr().length); | ||
var myAlignedDecimal = this.alignDecimal(maxDecimalLength); | ||
var offsetAlignedDecimal = offset.alignDecimal(maxDecimalLength); | ||
var valueStr = (myAlignedDecimal + offsetAlignedDecimal).toString(); // We need fill string length back to `maxDecimalLength` to avoid parser failed | ||
var _trimNumber = (0, _numberUtil.trimNumber)(valueStr), | ||
negativeStr = _trimNumber.negativeStr, | ||
trimStr = _trimNumber.trimStr; | ||
var hydrateValueStr = "".concat(negativeStr).concat(trimStr.padStart(maxDecimalLength + 1, '0')); | ||
return new BigIntDecimal("".concat(hydrateValueStr.slice(0, -maxDecimalLength), ".").concat(hydrateValueStr.slice(-maxDecimalLength))); | ||
} | ||
}, { | ||
key: "isEmpty", | ||
value: function isEmpty() { | ||
return this.empty; | ||
} | ||
}, { | ||
key: "isNaN", | ||
value: function isNaN() { | ||
return this.nan; | ||
} | ||
}, { | ||
key: "isInvalidate", | ||
value: function isInvalidate() { | ||
return this.isEmpty() || this.isNaN(); | ||
} | ||
}, { | ||
key: "equals", | ||
value: function equals(target) { | ||
return this.toString() === (target === null || target === void 0 ? void 0 : target.toString()); | ||
} | ||
}, { | ||
key: "lessEquals", | ||
value: function lessEquals(target) { | ||
return this.add(target.negate().toString()).toNumber() <= 0; | ||
} | ||
}, { | ||
key: "toNumber", | ||
value: function toNumber() { | ||
if (this.isNaN()) { | ||
return NaN; | ||
} | ||
return Number(this.toString()); | ||
} | ||
}, { | ||
key: "toString", | ||
value: function toString() { | ||
var safe = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; | ||
if (!safe) { | ||
return this.origin; | ||
} | ||
if (this.isInvalidate()) { | ||
return ''; | ||
} | ||
return (0, _numberUtil.trimNumber)("".concat(this.getMark()).concat(this.getIntegerStr(), ".").concat(this.getDecimalStr())).fullStr; | ||
} | ||
}]); | ||
return BigIntDecimal; | ||
}(); | ||
exports.BigIntDecimal = BigIntDecimal; | ||
function getMiniDecimal(value) { | ||
@@ -290,7 +33,7 @@ // We use BigInt here. | ||
if ((0, _supportUtil.supportBigInt)()) { | ||
return new BigIntDecimal(value); | ||
return new _BigIntDecimal.default(value); | ||
} | ||
return new _NumberDecimal.default(value); | ||
} | ||
return new NumberDecimal(value); | ||
} | ||
/** | ||
@@ -300,23 +43,16 @@ * Align the logic of toFixed to around like 1.5 => 2. | ||
*/ | ||
function toFixed(numStr, separatorStr, precision) { | ||
var cutOnly = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; | ||
if (numStr === '') { | ||
return ''; | ||
} | ||
var _trimNumber2 = (0, _numberUtil.trimNumber)(numStr), | ||
negativeStr = _trimNumber2.negativeStr, | ||
integerStr = _trimNumber2.integerStr, | ||
decimalStr = _trimNumber2.decimalStr; | ||
var _trimNumber = (0, _numberUtil.trimNumber)(numStr), | ||
negativeStr = _trimNumber.negativeStr, | ||
integerStr = _trimNumber.integerStr, | ||
decimalStr = _trimNumber.decimalStr; | ||
var precisionDecimalStr = "".concat(separatorStr).concat(decimalStr); | ||
var numberWithoutDecimal = "".concat(negativeStr).concat(integerStr); | ||
if (precision >= 0) { | ||
// We will get last + 1 number to check if need advanced number | ||
var advancedNum = Number(decimalStr[precision]); | ||
if (advancedNum >= 5 && !cutOnly) { | ||
@@ -326,15 +62,11 @@ var advancedDecimal = getMiniDecimal(numStr).add("".concat(negativeStr, "0.").concat('0'.repeat(precision)).concat(10 - advancedNum)); | ||
} | ||
if (precision === 0) { | ||
return numberWithoutDecimal; | ||
} | ||
return "".concat(numberWithoutDecimal).concat(separatorStr).concat(decimalStr.padEnd(precision, '0').slice(0, precision)); | ||
} | ||
if (precisionDecimalStr === '.0') { | ||
return numberWithoutDecimal; | ||
} | ||
return "".concat(numberWithoutDecimal).concat(precisionDecimalStr); | ||
} |
@@ -0,1 +1,3 @@ | ||
import type { ValueType } from './interface'; | ||
export declare function isEmpty(value: ValueType): boolean; | ||
/** | ||
@@ -2,0 +4,0 @@ * Format string number to readable number |
@@ -8,7 +8,10 @@ "use strict"; | ||
exports.isE = isE; | ||
exports.isEmpty = isEmpty; | ||
exports.num2str = num2str; | ||
exports.trimNumber = trimNumber; | ||
exports.validateNumber = validateNumber; | ||
var _supportUtil = require("./supportUtil"); | ||
function isEmpty(value) { | ||
return !value && value !== 0 && !Number.isNaN(value) || !String(value).trim(); | ||
} | ||
@@ -21,16 +24,15 @@ /** | ||
var negative = str.startsWith('-'); | ||
if (negative) { | ||
str = str.slice(1); | ||
} | ||
str = str // Remove decimal 0. `1.000` => `1.`, `1.100` => `1.1` | ||
.replace(/(\.\d*[^0])0*$/, '$1') // Remove useless decimal. `1.` => `1` | ||
.replace(/\.0*$/, '') // Remove integer 0. `0001` => `1`, 000.1' => `.1` | ||
str = str | ||
// Remove decimal 0. `1.000` => `1.`, `1.100` => `1.1` | ||
.replace(/(\.\d*[^0])0*$/, '$1') | ||
// Remove useless decimal. `1.` => `1` | ||
.replace(/\.0*$/, '') | ||
// Remove integer 0. `0001` => `1`, 000.1' => `.1` | ||
.replace(/^0+/, ''); | ||
if (str.startsWith('.')) { | ||
str = "0".concat(str); | ||
} | ||
var trimStr = str || '0'; | ||
@@ -40,7 +42,5 @@ var splitNumber = trimStr.split('.'); | ||
var decimalStr = splitNumber[1] || '0'; | ||
if (integerStr === '0' && decimalStr === '0') { | ||
negative = false; | ||
} | ||
var negativeStr = negative ? '-' : ''; | ||
@@ -56,3 +56,2 @@ return { | ||
} | ||
function isE(number) { | ||
@@ -62,2 +61,3 @@ var str = String(number); | ||
} | ||
/** | ||
@@ -67,28 +67,20 @@ * [Legacy] Convert 1e-9 to 0.000000001. | ||
*/ | ||
function getNumberPrecision(number) { | ||
var numStr = String(number); | ||
if (isE(number)) { | ||
var precision = Number(numStr.slice(numStr.indexOf('e-') + 2)); | ||
var decimalMatch = numStr.match(/\.(\d+)/); | ||
if (decimalMatch !== null && decimalMatch !== void 0 && decimalMatch[1]) { | ||
precision += decimalMatch[1].length; | ||
} | ||
return precision; | ||
} | ||
return numStr.includes('.') && validateNumber(numStr) ? numStr.length - numStr.indexOf('.') - 1 : 0; | ||
} | ||
/** | ||
* Convert number (includes scientific notation) to -xxx.yyy format | ||
*/ | ||
function num2str(number) { | ||
var numStr = String(number); | ||
if (isE(number)) { | ||
@@ -98,28 +90,26 @@ if (number > Number.MAX_SAFE_INTEGER) { | ||
} | ||
if (number < Number.MIN_SAFE_INTEGER) { | ||
return String((0, _supportUtil.supportBigInt)() ? BigInt(number).toString() : Number.MIN_SAFE_INTEGER); | ||
} | ||
numStr = number.toFixed(getNumberPrecision(numStr)); | ||
} | ||
return trimNumber(numStr).fullStr; | ||
} | ||
function validateNumber(num) { | ||
if (typeof num === 'number') { | ||
return !Number.isNaN(num); | ||
} // Empty | ||
} | ||
// Empty | ||
if (!num) { | ||
return false; | ||
} | ||
return (// Normal type: 11.28 | ||
/^\s*-?\d+(\.\d+)?\s*$/.test(num) || // Pre-number: 1. | ||
/^\s*-?\d+\.\s*$/.test(num) || // Post-number: .1 | ||
return ( | ||
// Normal type: 11.28 | ||
/^\s*-?\d+(\.\d+)?\s*$/.test(num) || | ||
// Pre-number: 1. | ||
/^\s*-?\d+\.\s*$/.test(num) || | ||
// Post-number: .1 | ||
/^\s*-?\.\d+\s*$/.test(num) | ||
); | ||
} |
@@ -7,5 +7,4 @@ "use strict"; | ||
exports.supportBigInt = supportBigInt; | ||
function supportBigInt() { | ||
return typeof BigInt === 'function'; | ||
} |
{ | ||
"name": "@rc-component/mini-decimal", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "Lite lib to only support decimal add calculation", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -1,2 +0,2 @@ | ||
# rc-portal | ||
# @rc-component/mini-decimal | ||
@@ -7,10 +7,10 @@ React 18 supported Portal Component. | ||
[npm-image]: http://img.shields.io/npm/v/rc-portal.svg?style=flat-square | ||
[npm-url]: http://npmjs.org/package/rc-portal | ||
[github-actions-image]: https://github.com/react-component/portal/workflows/CI/badge.svg | ||
[github-actions-url]: https://github.com/react-component/portal/actions | ||
[codecov-image]: https://img.shields.io/codecov/c/github/react-component/portal/master.svg?style=flat-square | ||
[codecov-url]: https://codecov.io/gh/react-component/portal/branch/master | ||
[download-image]: https://img.shields.io/npm/dm/rc-portal.svg?style=flat-square | ||
[download-url]: https://npmjs.org/package/rc-portal | ||
[npm-image]: http://img.shields.io/npm/v/@rc-component/mini-decimal.svg?style=flat-square | ||
[npm-url]: http://npmjs.org/package/@rc-component/mini-decimal | ||
[github-actions-image]: https://github.com/react-component/mini-decimal/workflows/CI/badge.svg | ||
[github-actions-url]: https://github.com/react-component/mini-decimal/actions | ||
[codecov-image]: https://img.shields.io/codecov/c/github/react-component/mini-decimal/master.svg?style=flat-square | ||
[codecov-url]: https://codecov.io/gh/react-component/mini-decimal/branch/master | ||
[download-image]: https://img.shields.io/npm/dm/@rc-component/mini-decimal.svg?style=flat-square | ||
[download-url]: https://npmjs.org/package/@rc-component/mini-decimal | ||
@@ -21,36 +21,3 @@ ## Development | ||
npm install | ||
npm start | ||
open http://localhost:8000 | ||
npm test | ||
``` | ||
## Feature | ||
- React life cycle support portal component | ||
## Install | ||
[![rc-portal](https://nodei.co/npm/rc-portal.png)](https://npmjs.org/package/rc-portal) | ||
## Usage | ||
```js | pure | ||
import Portal from 'rc-portal'; | ||
const Demo = () => { | ||
return <Portal open>Hello World</Portal>; | ||
}; | ||
export default Demo; | ||
``` | ||
## 🔥 API | ||
We use typescript to create the Type definition. You can view directly in IDE. But you can still check the type definition [here](https://github.com/react-component/portal/blob/master/src/interface.ts). | ||
### Portal | ||
| Prop | Description | Type | Default | | ||
| ------------ | ---------------------------------- | ------------------------ | ------------- | | ||
| getContainer | Customize portal container element | Element \| () => Element | document.body | | ||
| open | Show the portal | boolean | false | | ||
| autoLock | Lock screen scroll when open | boolean | false | |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
42927
31
1164
22
1