List
pdfx/listFreeComponent
List component with bullet, numbered, checklist, icon, multi-level, and descriptive variants
See it running
Open the demo on pdfx
pdfx.akashpise.dev/docs/components/listInstall it
npx shadcn@latest add https://pdfx.akashpise.dev/r/list.jsonSource
1import { Text as PDFText, View } from '@react-pdf/renderer';2import type { Style } from '@react-pdf/types';3import type React from 'react';4import { usePdfxTheme, useSafeMemo } from '../lib/pdfx-theme-context';5import { createListStyles } from './pdfx-list.styles';6import type { ListItem, ListVariant, PdfListProps } from './pdfx-list.types';78type Styles = ReturnType<typeof createListStyles>;9type GapProp = 'xs' | 'sm' | 'md';1011function getGapStyle(gap: GapProp, styles: Styles): Style {12 if (gap === 'xs') return styles.itemRowGapXs;13 if (gap === 'md') return styles.itemRowGapMd;14 return styles.itemRowGapSm;15}1617function buildRowStyles(18 index: number,19 total: number,20 gap: GapProp,21 styles: Styles,22 align: 'start' | 'center' = 'start'23): Style[] {24 const row: Style[] = [align === 'center' ? styles.itemRowCenter : styles.itemRow];25 if (index !== total - 1) row.push(getGapStyle(gap, styles));26 return row;27}2829/** Bullet dot marker — solid filled for level 0, outline ring for nested levels. */30function dotMarker(level: number, styles: Styles): React.ReactElement {31 return level === 0 ? (32 <View style={styles.markerBulletWrap}>33 <View style={styles.markerBulletDot} />34 </View>35 ) : (36 <View style={styles.markerBulletSubWrap}>37 <View style={styles.markerBulletSubDot} />38 </View>39 );40}4142function renderBulletItem(43 item: ListItem,44 index: number,45 total: number,46 gap: GapProp,47 styles: Styles,48 level: number49): React.ReactElement {50 return (51 <View key={index}>52 <View style={buildRowStyles(index, total, gap, styles)}>53 {dotMarker(level, styles)}54 {/* flex:1 on the View, NOT on the Text — avoids Yoga height underestimation55 for multi-line Text nodes that would cause overlapping rows. */}56 <View style={styles.itemTextWrap}>57 <PDFText style={styles.itemText}>{item.text}</PDFText>58 </View>59 </View>60 {item.children && item.children.length > 061 ? renderItemList(item.children, 'bullet', gap, styles, level + 1)62 : null}63 </View>64 );65}6667function renderNumberedItem(68 item: ListItem,69 index: number,70 total: number,71 gap: GapProp,72 styles: Styles73): React.ReactElement {74 return (75 <View key={index} style={buildRowStyles(index, total, gap, styles, 'center')}>76 <View style={styles.markerNumberBadge}>77 <PDFText style={styles.markerNumberText}>{`${index + 1}`}</PDFText>78 </View>79 <View style={styles.itemTextWrap}>80// … truncated
What it pulls in
npm packages
Files it writes
More from pdfx
All 34 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Alertalert | pdfx | Components | Free | 1 dep | |
| Badgebadge | pdfx | Components | Free | 1 dep | |
| Cardcard | pdfx | Components | Free | 1 dep | |
| DataTabledata-table | pdfx | Components | Free | 1 dep · 3 files | |
| Dividerdivider | pdfx | Components | Free | 1 dep | |
| Formform | pdfx | Components | Free | 1 dep · 3 files | |
| Graphgraph | pdfx | Components | Free | 1 dep · 4 files | |
| Headingheading | pdfx | Components | Free | 1 dep |
