diff --git a/exercise1/index.html b/exercise1/index.html new file mode 100644 index 000000000..9a6535e54 --- /dev/null +++ b/exercise1/index.html @@ -0,0 +1,39 @@ + + +
+ + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.
+ +Maecenas nec semper ante, pellentesque posuere lorem. Nullam ipsum massa, consequat eget urna ut, pulvinar dignissim lorem. Nulla facilisi. Nam mattis eleifend metus. Fusce at commodo lorem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus pellentesque elit sem, vel blandit posuere.
" + }, + { + "title": "Section 2", + "content": "Mauris a orci sodales, scelerisque velit vitae, gravida nisl. Ut non laoreet eros, vel laoreet nisi. Praesent sed dolor dui. Proin non fringilla quam. Aliquam erat volutpat. Vestibulum vel arcu semper, lobortis turpis ac, ultricies nisi. Praesent id.
" + }, + { + "title": "Section 3", + "content": "Sed elementum sapien ut sapien imperdiet, eu venenatis enim rhoncus. Praesent euismod tincidunt rhoncus. Duis cras amet:
Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.
Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
" + } + ]; + + const tabsTitlesContainer = document.getElementById('tab-titles'); + const tabsContentsContainer = document.getElementById('tab-contents'); + const accordionContainer = document.getElementById('accordion'); + + data.forEach((section, index) => { + // Create tab title + const tabTitle = document.createElement('div'); + tabTitle.className = 'tab-title'; + tabTitle.innerText = section.title; + tabTitle.dataset.index = index; + tabTitle.tabIndex = 0; // Make tab title focusable + + // Create tab content + const tabContent = document.createElement('div'); + tabContent.className = 'tab-content'; + tabContent.innerHTML = section.content; + + tabTitle.addEventListener('click', () => { + document.querySelectorAll('.tab-title').forEach((title, i) => { + if (i === index) { + title.classList.add('active'); + } else { + title.classList.remove('active'); + } + }); + document.querySelectorAll('.tab-content').forEach((content, i) => { + if (i === index) { + content.style.display = 'block'; + } else { + content.style.display = 'none'; + } + }); + }); + + tabTitle.addEventListener('keydown', (e) => { + if (e.key === 'Enter' || e.key === ' ') { + tabTitle.click(); + } + }); + + tabsTitlesContainer.appendChild(tabTitle); + tabsContentsContainer.appendChild(tabContent); + + // Create accordion + const accordionItem = document.createElement('div'); + accordionItem.className = 'accordion-item'; + + const accordionTitle = document.createElement('div'); + accordionTitle.className = 'accordion-title'; + accordionTitle.innerText = section.title; + accordionTitle.dataset.index = index; + + const accordionContent = document.createElement('div'); + accordionContent.className = 'accordion-content'; + accordionContent.innerHTML = section.content; + + accordionTitle.addEventListener('click', () => { + document.querySelectorAll('.accordion-content').forEach((content, i) => { + if (i === index) { + content.style.display = content.style.display === 'block' ? 'none' : 'block'; + } else { + content.style.display = 'none'; + } + }); + }); + + accordionItem.appendChild(accordionTitle); + accordionItem.appendChild(accordionContent); + accordionContainer.appendChild(accordionItem); + }); + + // Open first tab and accordion on load + if (document.querySelector('.tab-title')) { + document.querySelector('.tab-title').classList.add('active'); + } + if (document.querySelector('.tab-content')) { + document.querySelector('.tab-content').style.display = 'block'; + } + if (document.querySelector('.accordion-content')) { + document.querySelector('.accordion-content').style.display = 'block'; + } +}); diff --git a/exercise2/styles.css b/exercise2/styles.css new file mode 100644 index 000000000..16a4b0aee --- /dev/null +++ b/exercise2/styles.css @@ -0,0 +1,114 @@ +body { + font-family: Arial, sans-serif; + background-color: #f4f4f9; + margin: 0; + padding: 0; +} + +.container { + width: 80%; + margin: 2rem auto; + background-color: #fff; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + border-radius: 8px; + overflow: hidden; +} + +.tabs, .accordion { + padding: 1rem; +} + +.tab-titles { + display: flex; + border-bottom: 1px solid #ddd; +} + +.tab-title { + padding: 10px 20px; + border: 1px solid #ddd; + cursor: pointer; + background: #f9f9f9; + margin-right: -1px; /* Prevent double border */ + border-bottom: none; + transition: background 0.3s, border-color 0.3s; + flex: 1; + text-align: center; + outline: none; /* Remove default focus outline */ +} + +.tab-title.active { + background: #fff; + border-bottom: 1px solid #fff; + color: #333; +} + +.tab-title:hover, .tab-title:focus { + background: #e9e9e9; +} + +.tab-title:focus { + outline: 2px solid #007BFF; /* Custom focus outline */ + z-index: 1; /* Ensure focus outline is visible */ +} + +.tab-content { + display: none; + padding: 20px; + border: 1px solid #ddd; + border-top: none; + animation: fadeIn 0.3s; +} + +.accordion-item { + border: 1px solid #ddd; + margin-bottom: 5px; + border-radius: 4px; + overflow: hidden; +} + +.accordion-title { + padding: 15px; + cursor: pointer; + background: #f9f9f9; + transition: background 0.3s; +} + +.accordion-title:hover { + background: #e9e9e9; +} + +.accordion-content { + display: none; + padding: 15px; + border-top: 1px solid #ddd; + animation: fadeIn 0.3s; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@media (min-width: 768px) { + .tabs { + display: flex; + } + + .accordion { + display: none; + } +} + +@media (max-width: 767px) { + .tabs { + display: none; + } + + .accordion { + display: block; + } +} diff --git a/readme.md b/readme.md index 72b342846..cecd3651c 100644 --- a/readme.md +++ b/readme.md @@ -1,40 +1,25 @@ -Introduction ---- -Thanks for taking the time to complete this frontend technical assessment. We will be focusing on software quality (scalability, readability, maintainability, etc.) and your eye for detail. You may include any libraries, but Vue.js is preferred and jQuery is not recommended. Along with following best practices, bonus points for following our [coding guidelines](https://github.com/mindarc/frontend-assessment/wiki/Coding-guidelines). - -Exercise 1 ---- -Build a responsive page based on the designs. - -##### Requirements -1. Match the designs exactly. -2. Needs to be responsive. - -##### Designs -* exercise1-desktop.png -* exercise1-mobile.png - -##### Assets -* Desktop banner - https://via.placeholder.com/1920x650 -* Mobile banner - https://via.placeholder.com/600x600 -* Content images - https://via.placeholder.com/400x300 - -Exercise 2 ---- -Read the `data.json` file and display the data as tabs on desktop and an accordion on mobile. - -##### Requirements -1. Display data in tabs on desktop. -2. Display data in an accordion on mobile. -3. Only 1 accordion/tab should be open at a time. -4. Open the first accordion/tab on load. -5. If the open accordion is selected, close it. - -###### Bonus points -* Improve the user experience with meaningful animations/transitions. -* Design and styling. -* Explain why the result of `('b' + 'a' + + 'a' + 'a').toLowerCase()` is `banana`. - -Submission ---- -We recommend submitting your completed assessment as a forked repository. Please replace README content with instructions and relevant documentation. +Exercise 1 + +> Created a responsive web page that displays data in a tabbed layout on desktops and an accordion layout on mobile devices. +> The header image will change based on the screen size, ensuring an optimized viewing experience for desktop and mobile view. +> Keyboard navigation is supported for tabs using Enter or Space key. + + +Exercise 2 + +- Desktop View (min-width: 768px): Data is shown in tabs. +- Mobile View (max-width: 767px): Data is shown in an accordion. +Key Features: + +> Only one tab/accordion section is open at a time. +> The first tab/accordion section is open by default. +> Tabs are made focusable by adding tabIndex = 0. +> Keyboard navigation is supported for tabs using Enter or Space keys. + + + +Banana Explained: + +From the concatenation that happened from the expression, + +"'b' + 'a'" is simple string concatenation. It combines the characters 'b' and 'a' to form the string "ba". the second part which is the "+ 'a'" tries to convert the character 'a' to a number. Since 'a' isn't a valid number, JavaScript evaluates this as NaN or "Not a Number". Lastly, "a" is simply the character 'a' added as is. So putting it all together forms the string "baNaNa" then by considering the method "toLowerCase()"converts all characters in the string to lowercase, gets us the final string of "banana". \ No newline at end of file