Skip to content

Commit

Permalink
Merge pull request #38 from neo4j-labs/feature/cards-component
Browse files Browse the repository at this point in the history
[Components] Cards component #36
  • Loading branch information
msenechal authored Jan 7, 2025
2 parents 5ef1e78 + c3ea70a commit b7e5cce
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Cybersecurity from './templates/cybersecurity/Home';
import Movie from './templates/movie/Home';
import ECommerce from './templates/ecommerce/Home';

import DemoCards from './templates/shared/components/DemoCards';
import Chatbot from './templates/shared/components/Chatbot';
import messagesData from './templates/shared/assets/ChatbotMessages.json';
import ConnectionModal from './templates/shared/components/ConnectionModal';
Expand Down Expand Up @@ -57,6 +58,7 @@ function App() {
}
/>
<Route path='/user-preview' element={<User />} />
<Route path='/cards-preview' element={<DemoCards />} />
<Route path='*' element={<PageNotFound />} />
</Routes>
</ThemeWrapper>
Expand Down
Binary file added src/assets/img/component/CardImg-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/component/CardImg-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions src/landingPage/categories/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import Card from '../components/Card';
import ChatbotImgDark from '../../assets/img/component/ChatbotImg-dark.png';
import ConnectionModalImgDark from '../../assets/img/component/ConnectionModalImg-dark.png';
import HeaderImgDark from '../../assets/img/component/HeaderImg-dark.png';
import CardImgDark from '../../assets/img/component/CardImg-dark.png';

// Light mode featured images
import ChatbotImgLight from '../../assets/img/component/ChatbotImg-light.png';
import ConnectionModalImgLight from '../../assets/img/component/ConnectionModalImg-light.png';
import HeaderImgLight from '../../assets/img/component/HeaderImg-light.png';
import CardImgLight from '../../assets/img/component/CardImg-light.png';

import { useContext } from 'react';
import { ThemeWrapperContext } from '../../context/ThemeWrapper';
Expand Down Expand Up @@ -48,6 +50,16 @@ export default function Component() {
}/src/templates/shared/components/Header.tsx`,
previewLink: '/header-preview',
},
{
title: 'Card',
description:
'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.',
image: colorMode === 'dark' ? CardImgDark : CardImgLight,
sourceCode: `https://github.com/neo4j-labs/neo4j-needle-starterkit/blob/${
import.meta.env.PACKAGE_VERSION
}/src/templates/shared/components/Card.tsx`,
previewLink: '/cards-preview',
},
];

return (
Expand Down
Binary file added src/templates/shared/assets/cardImg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 75 additions & 0 deletions src/templates/shared/components/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Box, Typography } from '@neo4j-ndl/react';
import React, { ReactNode } from 'react';

interface CardProps {
layout: 'vertical' | 'horizontal';
imageSrc?: string;
imageSize?: 'full' | 'small';
iconSystem?: React.ComponentType<React.SVGProps<SVGSVGElement>>;
children: ReactNode;
className?: string;
}

interface CardHeaderProps {
children: ReactNode;
}

interface CardSubheaderProps {
children: ReactNode;
}

interface CardContentProps {
children: ReactNode;
}

const Card: React.FC<CardProps> & {
Header: React.FC<CardHeaderProps>;
Subheader: React.FC<CardSubheaderProps>;
Content: React.FC<CardContentProps>;
} = ({ layout, imageSrc, imageSize = 'small', iconSystem, children, className }) => {
return (
<Box
className={`n-bg-palette-neutral-bg-weak border rounded-3xl shadow-lg mx-auto ${layout === 'horizontal' ? 'flex' : 'block'} ${className}`}
style={{ padding: 0 }}
>
<div className={`n-bg-palette-neutral-bg-weak border rounded-3xl shadow-lg mx-auto ${layout === 'horizontal' ? 'flex' : 'block'} ${className}`}>
{imageSrc && (
<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')}`}>
<img
src={imageSrc}
alt="Card Image"
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'}`}

/>
</div>
)}
{iconSystem && (
<div className='p-4'>
{React.createElement(iconSystem, { className: 'w-8 h-8' })}
</div>
)}
<div className={`p-4 ${layout === 'horizontal' ? 'flex flex-col justify-between w-2/3' : ''}`}>
{children}
</div>
</div>
</Box>
);
}

const Header: React.FC<CardHeaderProps> = ({ children }) => (
<Typography variant="h5" className="mb-2">{children}</Typography>
);

const Subheader: React.FC<CardSubheaderProps> = ({ children }) => (
<Typography variant="subheading-large" className="mb-2">{children}</Typography>
);

const Content: React.FC<CardContentProps> = ({ children }) => (
<Typography variant="body-small" className='flex flex-col gap-3'>{children}</Typography>
);

Card.Header = Header;
Card.Subheader = Subheader;
Card.Content = Content;

export default Card;
91 changes: 91 additions & 0 deletions src/templates/shared/components/DemoCards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import Card from './Card';
import testImg from '../assets/cardImg.png';
import { Button, Typography } from '@neo4j-ndl/react';
import { AcademicCapIconOutline, RocketLaunchIconOutline } from '@neo4j-ndl/react/icons';

export default function DemoCards() {
return (
<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">
<Card layout="vertical" imageSrc={testImg} imageSize="full" className="h-auto w-96">
<Card.Header>Header text</Card.Header>
<Card.Subheader>Subtitle or description</Card.Subheader>
<Card.Content>
<p>Some description about relatively important things but not too long since this is a card component.</p>
<ul className="list-disc list-inside">
<li>1 Key information</li>
<li>12.59 Key information</li>
<li>3 Key information</li>
</ul>
<div className='flex flex-row min-w-full justify-between'>
<Button size='small' color='danger' className='w-2/5 mx-2.5'><Typography variant="body-small">Cancel</Typography></Button>
<Button size='small' color='primary' className='w-2/5 mx-2.5'><Typography variant="body-small">Sign</Typography></Button>
</div>
</Card.Content>
</Card>

<Card layout="vertical" imageSrc={testImg} imageSize="full" className="h-auto w-96">
<Card.Content>
<p>Some description about relatively important things but not too long since this is a card component.</p>
<ul className="list-disc list-inside">
<li>18 Key information</li>
<li>12.59 Key information</li>
<li>5 Key information</li>
</ul>
</Card.Content>
</Card>

<Card layout="vertical" className="h-auto w-96" iconSystem={RocketLaunchIconOutline}>
<Card.Header>Header text</Card.Header>
<Card.Content>
<p>Some description about relatively important things but not too long since this is a card component.</p>
<ul className="list-disc list-inside">
<li>18 Key information</li>
<li>12.59 Key information</li>
<li>5 Key information</li>
</ul>
</Card.Content>
</Card>

<Card layout="horizontal" imageSrc={testImg} imageSize="full" className="h-72">
<Card.Header>Header text</Card.Header>
<Card.Subheader>Subtitle or description</Card.Subheader>
<Card.Content>
<p>Some description about relatively important things but not too long since this is a card component.</p>
<ul className="list-disc list-inside">
<li>18 Key information</li>
<li>12.59 Key information</li>
<li>5 Key information</li>
</ul>
<div className='flex flex-row min-w-full justify-between'>
<Button size='small' color='danger' className='w-2/5 mx-2.5'><Typography variant="body-small">Cancel</Typography></Button>
<Button size='small' color='primary' className='w-2/5 mx-2.5'><Typography variant="body-small">Sign</Typography></Button>
</div>
</Card.Content>
</Card>

<Card layout="horizontal" imageSrc={testImg} imageSize="full" className="h-44">
<Card.Content>
<p>Some description about relatively important things but not too long since this is a card component.</p>
<ul className="list-disc list-inside">
<li>1 Key information</li>
<li>12.59 Key information</li>
<li>3 Key information</li>
</ul>
</Card.Content>
</Card>

<Card layout="horizontal" iconSystem={AcademicCapIconOutline}>
<Card.Header>Header text</Card.Header>
<Card.Content>
<p>Some description about relatively important things but not too long since this is a card component.</p>
<ul className="list-disc list-inside">
<li>18 Key information</li>
<li>12.59 Key information</li>
<li>5 Key information</li>
</ul>
</Card.Content>
</Card>

</div>
);
}

0 comments on commit b7e5cce

Please sign in to comment.