@box/blueprint-web 14.16.1 → 14.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -4,6 +4,7 @@ import { GrayBlack } from '@box/blueprint-web-assets/tokens/tokens';
|
|
|
4
4
|
import clsx from 'clsx';
|
|
5
5
|
import React__default, { forwardRef, useState, useEffect } from 'react';
|
|
6
6
|
import { useBlueprintModernization } from '../blueprint-modernization-context/useBlueprintModernization.js';
|
|
7
|
+
import { getContrastTextColor } from '../utils/getContrastTextColor.js';
|
|
7
8
|
import styles from './avatar.module.js';
|
|
8
9
|
import { colors, iconSizes } from './consts.js';
|
|
9
10
|
|
|
@@ -32,6 +33,7 @@ const Avatar = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
|
|
32
33
|
setImageHasError(false);
|
|
33
34
|
}, [src]);
|
|
34
35
|
const backgroundColor = color || colors[(colorIndex || 0) % colors.length];
|
|
36
|
+
const foregroundColor = getContrastTextColor(backgroundColor);
|
|
35
37
|
const iconSize = iconSizes[size];
|
|
36
38
|
const imageIsLoading = !!src && !icon && !imageIsLoaded;
|
|
37
39
|
const shouldShowIcon = !anonymous && icon && (!src || !imageIsLoaded);
|
|
@@ -47,12 +49,14 @@ const Avatar = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
|
|
47
49
|
children: /*#__PURE__*/React__default.cloneElement(icon, {
|
|
48
50
|
width: iconSize,
|
|
49
51
|
height: iconSize,
|
|
52
|
+
color: icon.props.color ?? foregroundColor,
|
|
50
53
|
role: 'presentation'
|
|
51
54
|
})
|
|
52
55
|
}), shouldShowText && jsx("div", {
|
|
53
56
|
className: clsx(styles.text, styles[`length-${text.length}`]),
|
|
54
57
|
style: {
|
|
55
|
-
backgroundColor
|
|
58
|
+
backgroundColor,
|
|
59
|
+
color: foregroundColor
|
|
56
60
|
},
|
|
57
61
|
children: text
|
|
58
62
|
}), shouldShowAnonymousAvatar && jsx("div", {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Size9, Size7, Size5, Size4, Size3, Size2, Grimace50, Orange50, PurpleRain50, WatermelonRed50, LightBlue50, Yellorange50, GreenLight50, Yellow50,
|
|
1
|
+
import { Size9, Size7, Size5, Size4, Size3, Size2, Grimace50, Orange50, PurpleRain50, WatermelonRed50, LightBlue50, Yellorange50, GreenLight50, Yellow50, DarkBlue100, BoxBlue50 } from '@box/blueprint-web-assets/tokens/tokens';
|
|
2
2
|
|
|
3
3
|
const iconSizes = {
|
|
4
4
|
xsmall: Size2,
|
|
@@ -10,7 +10,7 @@ const iconSizes = {
|
|
|
10
10
|
};
|
|
11
11
|
const colorsMap = {
|
|
12
12
|
BoxBlue50,
|
|
13
|
-
|
|
13
|
+
DarkBlue100,
|
|
14
14
|
Yellow50,
|
|
15
15
|
GreenLight50,
|
|
16
16
|
Yellorange50,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type BoxBlue50, type
|
|
1
|
+
import { type BoxBlue50, type DarkBlue100, type GreenLight50, type Grimace50, type LightBlue50, type Orange50, type PurpleRain50, type WatermelonRed50, type Yellorange50, type Yellow50 } from '@box/blueprint-web-assets/tokens/tokens';
|
|
2
2
|
import { type ReactElement, type SVGProps } from 'react';
|
|
3
3
|
import { type RequireAllOrNone, type RequireExactlyOne } from 'type-fest';
|
|
4
4
|
import { type AvatarSizes } from './consts';
|
|
5
5
|
export type AvatarSize = (typeof AvatarSizes)[number];
|
|
6
|
-
export type Color = typeof BoxBlue50 | typeof
|
|
6
|
+
export type Color = typeof BoxBlue50 | typeof DarkBlue100 | typeof Yellow50 | typeof GreenLight50 | typeof Yellorange50 | typeof LightBlue50 | typeof WatermelonRed50 | typeof PurpleRain50 | typeof Orange50 | typeof Grimace50;
|
|
7
7
|
export interface Image {
|
|
8
8
|
/** The image to display. When the image is loading or if it fails to load, fallbacks are displayed in order:
|
|
9
9
|
* icon (if provided) → text (if provided) → anonymous user image.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ContrastTextColorOptions {
|
|
2
|
+
textOnLight?: string;
|
|
3
|
+
textOnDark?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Returns the text color with the highest contrast against the background.
|
|
7
|
+
*
|
|
8
|
+
* @param backgroundColor - The background color in any CSS-compatible format (hex, rgb, hsl, etc.)
|
|
9
|
+
* @param options (optional)
|
|
10
|
+
* - textOnLight: Text color to use on light backgrounds (defaults to GrayBlack)
|
|
11
|
+
* - textOnDark: Text color to use on dark backgrounds (defaults to GrayWhite)
|
|
12
|
+
* @returns The text color with higher contrast
|
|
13
|
+
*/
|
|
14
|
+
export declare function getContrastTextColor(backgroundColor: string, options?: ContrastTextColorOptions): string;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { GrayWhite, GrayBlack } from '@box/blueprint-web-assets/tokens/tokens';
|
|
2
|
+
import Color from 'color';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns the text color with the highest contrast against the background.
|
|
6
|
+
*
|
|
7
|
+
* @param backgroundColor - The background color in any CSS-compatible format (hex, rgb, hsl, etc.)
|
|
8
|
+
* @param options (optional)
|
|
9
|
+
* - textOnLight: Text color to use on light backgrounds (defaults to GrayBlack)
|
|
10
|
+
* - textOnDark: Text color to use on dark backgrounds (defaults to GrayWhite)
|
|
11
|
+
* @returns The text color with higher contrast
|
|
12
|
+
*/
|
|
13
|
+
function getContrastTextColor(backgroundColor, options = {}) {
|
|
14
|
+
const {
|
|
15
|
+
textOnLight = GrayBlack,
|
|
16
|
+
textOnDark = GrayWhite
|
|
17
|
+
} = options;
|
|
18
|
+
try {
|
|
19
|
+
const bgColor = Color(backgroundColor);
|
|
20
|
+
const onLightContrast = bgColor.contrast(Color(textOnLight));
|
|
21
|
+
const onDarkContrast = bgColor.contrast(Color(textOnDark));
|
|
22
|
+
return onLightContrast > onDarkContrast ? textOnLight : textOnDark;
|
|
23
|
+
} catch {
|
|
24
|
+
// If any colors are invalid, fallback to text on light
|
|
25
|
+
return textOnLight;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { getContrastTextColor };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@box/blueprint-web",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.17.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"publishConfig": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@ariakit/react": "0.4.21",
|
|
49
49
|
"@ariakit/react-core": "0.4.21",
|
|
50
|
-
"@box/blueprint-web-assets": "^4.115.
|
|
50
|
+
"@box/blueprint-web-assets": "^4.115.3",
|
|
51
51
|
"@internationalized/date": "^3.12.0",
|
|
52
52
|
"@radix-ui/react-accordion": "1.1.2",
|
|
53
53
|
"@radix-ui/react-checkbox": "1.0.4",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"type-fest": "^3.2.0"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
|
-
"@box/storybook-utils": "^0.18.
|
|
80
|
+
"@box/storybook-utils": "^0.18.3",
|
|
81
81
|
"@figma/code-connect": "1.4.4",
|
|
82
82
|
"@types/react": "^18.0.0",
|
|
83
83
|
"@types/react-dom": "^18.0.0",
|