This is a solution to the Tip calculator app challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.
Users should be able to:
- View the optimal layout for the app depending on their device's screen size
- See hover states for all interactive elements on the page
- Calculate the correct tip and total cost of the bill per person
- Semantic HTML5 markup
- CSS custom properties
- Flexbox
- CSS Grid
- Mobile-first workflow
- React - JS library
- Next.js - React framework
- Styled Components - For styles
Note: These are just examples. Delete this note and replace the list above with your own choices
-
<form action="#" novalidate>
This ensures that the form does not submit anywhere and does not perform any validation. -
The
element is a convenient way to create groups of widgets that share the same purpose, for styling and semantic purposes. You can label a by including a element just below the opening tag. -
The HTML element is a container element into which a site or app can inject the results of a calculation or the outcome of a user action.
const form = document.querySelector(".tip-calculator") as HTMLFormElement;
const formData = new FormData(form);
const data = Object.fromEntries(formData);
// {billAmount: '', tip-percentage: '5', numberOfPeople: ''}
- I tried to hide the radio button, while I am using grid for my layout,
display: none
on the.select-tip__radio[type="radio"]
seems to work, but lost the accessibility, so below is better
.select-tip__radio[type="radio"] {
position: absolute;
opacity: 0;
pointer-events: none;
}
- When changing checked color of the label, need to select checked on the radio button
input[type="radio"]:checked + label {
background-color: var(--color-button-tip-selected);
color: var(--color-button-tip-text-selected);
}
- I put a input below the radio button label in the sane div, and put it to disabled and use CSS to set
pointer-events: none
. So user can select the custom radio label just as the other.
<div class="select-tip__custom-container">
<input
class="select-tip__radio select-tip__radio--custom"
type="radio"
id="tip-percentage-custom"
name="tip-percentage"
value="0"
/>
<label
class="select-tip__radio-label select-tip__radio-label--custom"
for="tip-percentage-custom"
>
</label>
<input
type="number"
class="select-tip__radio-custom-input"
name="tip-percentage-custom-input"
placeholder="Custom"
min="0"
autocomplete="off"
disabled
/>
</div>
- When the user selected the custom radio label I use JS to set the input
disabled = false
, setpointer-events: auto
and focus on the input.
if (target.id === "tip-percentage-custom") {
customInput.disabled = false;
customInput.style.pointerEvents = "auto";
customInput.focus();
} else {
customInput.disabled = true;
customInput.style.pointerEvents = "none";
customInput.value = "";
}
- In TypeScript, the Record<K, T> utility type is used to define an object type with a set of keys K and a set of values T. It essentially represents an object where every key has a specific value type.
-
toFixed() will also not round correctly in some cases, also it return a string.
parseFloat("1.555").toFixed(2); // Returns 1.55 instead of 1.56. parseFloat("1.5550").toFixed(2); // Returns 1.55 instead of 1.56. // However, it will return correct result if you round 1.5551. parseFloat("1.5551").toFixed(2); // Returns 1.56 as expected.
-
using the Math.round() function, problem it will not leave 2 decimal place.
var a = 5.678948;
let b = 10.257683;
let c = 6.6456583;
let result1 = Math.round(a * 100) / 100;
let result2 = Math.round(b * 10) / 10;
let result3 = Math.round(x * 1000) / 1000;
console.log(result1); // 5.68
console.log(result2); // 10.3
console.log(typeof result2); // 6.646
- use
aria-live="polite"
for displaying error
- improve the accessibility on the screen reader reading the Tip Amount per person and the result.
- How to structure a web form - Learn how to use with radio input. Learn how to use
, for radio button to build a simple payment form with good html semantic elements. - How to stop form submission using JavaScript?
- Client-side form validation
-how to create a custom Input radio button which have attributes inside it - show me basic, how to style an input
- CodePen Home Radio button without the dot - a simple example
- Pure CSS - SVG Radio Selector Buttons - advance example
- Styling Radio Buttons with CSS (59 Custom Examples) - 59 different examples
- Custom Styling Radio Buttons: The Modern Way
- How TO - Custom Checkbox
- HTML Forms: Radio buttons with text fields - How to add custom tips in radio button
- Design your service using GOV.UK styles, components and patterns - Use this design system to make government services consistent with GOV.UK. Learn from the research and experience of other service teams and avoid repeating work that’s already been done.
- Website - Edward Pau
- Frontend Mentor - @edpau