Challenge: https://www.frontendmentor.io/challenges/pomodoro-app-KBFnycJ6G
FrontendMentor challenges are provided as ready for implementation designs and described functionality. Recently I discovered and played a bit with the AlpineJS and Tailwind frameworks and this project look like something that I can try to build using these technologies.
The idea of a Pomodoro technique is that during the day you can block chunks of time of 25 minutes and try to focus on doing one thing, without any destructions.
In the FrontendMentor's design the idea is evolved to have 3 shortcut values to set common time-chunks of 25, 5 and 15 minutes. Futhermore these values can then be changed in the application settings.
Original design providing the circled progress-bar that runs clockwise and time increments accordingly, however this part I changed to my liking - progress bar and time actually reducing values, rather than increasing them. So instead of going from 00:00 to 25:00, this implementation goes from 25:00 to 00:00 in the end.
Main Features:
- Ability to Start 3 types of timers
- Ability to change visual of the app
- Ability to pause, start and restart the timer
- Ability to customize each of the timers
That 100vh on mobile browsers is painful experience as of today, they don't respect this property and page looks cropped when address bar is visible. With this project it was super critical to be able to show settings button on one screen without cropping (Firefox) or scrolling extra pixels (Chrome).
I found a great article CSS Tricks: The trick to viewport units on mobile and used it with AlpineJS, thought without conversion to VH units, since it was enough for my use-case.
One of the challenging parts of this project is big button with radial progress bar and text on top of it. I thought that with CSS building it might be tricky and we as developers have a great SVG technology.
ATM I am not entirely happy with the result, moving between stops are a bit chunky even with the transitions. And there are a few great demos/articles that helped me to build this functionality
I was initially skeptical about the utility-based framework, but surprisingly I did ended up spending a lot less time on writing CSS and build size of resulted CSS is quite good as well - only ~20Kb!
I learned that you can actually implement your specific design system with editing the tailwind.config.js. A good idea for several branded sites is to have one shared tailwind config, which seem to be able to help with keeping consistent styles for all small landing pages for one company.
I was wondering, is there a place to set all text colors to specific value, and that way cleanup the html by removing unnecessary classes, and you actually can do it writing base styles!
I usually use JetBrains IDE's at work, and quite used to them, but finding out these amazing extensions for VSCode made me a lot more productive
- TailwindCSS IntelliSense This extension dynamically show you which tailwind classes you can use. But what I did not expected is that when you define a colour pallet for your project, it will actually generate class names with the things defined in the tailwind.config.js
- Headwind I found this extension a bit later on the road, but it is exactly what I was struggling with - automatically ordering the classes in the html elements. A lifesaver tool for me!
AlpineJS is kinda not designed to build applications, but rather to sparkle a bit of
interactivity to the static pages. We add this functionality by creating kinda small components,
and each component can have a scoped state if you use x-data
In the case of this project, I thought that it makes sense
to have
It is expected that this small framework could not include forms functionality, but here is a few things: first, there is awesome x-model property that let's you sync both ways data in the component and form input. With validation however everything starting to be messy really quickly. For this project it was fine to use a bit of hardcode to make 3 identical number inputs work and work with validation, however for bigger form I would add extra library/use different framework.
The main tools that I used with this project:
-
Alpine JS - A micro frontend framework with syntax similar to Vue JS. Amazing how easily you can add interactions to the single-page apps without heavy frameworks. In this projects the bigger framework might fit better (mostly because handling forms and validation is not a strong side of alpine), but in the end the Framework did its job and pretty well.
-
Tailwind CSS - Is a utility-based CSS framework. ideally you need to setup your deign system in tailwind.config.js file and use only utility functions in the code, no writing classes in CSS needed. It looks ugly on the first glance -> 10-20 classes putted in the HTML element, but there is a huge benefit of local scoped styles and that your CSS does not grow as you add new features to the application. In this project IMo Tailwind was a huge deal for me, allowing to style modal window with all the settings in less than hour.
I also used some tools that brings joy to the development process :)
- Husky - A really nice tool to run formatting and linting automatically before you commit the code, makes your git history a pleasant experience
- Prettier - Opinionated code formatter, I do like that I no longer need to worry about poorly formatted code. And a huge benefit that it can also format CSS and HTML files!
- Snowpack - Like webpack but so much faster and requires less configuration. Initially I was planning to go with Parcel - my goto build tool that requires zero configuration, but sadly support for PostCSS v8 was not there, and hot-reload of styles did not worked at all for the Tailwind part of the project. I was pleasantly surprised how Snowpack handled the PostCSS part without too much hassle.
-
First of all you would need a Node installed. See the latest instructions here. After this step is completed, check that NPM tool is available to you by running
npm -v
command, that should output to the console the current NPM version installed. -
Then you would need to install project dependencies from the package.json file, by running the
npm install
command. This command will install project dependencies to run the project locally and also all development tools that make developing this project more pleasant. -
npm run dev
will start the development server and automatically openlocalhost:8080
page in your default browser, so you should be able right away to see the project and try making changes in the codebase.