Utilities
Class merging, slugs, the link contract for a host's router, and the code highlighter.
The small functions and types active-ui uses itself, exported for your own components.
slugify: s-hertogenbosch-cafe
cn('px-2 py-1', 'px-4') = 'py-1 px-4'
// apps/docs/examples/ui/utilities.tsx'use client';
import {useState} from 'react';
import { Field, FieldDescription, FieldLabel,} from '@workspace/active-ui/components/primitives/field';import {Input} from '@workspace/active-ui/components/primitives/input';import {cn, slugify} from '@workspace/active-ui/lib/utils';
/** * `slugify` turns a display string into a URL-safe slug; `cn` merges * classes so that a later Tailwind class wins over a conflicting one. */export default function UtilitiesExample() { const [name, setName] = useState("'s-Hertogenbosch Café"); return ( <div className="grid w-full max-w-sm gap-6"> <Field> <FieldLabel htmlFor="slug-source">Name</FieldLabel> <Input id="slug-source" value={name} onChange={(event) => setName(event.target.value)} /> <FieldDescription> <code>slugify</code>: <code>{slugify(name) || "''"}</code> </FieldDescription> </Field> <p className="text-sm"> <code>cn('px-2 py-1', 'px-4')</code> ={' '} <code>'{cn('px-2 py-1', 'px-4')}'</code> </p> </div> );}What is here#
cn(...): merges class names, clsx-style arguments included, and resolves Tailwind conflicts so the later class wins:cn('px-is2 py- 1', 'px- 4') 'py-. Every component of the package uses it for its1 px- 4' class.Name slugify(value): a URL-safe slug, lower case, without diacritics, at most 80 characters. For ids and URL segments, not for security.LinkandComponent Link: the contract for your router's link. A component that renders a link, such as StatCard, takes it asComponent Props linkand passes onlyComponent href,classandName children; without it a plain<a>is used.loadandHighlighter(language) highlight: the Shiki highlighter behind CodeBlock andCode(code, language) use. Shiki and each language load on first use. The languages areHighlighted Code bash,css,diff,html,javascript,json,jsx,markdown,python,sql,tsx,typescriptandyaml, with the aliasesjs,md,py,sh,shell,ts,ymlandzsh; another language stays plain. The themes reach AA contrast for every token in light and dark.
Usage#
import {highlightCode} from '@workspace/active-ui/lib/highlighter';import {cn, slugify} from '@workspace/active-ui/lib/utils';
const lines = await highlightCode(source, 'ts'); // in a server componentAPI#
Functions, hooks and constants
- Type
CnFunction
Merge Tailwind CSS classes with clsx-style arguments (strings, arrays, objects, conditionals). Drop-in replacement for tw.
- Type
(value: string) => string
Convert an arbitrary display-string into a URL-safe slug.
Lower-cases, strips diacritics via NFD-decomposition, replaces any run of non-alphanumeric characters with a single hyphen, trims leading/trailing hyphens, and caps length at 80 characters.
Intended for IDs, slugs, and URL-segments derived from human-readable text — not for security-critical identifiers (no collision-resistance guarantee for similar inputs).
Types
What a host link component receives from a component of this package that renders a link: the destination, the component's class for the link and its content. Nothing else is passed.
The same three props as the grid's Grid in active-grid, so one host link serves both.
interface LinkComponentProps {
href: string;
className?: string;
children: ReactNode;
}A host's own link, for example a router link such as next/, so that navigation stays client-side. Without one a component renders a plain <a href> and the browser navigates. Passed per instance as the link prop of Stat and Dashboard.
type LinkComponent = ComponentType<LinkComponentProps>;Functions, hooks and constants
Loads a language and returns a highlighter for it, or null for a language that is not listed. Shiki and each language load on first use.
(language: string) => Promise<{ highlight(code: string, state?: GrammarState): { lines: DetailedReactHTMLElement<{ key: number; style: CSSProperties; className: string; }, HTMLElement>[][]; state: GrammarState | undefined; }; } | null>Highlights code once, for a server component or a build step: one React node per line, with a light and a dark colour per token, or null for a language that is not listed.
(code: string, language: string) => Promise<DetailedReactHTMLElement<{ key: number; style: CSSProperties; className: string; }, HTMLElement>[][] | null>