Apply darker course colors for high contrast UI

fixes: LS-2854
flag=high_contrast_course_colors

test plan:

- Create a user

- Enable High Contrast UI on their account.

- Navigate to calendar, course list and dashboard.

- Create a course for you, and right after, visit the calendar,
so the calendar flow defines a color for the course

- Create another course and got straight to the dashboard,
so the dashboard flow defines a color for that course

- Define a custom hash for a third course

- Check the colors on the course list, calendar and dashboard

- Enable the High Contrast Course Colors

- Check that all the colors now have a contrast ratio of at least 4.5:1

Change-Id: Idd5d4475acceb4742a29938237b88b0d403de611
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/279764
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Product-Review: Luis Oliveira <luis.oliveira@instructure.com>
Reviewed-by: Robin Kuss <rkuss@instructure.com>
QA-Review: Robin Kuss <rkuss@instructure.com>
This commit is contained in:
Luis Oliveira 2021-11-29 23:34:05 -03:00
parent 129f6c2225
commit 4d95fa28db
5 changed files with 53 additions and 4 deletions

View File

@ -139,6 +139,7 @@ gem "simple_oauth", "0.3.1", require: false
gem "twilio-ruby", "5.36.0", require: false
gem "vault", "0.15.0", require: false
gem "vericite_api", "1.5.3"
gem "wcag_color_contrast", "0.1.0"
gem "week_of_month", "1.2.5",
github: "instructure/week-of-month", ref: "b3013639e9474f302b5a6f27e4e45313e8d24902"
gem "will_paginate", "3.3.0", require: false # required for folio-pagination

View File

@ -1602,6 +1602,15 @@ class User < ActiveRecord::Base
get_preference(:new_user_tutorial_statuses) || {}
end
def apply_contrast(colors)
colors.each do |key, _v|
until WCAGColorContrast.ratio(colors[key].delete("#"), "ffffff") >= 4.5
rgb = colors[key].match(/^#(..)(..)(..)$/).captures.map { |c| (c.hex.to_i * 0.85).round }
colors[key] = "#%02x%02x%02x" % rgb
end
end
end
def custom_colors
colors_hash = get_preference(:custom_colors) || {}
if Shard.current != shard
@ -1615,6 +1624,9 @@ class User < ActiveRecord::Base
["#{opts.join("_")}_#{new_id}", value]
end.to_h
end
return apply_contrast colors_hash if prefers_high_contrast? && uses_high_contrast_course_colors?
colors_hash
end
@ -1716,6 +1728,10 @@ class User < ActiveRecord::Base
!!feature_enabled?(:high_contrast)
end
def uses_high_contrast_course_colors?
Account.site_admin.feature_enabled?(:high_contrast_course_colors)
end
def auto_show_cc?
!!feature_enabled?(:auto_show_cc)
end

View File

@ -177,6 +177,14 @@ high_contrast:
High Contrast enhances the color contrast of the UI (text, buttons, etc.), making those items more
distinct and easier to identify. Note: Institution branding will be disabled.
applies_to: User
high_contrast_course_colors:
state: allowed
display_name: High Contrast Course Colors
description:
high_contrast_course_colors_description: |-
High Contrast Course Colors darkens system provided and color picker course colors
(not manually defined ones) to improve contrast ratio
applies_to: SiteAdmin
important_dates:
state: hidden
display_name: Important Dates

View File

@ -3606,6 +3606,33 @@ describe User do
end
end
describe "#custom_colors" do
context "user has high_contrast and high_contrast_course_colors enables" do
let(:user) { user_model }
before do
user.enable_feature!(:high_contrast)
Account.site_admin.enable_feature!(:high_contrast_course_colors)
end
it "sufficiently darkens colors with a contrast below 4.5" do
user.preferences[:custom_colors] = {
user_1: "#5a92de",
course_1: "#199eb7",
course_2: "#ffffff",
course_3: "#c8c8c8",
course_4: "#767777"
}
expect(user.custom_colors.map { |_k, v| WCAGColorContrast.ratio(v.delete("#"), "ffffff") }).to all(be >= 4.5)
end
it "leaves colors with enough contrast alone" do
user.preferences[:custom_colors] = { user_1: "#757777" }
expect(user.custom_colors[:user_1]).to be("#757777")
end
end
end
describe "#prefers_no_celebrations?" do
let(:user) { user_model }

View File

@ -1024,10 +1024,7 @@ export default class Calendar {
// Get any custom colors that have been set
$.getJSON(`/api/v1/users/${this.options.userId}/colors/`, data => {
const customColors = data.custom_colors
const colors = colorSlicer.getColors(this.contextCodes.length, 275, {
unsafe: !ENV.use_high_contrast
})
const colors = colorSlicer.getColors(this.contextCodes.length, 275)
const newCustomColors = {}
const html = this.contextCodes
.map((contextCode, index) => {