Created
November 12, 2025 19:56
-
-
Save renoirb/2d08b6a87d556fdd088d57b458cf773a to your computer and use it in GitHub Desktop.
Definition List
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { cn } from '@/lib/utils'; | |
| /** | |
| * Represents a single definition term (dt) with zero or more definition details (dd) | |
| * | |
| * Describes what each probability category means in terms of historical distribution | |
| * | |
| * @example | |
| * ```tsx | |
| * // Single detail string | |
| * { term: 'Unusually high', details: 'Above the 80th percentile (top fifth of historical data)' } | |
| * | |
| * // Multiple details | |
| * { term: 'Complex term', details: ['First explanation', 'Second explanation'] } | |
| * | |
| * // No details (just a term) | |
| * { term: 'Simple term' } | |
| * ``` | |
| */ | |
| export interface DefinitionItem { | |
| /** | |
| * The term being defined (rendered as <dt>) | |
| * | |
| * @example 'Unusually high', 'Above normal' | |
| */ | |
| term: string; | |
| /** | |
| * Zero, one, or more definitions for the term (each rendered as <dd>) | |
| * - undefined: No details, just the term | |
| * - string: Single detail | |
| * - string[]: Multiple details | |
| * | |
| * @example 'Above the 66th percentile (upper third of historical data)' | |
| * @example ['First detail', 'Second detail'] | |
| */ | |
| details?: string | string[]; | |
| } | |
| /** | |
| * Reusable definition list renderer for dl/dt/dd pattern | |
| * | |
| * Handles the flexible details type (undefined | string | string[]) | |
| * and provides consistent styling for definition lists. | |
| * | |
| * Accepts optional className props to customize styling for dl, dt, and dd elements. | |
| */ | |
| interface DefinitionListProps { | |
| items: DefinitionItem[]; | |
| className?: string; | |
| dtClassName?: string; | |
| ddClassName?: string; | |
| } | |
| export const DefinitionList = (props: DefinitionListProps) => { | |
| const { | |
| items, | |
| className, | |
| dtClassName, | |
| ddClassName, | |
| } = props; | |
| const normalizeDetails = (details?: string | string[]): string[] => { | |
| if (!details) { | |
| return []; | |
| } | |
| return Array.isArray(details) ? details : [details]; | |
| }; | |
| return ( | |
| <dl className={cn('border-l-2 border-gray-300', className)}> | |
| {items.map(({ term, details = [] }, idx) => { | |
| const detailsArray = normalizeDetails(details); | |
| return ( | |
| <div key={idx} className="space-y-0.5"> | |
| <dt className={cn('font-semibold text-gray-800', dtClassName)}> | |
| {term} | |
| </dt> | |
| {detailsArray.map((detail, detailIdx) => ( | |
| <dd key={detailIdx} className={cn('text-gray-700', ddClassName)}> | |
| {detail} | |
| </dd> | |
| ))} | |
| </div> | |
| ); | |
| })} | |
| </dl> | |
| ); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment