-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: automatically adjust background color to meet or exceed AA cont…
…rast (#63) Co-authored-by: Liam DeBeasi <[email protected]>
- Loading branch information
1 parent
dd70d21
commit abce934
Showing
9 changed files
with
94 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<script setup lang="ts"> | ||
import { colorWand, checkmark } from 'ionicons/icons'; | ||
import { computeContrast } from '../utils'; | ||
import { ColorContrastCalc } from 'color-contrast-calc'; | ||
import { ref } from 'vue'; | ||
const props = defineProps(['modelValue', 'foreground', 'hint']); | ||
const emit = defineEmits(['update:modelValue']); | ||
const showAdjustButton = ref(true); | ||
const adjustColor = () => { | ||
const contrast = computeContrast(props.foreground, props.modelValue); | ||
if (contrast < 4.5) { | ||
const foregroundColor = ColorContrastCalc.colorFrom(props.foreground); | ||
const backgroundColor = ColorContrastCalc.colorFrom(props.modelValue); | ||
const adjustedBackgroundColor = foregroundColor.findBrightnessThreshold(backgroundColor, 'AA'); | ||
emit('update:modelValue', adjustedBackgroundColor.hexCode); | ||
} | ||
showAdjustButton.value = false; | ||
// Show a visual indicator that the operation succeeded to the clipboard. | ||
setTimeout(() => { | ||
showAdjustButton.value = true; | ||
}, 3000); | ||
} | ||
</script> | ||
|
||
<template> | ||
<div class="button-wrapper"> | ||
<button v-if="showAdjustButton" @click="adjustColor()" class="app-icon" :title="props.hint" :aria-label="props.hint"> | ||
<ion-icon aria-hidden="true" :icon="colorWand"></ion-icon> | ||
</button> | ||
<div class="app-icon" v-if="!showAdjustButton"> | ||
<ion-icon aria-label="Background color adjusted" :icon="checkmark" class="checkmark"></ion-icon> | ||
</div> | ||
<div class="status" role="status" aria-live="assertive"> | ||
<p v-if="!showAdjustButton">Background color adjusted</p> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<style scoped> | ||
.checkmark { | ||
cursor: default; | ||
} | ||
.status { | ||
opacity: 0; | ||
position: absolute; | ||
pointer-events: none; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { ColorContrastCalc } from 'color-contrast-calc'; | ||
|
||
export const computeContrast = (foreground: string, background: string) => { | ||
const foregroundRGB = ColorContrastCalc.colorFrom(foreground); | ||
const backgroundRGB = ColorContrastCalc.colorFrom(background); | ||
|
||
const ratio = foregroundRGB.contrastRatioAgainst(backgroundRGB); | ||
|
||
/** | ||
* Ratio should have at most two decimal places. Note that we do not round here | ||
* because a ratio of 4.995 should not be rounded up to 4.5. | ||
*/ | ||
return ratio.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]; | ||
} |
Binary file modified
BIN
+767 Bytes
(100%)
tests/test.spec.ts-snapshots/contrast-default-Mobile-Chrome-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+706 Bytes
(110%)
tests/test.spec.ts-snapshots/contrast-default-Mobile-Safari-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+767 Bytes
(100%)
tests/test.spec.ts-snapshots/contrast-default-firefox-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.