|
| 1 | += Card Component |
| 2 | + |
| 3 | +[cols="1a,1a"] |
| 4 | +|=== |
| 5 | +| Light | Dark |
| 6 | + |
| 7 | +| image::Components/CardLight.png[CardLight,width=600,height=600] |
| 8 | +| image::Components/CardDark.png[CardDark,width=600,height=600] |
| 9 | +|=== |
| 10 | + |
| 11 | +The Card component is a flexible and versatile UI element designed using a compound component pattern. It supports both vertical and horizontal layouts, optional images or icons, and structured content sections. The component provides a clean, modern interface for displaying organized information. |
| 12 | + |
| 13 | +https://needle-starterkit.graphapp.io/card-preview[Link to the live preview,window=_blank] |
| 14 | +
|
| 15 | +https://github.com/neo4j-labs/neo4j-needle-starterkit/blob/2.1/src/templates/shared/components/Card.tsx[Link to the component code,window=_blank] |
| 16 | +
|
| 17 | +== Pre-requisite |
| 18 | +
|
| 19 | +- Ensure you have the `@neo4j-ndl` library installed in your project to use this `Card` component. |
| 20 | +
|
| 21 | +== Usage |
| 22 | +
|
| 23 | +To use the Card component in your application, follow these steps: |
| 24 | +
|
| 25 | +. Import the component and required assets: |
| 26 | ++ |
| 27 | +[source,tsx] |
| 28 | +---- |
| 29 | +import Card from './path/to/Card'; |
| 30 | +import testImg from './assets/cardImg.png'; |
| 31 | +import { Button, Typography } from '@neo4j-ndl/react'; |
| 32 | +import { AcademicCapIconOutline, RocketLaunchIconOutline } from '@neo4j-ndl/react/icons'; |
| 33 | +---- |
| 34 | +
|
| 35 | +. Use the compound component pattern to build your card: |
| 36 | ++ |
| 37 | +[source,tsx] |
| 38 | +---- |
| 39 | +// Vertical card with image and full content |
| 40 | +<Card layout='vertical' imageSrc={testImg} imageSize='full' className='h-auto w-96'> |
| 41 | + <Card.Header>Header text</Card.Header> |
| 42 | + <Card.Subheader>Subtitle or description</Card.Subheader> |
| 43 | + <Card.Content> |
| 44 | + <p>Some description about relatively important things.</p> |
| 45 | + <ul className='list-disc list-inside'> |
| 46 | + <li>Key information item 1</li> |
| 47 | + <li>Key information item 2</li> |
| 48 | + <li>Key information item 3</li> |
| 49 | + </ul> |
| 50 | + <div className='flex flex-row min-w-full justify-between'> |
| 51 | + <Button size='small' color='danger' className='w-2/5 mx-2.5'> |
| 52 | + <Typography variant='body-small'>Cancel</Typography> |
| 53 | + </Button> |
| 54 | + <Button size='small' color='primary' className='w-2/5 mx-2.5'> |
| 55 | + <Typography variant='body-small'>Confirm</Typography> |
| 56 | + </Button> |
| 57 | + </div> |
| 58 | + </Card.Content> |
| 59 | +</Card> |
| 60 | +
|
| 61 | +// Horizontal card with icon |
| 62 | +<Card layout='horizontal' iconSystem={AcademicCapIconOutline}> |
| 63 | + <Card.Header>Header text</Card.Header> |
| 64 | + <Card.Content> |
| 65 | + <p>Content for horizontal layout card.</p> |
| 66 | + </Card.Content> |
| 67 | +</Card> |
| 68 | +---- |
| 69 | +
|
| 70 | +== Component Props |
| 71 | +
|
| 72 | +The main Card component accepts the following props: |
| 73 | +
|
| 74 | +[cols="1,2,1"] |
| 75 | +|=== |
| 76 | +| Name | Description | Required |
| 77 | +
|
| 78 | +| `layout` |
| 79 | +| Layout orientation: `'vertical'` or `'horizontal'` |
| 80 | +| Yes |
| 81 | +| `imageSrc` |
| 82 | +| Path to the image to display in the card |
| 83 | +| No |
| 84 | +| `imageSize` |
| 85 | +| Size of the image: `'full'` or `'small'` (default: `'small'`) |
| 86 | +| No |
| 87 | +| `iconSystem` |
| 88 | +| React component for an icon from `@neo4j-ndl/react/icons` |
| 89 | +| No |
| 90 | +| `children` |
| 91 | +| Child components (Card.Header, Card.Subheader, Card.Content) |
| 92 | +| Yes |
| 93 | +| `className` |
| 94 | +| Additional CSS classes for styling |
| 95 | +| No |
| 96 | +|=== |
| 97 | +
|
| 98 | +== Compound Components |
| 99 | +
|
| 100 | +The Card component uses a compound component pattern with three sub-components: |
| 101 | +
|
| 102 | +=== Card.Header |
| 103 | +Displays the main title of the card using `Typography variant='h5'`. |
| 104 | +
|
| 105 | +[source,tsx] |
| 106 | +---- |
| 107 | +<Card.Header>Your Card Title</Card.Header> |
| 108 | +---- |
| 109 | +
|
| 110 | +=== Card.Subheader |
| 111 | +Displays a subtitle or secondary information using `Typography variant='subheading-large'`. |
| 112 | +
|
| 113 | +[source,tsx] |
| 114 | +---- |
| 115 | +<Card.Subheader>Subtitle or description</Card.Subheader> |
| 116 | +---- |
| 117 | +
|
| 118 | +=== Card.Content |
| 119 | +Contains the main content of the card using `Typography variant='body-small'` with flex layout. |
| 120 | +
|
| 121 | +[source,tsx] |
| 122 | +---- |
| 123 | +<Card.Content> |
| 124 | + <p>Your main content here...</p> |
| 125 | + <ul>...</ul> |
| 126 | + <div>Buttons or other elements</div> |
| 127 | +</Card.Content> |
| 128 | +---- |
| 129 | +
|
| 130 | +== Key components |
| 131 | +
|
| 132 | +=== Layout System |
| 133 | +
|
| 134 | +The Card component supports two layout orientations that automatically adjust the content flow: |
| 135 | +
|
| 136 | +**Vertical Layout**: Content stacks vertically with image/icon at the top |
| 137 | +[source,tsx] |
| 138 | +---- |
| 139 | +<Card layout='vertical' imageSrc={testImg} imageSize='full'> |
| 140 | + {/* Content flows vertically */} |
| 141 | +</Card> |
| 142 | +---- |
| 143 | +
|
| 144 | +**Horizontal Layout**: Content flows horizontally with image/icon on the left |
| 145 | +[source,tsx] |
| 146 | +---- |
| 147 | +<Card layout='horizontal' imageSrc={testImg} imageSize='full' className='h-72'> |
| 148 | + {/* Content flows horizontally */} |
| 149 | +</Card> |
| 150 | +---- |
| 151 | +
|
| 152 | +=== Image and Icon Support |
| 153 | +
|
| 154 | +The component supports either images or system icons, but not both simultaneously: |
| 155 | +
|
| 156 | +**Image Support**: |
| 157 | +- `imageSize='full'`: Full-width/height image that adapts to layout |
| 158 | +- `imageSize='small'`: Small 16x16 image for minimal presence |
| 159 | +
|
| 160 | +[source,tsx] |
| 161 | +---- |
| 162 | +// Full-size image |
| 163 | +<Card layout='vertical' imageSrc={testImg} imageSize='full'> |
| 164 | + {/* Content */} |
| 165 | +</Card> |
| 166 | +
|
| 167 | +// Small image |
| 168 | +<Card layout='horizontal' imageSrc={testImg} imageSize='small'> |
| 169 | + {/* Content */} |
| 170 | +</Card> |
| 171 | +---- |
| 172 | +
|
| 173 | +**Icon Support**: Uses Neo4j Design Language icons |
| 174 | +[source,tsx] |
| 175 | +---- |
| 176 | +<Card layout='vertical' iconSystem={RocketLaunchIconOutline}> |
| 177 | + {/* Content */} |
| 178 | +</Card> |
| 179 | +---- |
| 180 | +
|
| 181 | +=== Compound Component Architecture |
| 182 | +
|
| 183 | +The Card uses React's compound component pattern, allowing flexible content composition: |
| 184 | +
|
| 185 | +[source,tsx] |
| 186 | +---- |
| 187 | +const Card: React.FC<CardProps> & { |
| 188 | + Header: React.FC<CardHeaderProps>; |
| 189 | + Subheader: React.FC<CardSubheaderProps>; |
| 190 | + Content: React.FC<CardContentProps>; |
| 191 | +} = ({ layout, imageSrc, imageSize, iconSystem, children, className }) => { |
| 192 | + // Component implementation |
| 193 | +}; |
| 194 | +
|
| 195 | +Card.Header = Header; |
| 196 | +Card.Subheader = Subheader; |
| 197 | +Card.Content = Content; |
| 198 | +---- |
| 199 | +
|
| 200 | +=== Responsive Design |
| 201 | +
|
| 202 | +The component automatically adapts to different layouts: |
| 203 | +
|
| 204 | +- **Horizontal layout**: Image takes 1/3 width, content takes 2/3 width |
| 205 | +- **Vertical layout**: Image takes full width, content stacks below |
| 206 | +- **Flexible styling**: Supports custom className for additional styling |
| 207 | +
|
| 208 | +[source,tsx] |
| 209 | +---- |
| 210 | +// Grid layout for multiple cards |
| 211 | +<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8'> |
| 212 | + {cards.map((card, index) => ( |
| 213 | + <Card key={index} layout='vertical' className='h-auto w-96'> |
| 214 | + {/* Card content */} |
| 215 | + </Card> |
| 216 | + ))} |
| 217 | +</div> |
| 218 | +---- |
| 219 | +
|
| 220 | +=== Content Flexibility |
| 221 | +
|
| 222 | +Each compound component provides semantic structure: |
| 223 | +
|
| 224 | +- **Header**: Main title with `h5` typography |
| 225 | +- **Subheader**: Secondary information with `subheading-large` typography |
| 226 | +- **Content**: Flexible container supporting any React content (text, lists, buttons, etc.) |
| 227 | +
|
| 228 | +[source,tsx] |
| 229 | +---- |
| 230 | +<Card.Content> |
| 231 | + <p>Text content</p> |
| 232 | + <ul className='list-disc list-inside'> |
| 233 | + <li>List items</li> |
| 234 | + </ul> |
| 235 | + <div className='flex justify-between'> |
| 236 | + <Button>Action 1</Button> |
| 237 | + <Button>Action 2</Button> |
| 238 | + </div> |
| 239 | +</Card.Content> |
| 240 | +---- |
0 commit comments