Skip to content

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

ComponentDescription
GitHubCardPre-built card for GitHub projects with stars, forks, language, and commits
NpmCardPre-built card for npm packages with downloads, version, and npm link
ShowcaseCardPre-built card for manual projects with live link and tech stack

Core Components

ComponentDescription
ProjectCardCard component for displaying individual project summaries
ProjectViewFull page view for detailed project information
ProjectGridContainer for grid layout of projects
SmartProjectGridTurnkey client component with built-in search, filters, and sort
ProjectListContainer for list layout of projects
FeaturedProjectFeatured project hero section
ProjectTypeFilterBarData-driven filter bar for project types
ProjectStatusFilterBarData-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 */}