@hennge/ui-core
v0.3.0
Published
A collection of design tokens and utilities for developing the HENNGE One Design System.
Keywords
Readme
@hennge/ui-core
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
pnpm add @hennge/ui-coreFeatures
- 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.
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.
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 resolutioncompose - Combining Variants
compose allows you to combine multiple tv variant definitions for more complex components.
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:
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:
This uses thefnm install.nvmrcfile 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.
pnpm devpnpm build
Builds the package for production. This script runs both tsdown to compile TypeScript code and dtsroll to generate declaration files.
pnpm buildpnpm typecheck
Runs the TypeScript compiler (tsc) to check for type errors without emitting any output files.
pnpm typecheckpnpm lint
Lints the codebase using Biome, ensuring code quality and consistency.
pnpm lintpnpm dtscheck
Checks TypeScript declaration files for correctness using @arethetypeswrong/cli. This is useful to verify that the package provides accurate type definitions.
pnpm dtscheckpnpm test
Runs the test suite using Vitest to verify the functionality of the package.
pnpm testDevelopment Workflow
A typical development workflow might look like this:
- Start the development server with
pnpm dev - Make changes to the source code
- Verify type correctness with
pnpm typecheck - Run tests with
pnpm testto ensure functionality - Lint your code with
pnpm lint - Build the package with
pnpm build - Verify declaration files with
pnpm dtscheck - Create a tarball for testing with
pnpm packto verify the final package contents
License
Apache-2.0 - see LICENSE for details.
