Skip to content
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

Merged
merged 5 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@

{% block content %}

<div class="registration-grid">
<h1 class="utrecht-heading-1">{% trans 'Registreren' %}</h1>
{% render_grid %}
{% if settings.DIGID_ENABLED and digid_url %}
{% render_column start=5 span=5 %}
{% render_card direction='horizontal' tinted=True compact=True %}
<a href="{{ digid_url }}" class="link digid-logo">
<img class="digid-logo__image" src="{% static 'accounts/digid_logo.svg' %}" alt="DigiD inlogpagina">
</a>
{% link bold=True href=digid_url text=_('Registreren met DigiD') secondary=True icon='arrow_forward' %}
{% link bold=True href=digid_url text=_('Registreren met DigiD') primary=True icon='arrow_forward' %}
{% endrender_card %}
{% endrender_column %}
{% endif %}
Expand All @@ -22,21 +22,20 @@
<a href="{{ eherkenning_url }}" class="link eherkenning-logo">
<img class="eherkenning-logo__image" src="{% static 'accounts/eherkenning.png' %}" height=30 alt="eHerkenning inlogpagina">
</a>
{% link bold=True href=eherkenning_url text=_('Registreren met eHerkenning') secondary=True icon='arrow_forward' %}
{% link bold=True href=eherkenning_url text=_('Registreren met eHerkenning') primary=True icon='arrow_forward' %}
{% endrender_card %}
{% endrender_column %}
{% endif %}

{% if login_allow_registration %}
{% render_column start=5 span=5 %}
{% render_card tinted=True compact=True %}
<h1 class="h3">{% trans "Registreren met E-mail" %}</h1><br>
<h3 class="h3">{% trans "Registreren met E-mail" %}</h3>
{% form form_object=form method="POST" id="registration-form" submit_text=_('Registreren') extra_classes="form__registration" show_required=True %}
{% endrender_card %}
{% endrender_column %}
{% endif %}

{% endrender_grid %}
</div>

{% endblock content %}
248 changes: 157 additions & 91 deletions src/open_inwoner/accounts/templates/registration/login.html

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<span class="nav-login--icon">
{% url 'login' as login_url %}
{% trans "Inloggen" as login %}
{% button text="" title="Inloggen" href=login_url icon="person" icon_position="before" primary=True icon_outlined=True transparent=True %}
{% button text="" title="Inloggen" href=login_url icon="person" icon_position="before" primary=True icon_outlined=True %}
</span>
{% endif %}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<span class="desktop-login__link">
{% url 'login' as login_url %}
{% trans "Inloggen" as login %}
{% button text="Inloggen" href=login_url icon="person" icon_position="before" primary=True icon_outlined=True transparent=True %}
{% button text="Inloggen" href=login_url icon="person" icon_position="before" primary=True icon_outlined=True %}
</span>
</div>
{% endif %}
83 changes: 83 additions & 0 deletions src/open_inwoner/js/components/form/LoginForm.js
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"]'
Comment on lines +54 to +57
Copy link
Contributor

@Bartvaderkin Bartvaderkin Apr 19, 2024

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 (to reverse() 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)

Copy link
Contributor Author

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.

)
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
Copy link
Contributor

@Bartvaderkin Bartvaderkin Apr 19, 2024

Choose a reason for hiding this comment

The 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))

1 change: 1 addition & 0 deletions src/open_inwoner/js/components/form/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ import './FileInput'
import './ChoiceListMultiple'
import './ChoiceListSingle'
import './DisableContactFormButton'
import './LoginForm'
3 changes: 3 additions & 0 deletions src/open_inwoner/js/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import './plan-preview'
import './questionnaire'
import './readmore'
import './search'
import { TabPanel } from './tab-panels'
import './toggle'
import { StatusAccordion } from './cases/status_accordion'
import './session'
Expand Down Expand Up @@ -58,6 +59,8 @@ const elementWrappers = [
[StatusAccordion.selector, (elt) => new StatusAccordion(elt)],
[FileInput.selector, (elt) => new FileInput(elt)],
[ToggleHide.selector, (elt) => new ToggleHide(elt)],
[TabPanel.selector, (elt) => new TabPanel(elt)],
// add more when needed
]

// harden against multiple events
Expand Down
72 changes: 72 additions & 0 deletions src/open_inwoner/js/components/tab-panels/index.js
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
Copy link
Contributor

Choose a reason for hiding this comment

The 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}"]`)
Copy link
Contributor

@Bartvaderkin Bartvaderkin Apr 19, 2024

Choose a reason for hiding this comment

The 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)
}
}
}
})
13 changes: 13 additions & 0 deletions src/open_inwoner/scss/components/Button/Button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@
border-color: transparent;
color: var(--color-primary);

&.button--primary {
border-color: transparent;
color: var(--color-primary);
background-color: transparent;

&:hover {
background-color: transparent;
border-color: transparent;
color: var(--color-primary);
text-decoration: underline;
}
}

&.button--secondary {
color: var(--color-secondary);
background-color: transparent;
Expand Down
20 changes: 11 additions & 9 deletions src/open_inwoner/scss/components/Card/Card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,22 @@

&--tinted {
--card-color-background: var(--color-gray-lightest);
border: var(--card-size-border) solid var(--color-gray-lightest);

// contrast for accessibility
.form .caption__content {
color: var(--color-tinted-mute);
}

.card__body--direction-horizontal .link .link__text {
text-align: right;
padding-left: var(--spacing-small);
.card__body--direction-horizontal {
display: flex;
justify-content: space-between;
padding: 20px;

.link .link__text {
text-align: right;
padding-left: var(--spacing-small);
}
}
}

Expand Down Expand Up @@ -264,11 +271,6 @@
}
}

&__body--direction-horizontal {
display: flex;
justify-content: space-between;
}

&__body--flex {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -356,7 +358,7 @@
}

/// On a stretched card, the one and only link after a list should be placed on above the bottom border.
&-- stretch &__body {
&--stretch &__body {
padding-bottom: var(--card-spacing);

@media (min-width: 768px) {
Expand Down
7 changes: 7 additions & 0 deletions src/open_inwoner/scss/components/LoginForm/LoginForm.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#login-form {
//display: none;

&.active {
display: grid;
}
}
2 changes: 1 addition & 1 deletion src/open_inwoner/scss/components/Logo/DigidLogo.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.digid-logo {
&__image {
height: 40px;
height: 50px;
}
}
Loading
Loading