docbrown/app/javascript/admin/controllers/creator_settings_controller.js
Ridhwana 8060f78893
Dynamically update the brand colors (#15432)
* Added alias for app/javascript/controllers

* Added hooks for Stimulus controller.

* Fixed eslint issue with @controllers alias.

* Initial working logo preview.

* Added explicit accept values for png and svg files only for a logo.

* Fixed content layout shift issue and resize to max height 80px.

* Cleaned up logo preview resizing.

* Added focus style to Upload logo label.

* Now the logo preview image has empty alt text as it's visual only.

* Fixed position of upload logo button.

* Removed tooltip for logo.

* Fixed check to load client-side controller.

* Put back tooltip, minus the aria-describedby

* Fixed E2E tests I broke.

* Made the logo preview visible to the accessibility tree.

* feat: update the brand colors on the page when we select a new one

* feat: update the radio button_tags to use crayons-radio

* feat: remove the fill attributes in the svg

* Added support for JPG image upload.

* Fixed height adjustment when width exceeds max preview width.

* feat: add form-background class with an accent

* feat: update the briightness accent on the page

* Fixed JS error if user cancelled file selection for a logo.

* Added the @routes webpack alias for routes.js.erb.

* Fixed data tooltip for assistive technologies.

* Fixed preview logo alignment with upload logo button.

* remove required as it's not doing anything

* feat: update the code brigtness code

* Opting to not show friendly error message if route fails to load.

* Fixed validation message not appearing for logo.

* Revert "Added the @routes webpack alias for routes.js.erb."

This reverts commit 3b6621dcde541f2fa05df6ff75af38955842b88e.

* Reverted to default styling of input[type="file"].

* Moved creator_settings_controller to admin/controllers.

* Updated E2E test for logo preview on the creator settings page.

* create tests for the brand color updates

* feat: update the description

* Update cypress/integration/creatorOnboardingFlows/creatorSettings.spec.js

Co-authored-by: Nick Taylor <nick@iamdeveloper.com>

* Update app/javascript/admin/controllers/creator_settings_controller.js

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* feat: do not update branding if an invalid color is provided

* feat: move the brightness code to its own accent calculator file in js utilities

* test: brightness ratios

* chore: remove whitespace

Co-authored-by: Nick Taylor <nick@dev.to>
Co-authored-by: Nick Taylor <nick@iamdeveloper.com>
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
2021-11-23 09:46:17 +02:00

96 lines
2.5 KiB
JavaScript

import { Controller } from '@hotwired/stimulus';
import { brightness } from '../../utilities/color/accentCalculator';
const MAX_LOGO_PREVIEW_HEIGHT = 80;
const MAX_LOGO_PREVIEW_WIDTH = 220;
/**
* Manages interactions on the Creator Settings page.
*/
export class CreatorSettingsController extends Controller {
static targets = ['previewLogo'];
/**
* 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;
// 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;
if (height > MAX_LOGO_PREVIEW_HEIGHT) {
width = (width / height) * MAX_LOGO_PREVIEW_HEIGHT;
height = MAX_LOGO_PREVIEW_HEIGHT;
}
if (width > MAX_LOGO_PREVIEW_WIDTH) {
width = MAX_LOGO_PREVIEW_WIDTH;
height = (height / width) * MAX_LOGO_PREVIEW_WIDTH;
}
image.style.width = `${width}px`;
image.style.height = `${height}px`;
this.previewLogoTarget.replaceChild(
image,
this.previewLogoTarget.firstChild,
);
},
{ once: true },
);
};
reader.readAsDataURL(firstFile);
}
/**
* Updates ths branding/colors on the Creator Settings Page.
*
* @param {Event} event
*/
updateBranding(event) {
const { value: color } = event.target;
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),
);
}
}