Kosmesis
Components

Typography

Prose text primitives (headings, lead, muted, inline code, blockquote). Purely presentational.

Installation

npx kosmesis add typography
pnpm dlx kosmesis add typography
yarn dlx kosmesis add typography
bunx kosmesis add typography

Copy and paste the following code into your project.

typography.tsx
import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import type { Children } from "@praxisjs/shared";import { cn } from "@/lib/utils";export interface TypographyProps {  class?: string;  id?: string;  children?: Children;}/** Purely presentational text primitives — no Morphos equivalent, same as upstream shadcn/ui. */@Component()export class TypographyH1 extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <h1 id={id} class={cn("scroll-m-20 text-4xl font-extrabold tracking-tight text-balance", cls)}>        {children}      </h1>    );  }}@Component()export class TypographyH2 extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <h2 id={id} class={cn("scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0", cls)}>        {children}      </h2>    );  }}@Component()export class TypographyH3 extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <h3 id={id} class={cn("scroll-m-20 text-2xl font-semibold tracking-tight", cls)}>        {children}      </h3>    );  }}@Component()export class TypographyH4 extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <h4 id={id} class={cn("scroll-m-20 text-xl font-semibold tracking-tight", cls)}>        {children}      </h4>    );  }}@Component()export class TypographyP extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <p id={id} class={cn("leading-7 [&:not(:first-child)]:mt-6", cls)}>        {children}      </p>    );  }}@Component()export class TypographyBlockquote extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <blockquote id={id} class={cn("mt-6 border-l-2 pl-6 italic", cls)}>        {children}      </blockquote>    );  }}@Component()export class TypographyInlineCode extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <code        id={id}        class={cn(          "relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold",          cls,        )}      >        {children}      </code>    );  }}@Component()export class TypographyLead extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <p id={id} class={cn("text-xl text-muted-foreground", cls)}>        {children}      </p>    );  }}@Component()export class TypographyLarge extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <div id={id} class={cn("text-lg font-semibold", cls)}>        {children}      </div>    );  }}@Component()export class TypographySmall extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <small id={id} class={cn("text-sm leading-none font-medium", cls)}>        {children}      </small>    );  }}@Component()export class TypographyMuted extends StatelessComponent<TypographyProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <p id={id} class={cn("text-sm text-muted-foreground", cls)}>        {children}      </p>    );  }}

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.

typography.tsx
import { StatelessComponent } from "@praxisjs/core";import { cx, Stylesheet, Styled, tokenVars } from "@praxisjs/css";import { Component } from "@praxisjs/decorators";import type { Children } from "@praxisjs/shared";import { KosmesisTokens } from "@/lib/kosmesis-theme";const t = tokenVars(KosmesisTokens);class TypographyStyles extends Stylesheet {  $h1 = this.css({ scrollMarginTop: "5rem", fontSize: "2.25rem", fontWeight: 800, letterSpacing: "-0.02em" });  $h2 = this.css({    scrollMarginTop: "5rem",    borderBottom: `1px solid ${t.border}`,    paddingBottom: "0.5rem",    fontSize: "1.875rem",    fontWeight: 600,    letterSpacing: "-0.02em",  }).first({ marginTop: "0" });  $h3 = this.css({ scrollMarginTop: "5rem", fontSize: "1.5rem", fontWeight: 600, letterSpacing: "-0.02em" });  $h4 = this.css({ scrollMarginTop: "5rem", fontSize: "1.25rem", fontWeight: 600, letterSpacing: "-0.02em" });  $p = this.css({ lineHeight: 1.75 }).not(":first-child", { marginTop: "1.5rem" });  $blockquote = this.css({ marginTop: "1.5rem", borderLeft: `2px solid ${t.border}`, paddingLeft: "1.5rem", fontStyle: "italic" });  $inlineCode = this.css({    position: "relative",    borderRadius: "0.25rem",    backgroundColor: t.muted,    padding: "0.2rem 0.3rem",    fontFamily: "monospace",    fontSize: "0.875rem",    fontWeight: 600,  });  $lead = this.css({ fontSize: "1.25rem", color: t.mutedForeground });  $large = this.css({ fontSize: "1.125rem", fontWeight: 600 });  $small = this.css({ fontSize: "0.875rem", lineHeight: 1, fontWeight: 500 });  $muted = this.css({ fontSize: "0.875rem", color: t.mutedForeground });}export interface TypographyProps {  class?: string;  id?: string;  children?: Children;}/** Purely presentational text primitives — no Morphos equivalent, same as upstream shadcn/ui. */@Component()export class TypographyH1 extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <h1 id={id} class={cx(this.$s.$h1, cls)}>        {children}      </h1>    );  }}@Component()export class TypographyH2 extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <h2 id={id} class={cx(this.$s.$h2, cls)}>        {children}      </h2>    );  }}@Component()export class TypographyH3 extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <h3 id={id} class={cx(this.$s.$h3, cls)}>        {children}      </h3>    );  }}@Component()export class TypographyH4 extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <h4 id={id} class={cx(this.$s.$h4, cls)}>        {children}      </h4>    );  }}@Component()export class TypographyP extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <p id={id} class={cx(this.$s.$p, cls)}>        {children}      </p>    );  }}@Component()export class TypographyBlockquote extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <blockquote id={id} class={cx(this.$s.$blockquote, cls)}>        {children}      </blockquote>    );  }}@Component()export class TypographyInlineCode extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <code id={id} class={cx(this.$s.$inlineCode, cls)}>        {children}      </code>    );  }}@Component()export class TypographyLead extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <p id={id} class={cx(this.$s.$lead, cls)}>        {children}      </p>    );  }}@Component()export class TypographyLarge extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <div id={id} class={cx(this.$s.$large, cls)}>        {children}      </div>    );  }}@Component()export class TypographySmall extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <small id={id} class={cx(this.$s.$small, cls)}>        {children}      </small>    );  }}@Component()export class TypographyMuted extends StatelessComponent<TypographyProps> {  @Styled(TypographyStyles) $s!: TypographyStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <p id={id} class={cx(this.$s.$muted, cls)}>        {children}      </p>    );  }}

Examples

Usage

import {
  TypographyBlockquote,
  TypographyH1,
  TypographyH2,
  TypographyH3,
  TypographyH4,
  TypographyInlineCode,
  TypographyLarge,
  TypographyLead,
  TypographyMuted,
  TypographyP,
  TypographySmall,
} from "@/components/ui/typography";

<TypographyH1>The Joke Tax</TypographyH1>
<TypographyLead>Everyone knows the story of the man who wanted more than everything.</TypographyLead>
<TypographyP>The king thought long and hard, and finally came up with <TypographyInlineCode>a brilliant plan</TypographyInlineCode>.</TypographyP>
<TypographyBlockquote>"After all," he said, "everyone paid the tax."</TypographyBlockquote>
<TypographyMuted>Enter your email below.</TypographyMuted>

Unlike most other components, these render native heading/paragraph elements directly — there's no single Typography root, just one class per text style, matching upstream shadcn/ui exactly.

On this page