UNPKG

1.93 kBJavaScriptView Raw
1'use strict';
2const lengthConv = new Map([
3 ['in', 96],
4 ['px', 1],
5 ['pt', 4 / 3],
6 ['pc', 16],
7]);
8
9const timeConv = new Map([
10 ['s', 1000],
11 ['ms', 1],
12]);
13
14const angleConv = new Map([
15 ['turn', 360],
16 ['deg', 1],
17]);
18/**
19 * @param {number} number
20 * @return {string}
21 */
22function dropLeadingZero(number) {
23 const value = String(number);
24
25 if (number % 1) {
26 if (value[0] === '0') {
27 return value.slice(1);
28 }
29
30 if (value[0] === '-' && value[1] === '0') {
31 return '-' + value.slice(2);
32 }
33 }
34
35 return value;
36}
37/**
38 * @param {number} number
39 * @param {string} originalUnit
40 * @param {lengthConv | timeConv | angleConv} conversions
41 * @return {string}
42 */
43function transform(number, originalUnit, conversions) {
44 let conversionUnits = [...conversions.keys()].filter((u) => {
45 return originalUnit !== u;
46 });
47
48 const base = number * /** @type {number} */ (conversions.get(originalUnit));
49
50 return conversionUnits
51 .map(
52 (u) =>
53 dropLeadingZero(base / /** @type {number} */ (conversions.get(u))) + u
54 )
55 .reduce((a, b) => (a.length < b.length ? a : b));
56}
57
58/**
59 * @param {number} number
60 * @param {string} unit
61 * @param {{time?: boolean, length?: boolean, angle?: boolean}} options
62 * @return {string}
63 */
64module.exports = function (number, unit, { time, length, angle }) {
65 let value = dropLeadingZero(number) + (unit ? unit : '');
66 let converted;
67 const lowerCaseUnit = unit.toLowerCase();
68 if (length !== false && lengthConv.has(lowerCaseUnit)) {
69 converted = transform(number, lowerCaseUnit, lengthConv);
70 }
71
72 if (time !== false && timeConv.has(lowerCaseUnit)) {
73 converted = transform(number, lowerCaseUnit, timeConv);
74 }
75
76 if (angle !== false && angleConv.has(lowerCaseUnit)) {
77 converted = transform(number, lowerCaseUnit, angleConv);
78 }
79
80 if (converted && converted.length < value.length) {
81 value = converted;
82 }
83
84 return value;
85};