diff --git a/.babelrc b/.babelrc index a5fa557..123ff25 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,32 @@ { - "presets": ["env"], - "plugins": ["transform-object-rest-spread"] + "env": { + "test": { + "presets": [ + [ + "env", + { + "targets": { + "node": "current" + } + } + ] + ] + }, + + "production": { + "presets": [ + [ + "env", + { + "targets": { + "browsers": "> 1%, last 2 versions, ie 8" + } + } + ] + ], + "plugins": [ + "babel-plugin-loop-optimizer" + ] + } + } } \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index a840809..635ace1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,14 @@ language: node_js - node_js: - - 7 - 6 - - 5 + - 8 + - 9 install: - npm install script: - - npm test + - npm run build + +after_success: + - npm run cover \ No newline at end of file diff --git a/dist/react-classlist-helper.js b/dist/react-classlist-helper.js index 277444c..f371a74 100644 --- a/dist/react-classlist-helper.js +++ b/dist/react-classlist-helper.js @@ -1,74 +1,169 @@ -'use strict'; +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["reactClasslistHelper"] = factory(); + else + root["reactClasslistHelper"] = factory(); +})(typeof self !== 'undefined' ? self : this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); +exports.tC = exports.cL = undefined; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; -exports.default = classList; +exports.classList = classList; exports.toggleClass = toggleClass; -var _lodash = require('lodash.isboolean'); - -var _lodash2 = _interopRequireDefault(_lodash); - -var _lodash3 = require('lodash.isobjectlike'); - -var _lodash4 = _interopRequireDefault(_lodash3); - -var _lodash5 = require('lodash.isstring'); - -var _lodash6 = _interopRequireDefault(_lodash5); - -var _lodash7 = require('lodash.isundefined'); - -var _lodash8 = _interopRequireDefault(_lodash7); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _assertions = __webpack_require__(1); function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } +/** + * Spred css class names provided as input + * + * @param {Array} args The classe's names. + * @return {string} final className + */ function classList() { - for (var _len = arguments.length, classes = Array(_len), _key = 0; _key < _len; _key++) { - classes[_key] = arguments[_key]; + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; } - if (classes.length === 0) { + if (args.length === 0) { return ''; } var classBuffer = []; - classes.forEach(function (className) { + var _a = args; + + var _f = function _f(className) { if (Array.isArray(className)) { - classBuffer = [].concat(_toConsumableArray(classBuffer), [className.reduce(function (total, classItem) { - return total + ' ' + classItem; + classBuffer = [].concat(_toConsumableArray(classBuffer), [className.reduce(function (total, curItem) { + return total + ' ' + curItem; })]); - } else if ((0, _lodash6.default)(className)) { + } else if ((0, _assertions.isString)(className)) { classBuffer = [].concat(_toConsumableArray(classBuffer), [className]); - } else if ((0, _lodash4.default)(className)) { + } else if ((0, _assertions.isObject)(className)) { var keys = Object.keys(className); - keys.forEach(function (key) { + var _a2 = keys; + + var _f2 = function _f2(key) { if (className[key] === true) { classBuffer = [].concat(_toConsumableArray(classBuffer), [key]); } - }); + }; + + for (var _i2 = 0; _i2 < _a2.length; _i2++) { + _f2(_a2[_i2], _i2, _a2); + } + + undefined; } else { throw new Error('Expected className to be a string but instead got ' + (typeof className === 'undefined' ? 'undefined' : _typeof(className))); } - }); + }; - return classBuffer.join(' '); + for (var _i = 0; _i < _a.length; _i++) { + _f(_a[_i], _i, _a); + } + + undefined; + + return classBuffer.join(' ').trim(); } +/** + * Toggle a class based on a condition. + * + * @param {string} className The class name + * @param {boolean} condition The condition + * @return {string} if condition is true, returns the string, if false, + * returns empty string + */ function toggleClass(className, condition) { - if ((0, _lodash8.default)(className) || !(0, _lodash6.default)(className)) { + if ((0, _assertions.isUndefined)(className) || !(0, _assertions.isString)(className)) { throw new Error('Expected className to be a string but instead got ' + (typeof className === 'undefined' ? 'undefined' : _typeof(className))); } - if ((0, _lodash8.default)(condition) || !(0, _lodash2.default)(condition)) { + if ((0, _assertions.isUndefined)(condition) || !(0, _assertions.isBoolean)(condition)) { throw new Error('Expected condition to be a boolean value but instead got ' + (typeof condition === 'undefined' ? 'undefined' : _typeof(condition))); } @@ -77,3 +172,67 @@ function toggleClass(className, condition) { return classList(ClassMap); } + +var cL = exports.cL = classList; +var tC = exports.tC = toggleClass; + +var defaultFunc = classList; + +exports.default = defaultFunc; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.isBoolean = isBoolean; +exports.isObject = isObject; +exports.isString = isString; +exports.isUndefined = isUndefined; +/** + * + * @param {*} value Any value + * @return {boolean} assertion + */ +function isBoolean(value) { + return typeof value === 'boolean' || (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && value !== null && typeof value.valueOf() === 'boolean'; +} + +/** + * + * @param {*} value Any value + * @return {boolean} assertion + */ +function isObject(value) { + return value !== null && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object'; +} + +/** + * + * @param {*} value Any value + * @return {boolean} assertion + */ +function isString(value) { + return typeof value === 'string' || value instanceof String; +} + +/** + * + * @param {*} value Any value + * @return {boolean} assertion + */ +function isUndefined(value) { + return typeof value === 'undefined'; +} + +/***/ }) +/******/ ]); +}); \ No newline at end of file diff --git a/dist/react-classlist-helper.min.js b/dist/react-classlist-helper.min.js index de53953..16a90d1 100644 --- a/dist/react-classlist-helper.min.js +++ b/dist/react-classlist-helper.min.js @@ -1 +1 @@ -'use strict';var _typeof='function'==typeof Symbol&&'symbol'==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&'function'==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?'symbol':typeof a};Object.defineProperty(exports,'__esModule',{value:!0});exports.default=classList,exports.toggleClass=toggleClass;var _lodash=require('lodash.isboolean'),_lodash2=_interopRequireDefault(_lodash),_lodash3=require('lodash.isobjectlike'),_lodash4=_interopRequireDefault(_lodash3),_lodash5=require('lodash.isstring'),_lodash6=_interopRequireDefault(_lodash5),_lodash7=require('lodash.isundefined'),_lodash8=_interopRequireDefault(_lodash7);function _interopRequireDefault(a){return a&&a.__esModule?a:{default:a}}function _toConsumableArray(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);b { + it('should be all functions and be ok', () => { + expect(isBoolean).to.be.a('function'); + expect(isObject).to.be.a('function'); + expect(isString).to.be.a('function'); + expect(isUndefined).to.be.a('function'); + }); + + it('should verify is a given value is of type boolean', () => { + expect(isBoolean(true)).to.be.true; + expect(isBoolean(false)).to.be.true; + + // eslint-disable-next-line no-new-wrappers + expect(isBoolean(new Boolean())).to.be.true; + + expect(isBoolean('string')).to.be.false; + expect(isBoolean(42)).to.be.false; + expect(isBoolean([])).to.be.false; + expect(isBoolean({})).to.be.false; + }); + + it('should verify if a given value is of type object', () => { + expect(isObject({})).to.be.true; + expect(isObject([])).to.be.true; + + // eslint-disable-next-line no-new-object + expect(isObject(new Object())).to.be.true; + + expect(isObject('string')).to.be.false; + expect(isObject(42)).to.be.false; + expect(isObject(true)).to.be.false; + }); + + it('should verify if a given value is of type string', () => { + expect(isString('hello')).to.be.true; + + // eslint-disable-next-line no-new-wrappers + expect(isString(new String())).to.be.true; + + expect(isString({})).to.be.false; + expect(isString(42)).to.be.false; + expect(isString(true)).to.be.false; + }); + + it('should verify if a given value is of type undefined', () => { + expect(isUndefined(undefined)).to.be.true; + + expect(isUndefined({})).to.be.false; + expect(isUndefined(42)).to.be.false; + expect(isUndefined(true)).to.be.false; + }); +}); diff --git a/src/index.js b/src/index.js index 5fab6a1..f7c93bc 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,9 @@ -import isBoolean from 'lodash.isboolean'; -import isObject from 'lodash.isobjectlike'; -import isString from 'lodash.isstring'; -import isUndefined from 'lodash.isundefined'; - +import { + isBoolean, + isObject, + isString, + isUndefined, +} from './assertions'; /** * Spred css class names provided as input diff --git a/src/index.spec.js b/src/index.spec.js index f75e305..86ad23e 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -1,12 +1,13 @@ +/* eslint-env node,mocha */ import { expect } from 'chai'; import { classList, toggleClass, cL, tC } from './index'; describe('React classList Function', () => { - it('should be defined without any erros', () => { expect(classList).to.be.a('function'); + // eslint-disable-next-line no-unused-expressions expect(classList).to.be.ok; }); @@ -81,7 +82,7 @@ describe('React classList Function', () => { it('should handle empty inputs gracefully', () => { const expectedOutput = ''; const output = classList(); - + expect(output).to.equal(expectedOutput); expect(output).to.be.a('string'); }); @@ -90,9 +91,9 @@ describe('React classList Function', () => { describe('React toggleClass Function', () => { - it('should be defined without any erros', () => { expect(classList).to.be.a('function'); + // eslint-disable-next-line no-unused-expressions expect(classList).to.be.ok; }); @@ -122,23 +123,18 @@ describe('React toggleClass Function', () => { expect(() => toggleClass(2, true)).to.throw(); expect(() => toggleClass('', '')).to.throw(); }); - }); describe('React classList alias', () => { - it('should be defined and be the classList function', () => { expect(cL).to.equal(classList); expect(cL).to.be.a('function'); }); - }); describe('React toggleClass alias', () => { - it('should be defined and be the toggleClass function', () => { expect(tC).to.equal(toggleClass); expect(tC).to.be.a('function'); }); - }); diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..c2addbe --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,53 @@ +const merge = require('webpack-merge'); +const MinifyPlugin = require('babel-minify-webpack-plugin'); +const path = require('path'); +const webpack = require('webpack'); + +function resolve(partial) { + return path.resolve(process.cwd(), partial); +} + +const babelLoader = { + test: /\.js$/, + exclude: /(node_modules|bower_components)/, + use: { + loader: 'babel-loader', + }, +}; + +const base = { + entry: './src/index', + + output: { + path: resolve('dist'), + library: 'reactClasslistHelper', + libraryTarget: 'umd', + }, + + module: { + rules: [ + babelLoader, + ], + }, + + plugins: [ + new webpack.EnvironmentPlugin(['NODE_ENV']), + ], +}; + +module.exports = [ + merge(base, { + output: { + filename: 'react-classlist-helper.js', + }, + }), + merge(base, { + output: { + filename: 'react-classlist-helper.min.js', + }, + + plugins: [ + new MinifyPlugin(), + ], + }), +];