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

Announce "signing in" state on login screen #12386

Merged
merged 15 commits into from
Jan 11, 2023
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
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