gear_menu_popover: Flatten nested lists for better accessibility.

This refactors popover list structure to use a flattened `ul > li`
structure along with aria-related additions, enabling screen reader
accessibility and announcing menu length and position (`# of n`).

Added ARIA roles:
- `role="menu"` to the parent `<ul>` element, indicating it is a widget
  offering a list of choices.

- `role="menuitem"`, `role="menuitemcheckbox"`,
  or`role="menuitemradio"` to child elements based on their function.

- `role="none"` to `<li>` elements, removing the implied `listitem`
  role that conflicts with the parent menu structure.
This commit is contained in:
Sayam Samal 2024-05-24 09:38:39 +05:30 committed by Tim Abbott
parent 3c1d248abe
commit ed9d2a7af6
2 changed files with 181 additions and 189 deletions

View File

@ -1343,10 +1343,11 @@ ul {
}
#gear-menu-dropdown {
.org-info {
.org-info-container {
padding: 9px 0 5px;
border-bottom: solid 1px var(--color-border-popover-menu-separator);
& li {
.org-info {
display: flex;
justify-content: flex-start;
font-size: 15px;

View File

@ -1,195 +1,186 @@
<div class="popover-menu" id="gear-menu-dropdown" aria-labelledby="settings-dropdown" data-simplebar>
<ul class="popover-menu-outer-list">
<li class="org-info popover-menu-outer-list-item">
<ul class="popover-menu-inner-list">
<li class="org-name popover-menu-inner-list-item">{{realm_name}}</li>
<li class="org-url popover-menu-inner-list-item">{{realm_url}}</li>
{{#if is_self_hosted }}
<li class="org-version popover-menu-inner-list-item">
<a href="#about-zulip" class="navigate-link-on-enter popover-menu-link">{{version_display_string}}</a>
</li>
{{#if server_needs_upgrade }}
<li class="org-upgrade popover-menu-inner-list-item">
<a href="https://zulip.readthedocs.io/en/stable/production/upgrade.html" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">{{t 'Upgrade to the latest release' }}</a>
</li>
{{/if}}
{{else}}
<li class="org-plan popover-menu-inner-list-item hidden-for-spectators">
{{#if is_plan_limited }}
<a href="/plans/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">Zulip Cloud Free</a>
{{else if is_plan_standard}}
<a href="/plans/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">Zulip Cloud Standard</a>
{{else if is_plan_standard_sponsored_for_free}}
<a href="/plans/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">Zulip Cloud Standard (sponsored)</a>
{{else if is_plan_plus}}
<a href="/plans/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">Zulip Cloud Plus</a>
{{/if}}
</li>
{{/if}}
{{#if (and (not is_self_hosted) user_has_billing_access (not is_plan_standard_sponsored_for_free)) }}
{{#if sponsorship_pending }}
<li class="org-upgrade popover-menu-inner-list-item">
<a href="/sponsorship/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">{{t "Sponsorship request pending" }}</a>
</li>
{{else}}
{{#if is_plan_limited }}
<li class="org-upgrade popover-menu-inner-list-item">
<a href="/upgrade/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">{{t "Upgrade to {standard_plan_name}" }}</a>
</li>
{{/if}}
{{#unless is_org_on_paid_plan}}
{{#if is_education_org }}
<li class="org-upgrade popover-menu-inner-list-item">
<a href="/sponsorship/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">{{t 'Request education pricing' }}</a>
</li>
{{else if (not is_business_org) }}
<li class="org-upgrade popover-menu-inner-list-item">
<a href="/sponsorship/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">{{t 'Request sponsorship' }}</a>
</li>
{{/if}}
{{/unless}}
{{/if}}
{{/if}}
</ul>
<div class="org-info-container">
<div class="org-info org-name">{{realm_name}}</div>
<div class="org-info org-url">{{realm_url}}</div>
{{#if is_self_hosted }}
<div class="org-info org-version">
<a href="#about-zulip" class="navigate-link-on-enter popover-menu-link">{{version_display_string}}</a>
</div>
{{#if server_needs_upgrade }}
<div class="org-info org-upgrade">
<a href="https://zulip.readthedocs.io/en/stable/production/upgrade.html" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">{{t 'Upgrade to the latest release' }}</a>
</div>
{{/if}}
{{else}}
<div class="org-info org-plan hidden-for-spectators">
{{#if is_plan_limited }}
<a href="/plans/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">Zulip Cloud Free</a>
{{else if is_plan_standard}}
<a href="/plans/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">Zulip Cloud Standard</a>
{{else if is_plan_standard_sponsored_for_free}}
<a href="/plans/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">Zulip Cloud Standard (sponsored)</a>
{{else if is_plan_plus}}
<a href="/plans/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">Zulip Cloud Plus</a>
{{/if}}
</div>
{{/if}}
{{#if (and (not is_self_hosted) user_has_billing_access (not is_plan_standard_sponsored_for_free)) }}
{{#if sponsorship_pending }}
<div class="org-info org-upgrade">
<a href="/sponsorship/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">{{t "Sponsorship request pending" }}</a>
</div>
{{else}}
{{#if is_plan_limited }}
<div class="org-info org-upgrade">
<a href="/upgrade/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">{{t "Upgrade to {standard_plan_name}" }}</a>
</div>
{{/if}}
{{#unless is_org_on_paid_plan}}
{{#if is_education_org }}
<div class="org-info org-upgrade">
<a href="/sponsorship/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">{{t 'Request education pricing' }}</a>
</div>
{{else if (not is_business_org) }}
<div class="org-info org-upgrade">
<a href="/sponsorship/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">{{t 'Request sponsorship' }}</a>
</div>
{{/if}}
{{/unless}}
{{/if}}
{{/if}}
</div>
<ul role="menu" class="popover-menu-list">
{{!-- Group 1 --}}
<li role="none" class="link-item popover-menu-list-item hidden-for-spectators">
<a role="menuitem" href="#channels/subscribed" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-hash" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Channel settings' }}</span>
</a>
</li>
<li class="popover-menu-outer-list-item">
<ul class="popover-menu-inner-list">
<li class="link-item popover-menu-inner-list-item hidden-for-spectators">
<a href="#channels/subscribed" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-hash" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Channel settings' }}</span>
</a>
</li>
<li class="link-item popover-menu-inner-list-item admin-menu-item hidden-for-spectators">
<a href="#organization" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-building" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Organization settings' }}</span>
</a>
</li>
{{#unless is_guest}}
<li class="link-item popover-menu-inner-list-item hidden-for-spectators">
<a href="#groups/your" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-user-cog" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Group settings' }}</span>
</a>
</li>
{{/unless}}
<li class="link-item popover-menu-inner-list-item hidden-for-spectators">
<a href="#settings" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-tool" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Personal settings' }}</span>
</a>
</li>
{{#unless is_guest}}
<li class="link-item popover-menu-inner-list-item hidden-for-spectators">
<a href="/stats" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-bar-chart" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Usage statistics' }}</span>
</a>
</li>
{{/unless}}
<li class="link-item popover-menu-inner-list-item only-visible-for-spectators">
<a tabindex="0" class="change-language-spectator popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-f-globe" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Select language' }}</span>
</a>
</li>
<li class="link-item popover-menu-inner-list-item gear-menu-select-dark-theme only-visible-for-spectators">
<a tabindex="0" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-moon" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Switch to dark theme' }}</span>
</a>
</li>
<li class="link-item popover-menu-inner-list-item gear-menu-select-light-theme only-visible-for-spectators">
<a tabindex="0" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-sun" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Switch to light theme' }}</span>
</a>
</li>
</ul>
<li role="none" class="link-item popover-menu-list-item admin-menu-item hidden-for-spectators">
<a role="menuitem" href="#organization" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-building" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Organization settings' }}</span>
</a>
</li>
<li class="hidden-for-spectators popover-menu-outer-list-item">
<ul class="popover-menu-inner-list">
<li class="link-item popover-menu-inner-list-item">
<a href="{{ apps_page_url }}" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-monitor" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Desktop & mobile apps' }}</span>
</a>
</li>
<li class="link-item popover-menu-inner-list-item">
<a href="/integrations/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-git-pull-request" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Integrations' }}</span>
</a>
</li>
<li class="link-item popover-menu-inner-list-item">
<a href="/api/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-file-text" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'API documentation' }}</span>
</a>
</li>
{{#if show_billing}}
<li class="link-item popover-menu-inner-list-item">
<a href="/billing/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-credit-card" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Billing' }}</span>
</a>
</li>
{{/if}}
{{#if promote_sponsoring_zulip}}
<li class="link-item popover-menu-inner-list-item">
<a href="https://zulip.com/help/support-zulip-project" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-heart" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Support Zulip' }}</span>
</a>
</li>
{{/if}}
{{#if show_remote_billing }}
<li class="link-item popover-menu-inner-list-item">
<a href="/self-hosted-billing/" id="open-self-hosted-billing" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-rocket" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Plan management' }}</span>
</a>
</li>
{{/if}}
{{#if show_plans}}
{{!-- This will be hidden for self hosted realms since they will have corporate disabled. --}}
<li class="link-item popover-menu-inner-list-item">
<a href="/plans/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-rocket" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Plans and pricing' }}</span>
</a>
</li>
{{/if}}
</ul>
{{#unless is_guest}}
<li role="none" class="link-item popover-menu-list-item hidden-for-spectators">
<a role="menuitem" href="#groups/your" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-user-cog" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Group settings' }}</span>
</a>
</li>
{{#if (or can_invite_users_by_email can_create_multiuse_invite is_spectator show_webathena)}}
<li class="popover-menu-outer-list-item">
<ul class="popover-menu-inner-list">
{{#if (or can_invite_users_by_email can_create_multiuse_invite)}}
<li class="link-item popover-menu-inner-list-item">
<a tabindex="0" class="invite-user-link popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-user-plus" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Invite users' }}</span>
</a>
</li>
{{/if}}
{{#if show_webathena}}
<li class="link-item popover-menu-inner-list-item" title="{{t 'Grant Zulip the Kerberos tickets needed to run your Zephyr mirror via Webathena' }}" id="webathena_login_menu">
<a href="#webathena" class="webathena_login popover-menu-link">
<i class="popover-menu-icon fa fa-bolt" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Link with Webathena' }}</span>
</a>
</li>
{{/if}}
<li class="link-item popover-menu-inner-list-item only-visible-for-spectators">
<a href="{{login_link}}" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-log-in" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Log in' }}</span>
</a>
</li>
</ul>
{{/unless}}
<li role="none" class="link-item popover-menu-list-item hidden-for-spectators">
<a role="menuitem" href="#settings" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-tool" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Personal settings' }}</span>
</a>
</li>
{{#unless is_guest}}
<li role="none" class="link-item popover-menu-list-item hidden-for-spectators">
<a role="menuitem" href="/stats" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-bar-chart" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Usage statistics' }}</span>
</a>
</li>
{{/unless}}
<li role="none" class="link-item popover-menu-list-item only-visible-for-spectators">
<a role="menuitem" tabindex="0" class="change-language-spectator popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-f-globe" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Select language' }}</span>
</a>
</li>
<li role="none" class="link-item popover-menu-list-item gear-menu-select-dark-theme only-visible-for-spectators">
<a role="menuitem" tabindex="0" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-moon" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Switch to dark theme' }}</span>
</a>
</li>
<li role="none" class="link-item popover-menu-list-item gear-menu-select-light-theme only-visible-for-spectators">
<a role="menuitem" tabindex="0" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-sun" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Switch to light theme' }}</span>
</a>
</li>
{{!-- Group 2 --}}
<li role="separator" class="popover-menu-separator"></li>
<li role="none" class="link-item popover-menu-list-item">
<a role="menuitem" href="{{ apps_page_url }}" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-monitor" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Desktop & mobile apps' }}</span>
</a>
</li>
<li role="none" class="link-item popover-menu-list-item">
<a role="menuitem" href="/integrations/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-git-pull-request" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Integrations' }}</span>
</a>
</li>
<li role="none" class="link-item popover-menu-list-item">
<a role="menuitem" href="/api/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-file-text" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'API documentation' }}</span>
</a>
</li>
{{#if show_billing}}
<li role="none" class="link-item popover-menu-list-item">
<a role="menuitem" href="/billing/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-credit-card" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Billing' }}</span>
</a>
</li>
{{/if}}
{{#if promote_sponsoring_zulip}}
<li role="none" class="link-item popover-menu-list-item">
<a role="menuitem" href="https://zulip.com/help/support-zulip-project" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-heart" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Support Zulip' }}</span>
</a>
</li>
{{/if}}
{{#if show_remote_billing }}
<li role="none" class="link-item popover-menu-list-item">
<a role="menuitem" href="/self-hosted-billing/" id="open-self-hosted-billing" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-rocket" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Plan management' }}</span>
</a>
</li>
{{/if}}
{{#if show_plans}}
{{!-- This will be hidden for self hosted realms since they will have corporate disabled. --}}
<li role="none" class="link-item popover-menu-list-item">
<a role="menuitem" href="/plans/" target="_blank" rel="noopener noreferrer" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-rocket" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Plans and pricing' }}</span>
</a>
</li>
{{/if}}
{{!-- Group 3 --}}
{{#if (or can_invite_users_by_email can_create_multiuse_invite is_spectator show_webathena)}}
<li role="separator" class="popover-menu-separator"></li>
{{/if}}
{{#if (or can_invite_users_by_email can_create_multiuse_invite)}}
<li role="none" class="link-item popover-menu-list-item">
<a role="menuitem" tabindex="0" class="invite-user-link popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-user-plus" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Invite users' }}</span>
</a>
</li>
{{/if}}
{{#if show_webathena}}
<li role="none" class="link-item popover-menu-list-item" title="{{t 'Grant Zulip the Kerberos tickets needed to run your Zephyr mirror via Webathena' }}" id="webathena_login_menu">
<a role="menuitem" href="#webathena" class="webathena_login popover-menu-link">
<i class="popover-menu-icon fa fa-bolt" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Link with Webathena' }}</span>
</a>
</li>
{{/if}}
<li role="none" class="link-item popover-menu-list-item only-visible-for-spectators">
<a role="menuitem" href="{{login_link}}" class="navigate-link-on-enter popover-menu-link">
<i class="popover-menu-icon zulip-icon zulip-icon-log-in" aria-hidden="true"></i>
<span class="popover-menu-label">{{t 'Log in' }}</span>
</a>
</li>
</ul>
</div>