Skip to content

Commit

Permalink
Merge pull request #16012 from opf/bug/55774-preselected-colors-for-s…
Browse files Browse the repository at this point in the history
…tatus-and-type-are-hard-to-see-in-dark-mode

[55774] Preselected colors for Status and Type are hard to see in dark mode
  • Loading branch information
HDinger authored Jul 4, 2024
2 parents 53efa3e + c4141fb commit f71c4e9
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 75 deletions.
127 changes: 94 additions & 33 deletions app/helpers/colors_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ def options_for_colors(colored_thing)
options = {}
options[:name] = c.name
options[:value] = c.id
options[:data] = {
color: c.hexcode,
bright: c.bright?,
dark: c.dark?,
background: c.contrasting_color(light_color: "transparent")
}
options[:selected] = true if c.id == colored_thing.color_id

colors.push(options)
Expand All @@ -50,21 +44,13 @@ def selected_color(colored_thing)
colored_thing.color_id
end

def colored_text(color)
background = color.contrasting_color(dark_color: "#333", light_color: "transparent")
style = "background-color: #{background}; color: #{color.hexcode}"
content_tag(:span, color.hexcode, class: "color--text-preview", style:)
end

#
# Styles to display colors itself (e.g. for the colors autocompleter)
##
def color_css
Color.find_each do |color|
concat ".__hl_inline_color_#{color.id}_dot::before { background-color: #{color.hexcode} !important;}"
concat ".__hl_inline_color_#{color.id}_dot::before { border: 1px solid #555555 !important;}" if color.bright?
concat ".__hl_inline_color_#{color.id}_text { color: #{color.hexcode} !important;}"
concat ".__hl_inline_color_#{color.id}_text { -webkit-text-stroke: 0.5px grey; text-stroke: 0.5px grey;}" if color.super_bright?
set_background_colors_for class_name: ".__hl_inline_color_#{color.id}_dot::before", hexcode: color.hexcode
set_foreground_colors_for class_name: ".__hl_inline_color_#{color.id}_text", hexcode: color.hexcode
end
end

Expand All @@ -80,27 +66,13 @@ def resource_color_css(name, scope)
next
end

styles = color.color_styles
background_style = styles.map { |k, v| "#{k}:#{v} !important" }.join(";")

if name === "type"
concat ".__hl_inline_#{name}_#{entry.id} { color: #{color.hexcode} !important;}"
concat ".__hl_inline_#{name}_#{entry.id} { -webkit-text-stroke: 0.5px grey;}" if color.super_bright?

border_color = color.super_bright? ? "#555555" : color.hexcode
concat ".__hl_background_#{name}_#{entry.id} { border-color: #{border_color} !important; }"
set_foreground_colors_for class_name: ".__hl_inline_#{name}_#{entry.id}", hexcode: color.hexcode
else
border_color = color.bright? ? "#555555" : color.hexcode
concat ".__hl_inline_#{name}_#{entry.id}::before { #{background_style}; border-color: #{border_color}; }\n"
set_background_colors_for class_name: ".__hl_inline_#{name}_#{entry.id}::before", hexcode: color.hexcode
end

concat ".__hl_background_#{name}_#{entry.id} { #{background_style}; }\n"

# Mark color as bright through CSS variable
# so it can be used to add a separate -bright class
unless color.bright?
concat ":root { --hl-#{name}-#{entry.id}-dark: #{styles[:color]} }\n"
end
set_background_colors_for class_name: ".__hl_background_#{name}_#{entry.id}", hexcode: color.hexcode
end
end

Expand All @@ -117,4 +89,93 @@ def icon_for_color(color, options = {})
def color_by_variable(variable)
DesignColor.find_by(variable:)&.hexcode
end

def set_background_colors_for(class_name:, hexcode:)
mode = User.current.pref.theme.split("_", 2)[0]

concat "#{class_name} { #{default_color_styles(hexcode)} }"
if mode == "dark"
concat "#{class_name} { #{default_variables_dark} }"
concat "#{class_name} { #{highlighted_background_dark} }"
else
concat "#{class_name} { #{default_variables_light} }"
concat "#{class_name} { #{highlighted_background_light} }"
end
end

def set_foreground_colors_for(class_name:, hexcode:)
mode = User.current.pref.theme.split("_", 2)[0]

concat "#{class_name} { #{default_color_styles(hexcode)} }"
if mode == "dark"
concat "#{class_name} { #{default_variables_dark} }"
concat "#{class_name} { #{highlighted_foreground_dark} }"
else
concat "#{class_name} { #{default_variables_light} }"
concat "#{class_name} { #{highlighted_foreground_light} }"
end
end

# rubocop:disable Layout/LineLength
def default_color_styles(hex)
color = ColorConversion::Color.new(hex)
rgb = color.rgb
hsl = color.hsl

"--color-r: #{rgb[:r]};
--color-g: #{rgb[:g]};
--color-b: #{rgb[:b]};
--color-h: #{hsl[:h]};
--color-s: #{hsl[:s]};
--color-l: #{hsl[:l]};
--perceived-lightness: calc( ((var(--color-r) * 0.2126) + (var(--color-g) * 0.7152) + (var(--color-b) * 0.0722)) / 255 );
--lightness-switch: max(0, min(calc((1/(var(--lightness-threshold) - var(--perceived-lightness)))), 1));"
end

def default_variables_dark
"--lightness-threshold: 0.6;
--background-alpha: 0.18;
--lighten-by: calc(((var(--lightness-threshold) - var(--perceived-lightness)) * 100) * var(--lightness-switch));"
end

def default_variables_light
"--lightness-threshold: 0.453;
--border-threshold: 0.75;
--border-alpha: max(0, min(calc((var(--perceived-lightness) - var(--border-threshold)) * 100), 1));"
end

def highlighted_background_dark
"color: hsl(var(--color-h), calc(var(--color-s) * 1%), calc((var(--color-l) + var(--lighten-by)) * 1%)) !important;
background: rgba(var(--color-r), var(--color-g), var(--color-b), var(--background-alpha)) !important;
border: 1px solid hsl(var(--color-h), calc(var(--color-s) * 1%), calc((var(--color-l) + var(--lighten-by)) * 1%)) !important;"
end

def highlighted_background_light
style = "color: hsl(0deg, 0%, calc(var(--lightness-switch) * 100%)) !important;
background: rgb(var(--color-r), var(--color-g), var(--color-b)) !important;"
mode = User.current.pref.theme

if mode == "light_high_contrast"
style += "border: 1px solid hsla(var(--color-h), calc(var(--color-s) * 1%), calc((var(--color-l) - 75) * 1%), 1) !important;"
else
style += "border: 1px solid hsla(var(--color-h), calc(var(--color-s) * 1%), calc((var(--color-l) - 25) * 1%), var(--border-alpha)) !important;"
end

style
end

def highlighted_foreground_dark
"color: hsla(var(--color-h), calc(var(--color-s) * 1%), calc((var(--color-l) + var(--lighten-by)) * 1%), 1) !important;"
end

def highlighted_foreground_light
mode = User.current.pref.theme

if mode == "light_high_contrast"
"color: hsla(var(--color-h), calc(var(--color-s) * 1%), calc((var(--color-l) - (var(--color-l) * 0.5)) * 1%), 1); !important;"
else
"color: hsla(var(--color-h), calc(var(--color-s) * 1%), calc((var(--color-l) - (var(--color-l) * 0.22)) * 1%), 1); !important;"
end
end
# rubocop:enable Layout/LineLength
end
2 changes: 1 addition & 1 deletion app/helpers/highlighting_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ def highlight_css_version_tag(max_updated_at = highlight_css_updated_at)
end

def highlight_css_updated_at
ApplicationRecord.most_recently_changed Status, IssuePriority, Type
ApplicationRecord.most_recently_changed Status, IssuePriority, Type, UserPreference
end
end
15 changes: 0 additions & 15 deletions app/models/colors/hex_color.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
module Colors
module HexColor
##
# Returns the best contrasting color, either white or black
# depending on the overall brightness.
def contrasting_color(light_color: "#FFFFFF", dark_color: "#333333")
if bright?
dark_color
else
light_color
end
end

##
# Get the fill style for this color.
# If the color is light, use a dark font.
Expand All @@ -30,10 +19,6 @@ def bright?
brightness_yiq >= 150
end

def dark?
brightness_yiq < 150
end

##
# Returns whether the color is very bright according to
# YIQ lightness.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddTimestampsToUserPreferences < ActiveRecord::Migration[7.1]
def change
add_timestamps :user_preferences, default: DateTime.now
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
@include text-shortener(false)
padding: 5px
margin-bottom: 0
background-color: var(--status-selector-bg-color)
border: 1px solid var(--status-selector-border-color)
color: white
background-color: var(--label-orange-bgColor-active)
border: 1px solid var(--label-orange-fgColor-rest)
color: var(--body-font-color)
max-width: 100%
display: flex

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,4 @@ export namespace Highlighting {

return '__hl_date_not_overdue';
}

export function isBright(styles:CSSStyleDeclaration, property:string, id:string|number) {
const variable = `--hl-${property}-${id}-dark`;
return styles.getPropertyValue(variable) !== '';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
overflow: hidden
padding: 0 0 0 5px
white-space: nowrap
border: none

.leftHandle
position: absolute
Expand Down
18 changes: 0 additions & 18 deletions spec/models/user_preference_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,6 @@
end
end

describe "#respond_to?" do
context "for created_at (key not in the schema)" do
it "is does not respond" do
expect(preference)
.not_to respond_to(:created_at)
end
end
end

describe "an unsupported method" do
context "for created_at (key not in the schema)" do
it "raises an error" do
expect { preference.created_at }
.to raise_error NoMethodError
end
end
end

describe "sort order" do
it_behaves_like "accepts real and false booleans",
:comments_in_reverse_order=,
Expand Down

0 comments on commit f71c4e9

Please sign in to comment.