Kosmesis
Components

Bubble

A single chat message bubble. Purely presentational.

Installation

npx kosmesis add bubble
pnpm dlx kosmesis add bubble
yarn dlx kosmesis add bubble
bunx kosmesis add bubble

Install the following dependencies:

npm install class-variance-authority
pnpm add class-variance-authority
yarn add class-variance-authority
bun add class-variance-authority

Copy and paste the following code into your project.

bubble.tsx
import { cva, type VariantProps } from "class-variance-authority";import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import type { Children } from "@praxisjs/shared";import { cn } from "@/lib/utils";export const bubbleVariants = cva("max-w-[80%] rounded-2xl px-4 py-2.5 text-sm leading-relaxed", {  variants: {    variant: {      sent: "ml-auto rounded-br-sm bg-primary text-primary-foreground",      received: "mr-auto rounded-bl-sm bg-muted text-foreground",    },  },  defaultVariants: {    variant: "received",  },});export interface BubbleProps extends VariantProps<typeof bubbleVariants> {  class?: string;  children?: Children;}/** Purely presentational — no Morphos equivalent. A single chat message bubble, used by `Message`. */@Component()export class Bubble extends StatelessComponent<BubbleProps> {  render() {    const { variant, class: cls, children } = this.props;    return <div class={cn(bubbleVariants({ variant }), cls)}>{children}</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.

bubble.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 BubbleStyles extends Stylesheet {  $root = this.css({ maxWidth: "80%", borderRadius: "1rem", padding: "0.625rem 1rem", fontSize: "0.875rem", lineHeight: 1.6 });  $sent = this.css({ marginLeft: "auto", borderBottomRightRadius: "0.25rem", backgroundColor: t.primary, color: t.primaryForeground });  $received = this.css({ marginRight: "auto", borderBottomLeftRadius: "0.25rem", backgroundColor: t.muted, color: t.foreground });}export type BubbleVariant = "sent" | "received";export interface BubbleProps {  variant?: BubbleVariant;  class?: string;  children?: Children;}/** Purely presentational — no Morphos equivalent. A single chat message bubble, used by `Message`. */@Component()export class Bubble extends StatelessComponent<BubbleProps> {  @Styled(BubbleStyles) $s!: BubbleStyles;  render() {    const { variant = "received", class: cls, children } = this.props;    const variantClass = variant === "sent" ? this.$s.$sent : this.$s.$received;    return <div class={cx(this.$s.$root, variantClass, cls)}>{children}</div>;  }}

Examples

Usage

import { Bubble } from "@/components/ui/bubble";

<Bubble variant="received">Hey, how's it going?</Bubble>
<Bubble variant="sent">Pretty good, thanks!</Bubble>

For avatar + role-based layout, see Message, which composes this.

On this page