Componenteditors0.92 KB gzipZero dependencies
Regex Visualizer
Match highlighter with validity flag.
Preview
Live Preview
Regex visualizer
ROW C SEAT 12, ROW D SEAT 04
Installation
Tokens guide →Add to your project via CLI (zero dependencies, code you own):
npx bigbullui add regex-visualizerOr install the full npm package:
npm install bigbulluiUsage
Open in StackBlitzimport { RegexVisualizer } from "@/components/ui/regex-visualizer";
<RegexVisualizer />Usage guidance
Use Regex Visualizer when a ticket stub surface needs Match highlighter with validity flag. Keep props minimal and prefer composition with sibling stubs.
Avoid Regex Visualizer for long form flows or dense data grids where a dedicated layout block fits better.
Source code
regex-visualizer.tsxZero dependencies (only React + utils). Copy and paste directly into your project:
"use client";
import * as React from "react";
import { cn } from "./lib/utils";
export interface RegexVisualizerProps extends React.HTMLAttributes<HTMLDivElement> {
defaultPattern?: string;
defaultSample?: string;
}
/** Regex match highlighter with group readout. */
export function RegexVisualizer({ defaultPattern = "ROW [A-Z]", defaultSample = "ROW C SEAT 12, ROW D SEAT 04", className, ...props }: RegexVisualizerProps) {
const [pattern, setPattern] = React.useState(defaultPattern);
const [sample, setSample] = React.useState(defaultSample);
const parts = React.useMemo(() => {
try {
const re = new RegExp(`(${pattern})`, "g");
return sample.split(re);
} catch {
return [sample];
}
}, [pattern, sample]);
let valid = true;
try {
new RegExp(pattern);
} catch {
valid = false;
}
return (
<div className={cn("w-full rounded-lg border-2 border-foreground bg-card p-4 shadow-md", className)} {...props}>
<p className="font-mono text-[10px] font-bold uppercase tracking-widest text-muted-foreground">Regex visualizer</p>
<input value={pattern} onChange={(e) => setPattern(e.target.value)} spellCheck={false} aria-label="Regex pattern" className={cn("mt-2 w-full rounded-md border border-dashed bg-secondary/40 p-2 font-mono text-sm text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring", valid ? "border-border" : "border-destructive")} />
<textarea value={sample} onChange={(e) => setSample(e.target.value)} rows={2} aria-label="Sample text" className="mt-2 w-full resize-none rounded-md border border-dashed border-border bg-secondary/40 p-2 font-mono text-xs text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring" />
<p className="mt-2 rounded-md border border-border bg-background p-2 font-mono text-xs leading-relaxed text-foreground" aria-live="polite">
{parts.map((p, i) =>
i % 2 === 1 ? <mark key={i} className="rounded bg-accent px-0.5 text-accent-foreground">{p}</mark> : <span key={i}>{p}</span>
)}
</p>
{!valid && <p className="mt-1 font-mono text-[11px] uppercase text-destructive">Invalid pattern</p>}
</div>
);
}