feat(shared/lib): add cn utility (clsx + tailwind-merge)

This commit is contained in:
Ilia Mashkov
2026-03-06 23:10:52 +03:00
parent a57fea4590
commit 53b9a8bf7a
5 changed files with 62 additions and 0 deletions

View File

@@ -52,5 +52,9 @@
"@storybook/addon-docs": "^10.2.16",
"playwright": "^1.58.2",
"@vitest/browser-playwright": "^4.0.18"
},
"dependencies": {
"clsx": "^2.1.1",
"tailwind-merge": "^3.5.0"
}
}

16
src/shared/lib/cn.test.ts Normal file
View File

@@ -0,0 +1,16 @@
import { describe, expect, it } from 'vitest';
import { cn } from './cn';
describe('cn', () => {
it('merges class strings', () => {
expect(cn('foo', 'bar')).toBe('foo bar');
});
it('deduplicates conflicting Tailwind classes (last wins)', () => {
expect(cn('p-4', 'p-8')).toBe('p-8');
});
it('ignores falsy values', () => {
expect(cn('foo', false, undefined, null, 'bar')).toBe('foo bar');
});
});

7
src/shared/lib/cn.ts Normal file
View File

@@ -0,0 +1,7 @@
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
/** Merge Tailwind classes without conflicts. Later classes win on collision. */
export function cn(...inputs: ClassValue[]): string {
return twMerge(clsx(inputs));
}

View File

@@ -1 +1,2 @@
export * from './api';
export { cn } from './cn';

34
vitest.unit.config.ts Normal file
View File

@@ -0,0 +1,34 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { svelte } from "@sveltejs/vite-plugin-svelte";
import { defineConfig } from "vitest/config";
const dirname =
typeof __dirname !== "undefined"
? __dirname
: path.dirname(fileURLToPath(import.meta.url));
export default defineConfig({
plugins: [
svelte({
hot: !process.env.VITEST,
}),
],
test: {
globals: true,
environment: "jsdom",
setupFiles: ["./src/tests/setup.ts"],
include: ["src/**/*.{test,spec}.{js,ts}"],
exclude: ["src/tests/e2e/**/*.{test,spec}.{js,ts}"],
},
resolve: {
alias: {
$lib: path.resolve("./src/lib"),
$shared: path.resolve("./src/shared"),
$pages: path.resolve("./src/pages"),
$features: path.resolve("./src/features"),
$entities: path.resolve("./src/entities"),
$widgets: path.resolve("./src/widgets"),
},
},
});