├── LICENSE ├── README.md ├── banner.png ├── coding-challenges └── challenges.md ├── components ├── README.md └── assets │ └── challenge-1.png └── trivia-questions ├── css.md ├── html.md ├── javascript.md ├── tailwindcss.md └── typescript.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Codetive 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![banner](banner.png) 2 | 3 | # Frontend Coding Challenges 4 | 5 | Welcome to the **Frontend Coding Challenges** repository! 6 | 7 | This repository is a collection of coding questions & challenges designed to help you improve your frontend development skills. 8 | 9 | ## Introduction 10 | 11 | This repository is part of the **Codetive** learning platform which launched its beta version on 30th September 2024. You can visit the platform [here](https://codetive.dev). 12 | 13 | The questions are organized by: 14 | - **Category** 15 | - 🥊 **Coding challenges**: Solve coding problems with our built-in code editor, complete with a preview, console, and automated tests—just like LeetCode! [practical, interview, algorithms, apis] 16 | 17 | - 📝 **Trivia questions**: Test your knowledge with quick, engaging web development quizzes. [quick, fun, reinforced learning, not practical for interview] 18 | 19 | - 📦**Components**: Tackle frontend challenges with provided UI and Figma files to bring designs to life. [interview, portfolio, practical, ui, figma] 20 | 21 | - **Difficulty** 22 | - Beginner 23 | - Intermediate 24 | - Advanced 25 | - Expert 26 | 27 | - **Language** 28 | - HTML 29 | - CSS 30 | - Javascript 31 | - Typescript 32 | - Tailwind 33 | - React (soon...) 34 | - Nextjs (soon...) 35 | - Nodejs (soon...) 36 | 37 | 38 | On top of that, on Codetive app all questions and challenges are sorted by tags such as **portoflio**, **interview**, **first job** etc. 39 | 40 | Codetive app will allow you to track progress, suggest weak areas and prepare learning paths for you. 41 | 42 | *Coding challenges and components are work in progress...* 43 | 44 | The trivia questions are organized by technology (HTML, CSS, JavaScript, Tailwind CSS, TypeScript) and difficulty levels (Beginner, Intermediate, Advanced, Expert). 45 | 46 | > **Note:** Trivia and are intended for fun and educational purposes. They are not necessarily reflective of the types of questions you would encounter in a real interview. So if you're preparing for an interview skip them or check out only advanced/expert ones, don't spend much time on them though. 47 | 48 | 49 | ## 🛠️ How to Report Bugs 50 | 51 | If you encounter any issues and mistakes please report it here: 52 | 53 | - **Report an Issue:** Navigate to the [Issues page](https://github.com/Codetive/frontend-coding-challenges/issues) and create a new issue. Please include a detailed description and, if possible, a screenshot. 54 | - **Submit a Pull Request (PR):** If you have a fix or questions you want to include feel free to fork the repo, make your changes, and submit a [Pull Request](https://github.com/your-repo/frontend-challenges/pulls). Check the detailed guide about PRs [Here](https://github.com/Codetive/frontend-coding-challenges#contribute) 55 | 56 | -------------------------------------------------------------------------------- /banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codetive/frontend-coding-challenges/c437bd2158409fc3149cb32b51c60698bb163f5a/banner.png -------------------------------------------------------------------------------- /coding-challenges/challenges.md: -------------------------------------------------------------------------------- 1 | *Each of the challenge you can do interactively on the Codetive app (launching late September 2024). Order of the questions might differ* 2 | 3 | --- 4 | 5 | Let's start with 2 short and quick warmup questions, so you can get familiar with the question template. 6 | 7 | ## 1. Sum of Two Numbers (warmup) 8 | 9 | **Objective**: Write a function that takes two numbers as input and returns their sum. 10 | 11 | **Instructions**: 12 | 13 | 1. Write a function named `sum` that accepts two arguments (both numbers). 14 | 2. The function should return the sum of the two input numbers. 15 | 16 | **Expected Output**: 17 | 18 | ```js 19 | sum(5, 3); // Output: 8 20 | sum(10, -2); // Output: 8 21 | ``` 22 | 23 | **Requirements**: 24 | 25 | - Function should return the sum of the two input numbers 26 | - Function works correctly with both positive and negative numbers 27 | - Function handles invalid inputs 28 | 29 | 30 | ## 2. Counter (warmup) 31 | 32 | *Beginner | Javascript/Typescript/React* 33 | 34 | **Objective**: Build a functional counter using HTML, CSS, and JS/TS/React. 35 | 36 | **Instructions**: 37 | 38 | 1. Create a simple counter with the following elements: 39 | - A display showing the current count. 40 | - Two buttons: one for incrementing the count and another for decrementing it. 41 | 42 | 2. The counter should start at `0` by default. 43 | 44 | 3. Clicking the "Increment" button should add `1` to the current count. 45 | 46 | 4. Clicking the "Decrement" button should subtract `1` from the current count. 47 | 48 | **Requirements**: 49 | 50 | - The counter must always start at `0` when the page loads. 51 | - The counter cannot go below `0` (disable the "Decrement" button or handle the logic to prevent negative counts). 52 | - The count must persist correctly between increments and decrements without refreshing the page. 53 | 54 | **Hints**: 55 | 56 | 1. Store the current count in a variable and update it when the buttons are clicked. 57 | 2. Update the displayed count by modifying the inner text of an HTML element (like a `` or `

`). 58 | 3. You can disable the "Decrement" button when the count is at `0` to prevent negative values. 59 | 60 | **Bonus:** 61 | - Add a reset button that sets the counter back to `0`. 62 | - Style the buttons and counter display 63 | 64 | ## 3. Infinite Scroll 65 | 66 | *Beginner | Javascript/Typescript/React* 67 | 68 | **Objective**: Implement an infinite scroll feature using JS/TS/React. 69 | 70 | **Instructions**: 71 | 72 | 1. Create a web page with a list of items that loads more items when the user scrolls to the bottom of the page. 73 | 2. The list should initially display `10` items. 74 | 3. When the user scrolls to the bottom, dynamically load the next `10` items and append them to the existing list. 75 | 4. Use an API or a mocked list of data to populate the items. 76 | 77 | **Requirements**: 78 | 79 | - Items must load dynamically without a full page reload. 80 | - The infinite scroll should work smoothly regardless of the data size. 81 | 82 | **Hints**: 83 | 84 | 1. Use JavaScript's `scroll` event to detect when the user reaches the bottom of the page. 85 | 2. Ensure that the new items are appended to the list smoothly without overwriting the current items. 86 | 3. Optionally, add a loading spinner to indicate that more data is being loaded. 87 | 88 | **Bonus:** 89 | - Add a "Load More" button as an alternative for users who don't want automatic loading. 90 | - Handle errors, showing a message if items can't be loaded. 91 | 92 | ## 4. Pokémon Fetcher 93 | 94 | *Beginner | React* 95 | 96 | **Objective**: Fetch and display Pokémon data using React. 97 | 98 | **Instructions**: 99 | 100 | 1. Create a React component named `PokemonFetcher`. 101 | 102 | 2. The component should fetch data from the **Pokémon API**: `https://pokeapi.co/api/v2/pokemon/ditto`. 103 | 104 | 3. Display the Pokémon’s name inside an `

` tag. 105 | 106 | 4. Display an image of the Pokémon using the `` tag. Use the `sprites.front_default` field from the API response for the image URL. 107 | 108 | **Requirements**: 109 | 110 | - Use the `useEffect` hook to fetch data from the API when the component mounts. 111 | - Use the `useState` hook to manage the following states: 112 | - Fetched Pokémon data. 113 | - Loading status (optional) 114 | - Error handling for failed API calls (optional) 115 | 116 | **Hints**: 117 | 118 | 1. Use `fetch` to retrieve the Pokémon data. 119 | 2. Handle different states: 120 | - Loading (while waiting for the data). 121 | - Success (once the data is fetched). 122 | - Error (if something goes wrong). 123 | 124 | **Bonus**: 125 | 126 | - Display a loading message or spinner while the data is being fetched. 127 | - Style the component to make it look good. 128 | 129 | ## 5. Skeleton Loader for Content 130 | 131 | *Beginner | Javascript/Typescript/React* 132 | 133 | **Objective**: Implement a skeleton loader for content while waiting for an API response. 134 | 135 | **Instructions**: 136 | 137 | 1. Create a functional React component named `ContentWithSkeleton`. 138 | 139 | 2. The component should fetch data from any public API of your choice (or use `https://jsonplaceholder.typicode.com/posts/1` as a default). 140 | 141 | 3. Display a skeleton loader while the data is being fetched. Once the data is fetched, replace the skeleton with the actual content (e.g., a title and body). 142 | 143 | 4. Ensure that the skeleton loader is styled to look like the content it will replace (e.g., rectangles for text blocks). 144 | 145 | **Requirements**: 146 | 147 | - Use the `useEffect` hook to fetch data when the component mounts. 148 | - Use the `useState` hook to manage loading, error, and success states. 149 | - Replace the skeleton with real data when the API call is successful. 150 | 151 | **Hints**: 152 | 153 | 1. Style the skeleton loader using CSS to simulate the structure of the final content (e.g., gray boxes representing text). 154 | 2. Handle different states: 155 | - Loading (display skeleton). 156 | - Success (display actual content). 157 | - Error (display an error message if the API call fails). 158 | 159 | **Bonus**: 160 | 161 | - Add animations to the skeleton loader to simulate loading (e.g., shimmer effect). 162 | - Ensure the skeleton loader is responsive and works on different screen sizes. 163 | 164 | ## 5. Skeleton Loader for Content 165 | 166 | *Beginner | Javascript/Typescript/React* 167 | 168 | **Objective**: Implement a skeleton loader for content while waiting for an API response. 169 | 170 | Example how it looks: [Link ->](https://ui.shadcn.com/docs/components/skeleton) 171 | 172 | **Instructions**: 173 | 174 | 1. Create a component named `ContentWithSkeleton` (or if you are not using React just create an HTML element). 175 | 176 | 2. The component should fetch data from any public API of your choice (or use `https://jsonplaceholder.typicode.com/posts/1` as a default). 177 | 178 | 3. Display a skeleton loader while the data is being fetched. Once the data is fetched, replace the skeleton with the actual content. 179 | 180 | 4. Ensure that the skeleton loader is styled to resemble the structure of the content it will replace (e.g., rectangles for text blocks). 181 | 182 | **Requirements**: 183 | 184 | - Fetch data when the component or page loads. 185 | - Manage loading, error, and success states to ensure the skeleton is replaced by actual content once the data is retrieved. 186 | 187 | **Hints**: 188 | 189 | 1. Use CSS to style the skeleton loader to simulate the final content structure (e.g., gray boxes representing text or images). 190 | 2. Handle different states: 191 | - Loading (display skeleton). 192 | - Success (display actual content). 193 | - Error (display an error message if the API call fails). 194 | 195 | **Bonus**: 196 | 197 | - Add animations to the skeleton loader, such as a `shimmer effect`, to simulate loading. 198 | - Handle errors, showing an error message if the API call fails or changing skeleton style 199 | 200 | ## 6. Flatten Array 201 | 202 | *Beginner | Javascript/Typescript* 203 | 204 | 205 | **Objective**: Write a function that takes a nested array and returns a flat array with all elements at the same level. 206 | 207 | **Instructions**: 208 | 209 | 1. Create a function called `flattenArray` that accepts an array containing nested arrays of various depths. 210 | 2. The function should return a new array where all the elements are "flattened" to the top level (i.e., no nested arrays). 211 | 212 | **Example**: 213 | 214 | ```js 215 | flattenArray([1, [2, 3], [4, [5, 6]]]); 216 | // Output: [1, 2, 3, 4, 5, 6] 217 | ``` 218 | **Requirements**: 219 | 220 | - The function must handle arrays with multiple levels of nesting. 221 | - You cannot use the built-in `Array.prototype.flat()` method. 222 | - The function should work recursively to ensure that deeply nested arrays are also flattened. 223 | 224 | **Hints**: 225 | 226 | 1. Use `recursion` to handle arrays nested at multiple levels. 227 | 2. `Concatenation` or `spreading` can help combine arrays when flattenin 228 | 229 | **Bonus**: 230 | 231 | - Add a second argument to the function that limits how deep it should flatten the array (like `Array.prototype.flat(depth)`). 232 | 233 | ## 7. Draggable and Droppable Elements 234 | 235 | *Beginner | Javascript/Typescript/React* 236 | 237 | **Objective**: Implement a UI where users can drag and drop boxes into a container. 238 | 239 | **Instructions**: 240 | 241 | 1. Create a draggable UI with a set of boxes placed outside a container. 242 | 2. The container should have a 2x2 grid layout. 243 | 3. Users should be able to drag and drop the boxes into the container. 244 | 245 | **Requirements**: 246 | 247 | - The boxes should be draggable. 248 | - The container should accept boxes dropped into it and maintain a grid layout (2x2). 249 | - Make sure the drag-and-drop functionality is intuitive and works smoothly. 250 | 251 | **Hints**: 252 | 253 | 1. Use `dragstart`, `dragover`, and `drop` events in JavaScript to handle the drag-and-drop functionality. 254 | 2. Ensure that the container keeps its 2x2 layout when the boxes are dropped into it. 255 | 256 | **Bonus**: 257 | 258 | - Implement a "snap to grid" feature, where the boxes automatically align to the nearest corner of the container when dropped. 259 | - Make the boxes repositionable after being dropped into the container. 260 | - Add info when a box is being dragged over the container (e.g., a highlight effect). 261 | 262 | ## 8. Mini CSS Library 263 | 264 | *Intermediate | Javascript/Typescript/React* 265 | 266 | **Objective**: Create a utility function that helps manage and generate CSS class names dynamically based on conditions. 267 | 268 | **Instructions**: 269 | 270 | 1. Write a function called `customCSS` that accepts an object as its argument. The object will have CSS class names as keys and conditions (boolean values) as their corresponding values. 271 | 272 | 2. The function should return a string of class names where the condition is true. 273 | 274 | 3. You should be able to pass multiple class names into the function, and it should only include those that meet the conditions. 275 | 276 | **Example**: 277 | 278 | ```js 279 | miniCSS({ 280 | 'btn-primary': true, 281 | 'btn-disabled': isDisabled, 282 | 'hidden': !isVisible 283 | }); 284 | // Output: 'btn-primary' (if `isDisabled` is false and `isVisible` is true) 285 | ``` 286 | 287 | **Requirements**: 288 | 289 | - Accept an object with class names as keys and boolean conditions as values. 290 | - Return a string of class names that satisfy the true condition. 291 | - Ignore any classes where the value is false. 292 | 293 | **Bonus:** 294 | 295 | 1. Add support for combining static class names with dynamic ones. 296 | 2. Allow function to accept more complex conditions, example: 297 | 298 | ```js 299 | miniCSS({ 300 | 'btn-primary': true, 301 | 'btn-disabled': isDisabled, 302 | 'hidden': !isVisible, 303 | 'md:text-lg': windowWidth > 768, // Responsive condition 304 | }); 305 | ``` 306 | 307 | ## 9. Notification Bell 308 | 309 | *Intermediate | Javascript/Typescript/React* 310 | 311 | **Objective**: Implement a notification bell component that shows an unread notification count and displays a list of notifications on click. 312 | 313 | **Instructions**: 314 | 315 | 1. Create a notification bell icon that displays the number of unread notifications. 316 | 2. Clicking the bell should open a list of notifications. 317 | 3. Include two buttons for different types of notifications (e.g., "Messages" and "Alerts"). Clicking these buttons should *simulate* adding new notifications of the respective type. 318 | 4. Add a button to clear all notifications under the list of notifications. 319 | 320 | **Requirements**: 321 | 322 | - The notification bell should display an unread count. 323 | - Clicking the bell should show a list of notifications. 324 | - The "Messages" and "Alerts" buttons should simulate adding a new notification of the corresponding type. 325 | - Add a "Clear All" button to remove all notifications. 326 | 327 | **Hints**: 328 | 329 | 1. You can style the notification list as a dropdown or a modal that opens when the bell is clicked. 330 | 2. Use conditional rendering to toggle between showing and hiding the notification list. 331 | 332 | **Bonus**: 333 | 334 | - Add animations or transitions when the notification list opens or closes. 335 | - Allow users to remove individual notifications from the list. 336 | - Add visual difference between notification types. 337 | 338 | ## 10. Custom Hook / Window Dimensions 339 | 340 | *Beginner | React* 341 | 342 | **Objective**: Implement a custom React hook that returns the current window dimensions (width and height). 343 | 344 | **Instructions**: 345 | 346 | 1. Create a custom hook named `useWindowDimensions`. 347 | 2. The hook should return an object containing the current width and height of the browser window. 348 | 3. The hook should update the dimensions in real-time when the window is resized. 349 | 350 | **Example Usage**: 351 | 352 | ```js 353 | const { width, height } = useWindowDimensions(); 354 | console.log(`Width: ${width}, Height: ${height}`); 355 | ``` 356 | 357 | **Requirements**: 358 | 359 | - The custom hook should listen for the resize event on the window and update the width and height values accordingly. 360 | - The hook returns the correct dimensions when the component mounts. 361 | 362 | **Hints**: 363 | 364 | 1. Use `useState` to store the width and height values. 365 | 2. Use `useEffect` to handle the window resize event and update the dimensions in real-time. 366 | 3. Remember to remove the event listener when the component unmounts to avoid memory leaks. 367 | 368 | ## 11. Progress Bar with Dynamic Updates 369 | 370 | *Beginner | Javascript/Typescript/React* 371 | 372 | **Objective**: Implement a progress bar that updates dynamically based on the input. 373 | 374 | **Instructions**: 375 | 376 | 1. Create a progress bar component that visually represents progress as a percentage. 377 | 2. Allow the progress value to update dynamically based on input. 378 | 3. The progress bar smoothly transitions as the value changes. 379 | 380 | **Example Usage**: 381 | 382 | - A button to increment progress by 10%. 383 | - Number input to update the progress value. 384 | 385 | **Requirements**: 386 | 387 | - The progress bar should display the current percentage of completion. 388 | - The progress bar should visually fill from 0% to 100% based on the progress value. 389 | 390 | **Bonus**: 391 | 392 | - Add a label inside the progress bar to display the current percentage. 393 | - Make the progress bar color change as it progresses (e.g., green for 0-50%, yellow for 51-80%, and red for 81-100%). 394 | 395 | ## 12. Debounce Input 396 | 397 | *Beginner | Javascript/Typescript* 398 | 399 | **Objective**: Implement an input field with a debounced event handler to optimize performance. 400 | 401 | **Instructions**: 402 | 403 | 1. Create an input field where user input is handled after a specified delay (debounced) to prevent unnecessary function calls (e.g., when searching or filtering data). 404 | 2. The event handler should only trigger after the user has stopped typing for a certain period (e.g., 500 milliseconds). 405 | 3. The input value should be displayed or logged *after* the debounce delay. 406 | 407 | **Requirements**: 408 | 409 | - Implement a debounce mechanism to delay the input handling. 410 | - The input value should only update **once** the debounce delay has passed without additional input. 411 | 412 | **Hints**: 413 | 414 | 1. You can use `setTimeout` and `clearTimeout` to manage the debounce logic. 415 | 416 | ## 13. Tooltip 417 | 418 | *Beginner | Javascript/Typescript/React* 419 | 420 | **Objective**: Implement a tooltip component that appears when hovering over an element and allows positioning control. 421 | 422 | **Instructions**: 423 | 424 | 1. Create a tooltip that appears when the user hovers over an element. 425 | 426 | **Requirements**: 427 | 428 | - The tooltip should appear on hover and disappear when the hover ends. 429 | - Allow customization of the tooltip's position (top, bottom, left, or right). 430 | - Implement a customizable delay before the tooltip shows and hides. 431 | 432 | **Hints**: 433 | 434 | 1. Use CSS for the positioning of the tooltip and for handling the hover effect. 435 | 2. You can use JavaScript to manage the delay and control when the tooltip appears or disappears. 436 | 3. Ensure that the tooltip remains visible while the user hovers over it. 437 | 4. With React you can experiment with `portals`. 438 | 439 | ## 14. Promise.all Polyfill 440 | 441 | *Advanced | Javascript/Typescript* 442 | 443 | **Objective**: Implement a polyfill for `Promise.all`, which takes an array of promises and returns a single promise that resolves when all of the input promises have resolved. 444 | 445 | **Instructions**: 446 | 447 | 1. Create a function named `promiseAll` that mimics the behavior of `Promise.all`. 448 | 2. The function should take an array of promises and return a single promise that: 449 | - Resolves with an array of resolved values when all promises are fulfilled. 450 | - Rejects immediately with the reason of the first promise that rejects. 451 | 452 | **Example Usage**: 453 | 454 | ```js 455 | promiseAll([promise1, promise2, promise3]) 456 | .then(values => console.log(values)) // All promises fulfilled, output an array of results 457 | .catch(error => console.error(error)); // One of the promises rejected 458 | ``` 459 | 460 | **Requirements**: 461 | 462 | - The `promiseAll` function should take an array of promises as input. 463 | - It should resolve with an array of resolved values if all promises resolve. 464 | - It should reject immediately with the reason of the first promise that rejects. 465 | - **You cannot use the native `Promise.all.`** 466 | 467 | **Hints:** 468 | 469 | - Use Promise.resolve() and Promise.reject() to handle the result of each promise. 470 | - Return a new promise that resolves or rejects based on the input promises. 471 | 472 | **Bonus:** 473 | 474 | 1. Handle non-promise values in the array by treating them as resolved promises. 475 | 476 | ## 15. Floating Chat Widget 477 | 478 | *Intermediate | Javascript/Typescript/React* 479 | 480 | **Objective**: Implement a floating chat widget that mimics a customer support chatbox, which can be opened and minimized. 481 | 482 | **Instructions**: 483 | 484 | 1. Create a floating button on the `bottom-right` of the screen that, when clicked, opens a chat window. 485 | 2. The chat window should allow users to type and send messages. 486 | 3. Include a button to close or minimize the chat window, returning to just the floating button. 487 | 488 | **Requirements**: 489 | 490 | - The floating button should be fixed to the `bottom-right` corner of the screen. 491 | - The chat window should appear and disappear when the floating button is clicked. 492 | - Users should be able to send messages in the chat window *(no actual backend needed for this task)*. 493 | - The chat window stays open as long as the user is interacting with it. 494 | 495 | **Bonus**: 496 | 497 | - Add basic chat-like functionality where the chat window displays sent messages in real time. 498 | - Implement a smooth transition effect when the chat window opens or closes. 499 | - Make chat window resizable. 500 | 501 | ## 16. Throttle API Calls 502 | 503 | **Objective**: Implement a function that throttles API calls, make sure that a function is only executed once within a specified time window, even if it's triggered multiple times. 504 | 505 | **Instructions**: 506 | 507 | 1. Create a function named `throttle` that limits how often an API call is made. If the function is called again within the time window, it should ignore the subsequent calls until the window has passed. 508 | 2. The function should take two arguments: 509 | - The API call function to throttle. 510 | - The throttle time in milliseconds (e.g., 2000 ms for a 2-second throttle). 511 | 3. Ensure the function can handle multiple calls but only executes the API call once per time window. 512 | 513 | **Example Usage:** 514 | 515 | *Advanced | Javascript/Typescript/React* 516 | 517 | ```js 518 | const throttledApiCall = throttle(apiCall, 2000); 519 | 520 | button.addEventListener('click', throttledApiCall); 521 | // Only allows the API call once every 2 seconds, even if the button is clicked multiple times. 522 | ``` 523 | 524 | **Requirements:** 525 | 526 | - Create a `throttle` function that limits how frequently an API call can be made. 527 | - The function should ignore subsequent calls during the window and only execute after the window has passed. 528 | - Ensure the API call function is executed at least once after the throttle window resets. 529 | 530 | **Hints:** 531 | 532 | 1. Use `setTimeout` or timestamps to track the time between calls. 533 | 2. Consider using `closures` to keep track of the throttle state between function calls. 534 | 535 | **Bonus:** 536 | 537 | 1. Allow the `throttle` function to accept an option that triggers the first call immediately, but enforces the throttle after that. 538 | 539 | ## 17. Multistep Form 540 | 541 | *Intermediate | Javascript/Typescript/React* 542 | 543 | **Note**: This challenge focuses more on logic than UI. If you want to also focus on and practice UI, visit our **UI Components** challenges. 544 | 545 | **Objective**: Implement a multistep form with 3 steps, where users can input data and navigate back and forth between steps. 546 | 547 | **Instructions**: 548 | 549 | 1. Create a form with at least 3 steps. Each step should contain a set of input fields. 550 | - Step 1: Personal Information (e.g., Name, Email). 551 | - Step 2: Contact Details (e.g., Phone Number, Address). 552 | - Step 3: Review (Display entered information for review before submission). 553 | 554 | 2. Include "Next" and "Back" buttons to allow users to navigate between the steps. 555 | 556 | 3. On the final step, provide a "Submit" button that `console.logs` or processes the form data. 557 | 558 | **Requirements**: 559 | 560 | - Users should be able to move between steps using the "Next" and "Back" buttons. 561 | - The form data should persist as users navigate between steps. 562 | 563 | **Hints**: 564 | 565 | 1. Use an array or object to store the form data and update it as the user progresses through the steps. 566 | 567 | **Bonus**: 568 | 569 | 1. Implement validation for the form fields (e.g., email format, required fields). 570 | 2. Allow users to directly jump to a specific step if they’ve already visited it. 571 | 3. Show a summary of all entered information on the final review step before submission. 572 | 573 | ## 18. Memoize Function 574 | 575 | *Expert | Javascript/Typescript/React* 576 | 577 | **Objective**: Implement a memoization function that caches the results of function calls to improve performance. 578 | 579 | **Instructions**: 580 | 581 | 1. Create a function named `memoize` that takes a function as an argument and returns a new function that caches the results of the function. 582 | 2. The memoized function should store the results of previous calls and return the cached result when the same arguments are provided. 583 | 3. The function should only recompute the result if the arguments have changed. 584 | 585 | **Example Usage**: 586 | 587 | ```js 588 | const slowFunction = (num) => { 589 | // Simulate a slow computation 590 | return new Promise((resolve) => { 591 | setTimeout(() => resolve(num * 2), 3000); // Simulates a 3-second delay 592 | }); 593 | }; 594 | 595 | const memoizedFunction = memoize(slowFunction); 596 | 597 | memoizedFunction(5).then(result => console.log(result)); // Calls slowFunction, outputs: 10 after 3 seconds 598 | memoizedFunction(5).then(result => console.log(result)); // Returns cached result, outputs: 10 immediately 599 | ``` 600 | 601 | **Requirements:** 602 | 603 | - The `memoize` function should cache the result of previous function calls based on the arguments provided. 604 | - When called with the same arguments, the function should return the cached result instead of recomputing it. 605 | - The cache should clear or replace old values when new ones are computed. 606 | 607 | **Hints:** 608 | 609 | 1. Use an `object` or `Map` to store the function arguments and their corresponding results. 610 | 2. Consider how you will handle multiple arguments and different types of data. 611 | 612 | **Bonus:** 613 | 614 | 1. Implement a cache size limit, where the oldest cached result is removed when the cache reaches its limit. 615 | 2. Add support for handling multiple arguments and deep comparisons of objects. 616 | 617 | ## 19. Dark Mode Toggler 618 | 619 | *Beginner | Javascript/Typescript/React* 620 | 621 | **Note**: This challenge focuses more on logic than UI. If you want to also focus on and practice UI, visit our **UI Components** challenges. 622 | 623 | **Objective**: Implement a dark mode toggle that switches between light and dark modes. 624 | 625 | **Instructions**: 626 | 627 | 1. Create a button or switch that toggles between light and dark modes when clicked. 628 | 2. Create some basic CSS styles to indicate theme difference 629 | 630 | **Requirements**: 631 | 632 | - Implement a function that toggles between light and dark modes. 633 | - Create basic CSS theme for light/dark mode. 634 | 635 | **Bonus**: 636 | 637 | 1. Automatically detect the user's OS-level dark mode preference and apply it on first load. 638 | 2. Add a transition effect when switching between modes. 639 | 640 | ## 20. Rate limiter 641 | 642 | *Expert | Javascript/Typescript* 643 | 644 | **Objective**: Implement a rate limiter that restricts the number of function executions within a specified time window. 645 | 646 | **Instructions**: 647 | 648 | 1. Create a function named `rateLimiter` that accepts two arguments: 649 | - A function to limit. 650 | - The maximum number of times the function can be executed within a specified time window (e.g., 5 times per 10 seconds). 651 | 2. Ensure that after reaching the limit, the function is blocked from executing until the time window resets. 652 | 653 | **Example Usage**: 654 | 655 | ```js 656 | const limitedFunction = rateLimiter(apiCall, 5, 10000); // 5 calls per 10 seconds 657 | 658 | limitedFunction(); // Executes the first call 659 | limitedFunction(); // Executes the second call 660 | // After 5 calls in 10 seconds, the function will be blocked until the next window starts. 661 | ``` 662 | 663 | **Requirements:** 664 | 665 | - The `rateLimiter` should limit how many times the function can be executed within a specific time window. 666 | - Once the limit is reached, further function calls should be blocked until the time window resets. 667 | - The time window should reset after a specified duration (e.g., every 10 seconds). 668 | - 669 | **Hints:** 670 | 671 | 1. Use timestamps to track when the time window starts and the number of function calls. 672 | 2. Use a counter to track how many times the function has been executed within the time window. 673 | 674 | **Bonus:** 675 | 676 | 1. Add the ability to reset the limiter manually. 677 | 2. Add key for each action, so different actions can be rate limited separately 678 | 679 | ## 21. Infinite Carousel 680 | 681 | *Intermediate | Javascript/Typescript/React* 682 | 683 | **Note**: This challenge focuses more on logic than UI. If you want to also focus on and practice UI, visit our **UI Components** challenges. 684 | 685 | **Objective**: Implement an infinite carousel component that allows users to cycle through items. 686 | 687 | **Instructions**: 688 | 689 | 1. Create a carousel that displays a series of items (e.g., images or cards) one at a time. 690 | 2. The carousel should loop infinitely, meaning that when the user reaches the last item, it cycles back to the first, and vice versa. 691 | 3. Include "Next" and "Previous" buttons to allow users to navigate through the items. 692 | 693 | **Requirements**: 694 | 695 | - The carousel should loop infinitely, so users can navigate through the items without reaching an end. 696 | - Add at least 5 items. 697 | 698 | **Hints**: 699 | 700 | 1. Use a state variable or index to track the current item in the carousel. 701 | 2. Reset the index to the start or end when it goes out of bounds to create the infinite loop. 702 | 3. Use a timer or interval to handle the automatic cycling of items (bonus). 703 | 704 | **Bonus**: 705 | 706 | 1. Automatic cycling - The carousel automatically cycles through the items after a set interval. 707 | 708 | ## 22. Flatten nested Object 709 | 710 | *Advanced | Javascript/Typescript* 711 | 712 | **Objective:** Write a function that takes a deeply nested object and returns a flat object with all keys flattened. 713 | 714 | **Instructions:** 715 | 716 | 1. Create a function called `flattenObject` that accepts an object with nested objects at various levels. 717 | 2. The function should return a new object where all nested keys are flattened into a single-level object, with the keys representing the nested structure using dot notation (e.g., `'key1.key2': value`). 718 | 719 | **Example:** 720 | 721 | ```js 722 | flattenObject({ 723 | a: 1, 724 | b: { 725 | c: 2, 726 | d: { 727 | e: 3 728 | } 729 | } 730 | }); 731 | // Output: { 'a': 1, 'b.c': 2, 'b.d.e': 3 } 732 | ``` 733 | 734 | **Requirements:** 735 | 736 | - The function must handle objects with multiple levels of nesting. 737 | - The function should work recursively to flatten deeply nested objects. 738 | - You cannot use any built-in flattening utilities. 739 | 740 | **Hints:** 741 | 742 | 1. Use `recursion` to flatten nested objects. 743 | 2. Use dot notation to `concatenate` keys as you go deeper into nested objects. 744 | 745 | **Bonus:** 746 | 747 | 1. Add a second argument to the function that limits how deep the object should be flattened. 748 | 749 | ## 23. Toast Notifications 750 | 751 | *Intermediate | Javascript/Typescript/React* 752 | 753 | **Note**: This challenge focuses more on logic than UI. If you want to also focus on and practice UI, visit our **UI Components** challenges. 754 | 755 | **Objective**: Implement a toast notification that allows displaying temporary messages that automatically disappear after a certain time. 756 | 757 | **Instructions**: 758 | 759 | 1. Create a function or component to show toast notifications with a message. 760 | 2. Each notification should disappear automatically after a specified duration (e.g., 3 seconds). 761 | 3. Provide the ability to trigger multiple notifications and display them in a queue. 762 | 763 | **Requirements**: 764 | 765 | - The toast notifications should be temporary and automatically disappear after a set time. 766 | - Support multiple notifications at once, displayed in a queue (stacked on top of each other). 767 | 768 | **Hints**: 769 | 770 | 1. Use a timeout to control how long each notification stays visible. 771 | 2. Use an array to manage multiple notifications and their removal from the list. 772 | 773 | **Bonus**: 774 | 775 | 1. Allow the user to dismiss a notification manually by clicking a close button. 776 | 2. Add different types of notifications (e.g., success, error, info) with corresponding styles. 777 | 778 | ## 24. Event queue 779 | 780 | *Advanced | Javascript/Typescript/React* 781 | 782 | **Objective:** Implement an event queue system that manages user actions (like liking posts) in sequence and handles cancelable events (e.g., like + unlike = no action). 783 | 784 | **Instructions:** 785 | 786 | 1. Create a function called `createEventQueue` that manages an event queue. 787 | 2. The event queue should support adding and canceling actions (e.g., "like post" followed by "unlike post" results in no event). 788 | 3. Ensure that events are processed in the order they were added, but allow new events to be triggered while previous events are still being processed. 789 | 790 | **Example:** 791 | 792 | ```js 793 | const eventQueue = createEventQueue(); 794 | 795 | eventQueue.add('like', () => console.log('Liked post 1')); 796 | eventQueue.add('unlike', () => console.log('Unliked post 1')); 797 | eventQueue.add('like', () => console.log('Liked post 2')); 798 | 799 | // Output: 800 | // Liked post 2 801 | 802 | // In this case, the "like" and "unlike" actions for post 1 cancel each other, 803 | // so only the "Liked post 2" event is processed. 804 | ``` 805 | 806 | **Requirements:** 807 | 808 | - Create a queue system that stores actions and processes them in sequence. 809 | - Ensure that cancelable actions (like/unlike) cancel each other when triggered for the same post. 810 | - Provide a way to trigger new events while the queue is still being processed. 811 | 812 | **Hints:** 813 | 814 | 1. Use an array to store the events in the queue. 815 | 2. Keep track of actions (like/unlike) to determine if they cancel each other out before executing them. 816 | 817 | ## 25. Keyboard Navigation 818 | 819 | **Beginner | Javascript/Typescript/React** 820 | 821 | **Objective**: Implement a simple keyboard navigation system that allows users to navigate between pages, create new pages, and delete pages using keyboard input. 822 | 823 | **Instructions**: 824 | 825 | 1. Create a system starting with 10 pages, each representing a simple page (can be a numbered div or section). 826 | 2. Use the **left** and **right** arrow keys to navigate between pages. 827 | 3. Pressing **Enter** should create a new page. 828 | 4. Pressing **Backspace** should delete the current page. 829 | 830 | **Requirements**: 831 | 832 | - The system should have 10 pages by default. 833 | - Allow users to navigate between pages using the left and right arrow keys. 834 | - Pressing **Enter** should add a new page, and pressing **Backspace** should delete the current page. 835 | - Ensure the user cannot navigate beyond the first or last page. 836 | 837 | **Example Usage**: 838 | 839 | - **Left arrow**: Moves to the previous page. 840 | - **Right arrow**: Moves to the next page. 841 | - **Enter**: Creates a new page at the current position. 842 | - **Backspace**: Deletes the current page. 843 | 844 | **Hints**: 845 | 846 | 1. Use **keyboard event listeners** to detect key presses. 847 | 2. Store the pages in an array and update the navigation state accordingly. 848 | 3. Ensure that creating or deleting pages updates the total number of pages and maintains navigation logic. 849 | 850 | **Bonus**: 851 | 852 | 1. Allow the user to skip to the first or last page using the **Home** and **End** keys. 853 | 854 | ## 26. Image Lazy Loading 855 | 856 | **Intermediate | Javascript/Typescript/React** 857 | 858 | **Objective**: Implement a lazy loading mechanism for images, so they load only when they are about to enter the user's viewport, improving performance and reducing unnecessary network requests. 859 | 860 | **Instructions**: 861 | 862 | 1. Build simple scrollable page with any images. 863 | 2. Create a function or component that handles the lazy loading of images. 864 | 2. The images should only load when they are about to enter the viewport. 865 | 3. Ensure that the mechanism works across multiple images on the page. 866 | 867 | **Requirements**: 868 | 869 | - The images should not load until they are close to appearing in the viewport. 870 | - Use a placeholder or a loading indicator until the image has fully loaded. 871 | - The lazy loading should work for multiple images on a single page. 872 | 873 | **Hints**: 874 | 875 | 1. Use the **Intersection Observer API** to detect when the images are about to enter the viewport. 876 | 2. Replace the placeholder with the actual image URL when the image is about to load. 877 | 878 | ## 27. Dialog with Actions (Cancel/Confirm) 879 | 880 | **Intermediate | Javascript/Typescript/React** 881 | 882 | **Note**: This challenge focuses more on logic than UI. If you want to also focus on and practice UI, visit our **UI Components** challenges. 883 | 884 | **Objective**: Implement an alert dialog that displays a message and provides "Cancel" and "Confirm" buttons for user interaction. 885 | 886 | **Instructions**: 887 | 888 | 1. Create a component that displays an alert dialog with a message. 889 | 2. Include two actions in the dialog: "Cancel" and "Confirm". 890 | 3. The "Cancel" action should close the dialog without any further action. 891 | 4. The "Confirm" action should trigger a specified function and then close the dialog. 892 | 893 | **Requirements**: 894 | 895 | - The dialog should be a modal, meaning it blocks interaction with the rest of the page until the user takes an action. 896 | - The component should handle both "Cancel" and "Confirm" actions appropriately. 897 | 898 | **Hints**: 899 | 900 | 1. Use a arguments/props to control the visibility of the dialog. 901 | 2. Ensure the dialog is positioned and styled to be centered on the screen. 902 | 3. Use event listeners to close the dialog when clicking outside of it or pressing the "Escape" key. 903 | 904 | ## 28. Deep Clone Function 905 | 906 | **Advanced | Javascript/Typescript** 907 | 908 | **Objective**: Implement a function that creates a deep clone of a given object or array, ensuring that all nested structures are also cloned. 909 | 910 | **Instructions**: 911 | 912 | 1. Create a function named `deepClone` that takes an object or array as an argument and returns a deep copy of it. 913 | 2. The cloned object or array should not share references with the original (i.e., modifying the clone should not affect the original). 914 | 3. Handle nested objects and arrays, ensuring all levels are cloned. 915 | 916 | **Example Usage**: 917 | 918 | ```js 919 | const original = { a: 1, b: { c: 2 } }; 920 | const cloned = deepClone(original); 921 | 922 | cloned.b.c = 3; 923 | 924 | console.log(original.b.c); // Output: 2 (original remains unchanged) 925 | console.log(cloned.b.c); // Output: 3 (cloned object is independent) 926 | ``` 927 | 928 | **Requirements:** 929 | 930 | - The `deepClone` function should work recursively to clone deeply nested `objects` and `arrays`. 931 | - The function should handle primitive values, `arrays`, and `objects` (not `Dates` or `RegExp`) 932 | 933 | **Hints:** 934 | 935 | 1. Use recursion to iterate through the structure of the object or array. 936 | 2. Ensure that each nested object or array is cloned and not simply referenced. 937 | 938 | ## 29. Password Strength Indicator 939 | 940 | **Intermediate | Javascript/Typescript** 941 | 942 | **Objective**: Implement a function that evaluates the strength of a password based on certain criteria and returns a strength score or label. 943 | 944 | **Instructions**: 945 | 946 | 1. Create a function called `checkPasswordStrength` that takes a password as input. 947 | 2. The function should evaluate the password based on the following criteria: 948 | - Length of the password. 949 | - Inclusion of uppercase and lowercase letters. 950 | - Inclusion of numbers. 951 | - Inclusion of special characters (e.g., `!@#$%^&*`). 952 | 3. The function should return a score or label such as "Weak", "Medium", or "Strong". 953 | 954 | **Example Usage**: 955 | 956 | ```js 957 | console.log(checkPasswordStrength('Password123')); // Output: "Medium" 958 | console.log(checkPasswordStrength('Password@123')); // Output: "Strong" 959 | console.log(checkPasswordStrength('pass')); // Output: "Weak" 960 | ``` 961 | 962 | **Requirements:** 963 | 964 | - The function should check for a combination of length, character variety (uppercase, lowercase, numbers, special characters). 965 | - Return a label or score to indicate the password strength. 966 | 967 | **Hints:** 968 | 969 | 1. Use `regular expressions` to check for the presence of numbers, uppercase letters, and special characters. 970 | 2. Create a point system based on the criteria and return the label based on the score. 971 | 972 | **Bonus:** 973 | 974 | 1. Provide suggestions to improve a weak password (e.g., "Add special characters"). 975 | 2. Allow customization of strength rules (e.g., minimum length, required character types). 976 | 977 | ## 30. Mini Form Validation Library 978 | 979 | **Intermediate | Javascript/Typescript** 980 | 981 | **Objective**: Implement a simple form validation library that allows validating form fields based on custom rules. 982 | 983 | **Instructions**: 984 | 985 | 1. Create a function named `validateForm` that takes an object representing form data and an object representing validation rules. 986 | 2. The function should validate each field based on the provided rules and return a result indicating whether the form is valid and what errors (if any) were found. 987 | 3. The validation rules should support checks for: 988 | - Required fields 989 | - Minimum/maximum length for text fields 990 | - Email format validation 991 | 992 | **Example Usage**: 993 | 994 | ```js 995 | const formData = { 996 | username: 'user123', 997 | password: 'pass', 998 | email: 'user@example.com', 999 | }; 1000 | 1001 | const validationRules = { 1002 | username: { required: true, minLength: 5 }, 1003 | password: { required: true, minLength: 8 }, 1004 | email: { required: true, email: true }, 1005 | }; 1006 | 1007 | const result = validateForm(formData, validationRules); 1008 | console.log(result); 1009 | // Output: { valid: false, errors: { password: 'Password must be at least 8 characters.' } } 1010 | ``` 1011 | 1012 | **Requirements:** 1013 | 1014 | - The function should validate based on rules like required, minLength, and email format. 1015 | - Return an object with a valid boolean and an errors object indicating what validation failed. 1016 | 1017 | **Bonus:** 1018 | 1019 | 1. Add support for validating multiple types of fields (e.g., numbers, dates). -------------------------------------------------------------------------------- /components/README.md: -------------------------------------------------------------------------------- 1 | *Work in progress* 2 | 3 | *Those are example questions which will be available both here written and as interactive challenges on Codetive website.* 4 | 5 | > *It's free feature btw :-)* 6 | 7 | ... 8 | -------------------------------------------------------------------------------- /components/assets/challenge-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codetive/frontend-coding-challenges/c437bd2158409fc3149cb32b51c60698bb163f5a/components/assets/challenge-1.png -------------------------------------------------------------------------------- /trivia-questions/css.md: -------------------------------------------------------------------------------- 1 | # Codetive CSS Triva Questions Documentation 2 | 3 | > **Note:** These questions are trivia-based and are intended for fun and educational purposes. They are not necessarily reflective of the types of questions you would encounter in a real interview. 4 | 5 | > **Documentation:** This is documentation to Codetive learning platform which will be launched in September 2024. Question `id` corresponds to id in the app database. 6 | 7 | ## Beginner 8 | 9 | ### What does CSS stand for? [#26] 10 | 11 | **Answer:** Cascading Style Sheets 12 | **Explanation:** `soon` 13 | 14 | ### Which HTML tag is used to define an internal style sheet? [#27] 15 | 16 | **Answer:** `