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:
parent
129f6c2225
commit
4d95fa28db
|
@ -139,6 +139,7 @@ gem "simple_oauth", "0.3.1", require: false
|
||||||
gem "twilio-ruby", "5.36.0", require: false
|
gem "twilio-ruby", "5.36.0", require: false
|
||||||
gem "vault", "0.15.0", require: false
|
gem "vault", "0.15.0", require: false
|
||||||
gem "vericite_api", "1.5.3"
|
gem "vericite_api", "1.5.3"
|
||||||
|
gem "wcag_color_contrast", "0.1.0"
|
||||||
gem "week_of_month", "1.2.5",
|
gem "week_of_month", "1.2.5",
|
||||||
github: "instructure/week-of-month", ref: "b3013639e9474f302b5a6f27e4e45313e8d24902"
|
github: "instructure/week-of-month", ref: "b3013639e9474f302b5a6f27e4e45313e8d24902"
|
||||||
gem "will_paginate", "3.3.0", require: false # required for folio-pagination
|
gem "will_paginate", "3.3.0", require: false # required for folio-pagination
|
||||||
|
|
|
@ -1602,6 +1602,15 @@ class User < ActiveRecord::Base
|
||||||
get_preference(:new_user_tutorial_statuses) || {}
|
get_preference(:new_user_tutorial_statuses) || {}
|
||||||
end
|
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
|
def custom_colors
|
||||||
colors_hash = get_preference(:custom_colors) || {}
|
colors_hash = get_preference(:custom_colors) || {}
|
||||||
if Shard.current != shard
|
if Shard.current != shard
|
||||||
|
@ -1615,6 +1624,9 @@ class User < ActiveRecord::Base
|
||||||
["#{opts.join("_")}_#{new_id}", value]
|
["#{opts.join("_")}_#{new_id}", value]
|
||||||
end.to_h
|
end.to_h
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return apply_contrast colors_hash if prefers_high_contrast? && uses_high_contrast_course_colors?
|
||||||
|
|
||||||
colors_hash
|
colors_hash
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1716,6 +1728,10 @@ class User < ActiveRecord::Base
|
||||||
!!feature_enabled?(:high_contrast)
|
!!feature_enabled?(:high_contrast)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def uses_high_contrast_course_colors?
|
||||||
|
Account.site_admin.feature_enabled?(:high_contrast_course_colors)
|
||||||
|
end
|
||||||
|
|
||||||
def auto_show_cc?
|
def auto_show_cc?
|
||||||
!!feature_enabled?(:auto_show_cc)
|
!!feature_enabled?(:auto_show_cc)
|
||||||
end
|
end
|
||||||
|
|
|
@ -177,6 +177,14 @@ high_contrast:
|
||||||
High Contrast enhances the color contrast of the UI (text, buttons, etc.), making those items more
|
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.
|
distinct and easier to identify. Note: Institution branding will be disabled.
|
||||||
applies_to: User
|
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:
|
important_dates:
|
||||||
state: hidden
|
state: hidden
|
||||||
display_name: Important Dates
|
display_name: Important Dates
|
||||||
|
|
|
@ -3606,6 +3606,33 @@ describe User do
|
||||||
end
|
end
|
||||||
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
|
describe "#prefers_no_celebrations?" do
|
||||||
let(:user) { user_model }
|
let(:user) { user_model }
|
||||||
|
|
||||||
|
|
|
@ -1024,10 +1024,7 @@ export default class Calendar {
|
||||||
// Get any custom colors that have been set
|
// Get any custom colors that have been set
|
||||||
$.getJSON(`/api/v1/users/${this.options.userId}/colors/`, data => {
|
$.getJSON(`/api/v1/users/${this.options.userId}/colors/`, data => {
|
||||||
const customColors = data.custom_colors
|
const customColors = data.custom_colors
|
||||||
const colors = colorSlicer.getColors(this.contextCodes.length, 275, {
|
const colors = colorSlicer.getColors(this.contextCodes.length, 275)
|
||||||
unsafe: !ENV.use_high_contrast
|
|
||||||
})
|
|
||||||
|
|
||||||
const newCustomColors = {}
|
const newCustomColors = {}
|
||||||
const html = this.contextCodes
|
const html = this.contextCodes
|
||||||
.map((contextCode, index) => {
|
.map((contextCode, index) => {
|
||||||
|
|
Loading…
Reference in New Issue