chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,270 @@
|
||||
---
|
||||
title: Card
|
||||
description: Versatile card components for displaying content in a structured, visually appealing format.
|
||||
featured: true
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="card-demo"
|
||||
description="A collection of card variations."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx @creative-tim/ui@latest add card
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install lucide-react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="card" title="components/ui/card.tsx" />
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card"
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Plain Card
|
||||
|
||||
A simple card with just content.
|
||||
|
||||
<ComponentPreview
|
||||
name="card-plain"
|
||||
description="A plain card with basic content."
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers {3-9}
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<p>
|
||||
This is a plain card with simple content. Perfect for displaying basic
|
||||
information.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
```
|
||||
|
||||
### Card with Title, Description, and Button
|
||||
|
||||
A card with header elements and a call-to-action button.
|
||||
|
||||
<ComponentPreview
|
||||
name="card-with-button"
|
||||
description="A card with title, description, and action button."
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers {3-16}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Card Title</CardTitle>
|
||||
<CardDescription>
|
||||
This is a brief description of the card content.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p>More detailed information goes here in the card content area.</p>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button>Learn More</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
```
|
||||
|
||||
### Blog Card
|
||||
|
||||
A card designed for blog post previews with image, title, excerpt, and metadata.
|
||||
|
||||
<ComponentPreview
|
||||
name="card-blog"
|
||||
description="A blog post card with image and metadata."
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers {3-24}
|
||||
<Card className="overflow-hidden">
|
||||
<img
|
||||
src="/blog-image.jpg"
|
||||
alt="Blog post"
|
||||
className="h-48 w-full object-cover"
|
||||
/>
|
||||
<CardHeader>
|
||||
<div className="text-muted-foreground flex items-center gap-2 text-sm">
|
||||
<Calendar className="h-4 w-4" />
|
||||
<span>March 15, 2025</span>
|
||||
<span>•</span>
|
||||
<span>5 min read</span>
|
||||
</div>
|
||||
<CardTitle>Getting Started with Next.js</CardTitle>
|
||||
<CardDescription>
|
||||
Learn how to build modern web applications with Next.js, React, and
|
||||
TypeScript.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardFooter>
|
||||
<Button variant="ghost">Read More</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
```
|
||||
|
||||
### E-commerce Product Card
|
||||
|
||||
A card designed for product listings with image, pricing, and add to cart functionality.
|
||||
|
||||
<ComponentPreview
|
||||
name="card-ecommerce"
|
||||
description="An e-commerce product card with pricing and actions."
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers {3-39}
|
||||
<Card className="overflow-hidden">
|
||||
<div className="relative">
|
||||
<img
|
||||
src="/product-image.jpg"
|
||||
alt="Product"
|
||||
className="h-64 w-full object-cover"
|
||||
/>
|
||||
<Badge className="absolute top-2 right-2">New</Badge>
|
||||
</div>
|
||||
<CardHeader>
|
||||
<CardTitle>Premium Wireless Headphones</CardTitle>
|
||||
<CardDescription>
|
||||
High-quality audio with active noise cancellation
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-1">
|
||||
<Star className="h-4 w-4 fill-yellow-400 text-yellow-400" />
|
||||
<Star className="h-4 w-4 fill-yellow-400 text-yellow-400" />
|
||||
<Star className="h-4 w-4 fill-yellow-400 text-yellow-400" />
|
||||
<Star className="h-4 w-4 fill-yellow-400 text-yellow-400" />
|
||||
<Star className="h-4 w-4" />
|
||||
<span className="text-muted-foreground text-sm">(128)</span>
|
||||
</div>
|
||||
<div className="text-2xl font-bold">$299</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter className="gap-2">
|
||||
<Button className="flex-1">
|
||||
<ShoppingCart className="mr-2 h-4 w-4" />
|
||||
Add to Cart
|
||||
</Button>
|
||||
<Button variant="outline" size="icon">
|
||||
<Heart className="h-4 w-4" />
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### Card
|
||||
|
||||
The root card container component.
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| --------- | ----------- | ----------- | ---------------------- |
|
||||
| className | `string` | `undefined` | Additional CSS classes |
|
||||
| children | `ReactNode` | `undefined` | Card content |
|
||||
|
||||
### CardHeader
|
||||
|
||||
Container for card header content (title, description).
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| --------- | ----------- | ----------- | ---------------------- |
|
||||
| className | `string` | `undefined` | Additional CSS classes |
|
||||
| children | `ReactNode` | `undefined` | Header content |
|
||||
|
||||
### CardTitle
|
||||
|
||||
The card title component.
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| --------- | ----------- | ----------- | ---------------------- |
|
||||
| className | `string` | `undefined` | Additional CSS classes |
|
||||
| children | `ReactNode` | `undefined` | Title text |
|
||||
|
||||
### CardDescription
|
||||
|
||||
The card description component.
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| --------- | ----------- | ----------- | ---------------------- |
|
||||
| className | `string` | `undefined` | Additional CSS classes |
|
||||
| children | `ReactNode` | `undefined` | Description text |
|
||||
|
||||
### CardContent
|
||||
|
||||
Container for the main card content.
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| --------- | ----------- | ----------- | ---------------------- |
|
||||
| className | `string` | `undefined` | Additional CSS classes |
|
||||
| children | `ReactNode` | `undefined` | Card body content |
|
||||
|
||||
### CardFooter
|
||||
|
||||
Container for card footer content (buttons, actions).
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| --------- | ----------- | ----------- | ---------------------- |
|
||||
| className | `string` | `undefined` | Additional CSS classes |
|
||||
| children | `ReactNode` | `undefined` | Footer content |
|
||||
|
||||
## Notes
|
||||
|
||||
- Cards are fully responsive and adapt to their container
|
||||
- Use `overflow-hidden` class on Card to clip images at rounded corners
|
||||
- Combine with other components like Button, Badge, and icons for rich layouts
|
||||
- Based on shadcn/ui Card component with Material Tailwind design enhancements
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Components
|
||||
description: Explore all the components available in the library.
|
||||
---
|
||||
|
||||
<ComponentsList />
|
||||
@@ -0,0 +1,236 @@
|
||||
---
|
||||
title: Software Purchase Card
|
||||
description: A card component for displaying and approving software purchase requests with details like start date, seats, pricing type, and price.
|
||||
featured: true
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="software-purchase-card-demo"
|
||||
description="A software purchase approval card."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add software-purchase-card
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install lucide-react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="software-purchase-card"
|
||||
title="components/cards/software-purchase.tsx"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { SoftwarePurchaseCard } from "@/components/cards/software-purchase"
|
||||
```
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
<SoftwarePurchaseCard
|
||||
softwareName="Enterprise Cloud Suite"
|
||||
startDate="2025-01-15"
|
||||
seats={50}
|
||||
pricingType="per-seat"
|
||||
price="$2,500"
|
||||
onApprove={() => console.log("Approved")}
|
||||
onDiscard={() => console.log("Discarded")}
|
||||
/>
|
||||
```
|
||||
|
||||
### Flat Rate Pricing
|
||||
|
||||
```tsx showLineNumbers
|
||||
<SoftwarePurchaseCard
|
||||
softwareName="Design Tools Pro"
|
||||
startDate="2025-02-01"
|
||||
seats={25}
|
||||
pricingType="flat-rate"
|
||||
price="$999"
|
||||
onApprove={handleApprove}
|
||||
onDiscard={handleDiscard}
|
||||
/>
|
||||
```
|
||||
|
||||
### Usage-Based Pricing
|
||||
|
||||
```tsx showLineNumbers
|
||||
<SoftwarePurchaseCard
|
||||
softwareName="API Gateway Service"
|
||||
startDate="2025-01-20"
|
||||
seats={10}
|
||||
pricingType="usage-based"
|
||||
price="$0.05/request"
|
||||
onApprove={handleApprove}
|
||||
onDiscard={handleDiscard}
|
||||
/>
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### SoftwarePurchaseCard
|
||||
|
||||
The main card component for displaying software purchase details.
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ------------ | -------------------------------------------- | -------------------------- | --------------------------------------------- |
|
||||
| softwareName | `string` | `"Enterprise Cloud Suite"` | Name of the software |
|
||||
| startDate | `string` | `"2025-01-15"` | Start date in ISO format (YYYY-MM-DD) |
|
||||
| seats | `number` | `50` | Number of user seats/licenses |
|
||||
| pricingType | `"per-seat" \| "flat-rate" \| "usage-based"` | `"per-seat"` | Type of pricing model |
|
||||
| price | `string` | `"$2,500"` | Price display string (can include formatting) |
|
||||
| onApprove | `() => void` | `undefined` | Callback function when approve button clicked |
|
||||
| onDiscard | `() => void` | `undefined` | Callback function when discard button clicked |
|
||||
|
||||
## Examples
|
||||
|
||||
### With State Management
|
||||
|
||||
```tsx showLineNumbers
|
||||
function PurchaseApproval() {
|
||||
const [status, setStatus] = useState<"pending" | "approved" | "discarded">(
|
||||
"pending"
|
||||
)
|
||||
|
||||
const handleApprove = () => {
|
||||
setStatus("approved")
|
||||
// API call to approve purchase
|
||||
approvePurchase(purchaseId)
|
||||
}
|
||||
|
||||
const handleDiscard = () => {
|
||||
setStatus("discarded")
|
||||
// API call to discard purchase
|
||||
discardPurchase(purchaseId)
|
||||
}
|
||||
|
||||
return (
|
||||
<SoftwarePurchaseCard
|
||||
softwareName="Marketing Automation Suite"
|
||||
startDate="2025-03-01"
|
||||
seats={75}
|
||||
pricingType="per-seat"
|
||||
price="$3,750"
|
||||
onApprove={handleApprove}
|
||||
onDiscard={handleDiscard}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### With Loading State
|
||||
|
||||
```tsx showLineNumbers
|
||||
function PurchaseApprovalWithLoading() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const handleApprove = async () => {
|
||||
setLoading(true)
|
||||
try {
|
||||
await approvePurchaseRequest()
|
||||
toast.success("Purchase approved successfully")
|
||||
} catch (error) {
|
||||
toast.error("Failed to approve purchase")
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<SoftwarePurchaseCard
|
||||
softwareName="Analytics Platform"
|
||||
startDate="2025-02-15"
|
||||
seats={100}
|
||||
pricingType="flat-rate"
|
||||
price="$5,000"
|
||||
onApprove={handleApprove}
|
||||
onDiscard={() => {}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Multiple Cards in a List
|
||||
|
||||
```tsx showLineNumbers
|
||||
function PurchaseRequestList() {
|
||||
const requests = [
|
||||
{
|
||||
id: 1,
|
||||
softwareName: "CRM Software",
|
||||
startDate: "2025-01-15",
|
||||
seats: 50,
|
||||
pricingType: "per-seat" as const,
|
||||
price: "$2,500",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
softwareName: "Project Management Tool",
|
||||
startDate: "2025-02-01",
|
||||
seats: 30,
|
||||
pricingType: "flat-rate" as const,
|
||||
price: "$999",
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{requests.map((request) => (
|
||||
<SoftwarePurchaseCard
|
||||
key={request.id}
|
||||
{...request}
|
||||
onApprove={() => handleApprove(request.id)}
|
||||
onDiscard={() => handleDiscard(request.id)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Block Example
|
||||
|
||||
For a full-page implementation with detailed purchase information, check out the [software-purchase-01](/blocks/software-purchase-01) block.
|
||||
|
||||
## Notes
|
||||
|
||||
- The date is automatically formatted using `toLocaleDateString` with US locale
|
||||
- The pricing type badge displays in a secondary variant for visual hierarchy
|
||||
- Icons from `lucide-react` are used for visual clarity (Calendar, Users, CreditCard, DollarSign)
|
||||
- The component uses the shadcn/ui Card, Button, and Badge components
|
||||
- The card is fully responsive with a max width of `md` (28rem)
|
||||
Reference in New Issue
Block a user