Getting Started
App Providerglobal.d.tsThemesTypes
cn(...args)Text ParserUnits Converters
AnchorAvatarBreadcrumbBurgerButtonCardCarouselCheckerCodeColor PickerCommandConfettiCopyButtonDouble Helix WordsFloating IndicatorGroupHighlight TextIndicatorInputKbdLabelLoaderPaginationPassword RequirementPolymorphic SlotProgressProseRatingRunning AreaScroll AreaSheetsSkeletonSliderStackSvgTableTabsTextareaTimelineTimesToasterTooltipTyping WordsTypography
useClickOutsideuseClipboarduseDeviceInfouseDialoguseDidUpdateuseDirectionuseDisclosureuseDocumentTitleuseDocumentVisibilityuseElementInfouseEyeDropperuseFetchuseFullscreenuseGeoLocationuseHotkeysuseHoveruseIduseImagePopupuseInputStateuseIntersectionuseIntervaluseIsomorphicEffectuseListStateuseLocalStorageuseMeasureScrollbaruseMediaQueryuseMergedRefuseMouseuseMoveuseMutationObserveruseNetworkuseOpenStateuseOrientationuseOSusePaginationusePWAInstalleruseRandomColorsuseReducedMotionuseReloaduseResizeObserveruseScrollIntoViewuseStateHistoryuseTimeoutuseTouchuseTriggeruseUncontrolleduseValidatedStateuseViewportSizeuseWindowEventuseWindowScroll
Docs
Web
Utilities
Cn
Types

Centralized TypeScript type definitions for consistent type usage across the app.

Text Parser

Text transformation and formatting utilities.


Edit this page on GitHub
  • Started
  • Utilities
  • Configuration
  • Components
  • Hooks
  • Examples
  • Github
  • Contributing
⌘+J

© 2025 oeri rights MIT


Designed in Earth-616

Built by oeri

cn(...args)

A utility function for conditionally combining class names in a readable and maintainable way.

Installation

  • npmjs.com/~khoeriilham
pnpm add xuxi@latest
npm install xuxi@latest
yarn add xuxi@latest
bun add xuxi@latest

Merge with tailwind-merge

import { cnx, type cnxValues } from "xuxi";
import { twMerge } from "tailwind-merge";
 
export function cn(...args: cnxValues[]) {
  // if (!args) return; // optional
  return twMerge(cnx(...args));
}

Usages

import { cn } from "@/utils/cn";
 
<div className={cn("bg-black/60 dark:bg-white/60 font-medium border", { "font-extrabold border-0": true })} />;

API References

  • xuxi
  • mdn

The cnx function is a utility to dynamically combine string class names based on various input types, such as strings, numbers, objects, arrays, or functions.

This function combines various input types and simplifies complex management by producing clean and valid strings.

Useful for dynamically managing string classes in JavaScript or TypeScript applications.

Syntax

function cnx(...args: cnxValues[]): string;
// allows receiving Arrays, Objects and Functions
cnx(['', baz, (foo as string) !== 'foo' && bar], { '': !props }, '', () => ({ '' }), undefined, [{ '' }, () => ({ '' })]);

How cnx works

  1. Initialization: An empty array (classes) is used to store valid strings.

  2. Input Iteration: Each item in the ...args parameter (spread operator) is processed with the following logic:

  • String or Number: Immediately converted to a string and inserted into the array.
  • Array: Processed recursively using cnx(...args) to support nested structures.
  • Object: Iterate over the keys and values ​​(key-value pairs). If the value is "truthy" (e.g., true), the key (class name) is added to the array.
  • Function: The function is called, and the result is processed recursively using cnx.
  • Null, Undefined, or Boolean: Ignored, passed without processing.
  1. Output: The collected classes are combined into a space-separated string.

Example of Usage

cnx("hello", "world");
// Output: "hello world"
 
cnx(() => "there", "dynamic");
// Output: "there dynamic"
 
cnx(["extra", 0, false, "bar"]);
// Output: "extra bar"
 
cnx(Boolean, Object, undefined, null, "", 0, NaN);
// Output: ""
 
cnx("hello", true && "foo", false && "bar");
// Output: "hello foo"
 
cnx(["foo"], ["", 0, false, "bar"], [["baz", [["hello"], "there"]]]);
// Output: "foo bar baz hello there"
 
cnx("foo", [1 && "bar", { baz: false, bat: null }, ["hello", ["world"]]], "cya");
// Output: "foo bar hello world cya"
 
cnx("foo", { primary: true, disabled: false }, ["extra", null, undefined], () => "dynamic");
// Output: "foo primary extra dynamic"
 
cnx([{ color: "red", fontSize: "16px" }, () => ({ backgroundColor: "blue" }), undefined, [{ margin: "10px" }, () => ({ padding: "5px" })]]);
// Output: "color fontSize backgroundColor margin padding"

Advantages

  1. Makes it easier to manage dynamic CSS classes.
  2. Logic wrangling of class merging in code.
  3. Useful in frameworks like React, Vue, or Svelte for changing class conditions.

IntelliSense

If you are using the vscode editor, enable autocomplete for the tailwindcss class using the following command:

  1. Install the Tailwind CSS IntelliSense Visual Studio Code extension
  2. Add to your settings.json:
"tailwindCSS.experimental.classRegex": [
  ["cnx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"],
  ["cn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"],
],
  1. Add config to your .eslintrc.json to eslint-plugin-tailwindcss configuration
{
  "extends": ["prettier", "plugin:tailwindcss/recommended"],
  "plugins": ["tailwindcss"],
  "ignorePatterns": [],
  "rules": {},
  "settings": {
    "tailwindcss": {
      "callees": ["cn", "merge", "twMerge"],
      "config": "tailwind.config.ts"
    }
  },
  "overrides": []
}