Skip to content

Commit

Permalink
Merge pull request #12386 from craftcms/a11y/login-announcement
Browse files Browse the repository at this point in the history
Announce "signing in" state on login screen
  • Loading branch information
brandonkelly authored Jan 11, 2023
2 parents ade6c2f + 33b8b58 commit 7b95b8e
Show file tree
Hide file tree
Showing 31 changed files with 171 additions and 28 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- Improved the color contrast and keyboard control of the Customize Sources modal. ([#12233](https://github.com/craftcms/cms/pull/12233))
- Improved info icons for screen readers. ([#12272](https://github.com/craftcms/cms/pull/12272))
- Removed input autofocussing throughout the control panel. ([#12324](https://github.com/craftcms/cms/discussions/12324), [#12332](https://github.com/craftcms/cms/pull/12332))
- Improved the login screen for screen readers. ([#12386](https://github.com/craftcms/cms/pull/12386))

### Administration
- Conditional layout components are now identified using a condition icon within field layout designers. ([#12250](https://github.com/craftcms/cms/issues/12250))
Expand Down Expand Up @@ -67,6 +68,7 @@
- Deprecated `craft\queue\jobs\GeneratePendingTransforms`. `GenerateImageTransform` should be used instead. ([#12340](https://github.com/craftcms/cms/pull/12340))
- Added `Craft.Accordion`. ([#12189](https://github.com/craftcms/cms/pull/12189))
- Added `Craft.ElementFieldSettings`.
- Added `Garnish.MultiFunctionBtn`.
- Deprecated `Craft.CategorySelectInput`. `Craft.BaseElementSelectInput` should be used instead. ([#11749](https://github.com/craftcms/cms/pull/11749))

### System
Expand Down
17 changes: 16 additions & 1 deletion src/templates/_includes/forms/button.twig
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{% set spinner = spinner ?? false -%}
{% set busyMessage = busyMessage ?? false %}
{% set failureMessage = failureMessage ?? false %}
{% set retryMessage = retryMessage ?? false %}
{% set successMessage = successMessage ?? false %}
{% set label = label ?? null %}
{% set attributes = {
type: type ?? 'button',
Expand All @@ -7,16 +11,27 @@
'btn',
not label ? 'btn-empty' : null,
]|filter),
data: {
'busy-message': busyMessage,
'failure-message': failureMessage,
'retry-message': retryMessage,
'success-message': successMessage,
}
}|merge(attributes ?? {}) -%}

{% apply spaceless %}
{% if spinner %}
<div role="status" class="visually-hidden"></div>
{% endif %}
{% tag 'button' with attributes %}
{{ label ? tag('div', {
class: 'label',
text: label,
}) }}
{% if spinner %}
<div class="spinner spinner-absolute"></div>
<div class="spinner spinner-absolute">
<span class="visually-hidden">{{ 'Loading'|t('app') }}</span>
</div>
{% endif %}
{% endtag %}
{% endapply -%}
6 changes: 5 additions & 1 deletion src/templates/login.twig
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@
id: 'submit',
label: 'Sign in'|t('app'),
spinner: true,
busyMessage: 'Signing in'|t('app'),
successMessage: 'Signed in'|t('app'),
failureMessage: 'Sign in unsuccessful'|t('app'),
retryMessage: 'Try again'|t('app'),
}) }}
</div>

Expand All @@ -103,7 +107,7 @@
</div>
</form>

<div id="login-errors" role="alert">
<div id="login-errors" role="status">
</div>

<a id="poweredby" href="http://craftcms.com/" title="{{ 'Powered by Craft CMS'|t('app') }}" aria-label="Craft CMS">
Expand Down
3 changes: 3 additions & 0 deletions src/translations/en/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -1328,10 +1328,13 @@
'Sign in as user' => 'Sign in as user',
'Sign in as {user}' => 'Sign in as {user}',
'Sign in' => 'Sign in',
'Sign in unsuccessful' => 'Sign in unsuccessful',
'Sign into Craft ID' => 'Sign into Craft ID',
'Sign out from Craft ID' => 'Sign out from Craft ID',
'Sign out now' => 'Sign out now',
'Sign out' => 'Sign out',
'Signed in' => 'Signed in',
'Signing in' => 'Signing in',
'Similar issues on GitHub' => 'Similar issues on GitHub',
'Similar questions on Stack Exchange' => 'Similar questions on Stack Exchange',
'Single' => 'Single',
Expand Down

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/web/assets/garnish/src/Garnish.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import HUD from './HUD.js';
import MenuBtn from './MenuBtn.js';
import MixedInput from './MixedInput.js';
import Modal from './Modal.js';
import MultiFunctionBtn from './MultiFunctionBtn.js';
import NiceText from './NiceText.js';
import Select from './Select.js';
import SelectMenu from './SelectMenu.js';
Expand Down Expand Up @@ -907,6 +908,7 @@ Object.assign(Garnish, {
MenuBtn,
MixedInput,
Modal,
MultiFunctionBtn,
NiceText,
Select,
SelectMenu,
Expand Down
114 changes: 114 additions & 0 deletions src/web/assets/garnish/src/MultiFunctionBtn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import Garnish from './Garnish.js';
import Base from './Base.js';
import $ from 'jquery';

/**
* Multi-Function Button
*/
export default Base.extend(
{
$btn: null,
$btnLabel: null,
$liveRegion: null,

defaultMessage: null,
busyMessage: null,
failureMessage: null,
retryMessage: null,
successMessage: null,

init: function (button, settings) {
this.setSettings(settings, Garnish.MultiFunctionBtn.defaults);
this.$btn = $(button);

// Is this already a multi-function button?
if (this.$btn.data('multifunction-btn')) {
console.warn(
'Double-instantiating a multi-function button on an element'
);
this.$btn.data('multifunction-btn').destroy();
}

this.$btnLabel = this.$btn.find('.label');
this.defaultMessage = this.$btnLabel.text();

if (this.$btn.prev().attr('role') === 'status') {
this.$liveRegion = this.$btn.prev();
}

this.busyMessage = this.$btn.data('busy-message');
this.failureMessage = this.$btn.data('failure-message');
this.retryMessage = this.$btn.data('retry-message');
this.successMessage = this.$btn.data('success-message');
},

busyEvent: function () {
this.$btn.addClass(this.settings.busyClass);

if (this.busyMessage) {
this.updateMessages(this.busyMessage, false);
}
},

failureEvent: function () {
this.endBusyState();

if (!this.failureMessage && !this.retryMessage) return;

if (this.failureMessage) {
this.updateMessages(this.failureMessage);
}

if (this.retryMessage) {
// If there was a failure message, ensure there's a delay before showing retry message
if (this.failureMessage) {
setTimeout(() => {
this.updateMessages(this.retryMessage);
}, this.settings.failureMessageDuration);
} else {
this.updateMessages(this.retryMessage);
}
}
},

successEvent: function () {
this.endBusyState();

if (this.successMessage) {
this.updateMessages(this.successMessage);
}
},

updateMessages: function (message, updateLabel = true) {
this.$liveRegion.text(message);

if (updateLabel) {
this.$btnLabel.text(message);
}

// Empty live region so a SR user navigating with virtual cursor doesn't find outdated message
setTimeout(() => {
// Bail out if there's now a different message in the live region
if (this.$liveRegion.text() !== message) return;

this.$liveRegion.empty();
}, this.settings.clearLiveRegionTimeout);
},

endBusyState: function () {
this.$btn.removeClass(this.settings.busyClass);
},

destroy: function () {
this.$btn.removeData('multifunction-btn');
this.base();
},
},
{
defaults: {
busyClass: 'loading',
clearLiveRegionTimeout: 2500,
failureMessageDuration: 3000,
},
}
);
2 changes: 1 addition & 1 deletion src/web/assets/generalsettings/dist/css/rebrand.css.map

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

Loading

0 comments on commit 7b95b8e

Please sign in to comment.