Full Portfolio Example
A complete portfolio page showcasing all major Projex components working together.
Features
- FeaturedProject - Hero section showcasing your best work
- ProjectGrid - Grid layout for all projects
- Interactive Controls:
- Layout toggle (grid/list)
- Filter by project type (GitHub, npm, hybrid, etc.)
- Filter by status (active, shipped, in-progress, etc.)
Code
tsx
import { FeaturedProject, ProjectGrid, ProjectCard } from '@manningworks/projex'
import { useState } from 'react'
function Portfolio() {
const [layout, setLayout] = useState<'grid' | 'list'>('grid')
const [filterType, setFilterType] = useState<string | null>(null)
const featuredProject = projects.find(p => p.id === 'featured')
const filteredProjects = projects.filter(p => {
if (filterType && p.type !== filterType) return false
return true
})
return (
<div>
<FeaturedProject project={featuredProject} />
<div className="controls">
<button onClick={() => setLayout('grid')}>Grid</button>
<button onClick={() => setLayout('list')}>List</button>
</div>
{layout === 'grid' ? (
<ProjectGrid>
{filteredProjects.map(project => (
<ProjectCard key={project.id} project={project} />
))}
</ProjectGrid>
) : (
<div className="list">
{filteredProjects.map(project => (
<ProjectCard key={project.id} project={project} />
))}
</div>
)}
</div>
)
}HTML Output
The components generate semantic HTML with data attributes for styling:
html
<!-- FeaturedProject -->
<div data-projex-featured>
<img data-projex-featured-image src="..." alt="Featured Project" />
<div data-projex-view>
<h2>Featured Project</h2>
<div data-projex-view-section data-projex-view-section-name="background">
Background story...
</div>
<div data-projex-view-section data-projex-view-section-name="why">
Why I built this...
</div>
<div data-projex-view-stats>
<span data-projex-stat="stars">1000 stars</span>
<span data-projex-stat="forks">200 forks</span>
</div>
<div data-projex-view-links>
<a href="..." data-projex-link data-projex-link-type="github">GitHub</a>
<a href="..." data-projex-link data-projex-link-type="live">Live</a>
</div>
</div>
</div>
<!-- ProjectGrid -->
<div data-projex-grid>
<div data-projex-card>
<!-- Card content -->
</div>
<div data-projex-card>
<!-- Card content -->
</div>
</div>
<!-- List view -->
<div class="list">
<div data-projex-card>
<!-- Card content -->
</div>
</div>Styling Example
CSS for the featured section and layouts:
css
/* Featured section */
[data-projex-featured] {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 48px;
border-radius: 16px;
margin-bottom: 32px;
color: #fff;
}
[data-projex-featured] h2 {
margin: 0 0 16px 0;
font-size: 2em;
}
/* Grid layout */
[data-projex-grid] {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 24px;
}
/* List layout */
.list {
display: flex;
flex-direction: column;
gap: 16px;
}
.list [data-projex-card] {
display: grid;
grid-template-columns: auto 1fr auto;
gap: 16px;
align-items: center;
padding: 16px;
border-bottom: 1px solid #e5e7eb;
}See the Styling Guide for comprehensive CSS examples.
Tips
- Use
featured: truein your project config to highlight your best work - Combine filters for more granular control
- Lazy load project data for better performance
- Add search for large project collections