Skip to main content

Overview

The portfolio uses Angular’s modern standalone components architecture, eliminating the need for NgModules. Each component is self-contained with its own TypeScript class, HTML template, CSS styles, and unit tests.

Standalone Components

Starting with Angular 14+, standalone components allow you to build applications without NgModules. This portfolio leverages this modern approach for a simpler, more maintainable architecture.
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-header',
  imports: [ CommonModule ],
  templateUrl: './header.html',
  styleUrl: './header.css'
})
export class Header {
  isMenuOpen = false;
  
  toggleMenu(): void {
    this.isMenuOpen = !this.isMenuOpen;
  }

  closeMenu(): void {
    this.isMenuOpen = false;
  }

   downloadCV(): void {
    const link = document.createElement('a');
    link.href = 'CV/JhonnyDiazCenteno_CV_DesarolladorWeb.pdf';
    link.download = 'JhonnyDiazCenteno_CV_DesarolladorWeb.pdf'; 
    link.click();
  }
}
Notice the absence of standalone: true in the Header component. In Angular 19+, components are standalone by default. The standalone: true flag is only needed if explicitly declaring it for backward compatibility or clarity.

Component Structure

Each component follows a consistent four-file structure:

1. TypeScript Class (.ts)

Contains the component logic, state, and methods. Location pattern: src/app/components/[component-name]/[component-name].ts Example:
  • src/app/components/header/header.ts
  • src/app/components/hero/hero.ts
  • src/app/components/about/about.ts

2. HTML Template (.html)

Defines the component’s view structure. Location pattern: src/app/components/[component-name]/[component-name].html

3. CSS Styles (.css)

Component-scoped styles using Tailwind CSS utility classes. Location pattern: src/app/components/[component-name]/[component-name].css

4. Unit Tests (.spec.ts)

Jasmine/Karma test specifications. Location pattern: src/app/components/[component-name]/[component-name].spec.ts

Available Components

The portfolio contains six main components:

Header

Navigation bar with menu toggle and CV download functionalityLocation: src/app/components/header/

Hero

Landing section with introduction and call-to-actionLocation: src/app/components/hero/

About

Personal information and skills overviewLocation: src/app/components/about/

Projects

Portfolio showcase with project cards and detailsLocation: src/app/components/projects/

Contact

Contact form and social media linksLocation: src/app/components/contact/

Footer

Footer with links and copyright informationLocation: src/app/components/footer/

Root Application Component

The App component serves as the root component that composes all other components together.
import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { Header } from './components/header/header';
import { Hero } from './components/hero/hero';
import { About } from './components/about/about';
import { Projects } from './components/projects/projects';
import { Contact } from './components/contact/contact';
import { Footer } from './components/footer/footer';


@Component({
  selector: 'app-root',
  standalone: true, 
  imports: [RouterOutlet, Header, Hero, About, Projects, Contact, Footer],
  templateUrl: './app.html',
  styleUrl: './app.css'
})
export class App {
  protected readonly title = signal('portafolio');
 
  toggleDarkMode() {
    document.documentElement.classList.toggle('dark');
  }
}
Key features:
  1. Explicit imports: All components are imported directly in the imports array
  2. Signal-based state: Uses Angular signals for reactive state management (title)
  3. Dark mode toggle: Manipulates the dark class on the root element
  4. Single template: Renders all components in a single-page layout

Component Communication

Parent to Child

Components can receive data through @Input() decorators (when needed).

Child to Parent

Components can emit events through @Output() decorators with EventEmitter (when needed).

Shared State

The application can use Angular signals for reactive state management across components.
Since this is a single-page portfolio without complex state management needs, most components are self-contained without extensive parent-child communication.

Benefits of Standalone Components

No need to declare, import, or export components in NgModules. Each component is self-contained.
Unused components and dependencies are more easily eliminated during the build process.
Less boilerplate code and easier to understand component dependencies.
The Angular compiler can optimize standalone components more efficiently.

Testing Components

Each component includes a .spec.ts file for unit testing:
# Run all tests
ng test

# Run tests for a specific component
ng test --include='**/header.spec.ts'
Make sure to update component tests when modifying component logic to maintain code quality and prevent regressions.

Build docs developers (and LLMs) love