mirror of
https://github.com/nicotsx/zerobyte.git
synced 2026-02-07 20:11:16 -05:00
* feat: background doctor operation * refactor(repo-details): design layout * refactor(doctor): support abort signal in all operations * chore: fix linting issue * chore: pr feedbacks * chore: merge conflicts * refactor: handle aborted signal in all operations * chore: pr feedbacks * chore: remove old migration
39 lines
985 B
TypeScript
39 lines
985 B
TypeScript
import { type ClassValue, clsx } from "clsx";
|
|
import { twMerge } from "tailwind-merge";
|
|
|
|
/** Conditional merge of class names */
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
/**
|
|
* Converts an arbitrary string into a URL-safe slug:
|
|
* - lowercase
|
|
* - trims whitespace
|
|
* - replaces non-alphanumeric runs with "-"
|
|
* - collapses multiple hyphens
|
|
* - trims leading/trailing hyphens
|
|
*/
|
|
/**
|
|
* Live slugify for UI: lowercases, normalizes dashes, replaces invalid runs with "-",
|
|
* collapses repeats, but DOES NOT trim leading/trailing hyphens so the user can type
|
|
* spaces/dashes progressively while editing.
|
|
*/
|
|
export function slugify(input: string): string {
|
|
return input
|
|
.toLowerCase()
|
|
.replace(/[ ]/g, "-")
|
|
.replace(/[^a-z0-9_-]+/g, "")
|
|
.replace(/[-]{2,}/g, "-")
|
|
.replace(/[_]{2,}/g, "_")
|
|
.trim();
|
|
}
|
|
|
|
export function safeJsonParse<T>(input: string): T | null {
|
|
try {
|
|
return JSON.parse(input) as T;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|