Skip to content
Snippets Groups Projects
Commit edb9b831 authored by ambient.impact's avatar ambient.impact
Browse files

Issue #3488464: Added documentation to new progress bar CSS and JS.

parent a734a158
Branches
Tags
1 merge request!10Issue #3488464: Implemented our own progress bar; removed Turbo progress
......@@ -12,14 +12,37 @@
'use strict';
/**
* Represents a progress bar delay wrapper.
*/
class ProgressBarDelay {
/**
* Time in milliseconds before the progress bar is shown.
*
* @type {Number}
*/
#delay = 0;
/**
* The visit timeout ID, if any.
*
* @type {Number|null}
*/
#visitTimeout = null;
/**
* The form submit timeout ID, if any.
*
* @type {Number|null}
*/
#formTimeout = null;
/**
* The progress bar instance that we're wrapping.
*
* @type {ProgressBar}
*/
#progressBar;
constructor(delay, progressBar) {
......@@ -30,6 +53,15 @@
}
/**
* Start the timeout to show the progress bar.
*
* @param {Number|null} timeoutId
* An existing timeout ID, if any.
*
* @return {Number}
* A new timeout ID.
*/
showAfterDelay(timeoutId) {
if (timeoutId !== null) {
......@@ -44,6 +76,13 @@
}
/**
* Hide the progress bar and cancel an existing timeout, if any.
*
* @param {Number|null} timeoutId
*
* @return {null}
*/
hideAndCancelDelay(timeoutId) {
if (timeoutId === null) {
......@@ -62,18 +101,27 @@
}
/**
* Show the progress bar after a delay for non-form submission visits.
*/
showVisitAfterDelay() {
this.#visitTimeout = this.showAfterDelay(this.#visitTimeout);
}
/**
* Hide the progress bar for non-form submission visits.
*/
hideVisit() {
this.#visitTimeout = this.hideAndCancelDelay(this.#visitTimeout);
}
/**
* Show the progress bar after a delay for form submissions.
*/
showFormAfterDelay() {
// Unlike the visit progress bar, we prefer to not replace an existing
......@@ -89,12 +137,20 @@
}
/**
* Hide the progress bar for form submissions.
*/
hideForm() {
this.#formTimeout = this.hideAndCancelDelay(this.#formTimeout);
}
/**
* Get the progress bar instance we're wrapping.
*
* @return {ProgressBar}
*/
get progressBar() {
return this.#progressBar;
}
......
:root {
/* Drupal blue. */
/**
* The progress bar colour.
*
* Defaults to Drupal blue.
*
* @type {Color}
*/
--refreshless-progress-bar-colour: #0678be;
/**
* The progress bar thickness.
*
* @type {Number}
*/
--refreshless-progress-bar-thickness: 3px;
/* Themes should override this to a more sensible value. */
/**
* The progress bar z-index.
*
* Themes should override this to a more sensible value.
*
* @type {Number}
*/
--refreshless-progress-bar-z-index: 2147483647;
/**
* The progress bar minimum/start value.
*
* This should be a percentage.
*
* @type {Number}
*/
--refreshless-progress-bar-start: 10%;
/**
* Progress bar width transition.
*/
--refreshless-progress-bar-width-transition:
width var(--refreshless-progress-bar-transition-duration) ease-out;
/**
* Progress bar opacity transition out.
*/
--refreshless-progress-bar-opacity-transition-out:
opacity
calc(var(--refreshless-progress-bar-transition-duration) / 2)
calc(var(--refreshless-progress-bar-transition-duration) / 2)
ease-in;
/**
* Progress bar opacity transition in.
*/
--refreshless-progress-bar-opacity-transition-in:
opacity
calc(var(--refreshless-progress-bar-transition-duration) / 2)
......
......@@ -29,35 +29,92 @@
}
/**
* CSS custom property base name.
*
* @type {String}
*/
const customPropertyBase = '--refreshless-progress-bar';
/**
* Name of the CSS custom property containing the transition duration.
*
* The value will be a time in ms.
*
* @type {String}
*/
const durationCustomProperty = `${customPropertyBase}-transition-duration`;
/**
* Name of the CSS custom property containing the progress bar delay.
*
* The value will be a time in ms.
*
* @type {String}
*/
const delayCustomProperty = `${customPropertyBase}-delay`;
/**
* Name of the CSS custom property containing the current progress bar value.
*
* The value will be float between 0 and 1, inclusive.
*
* @type {String}
*/
const valueCustomProperty = `${customPropertyBase}-value`;
const html = document.documentElement;
/**
* The once() identifier for attaching the progress bar.
* The <html> element.
*
* @type {String}
* @type {HTMLHtmlElement}
*/
const onceName = 'refreshless-turbo-progress-bar';
const html = document.documentElement;
/**
* Represents a progress bar.
*/
class ProgressBar {
/**
* The progress bar HTML element.
*
* @type {HTMLElement}
*/
#element;
/**
* Whether the progress bar is currently in the processing of hiding.
*
* @type {Boolean}
*/
#hiding = false;
/**
* The current value of the progress bar, from 0 to 1, inclusive.
*
* @type {Number}
*/
#value = 0;
/**
* Whether the progress bar is currently visible.
*
* @type {Boolean}
*/
#visible = false;
/**
* The trickle interval ID, or null if one is not active.
*
* @type {Number|null}
*/
#trickleInterval = null;
/**
* The progress bar transition duration, in milliseconds.
*
* @type {Number}
*/
#transitionDuration = 300;
constructor() {
......@@ -68,6 +125,9 @@
}
/**
* Show the progress bar if not already visible.
*/
show() {
if (this.#visible === true) {
......@@ -80,6 +140,9 @@
}
/**
* Hide the progress bar if visible and not already hiding.
*/
hide() {
if (!(this.#visible === true && this.#hiding === false)) {
......@@ -100,6 +163,9 @@
}
/**
* Set the progress bar as active, causing CSS to transition it in.
*/
#setActive() {
this.#element.classList.add(
......@@ -108,6 +174,9 @@
}
/**
* Set the progress bar as inactive, causing CSS to transition it out.
*/
#setInactive() {
this.#element.classList.remove(
......@@ -116,6 +185,12 @@
}
/**
* Transition the progress bar out.
*
* @return {Promise}
* A Promise that resolves when the transition is considered complete.
*/
#transitionOut() {
this.#setInactive();
......@@ -128,6 +203,15 @@
}
/**
* Explicitly set the progress bar to a value.
*
* @param {Number} value
* A number between 0 and 1, inclusive.
*
* @throws If value is NaN, or if the value is less than 0 or greater than
* 1.
*/
setValue(value) {
if (Number.isNaN(value)) {
......@@ -144,6 +228,9 @@
}
/**
* Install the progress bar in the document and set various properties.
*/
install() {
html.style.setProperty(
......@@ -170,6 +257,9 @@
}
/**
* Uninstall the progress bar from the document and remove properties.
*/
uninstall() {
if (this.#element.parentNode) {
......@@ -182,6 +272,9 @@
}
/**
* Start the trickling animation.
*/
startTrickling() {
if (this.#trickleInterval !== null) {
......@@ -194,6 +287,9 @@
}
/**
* Stop the trickling animation.
*/
stopTrickling() {
window.clearInterval(this.#trickleInterval);
......@@ -202,10 +298,18 @@
}
/**
* Trickle animation interval callback.
*
* This generates a random value to give the trickle the irregular movement.
*/
trickle = () => {
this.setValue(Math.min(1, this.#value + Math.random() / 100));
}
/**
* Update the progress bar element's value with the current value.
*/
async refresh() {
await new Promise(requestAnimationFrame);
......@@ -214,6 +318,11 @@
}
/**
* Finish/complete the progress bar to 100% and start hiding it.
*
* @return {[type]} [description]
*/
finish() {
this.setValue(1);
......@@ -222,14 +331,29 @@
}
/**
* Get the current value of the progress bar.
*
* @return {Number}
*/
get value() {
return this.#value;
}
/**
* Get the progress bar HTML element.
*
* @return {HTMLElement}
*/
get element() {
return this.#element;
}
/**
* Get the progress bar transition value.
*
* @return {Number}
*/
get transitionDuration() {
return this.#transitionDuration;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment