Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(tags): tag text color contrast #3653

Merged
merged 47 commits into from
Jan 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
806e0ad
add yiq calculator util
Ornanovitch Sep 25, 2022
8221242
use the new contast util to differentiate light/dark tags
Ornanovitch Sep 25, 2022
2119779
fix: invert logic
Ornanovitch Sep 25, 2022
9bee208
feat: add tag-dark and tag-light less config
Ornanovitch Sep 25, 2022
48b3c07
fix: convert 3 chars hex to 6 chars hex
Ornanovitch Sep 25, 2022
733eda0
Merge branch 'contrast-util' into tag-contrast
Ornanovitch Sep 25, 2022
abf7bf2
fix: rename import
Ornanovitch Sep 25, 2022
bd0e663
fix: clarify util name
Ornanovitch Sep 25, 2022
d3506ef
Merge branch 'contrast-util' into tag-contrast
Ornanovitch Sep 25, 2022
bf53cda
fix: rename function
Ornanovitch Sep 25, 2022
3de6afa
fix: invert less variables when dark mode is enabled
Ornanovitch Sep 25, 2022
acae7f7
fix: TagTiles contrast
Ornanovitch Sep 25, 2022
948dd34
refactor: simplify logic with a unique variable
Ornanovitch Sep 26, 2022
8a62250
refactor: simplify logic with a unique variable
Ornanovitch Sep 26, 2022
0c888f6
feat: add text color variables not depending on the dark/light mode
Ornanovitch Sep 26, 2022
6596ea9
Merge branch 'contrast-util' into tag-contrast
Ornanovitch Sep 26, 2022
04e2555
refactor: use isDark rather than getContrast
Ornanovitch Sep 26, 2022
928a151
refactor: change getContrast to isDark with for a more direct approach
Ornanovitch Sep 26, 2022
ebcad43
fix: adjust snippet description
Ornanovitch Sep 26, 2022
99b5036
refactor: change getContrast to isDark with for a more direct approach
Ornanovitch Sep 26, 2022
ad06247
fix: adjust snippet description
Ornanovitch Sep 26, 2022
311764c
Merge branch 'contrast-util' into tag-contrast
Ornanovitch Sep 26, 2022
6903b84
fix: TagHero contrast
Ornanovitch Sep 29, 2022
bb0f3ea
fix: DiscussionHero contrast
Ornanovitch Sep 29, 2022
76b625a
fix: newDiscussion contrast
Ornanovitch Sep 29, 2022
f35ad09
fix(newDiscussion): restore less rule when tag is not colored
Ornanovitch Sep 29, 2022
b22515f
fix: TagTiles description
Ornanovitch Oct 18, 2022
8e62e24
fix: TagTiles last posted
Ornanovitch Oct 18, 2022
4966bde
chore: change `var` to `let`
davwheat Oct 21, 2022
d67b2ec
Merge branch 'contrast-util' into tag-contrast
Ornanovitch Oct 21, 2022
e4cb2c9
refactor: keep it for backwards compatibility
Ornanovitch Nov 7, 2022
1898108
refactor: keep it for backwards compatibility
Ornanovitch Nov 7, 2022
6753dfc
Apply suggestions from code review
Ornanovitch Nov 7, 2022
c7f0d14
Resolved merge conflict
Ornanovitch Nov 7, 2022
66db7f1
fix: missed this when I was resolving
Ornanovitch Nov 7, 2022
542d964
fix: remove dist files from pull request
Ornanovitch Nov 7, 2022
c97ab15
Revert "Resolved merge conflict"
Ornanovitch Nov 7, 2022
27a6503
fix: missed this when I was resolving
Ornanovitch Nov 7, 2022
5d87fa3
fix
Ornanovitch Nov 7, 2022
f802034
Merge branch 'main' into tag-contrast
Ornanovitch Nov 8, 2022
ca01b4c
Update isDark.ts
Ornanovitch Nov 8, 2022
c930f1a
Merge branch 'main' into tag-contrast
SychO9 Nov 26, 2022
18557b3
chore: flexible contrast color fixing
SychO9 Nov 26, 2022
b6009a2
refactor(isDark): clarify the doc block
Ornanovitch Nov 26, 2022
d82b959
fix(isDark): increase the yiq threshold
Ornanovitch Nov 26, 2022
ad5ac9d
typo
Ornanovitch Nov 26, 2022
1cafcfe
fix: preserve design coloring through light and dark modes
SychO9 Nov 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion extensions/tags/js/src/common/helpers/tagLabel.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import extract from 'flarum/common/utils/extract';
import Link from 'flarum/common/components/Link';
Ornanovitch marked this conversation as resolved.
Show resolved Hide resolved
import classList from 'flarum/common/utils/classList';
import textContrastClass from 'flarum/common/helpers/textContrastClass';
import tagIcon from './tagIcon';

export default function tagLabel(tag, attrs = {}) {
Expand All @@ -13,7 +15,7 @@ export default function tagLabel(tag, attrs = {}) {
const color = tag.color();
if (color) {
attrs.style['--tag-bg'] = color;
attrs.className += ' colored';
attrs.className = classList(attrs.className, 'colored', textContrastClass(color));
}

if (link) {
Expand Down
3 changes: 2 additions & 1 deletion extensions/tags/js/src/forum/addTagFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import IndexPage from 'flarum/forum/components/IndexPage';
import DiscussionListState from 'flarum/forum/states/DiscussionListState';
import GlobalSearchState from 'flarum/forum/states/GlobalSearchState';
import classList from 'flarum/common/utils/classList';
import textContrastClass from 'flarum/common/helpers/textContrastClass';

import TagHero from './components/TagHero';
import Tag from '../common/models/Tag';
Expand Down Expand Up @@ -90,7 +91,7 @@ export default function () {
const newDiscussion = items.get('newDiscussion') as Mithril.Vnode<ComponentAttrs, {}>;

if (color) {
newDiscussion.attrs.className = classList([newDiscussion.attrs.className, 'Button--tagColored']);
newDiscussion.attrs.className = classList([newDiscussion.attrs.className, 'Button--tagColored', textContrastClass(color)]);
newDiscussion.attrs.style = { '--color': color };
}

Expand Down
4 changes: 3 additions & 1 deletion extensions/tags/js/src/forum/addTagLabels.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { extend } from 'flarum/common/extend';
import DiscussionListItem from 'flarum/forum/components/DiscussionListItem';
import DiscussionHero from 'flarum/forum/components/DiscussionHero';
import textContrastClass from 'flarum/common/helpers/textContrastClass';
import classList from 'flarum/common/utils/classList';

import tagsLabel from '../common/helpers/tagsLabel';
import sortTags from '../common/utils/sortTags';
Expand All @@ -23,7 +25,7 @@ export default function () {
const color = tags[0].color();
if (color) {
view.attrs.style = { '--hero-bg': color };
view.attrs.className += ' DiscussionHero--colored';
Ornanovitch marked this conversation as resolved.
Show resolved Hide resolved
view.attrs.className = classList(view.attrs.className, 'DiscussionHero--colored', textContrastClass(color));
}
}
});
Expand Down
7 changes: 6 additions & 1 deletion extensions/tags/js/src/forum/components/TagHero.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import Component from 'flarum/common/Component';
import textContrastClass from 'flarum/common/helpers/textContrastClass';
import tagIcon from '../../common/helpers/tagIcon';
Ornanovitch marked this conversation as resolved.
Show resolved Hide resolved
import classList from 'flarum/common/utils/classList';

export default class TagHero extends Component {
view() {
const tag = this.attrs.model;
const color = tag.color();

return (
<header className={'Hero TagHero' + (color ? ' TagHero--colored' : '')} style={color ? { '--hero-bg': color } : ''}>
<header
className={classList('Hero', 'TagHero', { 'TagHero--colored': color }, textContrastClass(color))}
style={color ? { '--hero-bg': color } : ''}
>
<div className="container">
<div className="containerNarrow">
<h2 className="Hero-title">
Expand Down
4 changes: 3 additions & 1 deletion extensions/tags/js/src/forum/components/TagsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import Link from 'flarum/common/components/Link';
import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
import listItems from 'flarum/common/helpers/listItems';
import humanTime from 'flarum/common/helpers/humanTime';
import textContrastClass from 'flarum/common/helpers/textContrastClass';
import classList from 'flarum/common/utils/classList';

import tagIcon from '../../common/helpers/tagIcon';
import tagLabel from '../../common/helpers/tagLabel';
Expand Down Expand Up @@ -58,7 +60,7 @@ export default class TagsPage extends Page {
const children = sortTags(tag.children() || []);

return (
<li className={'TagTile ' + (tag.color() ? 'colored' : '')} style={{ '--tag-bg': tag.color() }}>
<li className={classList('TagTile', { colored: tag.color() }, textContrastClass(tag.color()))} style={{ '--tag-bg': tag.color() }}>
<Link className="TagTile-info" href={app.route.tag(tag)}>
{tag.icon() && tagIcon(tag, {}, { useColor: false })}
<h3 className="TagTile-name">{tag.name()}</h3>
Expand Down
6 changes: 3 additions & 3 deletions extensions/tags/less/common/TagLabel.less
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
}

&.colored {
--tag-color: @body-bg;
Ornanovitch marked this conversation as resolved.
Show resolved Hide resolved
--tag-color: var(--contrast-color, var(--body-bg));
Ornanovitch marked this conversation as resolved.
Show resolved Hide resolved

.TagLabel-text {
color: var(--tag-color) !important;
Expand All @@ -31,13 +31,13 @@
&.colored {
--tag-color: var(--tag-bg);
margin-right: 5px;
background: @body-bg !important;
background-color: var(--contrast-color, var(--body-bg));
}
}
}
.DiscussionHero--colored {
&, a {
color: @body-bg;
color: var(--contrast-color, var(--body-bg));
}
}
.TagsLabel {
Expand Down
1 change: 1 addition & 0 deletions extensions/tags/less/forum.less
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
--button-primary-bg: var(--color);
--button-primary-bg-hover: var(--color);
--button-primary-bg-active: var(--color);
--button-color: var(--contrast-color);
}
.DiscussionHero {
.item-title {
Expand Down
2 changes: 1 addition & 1 deletion extensions/tags/less/forum/TagHero.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.TagHero {
&--colored {
--hero-color: #fff;
--hero-color: var(--body-bg);
}
}
12 changes: 3 additions & 9 deletions extensions/tags/less/forum/TagTiles.less
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
}
&.colored {
&, a {
color: @body-bg;
color: var(--contrast-color, var(--body-bg));
}
}
}
Expand Down Expand Up @@ -100,10 +100,7 @@
.TagTile-description {
font-size: 12px;
margin: 0 0 10px;

.TagTile.colored & {
color: fade(@body-bg, 70%);
}
opacity: 70%;
}
.TagTile-children {
font-weight: bold;
Expand All @@ -124,10 +121,7 @@
font-size: 12px;
border-top: 1px solid rgba(0, 0, 0, 0.15);
margin: 0 20px;

.TagTile.colored & {
color: fade(@body-bg, 70%);
}
opacity: 70%;

&:hover .TagTile-lastPostedDiscussion-title {
text-decoration: underline;
Expand Down
2 changes: 2 additions & 0 deletions framework/core/js/src/common/compat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import highlight from './helpers/highlight';
import username from './helpers/username';
import userOnline from './helpers/userOnline';
import listItems from './helpers/listItems';
import textContrastClass from './helpers/textContrastClass';
import Fragment from './Fragment';
import DefaultResolver from './resolvers/DefaultResolver';
import PaginatedListState from './states/PaginatedListState';
Expand Down Expand Up @@ -172,6 +173,7 @@ export default {
'helpers/username': username,
'helpers/userOnline': userOnline,
'helpers/listItems': listItems,
'helpers/textContrastClass': textContrastClass,
'resolvers/DefaultResolver': DefaultResolver,
'states/PaginatedListState': PaginatedListState,
'states/AlertManagerState': AlertManagerState,
Expand Down
5 changes: 5 additions & 0 deletions framework/core/js/src/common/helpers/textContrastClass.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import isDark from '../utils/isDark';

export default function textContrastClass(hexcolor: string): string {
return isDark(hexcolor) ? 'text-contrast--light' : 'text-contrast--dark';
}
18 changes: 11 additions & 7 deletions framework/core/js/src/common/utils/isDark.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/**
* The `isDark` utility converts a hex color to rgb, and then calcul a YIQ
* value in order to get the appropriate brightness value (is it dark or is it
* light?) See https://www.w3.org/TR/AERT/#color-contrast for references. A YIQ
* value >= 128 is a light color.
* The `isDark` utility converts a hex color to rgb, and then calculates a YIQ
* value in order to get the appropriate brightness value. See
* https://www.w3.org/TR/AERT/#color-contrast for references.
*
* A YIQ value >= 128 corresponds to a light color according to the W3C
* standards, but we use a custom threshold for each light and dark modes
* to preserve design consistency.
*/

export default function isDark(hexcolor: String) {
export default function isDark(hexcolor: string): boolean {
let hexnumbers = hexcolor.replace('#', '');

if (hexnumbers.length == 3) {
Expand All @@ -17,5 +19,7 @@ export default function isDark(hexcolor: String) {
const b = parseInt(hexnumbers.substr(4, 2), 16);
const yiq = (r * 299 + g * 587 + b * 114) / 1000;

return yiq >= 128 ? false : true;
const threshold = parseInt(window.getComputedStyle(document.body).getPropertyValue('--yiq-threshold'));

return yiq < threshold;
}
13 changes: 13 additions & 0 deletions framework/core/less/common/root.less
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@

--error-color: @error-color;

// ---------------------------------
// UTILITIES

--text-on-dark: @text-on-dark;
--text-on-light: @text-on-light;

& when (@config-dark-mode = true) {
--yiq-threshold: 108;
}
& when (@config-dark-mode = false) {
--yiq-threshold: 138;
}

// ---------------------------------
// COMPONENTS

Expand Down
11 changes: 11 additions & 0 deletions framework/core/less/common/scaffolding.less
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,14 @@ blockquote ol:last-child {
white-space: nowrap;
width: 1px;
}

.text-contrast {
&--dark {
--contrast-color: var(--text-on-light);
color: var(--contrast-color);
}
&--light {
--contrast-color: var(--text-on-dark);
color: var(--contrast-color);
}
}
11 changes: 7 additions & 4 deletions framework/core/less/common/variables.less
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
@secondary-hue: hue(@secondary-color);
@secondary-sat: saturation(@secondary-color);

@body-bg-light: #fff;
@body-bg-dark: hsl(@secondary-hue, min(20%, @secondary-sat), 10%);

// Derive the primary/secondary colors from the config variables. In dark mode,
// we make the user-set colors a bit darker, otherwise they will stand out too
// much.
Expand All @@ -23,7 +26,7 @@
@primary-color: @config-primary-color;
@secondary-color: @config-secondary-color;

@body-bg: #fff;
@body-bg: @body-bg-light;
@text-color: #111;
@link-color: saturate(@primary-color, 10%);
@heading-color: @text-color;
Expand All @@ -45,7 +48,7 @@
@primary-color: @config-primary-color;
@secondary-color: @config-secondary-color;

@body-bg: hsl(@secondary-hue, min(20%, @secondary-sat), 10%);
@body-bg: @body-bg-dark;
@text-color: #ddd;
@link-color: saturate(@primary-color, 10%);
@heading-color: @text-color;
Expand All @@ -68,8 +71,8 @@
// of the parents element's background. This allow not to change the color
// variable depending on the dark/light mode to get the same final color, and
// thus to simplify the logic.
@text-on-dark: #ddd;
@text-on-light: #111;
@text-on-dark: @body-bg-light;
@text-on-light: @body-bg-dark;

@hero-bg: @control-bg;
@hero-color: @control-color;
Expand Down
2 changes: 1 addition & 1 deletion framework/core/less/forum/Hero.less
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
margin-top: -1px;
background: var(--hero-bg);
text-align: center;
color: var(--hero-color);
color: var(--contrast-color, var(--hero-color));

h2 {
margin: 0;
Expand Down