feat(shared/lib): add cn utility (clsx + tailwind-merge)
This commit is contained in:
@@ -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
16
src/shared/lib/cn.test.ts
Normal 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
7
src/shared/lib/cn.ts
Normal 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));
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export * from './api';
|
||||
export { cn } from './cn';
|
||||
|
||||
34
vitest.unit.config.ts
Normal file
34
vitest.unit.config.ts
Normal 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"),
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user