Skip to main content

React Component Template Prompt

Context

Use this prompt to create new React components for Pacing Agency projects, particularly for the Docusaurus documentation site. Ensures consistent patterns including TypeScript, CSS Modules, props validation, and documentation.

Prerequisites

  • React and TypeScript knowledge
  • Project structure understanding
  • Component requirements defined

See existing components in docusaurus/src/theme/MDXComponents/ or docusaurus/src/components/.

Prompt Template

I need to create a new React component with the following requirements:

**Component Information:**
- Component name: [COMPONENT_NAME]
- Purpose: [PURPOSE]
- Location: [COMPONENT_PATH]
- Used in: [USAGE_CONTEXT]

**Props:**
- Required props: [REQUIRED_PROPS]
- Optional props: [OPTIONAL_PROPS]
- Prop types: [PROP_TYPES]

**Styling:**
- CSS approach: [CSS_APPROACH] (CSS Modules/Inline/Theme)
- Responsive: [RESPONSIVE_REQUIREMENTS]
- Dark mode: [DARK_MODE_SUPPORT]

**Features:**
- Interactivity: [INTERACTIONS]
- State management: [STATE_NEEDS]
- Event handlers: [EVENTS]
- Error handling: [ERROR_HANDLING]

Please provide:

1. **React component** (index.tsx or index.js)
2. **TypeScript types** (types.d.ts or inline)
3. **CSS Module** (styles.module.css)
4. **Usage examples** (how to import and use)
5. **Props documentation** (what each prop does)

Follow Pacing Agency patterns:
- TypeScript for type safety
- CSS Modules for scoped styling
- Props interface with JSDoc comments
- Error boundaries where appropriate
- Accessibility (WCAG compliance)

Format with clear sections and code blocks.

Variables to Customize

VariableDescriptionExample
[COMPONENT_NAME]Component name (PascalCase)"ToolMetadata", "PromptButton", "CategorySummary"
[PURPOSE]What the component does"Displays tool metadata from frontmatter"
[COMPONENT_PATH]File location"docusaurus/src/theme/MDXComponents/ToolMetadata/"
[USAGE_CONTEXT]Where component is used"Tool documentation pages", "MDX files"
[REQUIRED_PROPS]Required properties"toolName, category, monthlyCost"
[OPTIONAL_PROPS]Optional properties"renewalDate, accountType, notes"
[PROP_TYPES]TypeScript types"string, number, Date, enum"
[CSS_APPROACH]Styling method"CSS Modules with theme tokens"
[RESPONSIVE_REQUIREMENTS]Mobile/desktop"Mobile-first, stacks on small screens"
[DARK_MODE_SUPPORT]Theme support"Use --ifm-color-* variables"
[INTERACTIONS]User interactions"Click to expand, hover effects"
[STATE_NEEDS]State requirements"Expanded/collapsed state"
[EVENTS]Event handlers"onClick, onHover, onChange"
[ERROR_HANDLING]Error handling"Show fallback UI if data missing"

Expected Output

1. Component File (index.tsx)

import React, { useState } from 'react';
import styles from './styles.module.css';
import type { ToolMetadataProps } from './types';

/**
* ToolMetadata component displays structured metadata about tools.
* Used in tool documentation pages to show costs, renewals, and access info.
*/
export default function ToolMetadata({
toolName,
category,
monthlyCost,
renewalDate,
accountType,
accessUrl,
notes
}: ToolMetadataProps): JSX.Element {
const [isExpanded, setIsExpanded] = useState(false);

// Format cost as GBP currency
const formattedCost = new Intl.NumberFormat('en-GB', {
style: 'currency',
currency: 'GBP'
}).format(monthlyCost);

// Format renewal date
const formattedRenewal = renewalDate
? new Date(renewalDate).toLocaleDateString('en-GB')
: 'N/A';

return (
<div className={styles.toolMetadata}>
<div className={styles.header}>
<h3 className={styles.toolName}>{toolName}</h3>
<span className={styles.category}>{category}</span>
</div>

<div className={styles.details}>
<div className={styles.detailRow}>
<span className={styles.label}>Monthly Cost:</span>
<span className={styles.value}>{formattedCost}</span>
</div>

<div className={styles.detailRow}>
<span className={styles.label}>Renewal Date:</span>
<span className={styles.value}>{formattedRenewal}</span>
</div>

{accountType && (
<div className={styles.detailRow}>
<span className={styles.label}>Account Type:</span>
<span className={styles.value}>{accountType}</span>
</div>
)}

{accessUrl && (
<div className={styles.detailRow}>
<span className={styles.label}>Access:</span>
<a
href={accessUrl}
className={styles.accessLink}
target="_blank"
rel="noopener noreferrer"
>
Open Dashboard →
</a>
</div>
)}
</div>

{notes && (
<details className={styles.notes}>
<summary>Additional Notes</summary>
<p>{notes}</p>
</details>
)}
</div>
);
}

2. TypeScript Types (types.d.ts)

export type AccountType = 'CLIENT_OWNED' | 'INTERNAL' | 'CLIENT_ACCESS' | 'SHARED';

export interface ToolMetadataProps {
/** Tool name */
toolName: string;

/** Tool category (Website, Analytics, etc.) */
category: string;

/** Monthly cost in GBP */
monthlyCost: number;

/** Next renewal date (ISO format) */
renewalDate?: string;

/** Account ownership type */
accountType?: AccountType;

/** URL to access the tool dashboard */
accessUrl?: string;

/** Additional notes or important information */
notes?: string;
}

3. CSS Module (styles.module.css)

.toolMetadata {
border: 1px solid var(--ifm-color-emphasis-300);
border-radius: var(--ifm-border-radius);
padding: var(--ifm-spacing-vertical);
margin: var(--ifm-spacing-vertical) 0;
background-color: var(--ifm-color-emphasis-0);
}

.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--ifm-spacing-vertical);
padding-bottom: var(--ifm-spacing-vertical);
border-bottom: 1px solid var(--ifm-color-emphasis-200);
}

.toolName {
margin: 0;
font-size: 1.25rem;
color: var(--ifm-color-primary);
}

.category {
background-color: var(--ifm-color-primary-lightest);
color: var(--ifm-color-primary-darkest);
padding: 0.25rem 0.75rem;
border-radius: var(--ifm-border-radius);
font-size: 0.875rem;
font-weight: 600;
}

.details {
display: flex;
flex-direction: column;
gap: 0.75rem;
}

.detailRow {
display: flex;
justify-content: space-between;
align-items: center;
}

.label {
font-weight: 600;
color: var(--ifm-color-emphasis-700);
}

.value {
color: var(--ifm-color-emphasis-900);
}

.accessLink {
color: var(--ifm-color-primary);
text-decoration: none;
font-weight: 500;
}

.accessLink:hover {
text-decoration: underline;
}

.notes {
margin-top: var(--ifm-spacing-vertical);
padding-top: var(--ifm-spacing-vertical);
border-top: 1px solid var(--ifm-color-emphasis-200);
}

.notes summary {
cursor: pointer;
font-weight: 600;
color: var(--ifm-color-primary);
}

.notes p {
margin-top: 0.5rem;
color: var(--ifm-color-emphasis-700);
}

/* Responsive */
@media (max-width: 768px) {
.header {
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
}

.detailRow {
flex-direction: column;
align-items: flex-start;
gap: 0.25rem;
}
}

4. Usage Example

---
title: Webflow
category: Website
monthly_cost: 25.00
renewal_date: 2026-01-15
account_type: CLIENT_OWNED
access_url: https://webflow.com/dashboard
---

import ToolMetadata from '@site/src/theme/MDXComponents/ToolMetadata';

# Webflow

<ToolMetadata
toolName="Webflow"
category="Website"
monthlyCost={25.00}
renewalDate="2026-01-15"
accountType="CLIENT_OWNED"
accessUrl="https://webflow.com/dashboard"
notes="Client-owned account. We have Editor access."
/>

[Rest of documentation...]

Success Criteria

✅ Component renders correctly
✅ TypeScript types are complete
✅ CSS Modules applied correctly
✅ Dark mode works
✅ Responsive design
✅ Props validated
✅ Accessibility checked
✅ Usage examples provided


Last updated: 2026-01-07
Estimated time: 30 minutes