Skip to content

A simple app that presents an age in years, months, and days. Challenge by frontendmentor.io

Notifications You must be signed in to change notification settings

Pensive1/FEM-age-calculator-app

Repository files navigation

Frontend Mentor - Age calculator app solution

This is a solution to the Age calculator app challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.

Table of contents

Overview

The challenge

Users should be able to:

  • View an age in years, months, and days after submitting a valid date through the form
  • Receive validation errors if:
    • Any field is empty when the form is submitted
    • The day number is not between 1-31
    • The month number is not between 1-12
    • The year is in the future
    • The date is invalid e.g. 31/04/1991 (there are 30 days in April)
  • View the optimal layout for the interface depending on their device's screen size
  • See hover and focus states for all interactive elements on the page
  • Bonus: See the age numbers animate to their final number when the form is submitted

Screenshot

Preview of the age calculator

Main features

  • Responsive animated age calculator
  • Two-layer form field validation (HTML + JavaScript)
  • Auto-focus to next field after entering two valid digits

Links

My process

  1. Programmed the detailed age function
  2. Created the basic HTML for UI components
  3. Analysed element dimensions in Figma
  4. Styled the UI (mobile first)
  5. Added media queries for the desktop breakpoint
  6. Programmed validation functions
  7. Programmed the 'count-up' number animation
  8. Refactored and split functions into util files
  9. Created a basic test script for the calculator function

Built with

  • Vite
  • React - JS library
  • JavaScript
  • TypeScript
  • Sass (SCSS)
  • Mobile-first workflow
  • DOM Constraint API - Field validation
  • Vitest

What I learned

CSS

  1. Fluid font sizing can be achieved using the clamp function and flexbox:
.age {
  padding-top: 8rem;
  font-size: clamp($size-input, 6.4rem, 14vw);
  font-weight: 800;
  font-style: italic;
  line-height: 7rem;
  @include desktop {
    padding-top: 6rem;
    font-size: 10.5rem;
    line-height: 12rem;
  }

  &__data {
    display: flex;
    gap: 1rem;
  }

  &__unit {
    flex-shrink: 1;
  }
}
  1. Using translate with percentage values moves the element based on its own dimensions.

React

  1. useRef is not only used for getting a value but for accessing DOM properties of a referenced node. This was useful for field validation. Other than that, its great for getting a value without changing states.

  2. onBlur is React's equivalent of JavaScripts onFocusOut event.

  3. State update functions can be passed into utility functions as callbacks. It is then executed in the utility function body.

TypeScript for React

  • React.SyntheticEvent is used to define an event type when adding an event listener. Other forms of event types are:
    • KeyboardEvent: For key presses
    • FormEvent: For use with onInput

JavaScript

  • Timers (setInterval and setTimeout) need to be assigned to a variable. Else, there's no way to reference them when calling clearInterval/ clearTimeout.

  • Modulo operator: dividing a value by 0 returns NaN.

    In the count up function (animation utils), if targetVal was divided by 0, the result will be NaN creating a bug which causes the setInterval function to loop infinately. To fix this, we use the ternary operator to define the values per case:

    const remainder = steps > 0 ? targetVal % steps : 0;
  • e.preventDefault isn't only used for preventing form submission or hyperlinks. Additionally, it can be used to prevent certain letters from being entered in a form.

    The 'e' (Eulers number), '+' and '-' values are used to represent numbers. However, 'e' or 'E' sets the badInput validation value to true, triggering the field's invalid state.

    On top of validating against bad inputs, it improves the user experience to prevent these characters from being entered.

Deployment (GitHub Pages)

I learned how to deploy an automated vite app build using GitHub Actions and configuring vite.config accordingly. This was my first time working with GitHub Actions and would love to learn more things I could automate.

Continued development

Useful resources

Author

Acknowledgments

About

A simple app that presents an age in years, months, and days. Challenge by frontendmentor.io

Topics

Resources

Stars

Watchers

Forks