DEV Community

Santiago Salazar Pavajeau
Santiago Salazar Pavajeau

Posted on

React-Typescript and vanilla CSS portfolio project

I am working on my new portfolio website with react-typescript. This is a pretty simple application but a productive way to keep working with frontend technologies JS, Typescript, React, and CSS.

To get started with a react-typescript project run the following on your terminal (node, npm and typescript have to be installed previously).

npx create-react-app my-app --template typescript
Enter fullscreen mode Exit fullscreen mode

Writing a presentational component with React-typescript

In this case, I made a ProjectCard component. It will render the information of the project into a card.

import React from 'react';

export interface Project{
    title: string;
    description: string;
    demo: string;
    github: string;
    stack: string;  
}


export const ProjectCard = ({title, description, demo, github,stack}: Project) => {
    return (
        <>
            <div className="project-card">
                <h2>{title}</h2>
                <p>{description}</p>
                <button> <a href={demo}>Demo </a></button>

                <button><a href={github}>Github</a> </button>
                <p>{stack}</p>
            </div>          
        </>
    )
} 
Enter fullscreen mode Exit fullscreen mode

In the arrow function component declaration, we set the type of the argument(props) to be Project. That way when we pass the project data all the properties will be required with the corresponding type. I did not use React.FC to type the function because of this github issue and also found some context for functional components with TypeScript here.

Setting the type of the arguments to Project makes all the arguments mandatory so the method to render the cards is:

import {ProjectCard, Project} from './components/ProjectCard'

const App = () => {
  const renderProjects = () => {
    return projects.map((project: Project) => <ProjectCard title={project.title} description={project.description} demo={project.demo} github={project.github} stack={project.stack} />)
  }
 return(
  // html and components
  {renderProjects()}
  // html and components
 )
}
Enter fullscreen mode Exit fullscreen mode

When any of the ProjectCard props are missing or if they have the wrong type, TypeScript will throw an error. We import the Project interface in order to give a type to the project we are iterating through with the .map callback as well.

Vanilla CSS

In this project, I used both grid and flex side by side. Some of the highlights include using the grid to space the content horizontally into two "headers". The top "header" with my intro/profile and the bottom "header" with the projects. The settings for the horizontal grid were:

.App {
  display: grid;
  grid-template-columns: [left] 1fr [right];
}

.header{
 height: 500px;
}

.header2{
 height: 500px;
}
Enter fullscreen mode Exit fullscreen mode

The header divs have the height as their property to set how big the horizontal spaces should be.

Another interesting CSS feature I implemented was a horizontal scroll for the project cards. To do this we can add the following flex CSS properties to the header2 and the project card.

.header2{
 display: flex;
 flex-wrap: nowrap;
 overflow-x: auto;
}

.project-card{
 flex: none;
}
Enter fullscreen mode Exit fullscreen mode

These header2 properties with flex allow for the cards to keep rendering horizontally instead of creating a new row when the size of the container runs out. Then setting the flex to none on the project card allows the card to stay the same size regardless of the container size, this way the cards will stay readable and can be scrolled horizontally for navigation.

Some other CSS I added was basic responsiveness for the intro/profile header and styling to buttons. This is a work in progress so I am looking to add more features.

Source code

Feel more than welcome to reach out with any ideas/thoughts at LinkedIn or Twitter.

Top comments (0)