Skip to content

Commit abe01aa

Browse files
committed
Replaced Object.fromEntries with lodash methods to provide compatability older Node.js versions
1 parent 63367cc commit abe01aa

File tree

2 files changed

+103
-83
lines changed

2 files changed

+103
-83
lines changed

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,16 @@
3434
},
3535
"homepage": "https://github.com/semencov/tailwindcss-font-inter",
3636
"peerDependencies": {
37-
"tailwindcss": "~1.1.3"
37+
"tailwindcss": "^1.1.3"
3838
},
3939
"devDependencies": {
4040
"autoprefixer": "^9.6.1",
4141
"fontkit": "^1.8.0",
4242
"node-fetch": "^2.6.0",
4343
"parcel-bundler": "^1.12.4",
4444
"tailwindcss": "^1.1.3"
45+
},
46+
"dependencies": {
47+
"lodash": "^4.17.15"
4548
}
4649
}

src/index.js

Lines changed: 99 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,33 @@
1-
const inter = require('../inter.json');
1+
const { defaults, toPairs, fromPairs, flatMap } = require("lodash");
2+
const inter = require("../inter.json");
23

34
/**
45
* Helpers
56
*/
6-
const isString = val => typeof val === 'string';
7-
const isPlainObject = val => !!val && typeof val === 'object' && val.constructor === Object;
8-
const isArrayLike = obj => obj != null && typeof obj[Symbol.iterator] === 'function';
7+
const isString = val => typeof val === "string";
8+
const isPlainObject = val =>
9+
!!val && typeof val === "object" && val.constructor === Object;
10+
const isArrayLike = obj =>
11+
obj != null && typeof obj[Symbol.iterator] === "function";
912
const isEmpty = val => val == null || !(Object.keys(val) || val).length;
10-
const mapObject = (obj, cb) => Object.fromEntries(Object.entries(obj).map(val => cb(...val)));
11-
const filterObject = (obj, cb) => Object.fromEntries(Object.entries(obj).filter(val => cb(...val)));
13+
const mapObject = (obj, cb) => fromPairs(toPairs(obj).map(val => cb(...val)));
14+
const filterObject = (obj, cb) =>
15+
fromPairs(toPairs(obj).filter(val => cb(...val)));
1216
const round = (num, prec = 3) => parseFloat(num.toFixed(prec));
13-
const unquote = str => str.replace(/^['"]|['"]$/g, '').trim();
17+
const unquote = str => str.replace(/^['"]|['"]$/g, "").trim();
1418

1519
const unitsDefaults = (baseFontSize = 16) => ({
16-
'ch': 8,
17-
'ex': 7.15625,
18-
'em': baseFontSize,
19-
'rem': baseFontSize,
20-
'%': baseFontSize / 100,
21-
'in': 96,
22-
'cm': 96 / 2.54,
23-
'mm': 96 / 25.4,
24-
'pt': 96 / 72,
25-
'pc': 96 / 6,
26-
'px': 1
20+
ch: 8,
21+
ex: 7.15625,
22+
em: baseFontSize,
23+
rem: baseFontSize,
24+
"%": baseFontSize / 100,
25+
in: 96,
26+
cm: 96 / 2.54,
27+
mm: 96 / 25.4,
28+
pt: 96 / 72,
29+
pc: 96 / 6,
30+
px: 1
2731
});
2832

2933
/**
@@ -36,13 +40,10 @@ const unitsDefaults = (baseFontSize = 16) => ({
3640
*/
3741
function parseUnit(value) {
3842
let str = String(value);
39-
return [
40-
parseFloat(str, 10),
41-
str.match(/[\d.\-\+]*\s*(.*)/)[1] || ''
42-
]
43+
return [parseFloat(str, 10), str.match(/[\d.\-\+]*\s*(.*)/)[1] || ""];
4344
}
4445

45-
function getUnitConverter (baseFontSize = 16) {
46+
function getUnitConverter(baseFontSize = 16) {
4647
const defaults = unitsDefaults(baseFontSize);
4748

4849
return function toPX(str) {
@@ -53,11 +54,11 @@ function getUnitConverter (baseFontSize = 16) {
5354

5455
if (!isNaN(value) && unit) {
5556
let px = toPX(unit);
56-
return typeof px === 'number' ? value * px : 0;
57+
return typeof px === "number" ? value * px : 0;
5758
}
5859

5960
return 0;
60-
}
61+
};
6162
}
6263

6364
/**
@@ -95,7 +96,9 @@ function calcTracking(fontSize, a = -0.0223, b = 0.185, c = -0.1745) {
9596
* @return {String}
9697
*/
9798
function fontInterSelector(selector, modifier = null) {
98-
return modifier ? `${modifier} ${selector}, ${selector} ${modifier}, ${modifier}${selector}` : selector;
99+
return modifier
100+
? `${modifier} ${selector}, ${selector} ${modifier}, ${modifier}${selector}`
101+
: selector;
99102
}
100103

101104
/**
@@ -115,75 +118,78 @@ function fontSizeRule(selector, fontSize, lineHeight, { a, b, c }) {
115118
return [
116119
selector,
117120
{
118-
'font-size': typeof fontSize !== 'string' ? `${fontSize}px` : fontSize,
119-
'letter-spacing': `${round(tracking)}em`,
120-
'line-height': `${round(leading)}px`,
121-
},
121+
"font-size": typeof fontSize !== "string" ? `${fontSize}px` : fontSize,
122+
"letter-spacing": `${round(tracking)}em`,
123+
"line-height": `${round(leading)}px`
124+
}
122125
];
123126
}
124127

125128
function normalizeEntry(key, value) {
126-
value = typeof value === 'boolean' ? '' + 1 * value : '' + value;
127-
value = value !== '1' && value !== 'undefined' ? value : '1';
129+
value = typeof value === "boolean" ? "" + 1 * value : "" + value;
130+
value = value !== "1" && value !== "undefined" ? value : "1";
128131

129132
return [unquote(key), value];
130133
}
131134

132-
function generateFeatures(features, availableFeatures, { disableUnusedFeatures = false }) {
135+
function generateFeatures(
136+
features,
137+
availableFeatures,
138+
{ disableUnusedFeatures = false }
139+
) {
133140
let settings = [];
134141

135142
if (!isPlainObject(features)) {
136143
if (isString(features)) {
137-
features = Object.fromEntries(features.split(',').map(f => f.trim().split(' ')));
144+
features = fromPairs(features.split(",").map(f => f.trim().split(" ")));
138145
}
139146

140-
features = Object.fromEntries(
147+
features = fromPairs(
141148
features.map(feature => {
142149
let key, value;
143150

144151
if (isString(feature)) {
145-
[key, value = '1'] = feature.replace(/\s\s+/g, ' ').split(' ', 2);
152+
[key, value = "1"] = feature.replace(/\s\s+/g, " ").split(" ", 2);
146153
} else if (isArrayLike(feature)) {
147-
[key, value = '1'] = feature;
154+
[key, value = "1"] = feature;
148155
} else if (isPlainObject(feature)) {
149-
[key, value = '1'] = Object.entries(feature)[0];
156+
[key, value = "1"] = toPairs(feature)[0];
150157
}
151158

152159
return normalizeEntry(key, value);
153160
})
154161
);
155162
} else {
156-
features = mapObject(features, (key, value = '1') => normalizeEntry(key, value));
163+
features = mapObject(features, (key, value = "1") =>
164+
normalizeEntry(key, value)
165+
);
157166
}
158167

159168
features = filterObject(features, key => availableFeatures.includes(key));
160169

161170
if (!!disableUnusedFeatures) {
162-
let available = Object.fromEntries(availableFeatures.map(val => [val, '0']));
163-
features = Object.assign({}, available, features);
171+
let available = fromPairs(availableFeatures.map(val => [val, "0"]));
172+
features = defaults(features, available);
164173
}
165174

166-
return Object.entries(features)
175+
return toPairs(features)
167176
.map(([key, value]) => `"${key}" ${value}`)
168177
.filter(val => !!val)
169178
.sort()
170-
.join(', ')
179+
.join(", ")
171180
.trim();
172181
}
173182

174183
module.exports = (opts = {}) => {
175-
const options = Object.assign(
176-
{
177-
a: -0.0223,
178-
b: 0.185,
179-
c: -0.1745,
180-
baseFontSize: 16,
181-
baseLineHeight: 1.5, // as in preflight.css
182-
importFontFace: false,
183-
disableUnusedFeatures: false,
184-
},
185-
opts
186-
);
184+
const options = defaults(opts, {
185+
a: -0.0223,
186+
b: 0.185,
187+
c: -0.1745,
188+
baseFontSize: 16,
189+
baseLineHeight: 1.5, // as in preflight.css
190+
importFontFace: false,
191+
disableUnusedFeatures: false
192+
});
187193

188194
return ({ addBase, addUtilities, variants, e, theme }) => {
189195
let { availableFeatures, utilities, base } = inter;
@@ -196,56 +202,67 @@ module.exports = (opts = {}) => {
196202
addUtilities(utilities);
197203

198204
// Add .font-feature-{modier} utility classes
199-
let interFontFeatures = filterObject(theme('interFontFeatures', {}), (key, val) => !isEmpty(val));
200-
let fontFeatures = Object.entries(interFontFeatures).map(([modifier, value]) => {
205+
let interFontFeatures = filterObject(
206+
theme("interFontFeatures", {}),
207+
(key, val) => !isEmpty(val)
208+
);
209+
let fontFeatures = toPairs(interFontFeatures).map(([modifier, value]) => {
201210
let features = generateFeatures(value, availableFeatures, options);
202211
return features.length > 0 ? [modifier, features] : null;
203212
});
204213

205-
let featureRules = Object.fromEntries(
214+
let featureRules = fromPairs(
206215
fontFeatures
207216
.filter(val => !isEmpty(val))
208217
.map(([modifier, value]) => {
209218
return [
210219
fontInterSelector(`.${e(`font-feature-${modifier}`)}`),
211220
{
212-
'font-feature-settings': value,
213-
},
221+
"font-feature-settings": value
222+
}
214223
];
215224
})
216225
);
217226

218227
let featureUtilities = {
219-
'.font-feature-normal': { 'font-feature-settings': 'normal' },
220-
...featureRules,
228+
".font-feature-normal": { "font-feature-settings": "normal" },
229+
...featureRules
221230
};
222231

223-
addUtilities(featureUtilities, variants('interFontFeatures'));
232+
addUtilities(featureUtilities, variants("interFontFeatures"));
224233

225234
// Add .text-inter-{size} utility classes
226235
// Modifiers are inherited from fontSize config
227236
const px = getUnitConverter(options.baseFontSize);
228237

229-
const textSizeUtilities = Object.fromEntries(
230-
Object.entries(theme('fontSize', {}))
231-
.flatMap(([modifier, fontSize]) => {
232-
let size = px(fontSize);
233-
let selector = fontInterSelector(`.${e(`text-inter-${modifier}`)}`);
234-
let baseRule = fontSizeRule(selector, size, options.baseLineHeight, options);
235-
236-
let leadingRules = Object.entries(theme('lineHeight', {}))
237-
.map(([modifier, lineHeight]) => {
238-
let inheritSelector = fontInterSelector(selector, `.${e(`leading-${modifier}`)}`);
239-
return fontSizeRule(inheritSelector, size, lineHeight, options);
240-
});
241-
242-
// TODO: Add modifiers for tailwind's tracking
243-
let trackingRules = [];
244-
245-
return [baseRule, ...leadingRules, ...trackingRules];
246-
})
238+
const textSizeUtilities = fromPairs(
239+
flatMap(toPairs(theme("fontSize", {})), ([modifier, fontSize]) => {
240+
let size = px(fontSize);
241+
let selector = fontInterSelector(`.${e(`text-inter-${modifier}`)}`);
242+
let baseRule = fontSizeRule(
243+
selector,
244+
size,
245+
options.baseLineHeight,
246+
options
247+
);
248+
249+
let leadingRules = toPairs(theme("lineHeight", {})).map(
250+
([modifier, lineHeight]) => {
251+
let inheritSelector = fontInterSelector(
252+
selector,
253+
`.${e(`leading-${modifier}`)}`
254+
);
255+
return fontSizeRule(inheritSelector, size, lineHeight, options);
256+
}
257+
);
258+
259+
// TODO: Add modifiers for tailwind's tracking
260+
let trackingRules = [];
261+
262+
return [baseRule, ...leadingRules, ...trackingRules];
263+
})
247264
);
248265

249-
addUtilities(textSizeUtilities, variants('fontSize'));
266+
addUtilities(textSizeUtilities, variants("fontSize"));
250267
};
251268
};

0 commit comments

Comments
 (0)