Skip to content

Commit b7e5cce

Browse files
authored
Merge pull request #38 from neo4j-labs/feature/cards-component
[Components] Cards component #36
2 parents 5ef1e78 + c3ea70a commit b7e5cce

File tree

7 files changed

+180
-0
lines changed

7 files changed

+180
-0
lines changed

src/App.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Cybersecurity from './templates/cybersecurity/Home';
1313
import Movie from './templates/movie/Home';
1414
import ECommerce from './templates/ecommerce/Home';
1515

16+
import DemoCards from './templates/shared/components/DemoCards';
1617
import Chatbot from './templates/shared/components/Chatbot';
1718
import messagesData from './templates/shared/assets/ChatbotMessages.json';
1819
import ConnectionModal from './templates/shared/components/ConnectionModal';
@@ -57,6 +58,7 @@ function App() {
5758
}
5859
/>
5960
<Route path='/user-preview' element={<User />} />
61+
<Route path='/cards-preview' element={<DemoCards />} />
6062
<Route path='*' element={<PageNotFound />} />
6163
</Routes>
6264
</ThemeWrapper>
63.4 KB
Loading
63.8 KB
Loading

src/landingPage/categories/Component.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import Card from '../components/Card';
55
import ChatbotImgDark from '../../assets/img/component/ChatbotImg-dark.png';
66
import ConnectionModalImgDark from '../../assets/img/component/ConnectionModalImg-dark.png';
77
import HeaderImgDark from '../../assets/img/component/HeaderImg-dark.png';
8+
import CardImgDark from '../../assets/img/component/CardImg-dark.png';
89

910
// Light mode featured images
1011
import ChatbotImgLight from '../../assets/img/component/ChatbotImg-light.png';
1112
import ConnectionModalImgLight from '../../assets/img/component/ConnectionModalImg-light.png';
1213
import HeaderImgLight from '../../assets/img/component/HeaderImg-light.png';
14+
import CardImgLight from '../../assets/img/component/CardImg-light.png';
1315

1416
import { useContext } from 'react';
1517
import { ThemeWrapperContext } from '../../context/ThemeWrapper';
@@ -48,6 +50,16 @@ export default function Component() {
4850
}/src/templates/shared/components/Header.tsx`,
4951
previewLink: '/header-preview',
5052
},
53+
{
54+
title: 'Card',
55+
description:
56+
'A versatile card component that can be used to display information in a clean and organized way. It is designed to be easily customizable to fit your needs.',
57+
image: colorMode === 'dark' ? CardImgDark : CardImgLight,
58+
sourceCode: `https://github.com/neo4j-labs/neo4j-needle-starterkit/blob/${
59+
import.meta.env.PACKAGE_VERSION
60+
}/src/templates/shared/components/Card.tsx`,
61+
previewLink: '/cards-preview',
62+
},
5163
];
5264

5365
return (
18.6 KB
Loading
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { Box, Typography } from '@neo4j-ndl/react';
2+
import React, { ReactNode } from 'react';
3+
4+
interface CardProps {
5+
layout: 'vertical' | 'horizontal';
6+
imageSrc?: string;
7+
imageSize?: 'full' | 'small';
8+
iconSystem?: React.ComponentType<React.SVGProps<SVGSVGElement>>;
9+
children: ReactNode;
10+
className?: string;
11+
}
12+
13+
interface CardHeaderProps {
14+
children: ReactNode;
15+
}
16+
17+
interface CardSubheaderProps {
18+
children: ReactNode;
19+
}
20+
21+
interface CardContentProps {
22+
children: ReactNode;
23+
}
24+
25+
const Card: React.FC<CardProps> & {
26+
Header: React.FC<CardHeaderProps>;
27+
Subheader: React.FC<CardSubheaderProps>;
28+
Content: React.FC<CardContentProps>;
29+
} = ({ layout, imageSrc, imageSize = 'small', iconSystem, children, className }) => {
30+
return (
31+
<Box
32+
className={`n-bg-palette-neutral-bg-weak border rounded-3xl shadow-lg mx-auto ${layout === 'horizontal' ? 'flex' : 'block'} ${className}`}
33+
style={{ padding: 0 }}
34+
>
35+
<div className={`n-bg-palette-neutral-bg-weak border rounded-3xl shadow-lg mx-auto ${layout === 'horizontal' ? 'flex' : 'block'} ${className}`}>
36+
{imageSrc && (
37+
<div className={`relative overflow-hidden ${layout === 'horizontal' ? (imageSize === 'full' ? 'w-1/3' : 'w-16 h-16 mr-4') : (imageSize === 'full' ? 'w-full h-64' : 'w-16 h-16 mb-4')}`}>
38+
<img
39+
src={imageSrc}
40+
alt="Card Image"
41+
className={`${imageSize === 'full' ? 'object-cover w-full h-full' : 'object-cover w-16 h-16'} ${layout === 'horizontal' ? 'rounded-tl-3xl rounded-bl-3xl' : 'rounded-tl-3xl rounded-tr-3xl'}`}
42+
43+
/>
44+
</div>
45+
)}
46+
{iconSystem && (
47+
<div className='p-4'>
48+
{React.createElement(iconSystem, { className: 'w-8 h-8' })}
49+
</div>
50+
)}
51+
<div className={`p-4 ${layout === 'horizontal' ? 'flex flex-col justify-between w-2/3' : ''}`}>
52+
{children}
53+
</div>
54+
</div>
55+
</Box>
56+
);
57+
}
58+
59+
const Header: React.FC<CardHeaderProps> = ({ children }) => (
60+
<Typography variant="h5" className="mb-2">{children}</Typography>
61+
);
62+
63+
const Subheader: React.FC<CardSubheaderProps> = ({ children }) => (
64+
<Typography variant="subheading-large" className="mb-2">{children}</Typography>
65+
);
66+
67+
const Content: React.FC<CardContentProps> = ({ children }) => (
68+
<Typography variant="body-small" className='flex flex-col gap-3'>{children}</Typography>
69+
);
70+
71+
Card.Header = Header;
72+
Card.Subheader = Subheader;
73+
Card.Content = Content;
74+
75+
export default Card;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import Card from './Card';
2+
import testImg from '../assets/cardImg.png';
3+
import { Button, Typography } from '@neo4j-ndl/react';
4+
import { AcademicCapIconOutline, RocketLaunchIconOutline } from '@neo4j-ndl/react/icons';
5+
6+
export default function DemoCards() {
7+
return (
8+
<div className="min-h-screen max-h-full p-8 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 n-bg-palette-neutral-bg-default">
9+
<Card layout="vertical" imageSrc={testImg} imageSize="full" className="h-auto w-96">
10+
<Card.Header>Header text</Card.Header>
11+
<Card.Subheader>Subtitle or description</Card.Subheader>
12+
<Card.Content>
13+
<p>Some description about relatively important things but not too long since this is a card component.</p>
14+
<ul className="list-disc list-inside">
15+
<li>1 Key information</li>
16+
<li>12.59 Key information</li>
17+
<li>3 Key information</li>
18+
</ul>
19+
<div className='flex flex-row min-w-full justify-between'>
20+
<Button size='small' color='danger' className='w-2/5 mx-2.5'><Typography variant="body-small">Cancel</Typography></Button>
21+
<Button size='small' color='primary' className='w-2/5 mx-2.5'><Typography variant="body-small">Sign</Typography></Button>
22+
</div>
23+
</Card.Content>
24+
</Card>
25+
26+
<Card layout="vertical" imageSrc={testImg} imageSize="full" className="h-auto w-96">
27+
<Card.Content>
28+
<p>Some description about relatively important things but not too long since this is a card component.</p>
29+
<ul className="list-disc list-inside">
30+
<li>18 Key information</li>
31+
<li>12.59 Key information</li>
32+
<li>5 Key information</li>
33+
</ul>
34+
</Card.Content>
35+
</Card>
36+
37+
<Card layout="vertical" className="h-auto w-96" iconSystem={RocketLaunchIconOutline}>
38+
<Card.Header>Header text</Card.Header>
39+
<Card.Content>
40+
<p>Some description about relatively important things but not too long since this is a card component.</p>
41+
<ul className="list-disc list-inside">
42+
<li>18 Key information</li>
43+
<li>12.59 Key information</li>
44+
<li>5 Key information</li>
45+
</ul>
46+
</Card.Content>
47+
</Card>
48+
49+
<Card layout="horizontal" imageSrc={testImg} imageSize="full" className="h-72">
50+
<Card.Header>Header text</Card.Header>
51+
<Card.Subheader>Subtitle or description</Card.Subheader>
52+
<Card.Content>
53+
<p>Some description about relatively important things but not too long since this is a card component.</p>
54+
<ul className="list-disc list-inside">
55+
<li>18 Key information</li>
56+
<li>12.59 Key information</li>
57+
<li>5 Key information</li>
58+
</ul>
59+
<div className='flex flex-row min-w-full justify-between'>
60+
<Button size='small' color='danger' className='w-2/5 mx-2.5'><Typography variant="body-small">Cancel</Typography></Button>
61+
<Button size='small' color='primary' className='w-2/5 mx-2.5'><Typography variant="body-small">Sign</Typography></Button>
62+
</div>
63+
</Card.Content>
64+
</Card>
65+
66+
<Card layout="horizontal" imageSrc={testImg} imageSize="full" className="h-44">
67+
<Card.Content>
68+
<p>Some description about relatively important things but not too long since this is a card component.</p>
69+
<ul className="list-disc list-inside">
70+
<li>1 Key information</li>
71+
<li>12.59 Key information</li>
72+
<li>3 Key information</li>
73+
</ul>
74+
</Card.Content>
75+
</Card>
76+
77+
<Card layout="horizontal" iconSystem={AcademicCapIconOutline}>
78+
<Card.Header>Header text</Card.Header>
79+
<Card.Content>
80+
<p>Some description about relatively important things but not too long since this is a card component.</p>
81+
<ul className="list-disc list-inside">
82+
<li>18 Key information</li>
83+
<li>12.59 Key information</li>
84+
<li>5 Key information</li>
85+
</ul>
86+
</Card.Content>
87+
</Card>
88+
89+
</div>
90+
);
91+
}

0 commit comments

Comments
 (0)