-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
contrib/assets/dropdown.js: refactor dropdown
- Loading branch information
Showing
8 changed files
with
169 additions
and
201 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
|
||
### Changed | ||
|
||
- unify dropdown and refactor following files: dropdown.js, _dropdown.scss, item_detail_dropdown.html, user_indicator.html, _user_indicator.scss | ||
|
||
### Removed | ||
- deleted user_indicator.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,65 @@ | ||
const Dropdown = { | ||
toggleDropdown (event) { | ||
const dropdown = event.currentTarget.parentNode | ||
const isOpen = dropdown.getAttribute('aria-expanded') === 'true' | ||
class Dropdown { | ||
constructor (container) { | ||
this.container = container | ||
this.trigger = container.querySelector('[data-dropdown-trigger]') | ||
this.dropdown = container.querySelector('[data-dropdown-menu]') | ||
this.closeTimeout = null | ||
|
||
dropdown.setAttribute('aria-expanded', !isOpen) | ||
this.init() | ||
} | ||
|
||
const menu = dropdown.querySelector('.dropdown__menu') | ||
menu.classList.toggle('dropdown__menu--show', !isOpen) | ||
init () { | ||
this.trigger.addEventListener('click', (event) => this.toggleDropdown(event)) | ||
this.dropdown.addEventListener('keyup', (event) => this.handleKeyup(event)) | ||
this.dropdown.addEventListener('focusout', (event) => this.handleFocusout(event)) | ||
} | ||
|
||
if (!isOpen) { | ||
const menu = dropdown.querySelector('.dropdown__menu') | ||
menu.firstElementChild.focus() | ||
toggleDropdown (event) { | ||
event.preventDefault() | ||
if (this.container.classList.contains('dropdown--open')) { | ||
this.closeDropdown() | ||
} else { | ||
this.openDropdown() | ||
} | ||
}, | ||
} | ||
|
||
openDropdown () { | ||
this.container.classList.add('dropdown--open') | ||
this.trigger.setAttribute('aria-expanded', true) | ||
document.addEventListener('click', this.outsideClickListener) | ||
} | ||
|
||
closeDropdown (event) { | ||
const dropdowns = document.querySelectorAll('.js-dropdown') | ||
dropdowns.forEach(function (dropdown) { | ||
const isOpen = dropdown.getAttribute('aria-expanded') === 'true' | ||
if (isOpen && !dropdown.contains(event.target)) { | ||
dropdown.setAttribute('aria-expanded', 'false') | ||
const menu = dropdown.querySelector('.dropdown__menu') | ||
menu.classList.remove('dropdown__menu--show') | ||
} | ||
}) | ||
}, | ||
if (event) event.stopPropagation() | ||
document.removeEventListener('click', this.outsideClickListener) | ||
this.container.classList.remove('dropdown--open') | ||
this.trigger.setAttribute('aria-expanded', false) | ||
clearTimeout(this.closeTimeout) | ||
} | ||
|
||
init () { | ||
const dropdowns = document.querySelectorAll('.js-dropdown') | ||
if (dropdowns.length > 0) { | ||
dropdowns.forEach(function (button) { | ||
button.addEventListener('click', Dropdown.toggleDropdown) | ||
}) | ||
handleKeyup (event) { | ||
if (event.keyCode === 27) { | ||
this.closeDropdown() | ||
this.trigger.focus() | ||
} | ||
} | ||
|
||
handleFocusout (event) { | ||
this.closeTimeout = setTimeout(() => { | ||
if (!this.dropdown.contains(event.relatedTarget)) { | ||
this.closeDropdown() | ||
} | ||
}, 10) | ||
} | ||
|
||
document.addEventListener('click', Dropdown.closeDropdown) | ||
outsideClickListener = (event) => { | ||
if (!this.container.contains(event.target) && event.target !== this.close) { | ||
this.closeDropdown() | ||
} | ||
} | ||
} | ||
|
||
export default Dropdown | ||
document.addEventListener('DOMContentLoaded', () => { | ||
const dropdowns = document.querySelectorAll('[data-dropdown]') | ||
dropdowns.forEach(dropdown => new Dropdown(dropdown)) | ||
}) |
6 changes: 3 additions & 3 deletions
6
meinberlin/apps/contrib/templates/meinberlin_contrib/includes/item_detail_dropdown.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
104 changes: 49 additions & 55 deletions
104
meinberlin/apps/users/templates/meinberlin_users/user_indicator.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,55 @@ | ||
{% load i18n static %} | ||
|
||
<div class="user-indicator__container"> | ||
<div id="js-user-indicator" class="user-indicator__wrapper"> | ||
<div class="dropdown" data-dropdown> | ||
{% if request.user.is_authenticated %} | ||
<button | ||
id="js-user-indicator-trigger" | ||
type="button" | ||
aria-haspopup="menu" | ||
aria-controls="js-user-indicator-dropdown" | ||
tabindex="0"> | ||
<i class="fas fa-user text--color-primary" aria-hidden="true"></i> | ||
{{ request.user.username }} | ||
</button> | ||
<div role="menu" class="dropdown" id="js-user-indicator-dropdown" aria-label="Login of Register" tabindex="-1"> | ||
<button id="js-user-indicator-close" type="button" class="button button--close user-indicator__close" title="{% translate 'close' %}" aria-label="{% translate 'menu close' %}"></button> | ||
<ul class="list--clean"> | ||
<li><b>{% translate "My account" %}</b></li> | ||
<li><a href="{% url 'account' %}" role="menuitem">{% translate "Account Settings" %}</a></li> | ||
{% for organisation in request.user.organisations %} | ||
<li><a href="{% url 'a4dashboard:project-list' organisation_slug=organisation.slug %}" role="menuitem">{{ organisation.name }}</a></li> | ||
{% endfor %} | ||
{% if request.user.is_superuser %} | ||
<li><a href="{% url 'meinberlin_platformemails:create' %}" role="menuitem">{% translate "Platform Email" %}</a></li> | ||
{% endif %} | ||
<li> | ||
<form class="block--nogap text--color-dark" action="{% url 'account_logout' %}" method="post" aria-label="{% translate 'Logout' %}" role="menuitem"> | ||
{% csrf_token %} | ||
<input type="hidden" name="next" value="{{ redirect_field_value }}"> | ||
<button type="submit">{% translate "Logout" %}</button> | ||
</form> | ||
</li> | ||
</ul> | ||
</div> | ||
{% else %} | ||
<button | ||
id="js-user-indicator-trigger" | ||
type="button" | ||
aria-haspopup="menu" | ||
aria-controls="js-user-indicator-dropdown" | ||
tabindex="0"> | ||
<i class="fas fa-user text--color-primary" aria-hidden="true"></i> | ||
{% translate "Login" %} | ||
</button> | ||
<div role="menu" class="dropdown" id="js-user-indicator-dropdown" aria-label="Login of Register" tabindex="-1"> | ||
<button id="js-user-indicator-close" type="button" class="button button--close user-indicator__close" title="{% translate 'close' %}" aria-label="{% translate 'menu close' %}"></button> | ||
<ul class="list--clean"> | ||
<li> | ||
<a class="button button--light" href="{% url 'account_login' %}?next={{ redirect_field_value|urlencode }}" role="menuitem">{% translate "Login" %}</a> | ||
</li> | ||
<li> | ||
<a href="{% url 'account_signup' %}?next={{ redirect_field_value|urlencode }}" role="menuitem">{% translate "Register" %}</a> | ||
</li> | ||
<li> | ||
<a href="{% url 'account_reset_password' %}?next={{ redirect_field_value|urlencode }}" role="menuitem">{% translate "Forgot password?" %}</a> | ||
</li> | ||
</ul> | ||
</div> | ||
{% endif %} | ||
<button data-dropdown-trigger type="button" aria-haspopup="menu" aria-controls="dropdown-menu" tabindex="0"> | ||
<i class="fas fa-user text--color-primary" aria-hidden="true"></i> | ||
{{ request.user.username }} | ||
</button> | ||
<div role="menu" class="dropdown__menu" aria-label="{% translate "Account" %}" tabindex="-1" data-dropdown-menu> | ||
<h2>{% translate "My account" %}</h2> | ||
<ul class="list--clean"> | ||
<li class="dropdown__item"> | ||
<a href="{% url 'account' %}" role="menuitem">{% translate "Account Settings" %}</a> | ||
</li> | ||
{% for organisation in request.user.organisations %} | ||
<li class="dropdown__item"> | ||
<a href="{% url 'a4dashboard:project-list' organisation_slug=organisation.slug %}" role="menuitem">{{ organisation.name }}</a> | ||
</li> | ||
{% endfor %} | ||
{% if request.user.is_superuser %} | ||
<li class="dropdown__item"> | ||
<a href="{% url 'meinberlin_platformemails:create' %}" role="menuitem">{% translate "Platform Email" %}</a> | ||
</li> | ||
{% endif %} | ||
<li class="dropdown__item"> | ||
<form class="block--nogap text--color-dark" action="{% url 'account_logout' %}" method="post" aria-label="{% translate 'Logout' %}" role="menuitem"> | ||
{% csrf_token %} | ||
<input type="hidden" name="next" value="{{ redirect_field_value }}"> | ||
<button class="button button--light" type="submit">{% translate "Logout" %}</button> | ||
</form> | ||
</li> | ||
</ul> | ||
</div> | ||
{% else %} | ||
<button data-dropdown-trigger type="button" aria-haspopup="menu" aria-controls="dropdown-menu" tabindex="0"> | ||
<i class="fas fa-user text--color-primary" aria-hidden="true"></i> | ||
{% translate "Login" %} | ||
</button> | ||
<div role="menu" class="dropdown__menu" aria-label="{% translate "Login or Register" %}" tabindex="-1" data-dropdown-menu> | ||
<ul class="list--clean"> | ||
<li class="dropdown__item"> | ||
<a class="button button--light" href="{% url 'account_login' %}?next={{ redirect_field_value|urlencode }}" role="menuitem">{% translate "Login" %}</a> | ||
</li> | ||
<li class="dropdown__item"> | ||
<a href="{% url 'account_signup' %}?next={{ redirect_field_value|urlencode }}" role="menuitem">{% translate "Register" %}</a> | ||
</li> | ||
<li class="dropdown__item"> | ||
<a href="{% url 'account_reset_password' %}?next={{ redirect_field_value|urlencode }}" role="menuitem">{% translate "Forgot password?" %}</a> | ||
</li> | ||
</ul> | ||
</div> | ||
{% endif %} | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.