<aside> 👋 Hello! Before we get started, we just wanted to thank you for taking on this exercise. We know 3 hours is a long time to be coding outside of work but, we’re excited you’re doing this and are looking forward to meeting you in person. Best of luck! </aside> # Instructions This is a 3 hour exercise. You’re welcome to stop before then, but please don’t spend any more time than that. We don’t expect that anyone will finish the entirety of the interview. There are two parts to this exercise. In the first part, you’ll be building a pagination component in your choice of frontend framework. We primarily work with Vue at Propel, but you’re welcome to use whatever you think will demonstrate your strengths the best. In the second part, you’ll choose from various improvements either to the design, tooling or feature set of the pagination component. We do not expect you to complete all the suggested improvements. Please keep the time limit in mind and select the improvement that you feel best suit your skillset/interests. Please be mindful of budgeting your time between the two parts of the exercise (we anticipate part one should take about 2/3 of your time and part two should take about 1/3). If you’re stuck on a certain section or test case, consider coming back to it or moving on to cover other areas of the exercise. This is an open-book take-home! Feel free to use Google, Stack Overflow, MDN docs, or any other references you use during normal work. Searches about the pagination logic itself, however, are strictly forbidden. ## Environment Please complete the exercise in Coderpad at the link provided in the exercise email. ********************************************************Please do all of your coding in Coderpad. Do not copy and paste code in.******************************************************** If you’re new to CoderPad or this is your first time using it you can read more about what the experience is like and try out a sandbox environment [here](https://coderpad.io/resources/docs/for-candidates/coderpad-live-candidate-guide/) before beginning the exercise. We primarily use Vue at Propel but please use the framework you feel most comfortable in. You can switch the Coderpad to your framework of choice by selecting the ellipses menu in the top left corner and selecting ‘Switch Language’. [Switching from a Vue app to a React app in Coderpad](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a218726b-df7c-4c14-a3a8-ed2d5d6b9c65/Screen_Recording_2022-12-02_at_12.35.15_PM.mov) Switching from a Vue app to a React app in Coderpad ## Evaluation Our rubric is made of three categories: - Your pagination logic: for the [seven test cases](https://www.notion.so/Senior-Frontend-Engineer-Take-Home-e5138a92f26c4ff9b733a18bb35f15d6), how many of them display the right numbers and ellipses, regardless of how it looks. - State management: does your pagination component respond to clicks on buttons and track the current page in its state. - Your fidelity to the [design](https://www.notion.so/Senior-Frontend-Engineer-Take-Home-e5138a92f26c4ff9b733a18bb35f15d6): we'll be looking at the level of detail you can get in mimicking the examples. - Whether or not you successfully implemented one [improvement](https://www.notion.so/Senior-Frontend-Engineer-Take-Home-e5138a92f26c4ff9b733a18bb35f15d6). Perfection is not required to pass: if you're getting hung up on one test case or element, please feel free to move on. Here are things we won't be evaluating: - Whether or not your code is "ready for production". While we're looking for the code being readable, we'd expect a refactoring pass before deploying any of this. - How much time you had left when you finished. - Whether your design is responsive. Don't worry about mobile cases. # Part 1. Pagination Component Build a pagination component that takes `curPage` , `totalPages`, and `maxVisiblePages` props and returns a set of buttons to access each page. The component should look something like this: ![Example 4.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8c69e480-551d-489a-a598-75d7c7108f71/Example_4.jpg) ## Behavior More specifically, the component should: 1. Render at most `maxVisiblePages` buttons. 2. Always show a button for the first page. 3. Always show a button for the last page. 4. Render ellipses where appropriate. These do not count as buttons. 5. Emphasize the current selected page given the design spec below. 6. Respond to button clicks by updating the current page. You can assume reasonable values for each of the parameters. For example, `maxVisiblePages` will always be at least 3. You can assume that `maxVisiblePages` will be at most `totalPages`. ## Design Spec Each button rendered by the pagination component should be a 36 by 36 pixel square, and each button should be spaced 12 pixels away from the previous one. The spec uses [Lato](https://fonts.google.com/specimen/Lato), but any font will do. ![Design Spec.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ebcf1043-bb9f-4c84-a705-8dab42ca56c6/Design_Spec.jpg) ## Test Cases <aside> 📢 The following code examples use Vue syntax where `curPage`, `totalPages`, and `maxVisiblePages` props are passed into a `Pagination` component as numbers. </aside> ```jsx <Pagination :curPage="1" :totalPages="11" :maxVisiblePages="11" /> ``` ![Example 1.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/e4327247-b407-43af-a2ef-1a98885fd93d/Example_1.jpg) ```jsx <Pagination :curPage="1" :totalPages="30" :maxVisiblePages="11" /> ``` ![Example 2.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/53d1ae98-d828-4fd2-a6fa-28c2c0ca5ae4/Example_2.jpg) ```jsx <Pagination :curPage="6" :totalPages="30" :maxVisiblePages="11" /> ``` ![Example 3.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/181a6bd0-bb65-4a45-b031-bbd14d276386/Example_3.jpg) ```jsx <Pagination :curPage="7" :totalPages="30" :maxVisiblePages="11" /> ``` ![Example 4.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b577085e-1e38-49a0-a056-d090aeaaa801/Example_4.jpg) ```jsx <Pagination :curPage="24" :totalPages="30" :maxVisiblePages="11" /> ``` ![Example 5.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1f50fde9-d610-4e59-9d00-4facaea4ffb0/Example_5.jpg) ```jsx <Pagination :curPage="27" :totalPages="30" :maxVisiblePages="11" /> ``` ![Example 6.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/01f805e4-c908-4a65-824e-bc8969a07240/Example_6.jpg) ```jsx <Pagination :curPage="30" :totalPages="30" :maxVisiblePages="11" /> ``` ![Example 7.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b1ace509-fde2-40e3-a242-3b482ea8212b/Example_7.jpg) # Part 2. Improvements With the remaining time you have, please choose one of the following options to tackle. Pick the one that you think will demonstrate your skills and interests the best. ## A. Show hidden pages Because the component doesn’t render every page, users sometimes can’t find the page they’re looking for. In this case, it’d be useful to have an interaction that reveals the pages that have been omitted. Let’s add a new way to interact with our pagination component: using the ellipsis to display more pages. When the component renders a single ellipsis, tapping that ellipsis should reveal all the pages that were truncated. The component should also render a button to reset the component back to its original state. Once the user hits reset, the reset button should no longer be rendered. ![Tap to expand 1.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/52eed616-5ed9-41d8-a21e-584051f81bc6/Tap_to_expand_1.jpg) If there are two ellipses, tapping one should *not* reveal the other one’s pages. Same as before, the component should provide a reset button. ![Tap to expand 2.jpg](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f850fa37-e7b6-46ea-8b00-84221938e0c5/Tap_to_expand_2.jpg) ## B. Add and configure ESLint Using the coderpad shell as you would on your own machine, add and configure ESlint for the app that contains your Pagination component. Feel free to go as deep as you’d like in terms of rule sets or additional formatting tools like Prettier. ## C. Hover and click animations The design team has asked us to add some polish to our new component. They want a flashy animation when a user hovers over the page to encourage users to tap on pages. For this improvement, please add the following animations to the component. This can be done purely with CSS, but you may add any animation library you want. On hover, the component should render two rounded rectangles that expand outwards from the button. Each rectangle extends 5px out from the one inside it in each direction. The animation should last 200ms total. The first rectangle should take 100ms to animate, and then the second rectangle should take another 100ms after that. ![base hover.gif](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/2ff86342-1fbc-41a3-b609-b8bea5b98c5d/base_hover.gif) If the page is already selected, the component should render darker rectangles. The button itself should also lighten a bit. ![selected hover.gif](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/70a3632d-f753-4e46-968d-58d1c1ff0ebb/selected_hover.gif) Ellipses should not have a hover effect, since they are not clickable. If the page is selected while the rings are showing, they should animate to the new color smoothly following the same timeline as before (100ms for the first rectangle and 100ms for the second rectangle). ![click and over.gif](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/abe19742-ba54-4c21-9173-4b57bd4e6369/click_and_over.gif) ## D. Redesign the component to fit a new design system Implement a visual redesign of the Pagination component as if it were to be added to this [design system](https://workbench.gusto.com/). The system does not have a Pagination component, instead please use the general design and look/feel of the system to guide your choices.