-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#2036] Add tab-design for login page #992
Changes from all commits
a0daf4b
ad225a4
dfd16d9
dcb8f2f
c959b4f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
export class LoginFormFocus { | ||
static selector = '#login-form' | ||
|
||
constructor(node) { | ||
this.node = node | ||
this.usernameInput = node.querySelector('input[name="username"]') | ||
this.loginFormColumn = document.getElementById('column__login-form') | ||
this.emailToggleParent = document.getElementById('column__email-toggle') | ||
|
||
this.removeAutofocusAndFocus() | ||
this.hideLoginFormOnLoad() | ||
this.addEmailToggleListener() | ||
this.activateTabFromHash() | ||
} | ||
|
||
removeAutofocusAndFocus() { | ||
if (this.usernameInput) { | ||
this.usernameInput.removeAttribute('autofocus') | ||
this.usernameInput.blur() | ||
} | ||
} | ||
|
||
hideLoginFormOnLoad() { | ||
if (this.loginFormColumn) { | ||
this.emailToggleParent.setAttribute('aria-expanded', 'false') | ||
this.loginFormColumn.classList.add('hide') | ||
} | ||
} | ||
|
||
addEmailToggleListener() { | ||
if (this.emailToggleParent) { | ||
const emailToggleParents = | ||
this.emailToggleParent.querySelectorAll('.link') | ||
emailToggleParents.forEach((link) => { | ||
link.addEventListener('click', (event) => { | ||
event.preventDefault() | ||
this.emailToggleParent.classList.add('hide') | ||
this.toggleLoginFormVisibility() | ||
}) | ||
}) | ||
} | ||
} | ||
|
||
toggleLoginFormVisibility() { | ||
if (this.loginFormColumn) { | ||
this.loginFormColumn.classList.toggle('hide') | ||
this.usernameInput.focus() | ||
} | ||
} | ||
|
||
activateTabFromHash() { | ||
const hash = window.location.hash | ||
const particulierLink = document.querySelector( | ||
'.tab__header[href="/accounts/login/#particulier"]' | ||
) | ||
const zakelijkLink = document.querySelector( | ||
'.tab__header[href="/accounts/login/#zakelijk"]' | ||
) | ||
const particulierTab = document.getElementById('particulier') | ||
const zakelijkTab = document.getElementById('zakelijk') | ||
|
||
if (hash.includes('zakelijk')) { | ||
particulierLink.classList.remove('active') | ||
particulierTab.classList.remove('active') | ||
particulierTab.classList.add('hide') | ||
|
||
zakelijkTab.classList.remove('hide') | ||
zakelijkTab.classList.add('active') | ||
zakelijkLink.classList.add('active') | ||
} else { | ||
particulierTab.classList.remove('hide') | ||
particulierLink.classList.add('active') | ||
particulierTab.classList.remove('active') | ||
|
||
zakelijkTab.classList.add('hide') | ||
zakelijkTab.classList.remove('active') | ||
zakelijkLink.classList.remove('active') | ||
} | ||
} | ||
} | ||
|
||
const loginformFocuses = document.querySelectorAll(LoginFormFocus.selector) | ||
;[...loginformFocuses].forEach((element) => new LoginFormFocus(element)) | ||
Comment on lines
+82
to
+83
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feedback for later: The queryselector has a forEach() so you can just chain from that: document.querySelectorAll(LoginFormFocus.selector).forEach((element) => new LoginFormFocus(element)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
export class TabPanel { | ||
static selector = '.login-tab--container' | ||
|
||
constructor(node) { | ||
this.node = node | ||
this.tabHeadersRow = node.querySelector('.tabs__headers') | ||
this.tabHeaders = node.querySelectorAll('.tab__header') | ||
this.tabContent = node.querySelectorAll('.tab__content') | ||
|
||
this.tabHeadersRow.addEventListener('click', (e) => { | ||
e.preventDefault() // Prevent 'other' tab__panel from disappearing immediately | ||
|
||
const target = e.target.closest('.tab__header') | ||
if (target) { | ||
const index = [...this.tabHeaders].indexOf(target) | ||
if (index !== -1) { | ||
this.hideContent() | ||
this.showContent(index) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
hideContent() { | ||
this.tabContent.forEach((item) => { | ||
item.classList.add('hide') | ||
item.classList.remove('active') | ||
}) | ||
this.tabHeaders.forEach((item) => { | ||
item.classList.remove('active') | ||
}) | ||
} | ||
|
||
showContent(index = 0) { | ||
this.tabContent.forEach((item, idx) => { | ||
if (idx === index) { | ||
item.classList.remove('hide') | ||
item.classList.add('active') | ||
} else { | ||
item.classList.add('hide') | ||
item.classList.remove('active') | ||
} | ||
}) | ||
this.tabHeaders.forEach((item, idx) => { | ||
if (idx === index) { | ||
item.classList.add('active') | ||
} else { | ||
item.classList.remove('active') | ||
} | ||
}) | ||
} | ||
} | ||
|
||
const tabpanels = document.querySelectorAll(TabPanel.selector) | ||
;[...tabpanels].forEach((tabpanel) => new TabPanel(tabpanel)) | ||
Comment on lines
+54
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😉 |
||
|
||
// Activate tab from hash on page load | ||
// Relies on instantiated TabPanel instances | ||
window.addEventListener('load', () => { | ||
const hash = window.location.hash | ||
if (hash) { | ||
const tabHeader = document.querySelector(`.tab__header[href="${hash}"]`) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't work as the tabs have the path AND a hash as href now. And in general I feel it is better to not select on href like this because it often has these issues with unexpected dependencies here or there. (see also the earlier note about LoginForm.js) |
||
if (tabHeader) { | ||
const index = [...tabHeader.parentNode.children].indexOf(tabHeader) | ||
const tabPanel = tabHeader.closest('.tab--container') | ||
const tabPanelInstance = tabPanel && tabPanel.TabPanel | ||
if (tabPanelInstance) { | ||
tabPanelInstance.showContent(index) | ||
} | ||
} | ||
} | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#login-form { | ||
//display: none; | ||
|
||
&.active { | ||
display: grid; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
.digid-logo { | ||
&__image { | ||
height: 40px; | ||
height: 50px; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feedback for later: Django URL's are technically dynamic so we don't want hardcoded URL's in the Javascript (or HTML, CSS etc). This is why there are
{% url "xyz" %}
and{% static 'xyz' %}
in the templates (toreverse()
the URLs from whatever is in the urls.py's).So these Link selectors should be different and not use the href=, but a class or id (possibly chain a
.querySelector()
from the Tab elements you grab by ID just below)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, @Bartvaderkin I will have to create new id's/selectors here because the tabs are not inside those panels-with-id's;
they are elsewhere in the HTML structure.