* spelling: access Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: additional Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: administrative Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: aggregate Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: assigns Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: attributes Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: autocomplete Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: because Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: between Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: bootstrap Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: calculating Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: captcha Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: character Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: chosen Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: commenter Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: competitor Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: componentize Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: contrast Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: corresponding Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: description Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: destroyed Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: destroys Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: discussion Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: episode Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: escaped Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: evaluates Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: expired Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: explicitly Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: facebook Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: fragment Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: functionality Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: improper Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: incentive Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: interfere Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: latest Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: message Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: minimum Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: moderator Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: mouseover Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: mutual Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: nonexistent Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: notification Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: occasionally Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: occurrence Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: occurs Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: octokit Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: offset Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: omitted Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: opacity Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: organization Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: organizations Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: overridden Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: override Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: overriding Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: prefill Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: previous Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: profile Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: recycling Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: registered Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: repositories Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: rescuing Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: response Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: returns Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: second Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: separator Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: services Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: subscriber Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: subscription Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: success Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: successful Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: successfully Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: suppress Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: test Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: thought Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: uniqueness Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unknown Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unproductive Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unreachable Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unsuccessful Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: utilities Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: utility Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: valid Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: voluntarily Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: vomited Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: website Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: withholding Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
134 lines
3.6 KiB
JavaScript
134 lines
3.6 KiB
JavaScript
import { Controller } from '@hotwired/stimulus';
|
|
import { isLowContrast } from '@utilities/color/contrastValidator';
|
|
import { brightness } from '@utilities/color/accentCalculator';
|
|
|
|
const MAX_LOGO_PREVIEW_HEIGHT = 80;
|
|
|
|
/**
|
|
* Manages interactions on the Creator Settings page.
|
|
*/
|
|
export class CreatorSettingsController extends Controller {
|
|
static targets = ['previewLogo', 'colorContrastError', 'brandColor'];
|
|
|
|
/**
|
|
* Displays a preview of the image selected by the user.
|
|
*
|
|
* @param {Event} event
|
|
*/
|
|
previewLogo(event) {
|
|
const {
|
|
target: {
|
|
files: [firstFile],
|
|
},
|
|
} = event;
|
|
|
|
if (!firstFile) {
|
|
// Most likely the user cancelled the file selection.
|
|
return;
|
|
}
|
|
|
|
const reader = new FileReader();
|
|
|
|
reader.onload = () => {
|
|
const imageURL = reader.result;
|
|
const image = document.createElement('img');
|
|
image.src = imageURL;
|
|
image.className = 'site-logo';
|
|
|
|
// The logo preview image is purely visual so no need to communicate this to assistive technology.
|
|
image.alt = 'preview of logo selected';
|
|
|
|
image.addEventListener(
|
|
'load',
|
|
(event) => {
|
|
let {
|
|
target: { width, height },
|
|
} = event;
|
|
|
|
this.previewLogoTarget.replaceChild(
|
|
image,
|
|
this.previewLogoTarget.firstChild,
|
|
);
|
|
|
|
const maxLogoPreviewWidth = parseInt(
|
|
getComputedStyle(image).getPropertyValue('--max-width'),
|
|
10,
|
|
);
|
|
|
|
if (height > MAX_LOGO_PREVIEW_HEIGHT) {
|
|
width = (MAX_LOGO_PREVIEW_HEIGHT / height) * width;
|
|
height = MAX_LOGO_PREVIEW_HEIGHT;
|
|
}
|
|
|
|
if (width > maxLogoPreviewWidth) {
|
|
height = (maxLogoPreviewWidth / width) * height;
|
|
width = maxLogoPreviewWidth;
|
|
}
|
|
|
|
image.width = width;
|
|
image.height = height;
|
|
},
|
|
{ once: true },
|
|
);
|
|
};
|
|
|
|
reader.readAsDataURL(firstFile);
|
|
}
|
|
|
|
/**
|
|
* Validates the color contrast for accessibility,
|
|
* if the contrast is okay, it updates the branding,
|
|
* else it displays the error.
|
|
* @param {Event} event
|
|
*/
|
|
handleValidationsAndUpdates(event) {
|
|
const { value: color } = event.target;
|
|
|
|
if (isLowContrast(color)) {
|
|
this.colorContrastErrorTarget.innerText =
|
|
'The selected color must be darker for accessibility purposes.';
|
|
} else {
|
|
this.updateBranding(color);
|
|
this.colorContrastErrorTarget.innerText = '';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates ths branding/colors on the Creator Settings Page.
|
|
* by overriding the accent-color in the :root object
|
|
*
|
|
* @param {String} color
|
|
*/
|
|
updateBranding(color) {
|
|
if (!new RegExp(event.target.getAttribute('pattern')).test(color)) {
|
|
return;
|
|
}
|
|
|
|
document.documentElement.style.setProperty('--accent-brand', color);
|
|
|
|
// We need to recalculate '--accent-brand-darker' in javascript as it's
|
|
// currently being calculated in ruby. It is used for the hover effect
|
|
// over the button.
|
|
// 0.85 represents the brightness value set in Ruby to calculate
|
|
// '--accent-brand-darker'
|
|
document.documentElement.style.setProperty(
|
|
'--accent-brand-darker',
|
|
brightness(color, 0.85),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Prevents a submission of the form if the
|
|
* color contrast is low.
|
|
*
|
|
* @param {Event} event
|
|
*/
|
|
formValidations(event) {
|
|
const { value: color } = this.brandColorTarget;
|
|
if (isLowContrast(color)) {
|
|
event.preventDefault();
|
|
this.colorContrastErrorTarget.classList.remove('hidden');
|
|
// we don't want the form to submit if the contrast is low
|
|
}
|
|
}
|
|
}
|