Kosmesis
Components

Code Block

A plain code display with a copy button. Purely presentational — no Morphos equivalent.

Installation

npx kosmesis add code-block
pnpm dlx kosmesis add code-block
yarn dlx kosmesis add code-block
bunx kosmesis add code-block

Copy and paste the following code into your project.

code-block.tsx
import { StatefulComponent } from "@praxisjs/core";import { Component, Prop, State } from "@praxisjs/decorators";import { cn } from "@/lib/utils";export interface CodeBlockProps {  code: string;  language?: string;  filename?: string;  class?: string;}// Deliberately avoids a heavy syntax-highlighter dependency like shiki — bring your own// highlighted HTML via `children` if you need real highlighting.@Component()export class CodeBlock extends StatefulComponent {  @Prop() code = "";  @Prop() language?: string;  @Prop() filename?: string;  @Prop() class?: string;  @State() _copied = false;  private _timeout?: ReturnType<typeof setTimeout>;  async copy(): Promise<void> {    try {      await navigator.clipboard.writeText(this.code);      this._copied = true;      clearTimeout(this._timeout);      this._timeout = setTimeout(() => { this._copied = false; }, 1500);    } catch {      // clipboard unavailable (insecure context, permission denied, ...) — no-op    }  }  onUnmount(): void {    clearTimeout(this._timeout);  }  render() {    return (      <div data-slot="code-block" class={cn("overflow-hidden rounded-lg border bg-muted/30", this.class)}>        {(this.filename ?? this.language) !== undefined && (          <div class="flex items-center justify-between border-b bg-muted/50 px-4 py-2 text-xs text-muted-foreground">            <span>{this.filename ?? this.language}</span>          </div>        )}        <div class="relative">          <pre class="overflow-x-auto p-4 text-sm">            <code>{this.code}</code>          </pre>          <button            type="button"            aria-label="Copy code"            class="absolute top-2 right-2 rounded-md border bg-background px-2 py-1 text-xs text-muted-foreground hover:bg-accent hover:text-accent-foreground"            onClick={() => { void this.copy(); }}          >            {() => (this._copied ? "Copied!" : "Copy")}          </button>        </div>      </div>    );  }}

Install the following dependencies:

npm install @praxisjs/css
pnpm add @praxisjs/css
yarn add @praxisjs/css
bun add @praxisjs/css

Copy and paste the following code into your project.

code-block.tsx
import { StatefulComponent } from "@praxisjs/core";import { cx, Stylesheet, Styled, tokenVars } from "@praxisjs/css";import { Component, Prop, State } from "@praxisjs/decorators";import { KosmesisTokens } from "@/lib/kosmesis-theme";const t = tokenVars(KosmesisTokens);class CodeBlockStyles extends Stylesheet {  $root = this.css({    overflow: "hidden",    borderRadius: "0.5rem",    border: `1px solid ${t.border}`,    backgroundColor: `color-mix(in oklab, ${t.muted} 30%, transparent)`,  });  $header = this.css({    display: "flex",    alignItems: "center",    justifyContent: "space-between",    borderBottom: `1px solid ${t.border}`,    backgroundColor: `color-mix(in oklab, ${t.muted} 50%, transparent)`,    padding: "0.5rem 1rem",    fontSize: "0.75rem",    color: t.mutedForeground,  });  $body = this.css({ position: "relative" });  $pre = this.css({ overflowX: "auto", padding: "1rem", fontSize: "0.875rem" });  $copy = this.css({    position: "absolute",    top: "0.5rem",    right: "0.5rem",    borderRadius: "0.375rem",    border: `1px solid ${t.border}`,    backgroundColor: t.background,    padding: "0.25rem 0.5rem",    fontSize: "0.75rem",    color: t.mutedForeground,    cursor: "pointer",  }).on("&:hover", { backgroundColor: t.accent, color: t.accentForeground });}export interface CodeBlockProps {  code: string;  language?: string;  filename?: string;  class?: string;}// Deliberately avoids a heavy syntax-highlighter dependency like shiki — bring your own// highlighted HTML via `children` if you need real highlighting.@Component()export class CodeBlock extends StatefulComponent {  @Styled(CodeBlockStyles) $s!: CodeBlockStyles;  @Prop() code = "";  @Prop() language?: string;  @Prop() filename?: string;  @Prop() class?: string;  @State() _copied = false;  private _timeout?: ReturnType<typeof setTimeout>;  async copy(): Promise<void> {    try {      await navigator.clipboard.writeText(this.code);      this._copied = true;      clearTimeout(this._timeout);      this._timeout = setTimeout(() => { this._copied = false; }, 1500);    } catch {      // clipboard unavailable (insecure context, permission denied, ...) — no-op    }  }  onUnmount(): void {    clearTimeout(this._timeout);  }  render() {    return (      <div data-slot="code-block" class={cx(this.$s.$root, this.class)}>        {(this.filename ?? this.language) !== undefined && <div class={this.$s.$header}>{this.filename ?? this.language}</div>}        <div class={this.$s.$body}>          <pre class={this.$s.$pre}>            <code>{this.code}</code>          </pre>          <button type="button" aria-label="Copy code" class={this.$s.$copy} onClick={() => { void this.copy(); }}>            {() => (this._copied ? "Copied!" : "Copy")}          </button>        </div>      </div>    );  }}

Examples

About

Purely presentational — no Morphos equivalent, and deliberately avoids a heavy syntax-highlighter dependency like shiki (same reasoning Carousel avoids Embla): plain <pre><code> with a copy button, no highlighting.

Usage

import { CodeBlock } from "@/components/ui/code-block";

<CodeBlock code={source} language="ts" filename="greet.ts" />

Props

PropTypeDefault
codestring
languagestring
filenamestring
classstring

On this page