Files
vercel__streamdown/packages/streamdown/lib/code-block/container.tsx
Dmitrii 00872f0e10 feat: add Tailwind CSS prefix support (#408)
* feat: add Tailwind CSS prefix support

* fix: prevent double-prefixing of already-prefixed CSS classes

When cn() output (e.g. 'tw:size-full') is passed as className to a child
component that also calls cn() with the same prefix, prefixClasses() was
naively prepending the prefix again, producing 'tw:tw:size-full'.

Fix: skip classes that already start with the prefix+colon sentinel.

Add tests for both the all-already-prefixed and mixed cases.

* fix: lint errors — sort imports, format, hoist regex constants

* Add changeset for Tailwind prefix support

* fix: review fixes for tailwind prefix PR

- Bump changeset to minor (new feature, not patch)
- Rename shadowed cn import to baseCn in code-block/body.tsx
- Document that user className values are also prefixed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Troitskii <jsleitor@gmail.com>
Co-authored-by: Hayden Bleasel <hello@haydenbleasel.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 13:39:50 -08:00

39 lines
1.0 KiB
TypeScript

import type { ComponentProps } from "react";
import { useCn } from "../prefix-context";
type CodeBlockContainerProps = ComponentProps<"div"> & {
language: string;
/** Whether the code block is still being streamed (incomplete) */
isIncomplete?: boolean;
};
export const CodeBlockContainer = ({
className,
language,
style,
isIncomplete,
...props
}: CodeBlockContainerProps) => {
const cn = useCn();
return (
<div
className={cn(
"my-4 flex w-full flex-col gap-2 rounded-xl border border-border bg-sidebar p-2",
className
)}
data-incomplete={isIncomplete || undefined}
data-language={language}
data-streamdown="code-block"
style={{
// Use content-visibility to skip rendering off-screen blocks
// This can significantly improve performance for large documents
contentVisibility: "auto",
// Provide a hint for layout to prevent layout shifts
containIntrinsicSize: "auto 200px",
...style,
}}
{...props}
/>
);
};