Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions apps/platform/components/showcase/component-live-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { SpotlightButtonDemo } from "@/components/showcase/spotlight-button-demo";
import { Card, CardContent, CardHeader, CardFooter } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { Separator } from "@/components/ui/separator";
import { Textarea } from "@/components/ui/textarea";
import { Text } from "@/components/ui/text";

function PreviewShell({
children,
Expand Down Expand Up @@ -362,6 +367,56 @@ export function TextCodeInlinePreview() {
);
}

export function CardInlinePreview() {
return (
<PreviewShell>
<Card className="mx-auto w-full max-w-sm">
<CardHeader>
<Text variant="h3">Card Title</Text>
<Text variant="muted">Description or subtitle goes here.</Text>
</CardHeader>
<CardContent>
<Text>Main content area for your card data.</Text>
</CardContent>
<CardFooter>
<Text variant="small">Footer Action Area</Text>
</CardFooter>
</Card>
</PreviewShell>
);
}

export function LabelInlinePreview() {
return (
<PreviewShell>
<div className="flex flex-col gap-2">
<Label>Email Address</Label>
<Input placeholder="Enter your email" />
</div>
</PreviewShell>
);
}

export function SeparatorInlinePreview() {
return (
<PreviewShell>
<div className="flex flex-col gap-4">
<Text>Section Top</Text>
<Separator />
<Text>Section Bottom</Text>
</div>
</PreviewShell>
);
}

export function TextareaInlinePreview() {
return (
<PreviewShell>
<Textarea placeholder="Describe your issue..." className="min-h-[120px]" />
</PreviewShell>
);
}

export function ComponentLivePreview({ slug }: { slug: string }) {
switch (slug) {
case "button":
Expand All @@ -374,6 +429,14 @@ export function ComponentLivePreview({ slug }: { slug: string }) {
return <BadgeLivePreview />;
case "text":
return <TextLivePreview />;
case "card":
return <CardInlinePreview />;
case "label":
return <LabelInlinePreview />;
case "separator":
return <SeparatorInlinePreview />;
case "textarea":
return <TextareaInlinePreview />;
case "spotlight-button":
return <SpotlightButtonDemo />;
default:
Expand Down
69 changes: 69 additions & 0 deletions apps/platform/components/ui/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"use client"

import * as React from "react"
import { cn } from "@/lib/utils"

function Card({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card"
className={cn(
"bg-card text-card-foreground flex flex-col rounded-xl border shadow-sm",
className
)}
{...props}
/>
)
}

function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-header"
className={cn("flex flex-col gap-1.5 p-6", className)}
{...props}
/>
)
}

function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-title"
className={cn("leading-none font-semibold tracking-tight", className)}
{...props}
/>
)
}

function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-description"
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
}

function CardContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-content"
className={cn("p-6 pt-0", className)}
{...props}
/>
)
}

function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-footer"
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
)
}

export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
23 changes: 23 additions & 0 deletions apps/platform/components/ui/label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use client"

import * as React from "react"
import { Label as LabelPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"

function Label({
className,
...props
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
return (
<LabelPrimitive.Root
data-slot="label"
className={cn(
"text-sm font-medium leading-none select-none group-data-[disabled=true]/field:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
className
)}
{...props}
/>
)
}

export { Label }
50 changes: 50 additions & 0 deletions apps/platform/components/ui/text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use client"

import * as React from "react"
import { cn } from "@/lib/utils"

type TextVariant =
| "default"
| "h1"
| "h2"
| "h3"
| "h4"
| "p"
| "blockquote"
| "code"
| "lead"
| "large"
| "small"
| "muted";

interface TextProps extends React.ComponentProps<"p"> {
variant?: TextVariant;
}

const TextStyleContext = React.createContext<string | undefined>(undefined);

function Text({ className, variant = "default", ...props }: TextProps) {
const styles = {
default: "text-foreground",
h1: "scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl",
h2: "scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0",
h3: "scroll-m-20 text-2xl font-semibold tracking-tight",
h4: "scroll-m-20 text-xl font-semibold tracking-tight",
p: "leading-7 [&:not(:first-child)]:mt-6",
blockquote: "mt-6 border-l-2 pl-6 italic",
code: "relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold",
lead: "text-xl text-muted-foreground",
large: "text-lg font-semibold",
small: "text-sm font-medium leading-none",
muted: "text-sm text-muted-foreground",
};

return (
<p
className={cn(styles[variant], className)}
{...props}
/>
);
}

export { Text, TextStyleContext };
59 changes: 59 additions & 0 deletions apps/platform/content/docs/components/card.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: Card
description: A flexible container component with support for headers, content, and footers.
kind: component
category: Components
image: /logo.png
---

import { CodeBlock } from "@/components/showcase/code-block";
import {
ApiTable,
DocSection,
DocSubsection,
} from "@/components/showcase/docs-primitives";
import { CompPreview } from "@/components/mdx/component-preview";
import { CardInlinePreview } from "@/components/showcase/component-live-preview";

## Import

<DocSection>
<CodeBlock language="tsx" title="Import" showLineNumbers={false}>
{`import { Card, CardHeader, CardContent, CardFooter } from "@/components/ui/card";
import { Text } from "@/components/ui/text";`}
</CodeBlock>
</DocSection>

## Usage

<DocSection>
The `Card` component provides a structured layout with consistent padding and borders for grouping related information.

### Basic Card

<DocSubsection>
A standard card with header, content, and footer.
<CompPreview
code={`<Card>
<CardHeader>
<Text variant="h3">Card Title</Text>
<Text variant="muted">Card Description</Text>
</CardHeader>
<CardContent>
<Text>This is the main content of the card.</Text>
</CardContent>
<CardFooter>
<Text variant="small">Footer Content</Text>
</CardFooter>
</Card>`}
>
<CardInlinePreview />
</CompPreview>
</DocSubsection>
</DocSection>

## API Reference

<DocSection>
`Card`, `CardHeader`, `CardContent`, and `CardFooter` all extend the standard `View` props.
</DocSection>
50 changes: 50 additions & 0 deletions apps/platform/content/docs/components/label.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
title: Label
description: An accessible label component for form inputs and other interactive elements.
kind: component
category: Components
image: /logo.png
---

import { CodeBlock } from "@/components/showcase/code-block";
import {
ApiTable,
DocSection,
DocSubsection,
} from "@/components/showcase/docs-primitives";
import { CompPreview } from "@/components/mdx/component-preview";
import { LabelInlinePreview } from "@/components/showcase/component-live-preview";

## Import

<DocSection>
<CodeBlock language="tsx" title="Import" showLineNumbers={false}>
{`import { Label } from "@/components/ui/label";`}
</CodeBlock>
</DocSection>

## Usage

<DocSection>
The `Label` component provides a consistent typography style for labeling form fields.

### Basic Usage

<DocSubsection>
Use it alongside an input to provide clear context.
<CompPreview
code={`<View className="gap-2">
<Label>Email Address</Label>
<Input placeholder="Enter your email" />
</View>`}
>
<LabelInlinePreview />
</CompPreview>
</DocSubsection>
</DocSection>

## API Reference

<DocSection>
`Label` extends the standard `Text` props from React Native.
</DocSection>
2 changes: 1 addition & 1 deletion apps/platform/content/docs/components/meta.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"title": "Components",
"pages": ["button", "text", "spotlight-button"]
"pages": ["button", "text", "input", "badge", "avatar", "card", "label", "separator", "textarea", "spotlight-button"]
}
Loading
Loading