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

Fancy Crumbs a11y #13923

Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
23b193c
User inner focus ring for hamburger button
brianjhanson Nov 8, 2023
ccbcd3b
Make `.label-link` focus visible
brianjhanson Nov 8, 2023
54aeab4
Add ability to label disclosure menu button
brianjhanson Nov 9, 2023
0b0b9f8
Separate link from button
brianjhanson Nov 9, 2023
11b61c8
Fix scrollbar flash on load
brianjhanson Nov 9, 2023
61ce86d
Separate current label text from button
brianjhanson Nov 9, 2023
5a16d93
Move icon into link
brianjhanson Nov 9, 2023
de51736
Rebuild
brianjhanson Nov 9, 2023
59ecb94
Hamburger hover follows links
brianjhanson Nov 10, 2023
0ec795d
Darken button text on hover
brianjhanson Nov 10, 2023
2413807
Build assets
brianjhanson Nov 10, 2023
a417e73
Cleanup disclosure menu hover states
brianjhanson Nov 13, 2023
34ae329
Remove titles
brianjhanson Nov 13, 2023
f14da63
Context -> Select context
brianjhanson Nov 13, 2023
96428ac
Revert spacing
brianjhanson Nov 13, 2023
60f0f39
Hide icon
brianjhanson Nov 13, 2023
f18c47b
Fix speak property (hopefully)
brianjhanson Nov 13, 2023
bacfd8e
Remove h6 from revisions menu
brianjhanson Nov 13, 2023
426966f
Refactor status html
brianjhanson Nov 13, 2023
5392c6d
Better error fix
brianjhanson Nov 13, 2023
98f3b0e
Adjust heading level
brianjhanson Nov 13, 2023
bd2885b
Make checkmark unpronouncable
brianjhanson Nov 13, 2023
1f0dc6f
Add hidden selected text
brianjhanson Nov 15, 2023
9862a71
Ability to add `headingAttributes` for menu groups
brianjhanson Nov 15, 2023
0821c2d
Allow customizing item heading tags
brianjhanson Nov 16, 2023
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
5 changes: 4 additions & 1 deletion src/elements/Entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,10 @@ protected function crumbs(): array
'url' => 'entries',
],
[
'menu' => $sectionOptions->all(),
'menu' => [
'label' => Craft::t('app', 'Select entry type'),
'items' => $sectionOptions->all(),
],
],
];

Expand Down
4 changes: 2 additions & 2 deletions src/helpers/Cp.php
Original file line number Diff line number Diff line change
Expand Up @@ -2332,8 +2332,8 @@ public static function disclosureMenu(array $items, array $config = []): string
->first(fn(array $i) => $i['selected'] ?? false);

if ($selectedItem) {
$config['buttonLabel'] = $selectedItem['label'] ?? null;
$config['buttonHtml'] = $selectedItem['html'] ?? null;
$config['label'] = $selectedItem['label'] ?? null;
$config['html'] = $selectedItem['html'] ?? null;
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/templates/_includes/disclosuremenu.twig
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,18 @@
{% endmacro %}

{% if withButton %}
{% if hiddenLabel ?? false %}
{% set hiddenLabelId = "#{id}-label" %}
<label id="{{ hiddenLabelId }}" class="visually-hidden">{{ hiddenLabel }}</label>
{% if html ?? false %}
{{ html | raw }}
{% elseif label ?? false %}
<span >{{ label }}</span>
{% endif %}

{{ tag('button', {
class: ['btn', 'menubtn'],
type: 'button',
aria: {
controls: id,
describedby: hiddenLabelId ?? null,
label: hiddenLabel ?? null
},
data: {
'disclosure-trigger': true,
Expand Down
49 changes: 26 additions & 23 deletions src/templates/_layouts/components/crumbs.twig
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
<nav aria-label="{{ 'Breadcrumbs'|t('app') }}">
<ul id="crumb-list">
{% for crumb in crumbs %}
{% if crumb.menu is defined %}
{% set hasMenuItems = crumb.menu is defined and crumb.menu.items is defined %}
{% if hasMenuItems %}
{% set crumb = (
crumb.menu|map(o => (o.group ?? false) ? (o.options ?? []) : [o])|flatten(1)|firstWhere(o => o.selected ?? false) ?: {}
)|merge(crumb) %}
crumb.menu.items|map(o => (o.group ?? false) ? (o.options ?? []) : [o])|flatten(1)|firstWhere(o => o.selected ?? false) ?: {}
)|merge(crumb) %}
{% endif %}

{% tag 'li' with {
Expand All @@ -20,36 +21,38 @@
{{ crumb.html|raw }}
{% else %}
{% set labelId = "crumb-label#{random()}" %}

{% tag 'a' with {
id: crumb.id ?? null,
href: crumb.url is defined ? url(crumb.url) : null,
} %}
{% if crumb.icon is defined %}
<span data-icon="{{ crumb.icon }}" aria-hidden></span>
{% endif %}
<span id="{{ labelId }}">
{{ crumb.label ?? crumb.html|raw }}
</span>

{% if crumb.menu is defined %}
{% set menuId = crumb.id is defined ? "#{crumb.id}-menu" : "crumb-menu#{random()}" %}
{{ tag('button', {
class: ['btn', 'menubtn'],
type: 'button',
title: 'Menu'|t('app'),
aria: {
controls: menuId,
describedby: labelId,
},
data: {
'disclosure-trigger': true,
},
}) }}
{% endif %}
{{ crumb.label ?? crumb.html|raw }}
{% endtag %}

{% if crumb.menu is defined %}
{{ disclosureMenu(crumb.menu, {
{% if crumb.menu is defined and crumb.menu.items is defined %}
{% set menuId = crumb.id is defined ? "#{crumb.id}-menu" : "crumb-menu#{random()}" %}
{% set menuLabel = crumb.menu.label ?? null %}
{{ tag('button', {
class: ['btn', 'menubtn'],
type: 'button',
title: 'Menu'|t('app'),
aria: {
label: menuLabel,
controls: menuId,
describedby: menuLabel ? null : labelId,
},
data: {
'disclosure-trigger': true,
},
}) }}
{% endif %}

{% if hasMenuItems %}
{{ disclosureMenu(crumb.menu.items, {
id: menuId,
withButton: false,
}) }}
Expand Down
5 changes: 4 additions & 1 deletion src/templates/_layouts/elementindex.twig
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
id: 'site-crumb',
icon: 'world',
label: selectedSite.name|t('site'),
menu: siteMenuItems(selectableSites, selectedSite),
menu: {
items: siteMenuItems(selectableSites, selectedSite),
label: 'Select site'|t('site')
}
}) %}
{% endif %}

Expand Down
1 change: 1 addition & 0 deletions src/translations/en/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@
'Change icon' => 'Change icon',
'Change logo' => 'Change logo',
'Change photo' => 'Change photo',
'Change site' => 'Change site',
'Changelog' => 'Changelog',
'Changes discarded.' => 'Changes discarded.',
'Changes saved.' => 'Changes saved.',
Expand Down
14 changes: 8 additions & 6 deletions src/web/CpScreenResponseFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,14 @@ private function _formatTemplate(YiiResponse $response, CpScreenResponseBehavior
'id' => 'site-crumb',
'icon' => 'world',
'label' => Craft::t('site', $behavior->site->name),
'menu' => !empty($behavior->selectableSites)
? Cp::siteMenuItems($behavior->selectableSites, $behavior->site, [
'includeOmittedSites' => true,
])
: null,
'menu' => [
'label' => Craft::t('site', 'Select site'),
'items' => !empty($behavior->selectableSites)
? Cp::siteMenuItems($behavior->selectableSites, $behavior->site, [
'includeOmittedSites' => true,
])
: null,
],
]);
}

Expand Down Expand Up @@ -216,7 +219,6 @@ private function _contextMenu(
'autoLabel' => true,
'buttonAttributes' => [
'id' => 'context-btn',
'class' => ['context-label'],
],
'hiddenLabel' => Craft::t('app', 'Context'),
], $namespace);
Expand Down
3 changes: 2 additions & 1 deletion src/web/assets/admintable/dist/css/app.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/web/assets/admintable/dist/css/app.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/web/assets/admintable/dist/js/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/admintable/dist/js/app.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/admintable/dist/manifest.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"app.css":"/css/app.css","app.js":"/js/app.js","app.js.map":"/js/app.js.map"}
{"app.css":"/css/app.css","app.js":"/js/app.js","app.css.map":"/css/app.css.map","app.js.map":"/js/app.js.map"}
2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/css/cp.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/css/cp.css.map

Large diffs are not rendered by default.

34 changes: 30 additions & 4 deletions src/web/assets/cp/src/css/_cp.scss
Original file line number Diff line number Diff line change
Expand Up @@ -483,8 +483,12 @@ li.crumb {

.btn {
--ui-control-color: var(--gray-400);
--ui-control-hover-color: var(--gray-500);
--ui-control-active-color: var(--gray-600);
--ui-control-hover-color: var(--gray-800);
--ui-control-active-color: var(--gray-700);

&:hover {
color: var(--ui-control-hover-color);
}
}
}

Expand All @@ -508,7 +512,7 @@ li.crumb {
}

&:hover {
color: var(--gray-400);
color: var(--link-color);
}
}

Expand All @@ -530,6 +534,12 @@ li.crumb {
}
}

#primary-nav-toggle {
&:focus-visible {
box-shadow: var(--inner-focus-ring);
}
}

#crumb-list {
display: flex;
flex-direction: row;
Expand Down Expand Up @@ -613,8 +623,15 @@ li.crumb {
flex-wrap: nowrap;
gap: var(--xs);

[data-icon] {
position: relative;
top: -1px;
}

.menubtn {
margin: 0 calc(var(--xs) * -1 + 2px);
position: relative;
top: -1px;
margin: 0 calc(var(--xs) * -1 / 2);
}

[data-icon='ellipsis']:before {
Expand All @@ -629,6 +646,10 @@ li.crumb {
.label-link {
max-width: 15em;

&:focus-visible {
box-shadow: var(--inner-focus-ring);
}

span:not(.context-label) {
display: block;
white-space: nowrap;
Expand Down Expand Up @@ -684,6 +705,11 @@ li.breadcrumb-toggle-wrapper {
}
}

.context-menu-container {
border: 1px solid var(--medium-hairline-color);
border-radius: calc(var(--touch-target-size) / 2);
}

.context-menu-container .menubtn {
@include margin-left(0);
}
Expand Down
18 changes: 17 additions & 1 deletion src/web/assets/cp/src/css/_main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3027,7 +3027,7 @@ table {
}

.context-label,
.context-menu-container .menubtn {
.context-menu-container {
display: inline-flex;
align-items: center;
@include margin-left(var(--xs));
Expand All @@ -3041,6 +3041,22 @@ table {
border: 1px solid var(--medium-hairline-color);
}

.context-menu-container:has(.menubtn) {
padding-right: 0;

> * {
display: inline-block;
padding-right: var(--s);
}
}

#global-header .context-menu-container .menubtn {
padding-left: calc(var(--s) * 0.8) !important;
border-left: 1px solid var(--medium-hairline-color);
border-radius: 0 calc(var(--touch-target-size) / 2)
calc(var(--touch-target-size) / 2) 0;
}

.context-menu-container .menubtn:hover {
border-color: var(--dark-hairline-color);
}
Expand Down
2 changes: 1 addition & 1 deletion src/web/assets/matrix/dist/MatrixInput.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/matrix/dist/MatrixInput.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/pluginstore/dist/css/app.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/pluginstore/dist/css/app.css.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/pluginstore/dist/js/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/pluginstore/dist/js/app.js.map

Large diffs are not rendered by default.