diff --git a/package.json b/package.json index ab23dee..3274f59 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,6 @@ "test": "jest && eslint .", "test:coverage": "jest --config jestconfig.coverage.json" }, - "dependencies": { - "lodash": "^4.17.21" - }, "peerDependencies": { "tailwindcss": "^3.0.1" }, diff --git a/src/plugin.js b/src/plugin.js index d9a18ac..5b0964e 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -1,10 +1,10 @@ -const _ = require('lodash') +const { reduce } = require('./util/lodash-fns') const extractGridAreaNames = require('./util/extractGridAreaNames') module.exports = function ({ addUtilities, matchUtilities, theme, variants }) { const gridAreaNames = extractGridAreaNames(theme('gridTemplateAreas')) - const templateAreas = _.reduce( + const templateAreas = reduce( theme('gridTemplateAreas'), (templates, area, name) => { return { diff --git a/src/util/extractGridAreaNames.js b/src/util/extractGridAreaNames.js index 03ca754..1d256aa 100644 --- a/src/util/extractGridAreaNames.js +++ b/src/util/extractGridAreaNames.js @@ -1,11 +1,11 @@ -const _ = require('lodash') +const { uniq, flatMap } = require('./lodash-fns') module.exports = function (gridTemplateAreas) { - return _.uniq( - _.flatMap(gridTemplateAreas, (row) => { - return _.flatMap(row, (area) => { + return uniq( + flatMap(gridTemplateAreas, (row) => { + return flatMap(row, (area) => { // extract grid area names from the gridTemplate - return _.flatMap(area.match(/[^\s]+/g), (match) => { + return flatMap(area.match(/[^\s]+/g), (match) => { if (match !== '.') { return match } diff --git a/src/util/lodash-fns.js b/src/util/lodash-fns.js new file mode 100644 index 0000000..317dea0 --- /dev/null +++ b/src/util/lodash-fns.js @@ -0,0 +1,48 @@ +function reduce(collection, item, initialVal) { + if (!collection) return [] + return Object.keys(collection).reduce( + (carry, current, index, array) => + item( + carry, + !Array.isArray(collection) ? collection[current] : current, + !Array.isArray(collection) ? current : array, + index + ), + initialVal + ) +} + +function baseFlatten(array, depth) { + const result = [] + if (!array) { + return result + } + + for (const value of array) { + if (depth && Array.isArray(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1) + } else { + result.push(...value) + } + } else { + result[result.length] = value + } + } + return result +} + +function flatMap(arr, mapper) { + if (!arr) return [] + return baseFlatten( + Object.keys(arr).map((value, index) => mapper(arr[value], !Array.isArray(arr) ? value : index)), + 1 + ) +} + +function uniq(arr) { + return [...new Set(arr)] +} + +module.exports = { reduce, flatMap, uniq } diff --git a/test/plugin.test.js b/test/plugin.test.js index 7f036b7..2dc74ec 100644 --- a/test/plugin.test.js +++ b/test/plugin.test.js @@ -1,20 +1,41 @@ -import _ from 'lodash' import escapeClassName from 'tailwindcss/lib/util/escapeClassName' import plugin from '../src/plugin' import { expect, test } from '@jest/globals' +function get(object, path, defaultValue) { + let localePath = path + if (typeof path === 'string') { + localePath = path.split('.').map((key) => { + const numKey = Number(key) + return Number.isNaN(numKey) ? key : numKey + }) + } + + let result = object + + for (const key of localePath) { + if (!result) { + return defaultValue + } + + result = result[key] + } + + return result ?? defaultValue +} + test('returns default utilities', () => { const addedUtilities = [] const config = {} - const getConfigValue = (path, defaultValue) => _.get(config, path, defaultValue) + const getConfigValue = (path, defaultValue) => get(config, path, defaultValue) const pluginApi = { config: getConfigValue, e: escapeClassName, theme: (path, defaultValue) => getConfigValue(`theme.${path}`, defaultValue), variants: (path, defaultValue) => { - if (_.isArray(config.variants)) { + if (Array.isArray(config.variants)) { return config.variants } @@ -100,13 +121,13 @@ test('returns all utilities for grid areas', () => { }, } - const getConfigValue = (path, defaultValue) => _.get(config, path, defaultValue) + const getConfigValue = (path, defaultValue) => get(config, path, defaultValue) const pluginApi = { config: getConfigValue, e: escapeClassName, theme: (path, defaultValue) => getConfigValue(`theme.${path}`, defaultValue), variants: (path, defaultValue) => { - if (_.isArray(config.variants)) { + if (Array.isArray(config.variants)) { return config.variants } @@ -200,13 +221,13 @@ test('works for multiple grid templates', () => { }, } - const getConfigValue = (path, defaultValue) => _.get(config, path, defaultValue) + const getConfigValue = (path, defaultValue) => get(config, path, defaultValue) const pluginApi = { config: getConfigValue, e: escapeClassName, theme: (path, defaultValue) => getConfigValue(`theme.${path}`, defaultValue), variants: (path, defaultValue) => { - if (_.isArray(config.variants)) { + if (Array.isArray(config.variants)) { return config.variants } @@ -302,13 +323,13 @@ test('works for more than two rows', () => { }, } - const getConfigValue = (path, defaultValue) => _.get(config, path, defaultValue) + const getConfigValue = (path, defaultValue) => get(config, path, defaultValue) const pluginApi = { config: getConfigValue, e: escapeClassName, theme: (path, defaultValue) => getConfigValue(`theme.${path}`, defaultValue), variants: (path, defaultValue) => { - if (_.isArray(config.variants)) { + if (Array.isArray(config.variants)) { return config.variants }