245 lines
7.3 KiB
TypeScript
245 lines
7.3 KiB
TypeScript
'use client';
|
|
|
|
/**
|
|
* ResponseBlock Component
|
|
*
|
|
* A semantic display block for API response examples with status indicators.
|
|
* Visually differentiates success and error responses through color psychology.
|
|
*
|
|
* ## Design Principles
|
|
*
|
|
* 1. **Status Communication**: Color instantly conveys response type
|
|
* - Green = Success (2xx responses, positive outcomes)
|
|
* - Red = Error (4xx/5xx responses, failures)
|
|
* - Consistent with universal traffic light conventions
|
|
*
|
|
* 2. **Information Layering**: Progressive disclosure of details
|
|
* - Status badge in top-right for immediate recognition
|
|
* - Optional title provides context
|
|
* - Content area for actual response data
|
|
* - Layered styling adds depth without clutter
|
|
*
|
|
* 3. **Visual Feedback**: Subtle effects reinforce status
|
|
* - Background tint matches status color
|
|
* - Border emphasis adds structure
|
|
* - Soft shadow/glow creates depth
|
|
* - All at low opacity to avoid overwhelming
|
|
*
|
|
* ## Status Semantics
|
|
*
|
|
* @param {'success'} success - Successful API responses (2xx status codes)
|
|
* - Visual: Green color palette (green-500)
|
|
* - Psychology: Positive, correct, achieved
|
|
* - Use cases: 200 OK, 201 Created, 204 No Content
|
|
* - Styling: bg-green-500/5, border-green-500/30, shadow-green-500/10
|
|
* - Badge: "✓ 200 Success", "✓ 201 Created"
|
|
*
|
|
* @param {'error'} error - Error API responses (4xx/5xx status codes)
|
|
* - Visual: Red color palette (red-500)
|
|
* - Psychology: Warning, problem, attention needed
|
|
* - Use cases: 400 Bad Request, 401 Unauthorized, 500 Server Error
|
|
* - Styling: bg-red-500/5, border-red-500/30, shadow-red-500/10
|
|
* - Badge: "✗ 400 Error", "✗ 500 Error"
|
|
*
|
|
* ## Opacity Strategy
|
|
*
|
|
* Three-tier opacity system:
|
|
* - Background: /5 (5% opacity) - Subtle tint, doesn't obscure content
|
|
* - Border: /30 (30% opacity) - Clear definition, visible structure
|
|
* - Shadow: /10 (10% opacity) - Soft depth, enhances without distraction
|
|
*
|
|
* This creates:
|
|
* - Cohesive visual grouping
|
|
* - Clear status communication
|
|
* - Maintains content readability
|
|
* - Professional, polished appearance
|
|
*
|
|
* ## Layout Structure
|
|
*
|
|
* ```
|
|
* ┌─────────────────────────────────────┐
|
|
* │ [STATUS BADGE] ←──┤ Absolute positioned
|
|
* │ Optional Title │
|
|
* │ (if provided) │
|
|
* │ │
|
|
* │ <pre><code> │
|
|
* │ Response content │
|
|
* │ ... │
|
|
* │ </code></pre> │
|
|
* └─────────────────────────────────────┘
|
|
* ```
|
|
*
|
|
* Positioning Strategy:
|
|
* - Container: relative positioning context
|
|
* - Badge: absolute top-3 right-3 (float in top-right)
|
|
* - Content: mt-6 when badge present (clear space for badge)
|
|
* - Title: mb-3 if provided (separate from content)
|
|
*
|
|
* ## Typography & Content
|
|
*
|
|
* Title (optional):
|
|
* - text-sm: Small, not competing with main content
|
|
* - font-semibold: Subtle emphasis
|
|
* - text-gray-300: Readable but secondary
|
|
* - Purpose: Labels response type, adds context
|
|
*
|
|
* Response Content:
|
|
* - text-xs: Appropriate for code samples
|
|
* - text-gray-300: High contrast on dark background
|
|
* - font-mono (implicit in <code>): Code appearance
|
|
* - overflow-x-auto: Handles long lines gracefully
|
|
*
|
|
* ## Usage Examples
|
|
*
|
|
* ```tsx
|
|
* // Success response with title
|
|
* <ResponseBlock
|
|
* status="success"
|
|
* statusCode={200}
|
|
* title="Expected Response:"
|
|
* content={`{
|
|
* "success": true,
|
|
* "data": { ... }
|
|
* }`}
|
|
* />
|
|
*
|
|
* // Error response without title
|
|
* <ResponseBlock
|
|
* status="error"
|
|
* statusCode={401}
|
|
* content={`{
|
|
* "error": "Unauthorized",
|
|
* "message": "Invalid API key"
|
|
* }`}
|
|
* />
|
|
*
|
|
* // Custom status label
|
|
* <ResponseBlock
|
|
* status="success"
|
|
* statusCode={201}
|
|
* statusLabel="✓ 201 Created"
|
|
* content="{ ... }"
|
|
* />
|
|
* ```
|
|
*
|
|
* ## Content Guidelines
|
|
*
|
|
* Response Content:
|
|
* - Use actual JSON/text from your API
|
|
* - Format with proper indentation (2 or 4 spaces)
|
|
* - Include realistic data (not just placeholders)
|
|
* - Show relevant fields (omit excessive detail)
|
|
* - Keep under 20-30 lines for readability
|
|
*
|
|
* Status Labels:
|
|
* - Include status code (200, 400, etc.)
|
|
* - Add descriptive text (Success, Error, Created)
|
|
* - Use checkmark (✓) for success
|
|
* - Use X (✗) for errors
|
|
* - Keep concise (2-3 words max)
|
|
*
|
|
* ## Accessibility
|
|
*
|
|
* - Semantic HTML structure (<pre><code>)
|
|
* - Color is supplementary (text + symbols)
|
|
* - High contrast text colors
|
|
* - StatusBadge includes aria-label
|
|
* - Proper heading hierarchy if title used
|
|
* - Scrollable overflow for long content
|
|
*
|
|
* ## Visual Language
|
|
*
|
|
* The ResponseBlock creates:
|
|
* - Immediate status recognition through color
|
|
* - Professional code presentation
|
|
* - Clear example/documentation relationship
|
|
* - Consistent pattern across all API docs
|
|
* - Supports learn-by-example documentation style
|
|
*
|
|
* @component
|
|
* @example
|
|
* <ResponseBlock
|
|
* status="success"
|
|
* statusCode={200}
|
|
* title="Success Response"
|
|
* content={jsonString}
|
|
* />
|
|
*/
|
|
|
|
import { StatusBadge, StatusType } from './StatusBadge';
|
|
|
|
/**
|
|
* Props for the ResponseBlock component
|
|
*/
|
|
export interface ResponseBlockProps {
|
|
/** Status type determining color scheme */
|
|
status: Extract<StatusType, 'success' | 'error'>;
|
|
/** HTTP status code (e.g., 200, 400, 500) */
|
|
statusCode: number;
|
|
/** The response content to display (typically JSON) */
|
|
content: string;
|
|
/** Optional title above the response */
|
|
title?: string;
|
|
/** Optional custom status label (default: auto-generated from statusCode) */
|
|
statusLabel?: string;
|
|
/** Optional CSS class name for additional styling */
|
|
className?: string;
|
|
}
|
|
|
|
/**
|
|
* Status styles mapping status type to background, border, and shadow colors
|
|
*/
|
|
const statusStyles = {
|
|
success: 'bg-green-500/5 border-green-500/30 shadow-lg shadow-green-500/10',
|
|
error: 'bg-red-500/5 border-red-500/30 shadow-lg shadow-red-500/10',
|
|
};
|
|
|
|
/**
|
|
* Generate default status label from code and status
|
|
*/
|
|
const getDefaultStatusLabel = (code: number, status: 'success' | 'error'): string => {
|
|
const symbol = status === 'success' ? '✓' : '✗';
|
|
const text = status === 'success' ? 'Success' : 'Error';
|
|
return `${symbol} ${code} ${text}`;
|
|
};
|
|
|
|
export const ResponseBlock = ({
|
|
status,
|
|
statusCode,
|
|
content,
|
|
title,
|
|
statusLabel,
|
|
className = '',
|
|
}: ResponseBlockProps) => {
|
|
const label = statusLabel || getDefaultStatusLabel(statusCode, status);
|
|
|
|
return (
|
|
<div
|
|
className={`
|
|
relative
|
|
p-4
|
|
border rounded-xl
|
|
${statusStyles[status]}
|
|
${className}
|
|
`}
|
|
>
|
|
{/* Status Badge - Floating Top Right */}
|
|
<div className="absolute top-3 right-3">
|
|
<StatusBadge status={status} size="sm">
|
|
{label}
|
|
</StatusBadge>
|
|
</div>
|
|
|
|
{/* Optional Title */}
|
|
{title && (
|
|
<p className="text-sm font-semibold text-gray-300 mb-3">{title}</p>
|
|
)}
|
|
|
|
{/* Response Content */}
|
|
<pre className={`text-xs text-gray-300 overflow-x-auto ${title || statusLabel ? 'mt-6' : ''}`}>
|
|
<code>{content}</code>
|
|
</pre>
|
|
</div>
|
|
);
|
|
};
|