npm package: @hennge/ui-core
Description: A collection of design tokens and utilities for developing the HENNGE One Design System.
Author: HENNGE
Latest version: 0.3.0

# @hennge/ui-core

[![npm version](https://img.shields.io/npm/v/@hennge/ui-core.svg)](https://www.npmjs.com/package/@hennge/ui-core)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/HENNGE/hennge-ui-react/blob/main/LICENSE)

A collection of design tokens and utilities for developing the HENNGE One Design System. This package provides powerful Tailwind CSS utilities for creating consistent and type-safe UI components.

## Installation

```bash
pnpm add @hennge/ui-core
```

## Features

- Type-safe variant APIs for Tailwind CSS
- Efficient class merging with automatic conflict resolution
- Easy composition of complex class combinations
- Full TypeScript support

## Usage

The package exports three main utilities for working with Tailwind classes:

### tv - Tailwind Variants

`tv` is an alias of `cva` with integrated `tailwind-merge`. It allows you to define component variants with a clean, type-safe API.

```tsx
import { tv } from '@hennge/ui-core';

const button = tv({
  base: "px-4 py-2 rounded font-medium focus:outline-none",
  variants: {
    intent: {
      primary: "bg-blue-500 text-white hover:bg-blue-600",
      secondary: "bg-gray-200 text-gray-800 hover:bg-gray-300"
    },
    size: {
      sm: "text-sm",
      md: "text-base",
      lg: "text-lg"
    }
  },
  defaultVariants: {
    intent: "primary",
    size: "md"
  }
});

// Usage
const className = button({ intent: "secondary", size: "lg" });
// Returns: "px-4 py-2 rounded font-medium focus:outline-none bg-gray-200 text-gray-800 hover:bg-gray-300 text-lg"
```

### tx - Tailwind Class Merger

`tx` is an alias of `clsx` with `tailwind-merge` integration. It allows you to conditionally combine Tailwind classes while automatically resolving conflicts.

```tsx
import { tx } from '@hennge/ui-core';

// Basic concatenation
tx('text-red-500', 'bg-blue-500');
// Returns: "text-red-500 bg-blue-500"

// Conditional classes
tx('text-red-500', isActive && 'font-bold');
// Returns: "text-red-500 font-bold" if isActive is true
// Returns: "text-red-500" if isActive is false

// Conflict resolution
tx('text-red-500', 'text-blue-500');
// Returns: "text-blue-500" (last class wins)

// Objects and arrays
tx('flex', { 'p-4': true, 'hidden': isMobile }, ['rounded', 'shadow']);
// Returns combined classes with proper conflict resolution
```

### compose - Combining Variants

`compose` allows you to combine multiple `tv` variant definitions for more complex components.

```tsx
import { tv, compose } from '@hennge/ui-core';

const baseButton = tv({
  base: "rounded-md focus:outline-none",
  variants: {
    size: {
      sm: "py-1 px-2 text-sm",
      md: "py-2 px-4 text-base",
      lg: "py-3 px-6 text-lg"
    }
  },
  defaultVariants: {
    size: "md"
  }
});

const coloredButton = tv({
  variants: {
    color: {
      blue: "bg-blue-500 hover:bg-blue-600 text-white",
      red: "bg-red-500 hover:bg-red-600 text-white",
      green: "bg-green-500 hover:bg-green-600 text-white"
    }
  },
  defaultVariants: {
    color: "blue"
  }
});

// Combine the variants
const button = compose(baseButton, coloredButton);

// Usage
const className = button({ size: "lg", color: "green" });
// Returns: "rounded-md focus:outline-none py-3 px-6 text-lg bg-green-500 hover:bg-green-600 text-white"
```

## TypeScript Support

All utilities are fully typed, providing autocomplete and type checking for your variants:

```tsx
import { tv, type VariantProps } from '@hennge/ui-core';

const button = tv({
  variants: {
    color: {
      primary: "bg-blue-500",
      secondary: "bg-gray-500"
    }
  }
});

type ButtonVariants = VariantProps<typeof button>;
// Inferred as: { color?: "primary" | "secondary" | undefined }
```

## API Reference

| Function | Description |
|----------|-------------|
| `tv` | Creates variant components with Tailwind classes |
| `tx` | Merges Tailwind classes with automatic conflict resolution |
| `compose` | Combines multiple variant components |

## Development

This section provides instructions on how to develop and maintain the `@hennge/ui-core` package.

### Prerequisites

- Node.js - Install the correct version using fnm:
  ```bash
  fnm install
  ```
  This uses the `.nvmrc` file in the project root to install and use the correct Node.js version.
- pnpm (used by the team for package management)

### Available Scripts

The package provides several pnpm scripts to assist with development, testing, and building:

#### `pnpm dev`

Starts the development mode with file watching enabled. This command runs `tsdown --watch`, which continuously compiles TypeScript files as they are modified, allowing for real-time feedback during development.

```bash
pnpm dev
```

#### `pnpm build`

Builds the package for production. This script runs both `tsdown` to compile TypeScript code and `dtsroll` to generate declaration files.

```bash
pnpm build
```

#### `pnpm typecheck`

Runs the TypeScript compiler (`tsc`) to check for type errors without emitting any output files.

```bash
pnpm typecheck
```

#### `pnpm lint`

Lints the codebase using Biome, ensuring code quality and consistency.

```bash
pnpm lint
```

#### `pnpm dtscheck`

Checks TypeScript declaration files for correctness using `@arethetypeswrong/cli`. This is useful to verify that the package provides accurate type definitions.

```bash
pnpm dtscheck
```

#### `pnpm test`

Runs the test suite using Vitest to verify the functionality of the package.

```bash
pnpm test
```

### Development Workflow

A typical development workflow might look like this:

1. Start the development server with `pnpm dev`
2. Make changes to the source code
3. Verify type correctness with `pnpm typecheck`
4. Run tests with `pnpm test` to ensure functionality
5. Lint your code with `pnpm lint`
6. Build the package with `pnpm build`
7. Verify declaration files with `pnpm dtscheck`
8. Create a tarball for testing with `pnpm pack` to verify the final package contents

## License

Apache-2.0 - see [LICENSE](https://github.com/HENNGE/hennge-ui-react/blob/main/LICENSE) for details.