Colorised spreadsheet (#1643)

* feat: colorise spreadSheet with rundown color

* feat: add colorisation in spreadsheet for block

* feat: border color

* fix: cleanup accessible color

* fix: review before merge (https://github.com/cpvalente/ontime/pull/1608)

* fix: usgae of map instead foreach (https://github.com/cpvalente/ontime/pull/1608)

* Update apps/server/src/services/sheet-service/SheetService.ts

Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>

* fix: comment condition

* fix: Remove Color plugin (but don't can get color like 'red' or 'black')

* fix: isLight for more clean code

* fix: remove map on isLight function

* fix: remove debug logger

* refactor colour

* lint

---------

Co-authored-by: Gwenitora <gwenitora.gardu74@gmail.com>
Co-authored-by: Gwenitora <61121870+Gwenitora@users.noreply.github.com>
Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
This commit is contained in:
Alex Christoffer Rasmussen
2025-06-24 22:38:03 +02:00
committed by GitHub
parent 984dcb0181
commit 4872cd0a48
14 changed files with 350 additions and 252 deletions
@@ -18,19 +18,19 @@ describe('getAccessibleColour()', () => {
it('handles named colours', () => {
const colour = 'red';
const { backgroundColor, color } = getAccessibleColour(colour);
expect(backgroundColor).toBe('#FF0000FF');
expect(backgroundColor).toBe('#ff0000ff');
expect(color).toBe('#fffffa');
});
it('handles hex colours', () => {
const colour = '#0F0';
const { backgroundColor, color } = getAccessibleColour(colour);
expect(backgroundColor).toBe('#00FF00FF');
expect(backgroundColor).toBe('#00ff00ff');
expect(color).toBe('black');
});
it('handles transparens', () => {
const colour = '#0F08';
const { backgroundColor, color } = getAccessibleColour(colour);
expect(backgroundColor).toBe('#0C940CFF');
expect(backgroundColor).toBe('#0c940cff');
expect(color).toBe('#fffffa');
});
});
+16 -19
View File
@@ -1,27 +1,27 @@
import Color from 'color';
import { RGBColour } from 'ontime-types';
import { colourToHex, cssOrHexToColour, isLightColour, mixColours } from 'ontime-utils';
type ColourCombination = {
backgroundColor: string;
color: string;
};
const defaultUiBackground: RGBColour = { red: 26, green: 26, blue: 26, alpha: 1 };
/**
* @description Selects text colour to maintain accessible contrast
* @param bgColour
* @return {{backgroundColor, color: string}}
*/
export const getAccessibleColour = (bgColour?: string): ColourCombination => {
if (bgColour) {
try {
const originalColour = Color(bgColour);
const backgroundColorMix = originalColour.alpha(1).mix(Color('#1a1a1a'), 1 - originalColour.alpha());
const textColor = backgroundColorMix.isLight() ? 'black' : '#fffffa';
return { backgroundColor: backgroundColorMix.hexa(), color: textColor };
} catch (_error) {
/* we do not handle errors here */
}
}
return { backgroundColor: '#1a1a1a', color: '#fffffa' };
if (!bgColour) return { backgroundColor: '#1a1a1a', color: '#fffffa' };
const originalColour = cssOrHexToColour(bgColour);
if (!originalColour) return { backgroundColor: '#1a1a1a', color: '#fffffa' };
const backgroundColorMix = mixColours(defaultUiBackground, originalColour, 1 - originalColour.alpha);
const textColor = isLightColour(backgroundColorMix) ? 'black' : '#fffffa';
return { backgroundColor: colourToHex(backgroundColorMix), color: textColor };
};
/**
@@ -39,11 +39,8 @@ export const timerPlaceholderMin = '––:––';
* Adds opacity to a given colour if possible
*/
export function alpha(colour: string, amount: number): string {
try {
const withAlpha = Color(colour).alpha(amount).hexa();
return withAlpha;
} catch (_error) {
/* we do not handle errors here */
}
return colour;
const originalColour = cssOrHexToColour(colour);
if (!originalColour) return colour;
originalColour.alpha = amount;
return colourToHex(originalColour);
}