Components
Projex provides compound components for building project showcase pages. All components ship with zero styling - only semantic HTML with data attributes for CSS targeting.
Available Components
Preset Components
| Component | Description |
|---|---|
| GitHubCard | Pre-built card for GitHub projects with stars, forks, language, and commits |
| NpmCard | Pre-built card for npm packages with downloads, version, and npm link |
| ShowcaseCard | Pre-built card for manual projects with live link and tech stack |
Core Components
| Component | Description |
|---|---|
| ProjectCard | Card component for displaying individual project summaries |
| ProjectView | Full page view for detailed project information |
| ProjectGrid | Container for grid layout of projects |
| SmartProjectGrid | Turnkey client component with built-in search, filters, and sort |
| ProjectList | Container for list layout of projects |
| FeaturedProject | Featured project hero section |
| ProjectTypeFilterBar | Data-driven filter bar for project types |
| ProjectStatusFilterBar | Data-driven filter bar for project statuses |
Design Principles
Compound Components
Components use the compound pattern for maximum flexibility. Consumers compose their own layout by combining subcomponents:
tsx
<ProjectCard>
<ProjectCard.Header project={project} />
<ProjectCard.Description project={project} />
<ProjectCard.Tags project={project} />
<ProjectCard.Stats project={project} />
<ProjectCard.Links project={project} />
</ProjectCard>Sub-components accept an optional project prop. When used inside a SmartProjectGrid, the project prop can be omitted and the component will read the project from context via ProjectGridProvider.
tsx
<SmartProjectGrid projects={projects} showSearch showFilters>
{(project) => (
<ProjectCard>
<ProjectCard.Header />
<ProjectCard.Description />
<ProjectCard.Tags />
<ProjectCard.Stats />
<ProjectCard.Links />
</ProjectCard>
)}
</SmartProjectGrid>Data Attributes
Every rendered element includes a data-projex-* attribute for styling hooks:
css
[data-projex-card] {
border: 1px solid #e5e7eb;
border-radius: 8px;
padding: 1.5rem;
}
[data-projex-card-header] {
display: flex;
justify-content: space-between;
}Conditional Rendering
Subcomponents return null when data is missing. No empty wrappers or placeholder text:
tsx
<ProjectCard.Tags project={project} /> {/* null if project.stack is empty */}
<ProjectCard.Stats project={project} /> {/* null if project.stats is null */}