Components
Order Summary
A line-item + total breakdown card. Purely presentational — no Morphos equivalent.
Installation
npx kosmesis add order-summarypnpm dlx kosmesis add order-summaryyarn dlx kosmesis add order-summarybunx kosmesis add order-summaryCopy and paste the following code into your project.
import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import type { Children } from "@praxisjs/shared";import { cn } from "@/lib/utils";export interface OrderSummaryProps { class?: string; children?: Children;}@Component()export class OrderSummary extends StatelessComponent<OrderSummaryProps> { render() { const { class: cls, children } = this.props; return ( <div data-slot="order-summary" class={cn("flex flex-col gap-3 rounded-lg border bg-card p-4 text-card-foreground", cls)}> {children} </div> ); }}export interface OrderSummaryItemProps { label: Children; value: Children; class?: string;}@Component()export class OrderSummaryItem extends StatelessComponent<OrderSummaryItemProps> { render() { const { label, value, class: cls } = this.props; return ( <div class={cn("flex items-center justify-between text-sm", cls)}> <span class="text-muted-foreground">{label}</span> <span class="font-medium text-foreground">{value}</span> </div> ); }}export interface OrderSummaryTotalProps { label?: Children; value: Children; class?: string;}@Component()export class OrderSummaryTotal extends StatelessComponent<OrderSummaryTotalProps> { render() { const { label = "Total", value, class: cls } = this.props; return ( <div class={cn("flex items-center justify-between border-t pt-3 text-base font-semibold text-foreground", cls)}> <span>{label}</span> <span>{value}</span> </div> ); }}Install the following dependencies:
npm install @praxisjs/csspnpm add @praxisjs/cssyarn add @praxisjs/cssbun add @praxisjs/cssCopy and paste the following code into your project.
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 OrderSummaryStyles extends Stylesheet { $root = this.css({ display: "flex", flexDirection: "column", gap: "0.75rem", borderRadius: "0.5rem", border: `1px solid ${t.border}`, backgroundColor: t.card, color: t.cardForeground, padding: "1rem", }); $item = this.css({ display: "flex", alignItems: "center", justifyContent: "space-between", fontSize: "0.875rem" }); $itemLabel = this.css({ color: t.mutedForeground }); $itemValue = this.css({ fontWeight: 500, color: t.foreground }); $total = this.css({ display: "flex", alignItems: "center", justifyContent: "space-between", borderTop: `1px solid ${t.border}`, paddingTop: "0.75rem", fontSize: "1rem", fontWeight: 600, color: t.foreground, });}export interface OrderSummaryProps { class?: string; children?: Children;}@Component()export class OrderSummary extends StatelessComponent<OrderSummaryProps> { @Styled(OrderSummaryStyles) $s!: OrderSummaryStyles; render() { const { class: cls, children } = this.props; return ( <div data-slot="order-summary" class={cx(this.$s.$root, cls)}> {children} </div> ); }}export interface OrderSummaryItemProps { label: Children; value: Children; class?: string;}@Component()export class OrderSummaryItem extends StatelessComponent<OrderSummaryItemProps> { @Styled(OrderSummaryStyles) $s!: OrderSummaryStyles; render() { const { label, value, class: cls } = this.props; return ( <div class={cx(this.$s.$item, cls)}> <span class={this.$s.$itemLabel}>{label}</span> <span class={this.$s.$itemValue}>{value}</span> </div> ); }}export interface OrderSummaryTotalProps { label?: Children; value: Children; class?: string;}@Component()export class OrderSummaryTotal extends StatelessComponent<OrderSummaryTotalProps> { @Styled(OrderSummaryStyles) $s!: OrderSummaryStyles; render() { const { label = "Total", value, class: cls } = this.props; return ( <div class={cx(this.$s.$total, cls)}> <span>{label}</span> <span>{value}</span> </div> ); }}Examples
About
Purely presentational — no Morphos equivalent. OrderSummaryTotal is visually distinct (larger,
bolder, top border) from OrderSummaryItem — always place it last.
Usage
import { OrderSummary, OrderSummaryItem, OrderSummaryTotal } from "@/components/ui/order-summary";
<OrderSummary>
<OrderSummaryItem label="Subtotal" value="$49.00" />
<OrderSummaryItem label="Shipping" value="$4.99" />
<OrderSummaryTotal value="$53.99" />
</OrderSummary>Props
OrderSummaryItem
| Prop | Type | Default |
|---|---|---|
label | Children | — |
value | Children | — |
class | string | — |
OrderSummaryTotal
| Prop | Type | Default |
|---|---|---|
label | Children | "Total" |
value | Children | — |
class | string | — |
OrderSummary accepts class and children only.