├── .editorconfig ├── .github ├── dependabot.yml └── workflows │ ├── node.js.yml │ └── release.yml ├── .gitignore ├── .npmignore ├── CONTRIBUTING.md ├── HISTORY.md ├── LICENSE ├── README.md ├── benchmarks ├── benchmarks.js ├── index.html ├── run.js └── runInBrowser.js ├── bind.d.ts ├── bind.js ├── dedupe.d.ts ├── dedupe.js ├── index.d.ts ├── index.js ├── package-lock.json ├── package.json └── tests ├── bind.js ├── bind.test-d.ts ├── dedupe.js ├── dedupe.test-d.ts ├── index.js └── index.test-d.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = false 9 | insert_final_newline = true 10 | indent_style = tab 11 | 12 | [*.json] 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.yml] 17 | indent_style = space 18 | indent_size = 2 19 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: daily 7 | - package-ecosystem: npm 8 | directory: / 9 | rebase-strategy: disabled 10 | versioning-strategy: increase 11 | schedule: 12 | interval: daily 13 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | test: 11 | name: Run tests on supported Node.js versions 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | # See supported Node.js versions at https://nodejs.org/en/about/previous-releases 18 | node-version: [18, 20, 21] 19 | 20 | steps: 21 | - name: Check out repository 22 | uses: actions/checkout@v4 23 | 24 | - name: Set up Node.js 25 | uses: actions/setup-node@v4 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | cache: npm 29 | 30 | - name: Install dependencies 31 | run: npm ci 32 | 33 | - name: Run tests 34 | run: npm test 35 | 36 | check-types: 37 | name: Check type definitions 38 | runs-on: ubuntu-latest 39 | 40 | steps: 41 | - name: Check out repository 42 | uses: actions/checkout@v4 43 | 44 | - name: Set up Node.js 45 | uses: actions/setup-node@v4 46 | with: 47 | node-version: 20 48 | cache: npm 49 | 50 | - name: Install dependencies 51 | run: npm ci 52 | 53 | - name: Check type definitions 54 | run: npm run check-types 55 | 56 | benchmarks: 57 | name: Run benchmarks 58 | runs-on: ubuntu-latest 59 | 60 | steps: 61 | - name: Check out repository 62 | uses: actions/checkout@v4 63 | 64 | - name: Set up Node.js 65 | uses: actions/setup-node@v4 66 | with: 67 | node-version: 20 68 | cache: npm 69 | 70 | - name: Install dependencies 71 | run: npm ci 72 | 73 | - name: Run benchmarks 74 | run: npm run bench 75 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | permissions: 7 | id-token: write 8 | 9 | jobs: 10 | publish: 11 | name: Publish package to NPM 12 | runs-on: ubuntu-latest 13 | environment: release 14 | 15 | steps: 16 | - name: Check out repository 17 | uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | persist-credentials: false 21 | 22 | - name: Set up Node.js 23 | uses: actions/setup-node@v4 24 | with: 25 | node-version: 20 26 | cache: npm 27 | registry-url: https://registry.npmjs.org 28 | 29 | - name: Publish to NPM 30 | run: npm publish 31 | env: 32 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 33 | NPM_CONFIG_PROVENANCE: true 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory 14 | coverage 15 | 16 | # Compiled binary addons (http://nodejs.org/api/addons.html) 17 | build/Release 18 | 19 | # Dependency directory 20 | node_modules 21 | 22 | # Users Environment Variables 23 | .lock-wscript 24 | 25 | # Mac OS X DS_Store 26 | .DS_Store 27 | 28 | benchmarks/runInBrowser.bundle.js 29 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /.*/ 2 | /.* 3 | /benchmarks/ 4 | /tests/ 5 | /CONTRIBUTING.md 6 | /HISTORY.md 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for your interest in classNames. Issues, PRs and suggestions welcome :) 4 | 5 | Before working on a PR, please consider the following: 6 | 7 | * Speed is a serious concern for this package as it is likely to be called a 8 | significant number of times in any project that uses it. As such, new features 9 | will only be accepted if they improve (or at least do not negatively impact) 10 | performance. 11 | * To demonstrate performance differences please set up a 12 | [JSPerf](http://jsperf.com) test and link to it from your issue / PR. 13 | * Tests must be added for any change or new feature before it will be accepted. 14 | 15 | A benchmark utility is included so that changes may be tested against the 16 | current published version. To run the benchmarks, run `npm install` in the 17 | root directory then run `npm run bench`. 18 | 19 | Please be aware though that local benchmarks are just a smoke-signal; they will 20 | run in the v8 version that your local Node.js uses, while classNames is _most_ 21 | often run across a wide variety of browsers and browser versions. 22 | 23 | It is recommended to test possible regressions in performance in all major 24 | browsers. This can be done by running `npm run bench-browser`, the benchmark 25 | will then be served from http://localhost:8080. 26 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v2.5.1 / 2023-12-29 4 | 5 | - Remove `workspaces` field from package ([#350](https://github.com/JedWatson/classnames/pull/350)) 6 | 7 | ## v2.5.0 / 2023-12-27 8 | 9 | - Restore ability to pass a TypeScript `interface` ([#341](https://github.com/JedWatson/classnames/pull/341)) 10 | - Add `exports` field to package ([#342](https://github.com/JedWatson/classnames/pull/342)) 11 | 12 | ## v2.4.0 / 2023-12-26 13 | 14 | - Use string concatenation to increase performance thanks [Jon Koops](https://github.com/jonkoops) ([#336](https://github.com/JedWatson/classnames/pull/336)) 15 | 16 | ## v2.3.3 / 2023-12-21 17 | 18 | - Fix default export, thanks [Remco Haszing](https://github.com/remcohaszing) ([#301](https://github.com/JedWatson/classnames/pull/301)) 19 | - Fix types for read-only arrays, thanks [Ben Thompson](https://github.com/BenGearset) ([#307](https://github.com/JedWatson/classnames/pull/307)) 20 | - Replace README examples with functional-style components, thanks [JoeDGit](https://github.com/JoeDGit) ([#303](https://github.com/JedWatson/classnames/pull/303)) 21 | 22 | ## v2.3.2 / 2022-09-13 23 | 24 | - Fix TypeScript types when using require, thanks [Mark Dalgleish](https://github.com/markdalgleish) ([#276](https://github.com/JedWatson/classnames/pull/276)) 25 | - Fix toString as `[Object object]` in a vm, thanks [Remco Haszing](https://github.com/remcohaszing) ([#281](https://github.com/JedWatson/classnames/pull/281)) 26 | 27 | ## v2.3.1 / 2021-04-03 28 | 29 | - Fix bind/dedupe TypeScript types exports 30 | - Fix mapping Value types, thanks [Remco Haszing](https://github.com/remcohaszing) 31 | - Removed non-existent named exports from types, thanks [Remco Haszing](https://github.com/remcohaszing) 32 | 33 | ## v2.3.0 / 2021-04-01 34 | 35 | - Added TypeScript types 36 | - Added consistent support for custom `.toString()` methods on arguments, thanks [Stanislav Titenko](https://github.com/resetko) 37 | 38 | ## v2.2.6 / 2018-06-08 39 | 40 | - Fixed compatibility issue with usage in an es module environment 41 | 42 | ## v2.2.5 / 2016-05-02 43 | 44 | - Improved performance of `dedupe` variant even further, thanks [Andres Suarez](https://github.com/zertosh) 45 | 46 | ## v2.2.4 / 2016-04-25 47 | 48 | - Improved performance of `dedupe` variant by about 2x, thanks [Bartosz Gościński](https://github.com/bgoscinski) 49 | 50 | ## v2.2.3 / 2016-01-05 51 | 52 | - Updated `bind` variant to use `[].join(' ')` as per the main script in 2.2.2 53 | 54 | ## v2.2.2 / 2016-01-04 55 | 56 | - Switched from string concatenation to `[].join(' ')` for a slight performance gain in the main function. 57 | 58 | ## v2.2.1 / 2015-11-26 59 | 60 | - Add deps parameter to the AMD module, fixes an issue using the Dojo loader, thanks [Chris Jordan](https://github.com/flipperkid) 61 | 62 | ## v2.2.0 / 2015-10-18 63 | 64 | - added a new `bind` variant for use with [css-modules](https://github.com/css-modules/css-modules) and similar abstractions, thanks to [Kirill Yakovenko](https://github.com/blia) 65 | 66 | ## v2.1.5 / 2015-09-30 67 | 68 | - reverted a new usage of `Object.keys` in `dedupe.js` that slipped through in the last release 69 | 70 | ## v2.1.4 / 2015-09-30 71 | 72 | - new case added to benchmarks 73 | - safer `hasOwnProperty` check 74 | - AMD module is now named, so you can do the following: 75 | 76 | ``` 77 | define(["classnames"], function (classNames) { 78 | var style = classNames("foo", "bar"); 79 | // ... 80 | }); 81 | ``` 82 | 83 | ## v2.1.3 / 2015-07-02 84 | 85 | - updated UMD wrapper to support AMD and CommonJS on the same pacge 86 | 87 | ## v2.1.2 / 2015-05-28 88 | 89 | - added a proper UMD wrapper 90 | 91 | ## v2.1.1 / 2015-05-06 92 | 93 | - minor performance improvement thanks to type caching 94 | - improved benchmarking and results output 95 | 96 | ## v2.1.0 / 2015-05-05 97 | 98 | - added alternate `dedupe` version of classNames, which is slower (10x) but ensures that if a class is added then overridden by a falsy value in a subsequent argument, it is excluded from the result. 99 | 100 | ## v2.0.0 / 2015-05-03 101 | 102 | - performance improvement; switched to `Array.isArray` for type detection, which is much faster in modern browsers. A polyfill is now required for IE8 support, see the Readme for details. 103 | 104 | ## v1.2.2 / 2015-04-28 105 | 106 | - license comment updates to simplify certain build scenarios 107 | 108 | ## v1.2.1 / 2015-04-22 109 | 110 | - added safe exporting for requireJS usage 111 | - clarified Bower usage and instructions 112 | 113 | ## v1.2.0 / 2015-03-17 114 | 115 | - added comprehensive support for array arguments, including nested arrays 116 | - simplified code slightly 117 | 118 | ## Previous 119 | 120 | Please see the git history for the details of previous versions. 121 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Jed Watson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Classnames 2 | 3 | > A simple JavaScript utility for conditionally joining classNames together. 4 | 5 |
17 | 18 | Install from the [npm registry](https://www.npmjs.com/) with your package manager: 19 | ```bash 20 | npm install classnames 21 | ``` 22 | 23 | Use with [Node.js](https://nodejs.org/en/), [Browserify](https://browserify.org/), or [webpack](https://webpack.github.io/): 24 | 25 | ```js 26 | const classNames = require('classnames'); 27 | classNames('foo', 'bar'); // => 'foo bar' 28 | ``` 29 | 30 | Alternatively, you can simply include `index.js` on your page with a standalone ` 10 |