Skip to content

Commit

Permalink
fix: Shopping List Label Text Color (#4302)
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-genson authored Oct 1, 2024
1 parent f1d56ca commit 3d1b087
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 41 deletions.
42 changes: 2 additions & 40 deletions frontend/components/Domain/ShoppingList/MultiPurposeLabel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@

<script lang="ts">
import { computed, defineComponent } from "@nuxtjs/composition-api";
// @ts-ignore missing color types
import Color from "@sphinxxxx/color-conversion";
import { getTextColor } from "~/composables/use-text-color";
import { MultiPurposeLabelSummary } from "~/lib/api/types/recipe";
Expand All @@ -21,44 +20,7 @@ export default defineComponent({
},
},
setup(props) {
const textColor = computed(() => {
if (!props.label.color) {
return "black";
}
return pickTextColorBasedOnBgColorAdvanced(props.label.color, "white", "black");
});
/*
Function to pick the text color based on the background color.
Based on -> https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
*/
const ACCESSIBILITY_THRESHOLD = 0.179;
function pickTextColorBasedOnBgColorAdvanced(bgColor: string, lightColor: string, darkColor: string) {
try {
const color = new Color(bgColor);
// if opacity is less than 0.3 always return dark color
if (color._rgba[3] < 0.3) {
return darkColor;
}
const uicolors = [color._rgba[0] / 255, color._rgba[1] / 255, color._rgba[2] / 255];
const c = uicolors.map((col) => {
if (col <= 0.03928) {
return col / 12.92;
}
return Math.pow((col + 0.055) / 1.055, 2.4);
});
const L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
return L > ACCESSIBILITY_THRESHOLD ? darkColor : lightColor;
} catch (error) {
console.warn(error);
return "black";
}
}
const textColor = computed(() => getTextColor(props.label.color));
return {
textColor,
Expand Down
39 changes: 39 additions & 0 deletions frontend/composables/use-text-color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// @ts-ignore missing color types
import Color from "@sphinxxxx/color-conversion";

const LIGHT_COLOR = "white";
const DARK_COLOR = "black";
const ACCESSIBILITY_THRESHOLD = 0.179;

/*
Function to pick the text color based on the background color.
Based on -> https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
*/
export function getTextColor(bgColor: string | undefined): string {
if (!bgColor) {
return DARK_COLOR;
}

try {
const color = new Color(bgColor);

// if opacity is less than 0.3 always return dark color
if (color._rgba[3] < 0.3) {
return DARK_COLOR;
}

const uicolors = [color._rgba[0] / 255, color._rgba[1] / 255, color._rgba[2] / 255];
const c = uicolors.map((col) => {
if (col <= 0.03928) {
return col / 12.92;
}
return Math.pow((col + 0.055) / 1.055, 2.4);
});
const L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
return L > ACCESSIBILITY_THRESHOLD ? DARK_COLOR : LIGHT_COLOR;
} catch (error) {
console.warn(error);
return DARK_COLOR;
}
}
12 changes: 11 additions & 1 deletion frontend/pages/shopping-lists/_id.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,15 @@
<div v-else>
<div v-for="(value, key) in itemsByLabel" :key="key" class="mb-6">
<div class="text-left">
<v-btn :color="getLabelColor(value[0]) ? getLabelColor(value[0]) : '#959595'">{{ key }}</v-btn>
<v-btn
:color="getLabelColor(value[0]) ? getLabelColor(value[0]) : '#959595'"
:style="{
'color': getTextColor(getLabelColor(value[0])),
'letter-spacing': 'normal',
}"
>
{{ key }}
</v-btn>
</div>
<v-divider/>
<draggable :value="value" handle=".handle" delay="250" :delay-on-touch-only="true" @start="loadingCounter += 1" @end="loadingCounter -= 1" @input="updateIndexUncheckedByLabel(key, $event)">
Expand Down Expand Up @@ -298,6 +306,7 @@ import ShoppingListItemEditor from "~/components/Domain/ShoppingList/ShoppingLis
import { useFoodStore, useLabelStore, useUnitStore } from "~/composables/store";
import { useShoppingListItemActions } from "~/composables/use-shopping-list-item-actions";
import { useShoppingListPreferences } from "~/composables/use-users/preferences";
import { getTextColor } from "~/composables/use-text-color";
import { uuid4 } from "~/composables/use-utils";
type CopyTypes = "plain" | "markdown";
Expand Down Expand Up @@ -1085,6 +1094,7 @@ export default defineComponent({
allUsers,
currentUserId,
updateSettings,
getTextColor,
};
},
head() {
Expand Down

0 comments on commit 3d1b087

Please sign in to comment.