Skip to content

Commit 99b5fbd

Browse files
committed
feat(ui-avatar,shared-types): add new ai color variant
1 parent 58d311c commit 99b5fbd

File tree

5 files changed

+148
-44
lines changed

5 files changed

+148
-44
lines changed

packages/shared-types/src/ComponentThemeVariables.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,25 @@ export type AlertTheme = {
6666
}
6767

6868
export type AvatarTheme = {
69-
background: Colors['contrasts']['white1010']
69+
background: string
7070
borderWidthSmall: Border['widthSmall']
7171
borderWidthMedium: Border['widthMedium']
72-
borderColor: Colors['contrasts']['grey1214']
72+
borderColor: string
7373
boxShadowColor: string
7474
boxShadowBlur: string
7575
fontFamily: Typography['fontFamily']
7676
fontWeight: Typography['fontWeightBold']
77-
color: Colors['contrasts']['blue4570']
78-
colorShamrock: Colors['contrasts']['green4570']
79-
colorBarney: Colors['contrasts']['blue4570']
80-
colorCrimson: Colors['contrasts']['orange4570']
81-
colorFire: Colors['contrasts']['red4570']
82-
colorLicorice: Colors['contrasts']['grey125125']
83-
colorAsh: Colors['contrasts']['grey4570']
77+
color: string
78+
colorShamrock: string
79+
colorBarney: string
80+
colorCrimson: string
81+
colorFire: string
82+
colorLicorice: string
83+
colorAsh: string
84+
85+
aiTopGradientColor: string
86+
aiBottomGradientColor: string
87+
aiFontColor: string
8488
}
8589

8690
export type BadgeTheme = {

packages/ui-avatar/src/Avatar/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@ readonly: true
2323
</div>
2424
```
2525

26+
### AI Avatar
27+
28+
There is a need for special, `ai avatars`. These have a specific look. You can achieve it the following way
29+
30+
```js
31+
---
32+
type: example
33+
readonly: true
34+
---
35+
<View display="block" padding="small medium" background="primary">
36+
<Avatar size="xx-small" color="ai" renderIcon={IconAiSolid} margin="0 small 0 0"/>
37+
<Avatar size="x-small" color="ai" renderIcon={IconAiSolid} margin="0 small 0 0"/>
38+
<Avatar size="small" color="ai" renderIcon={IconAiSolid} margin="0 small 0 0"/>
39+
<Avatar size="medium" color="ai" renderIcon={IconAiSolid} margin="0 small 0 0"/>
40+
<Avatar size="large" color="ai" renderIcon={IconAiSolid} margin="0 small 0 0"/>
41+
<Avatar size="x-large" color="ai" renderIcon={IconAiSolid} margin="0 small 0 0"/>
42+
<Avatar size="xx-large" color="ai" renderIcon={IconAiSolid} />
43+
</View>
44+
```
45+
2646
### Size
2747

2848
The `size` prop allows you to select from `xx-small`, `x-small`, `small`, `medium`, `large`, `x-large`, and `xx-large`. If the `auto` prop is set, the avatar size will adjust according to the font-size

packages/ui-avatar/src/Avatar/props.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ type AvatarOwnProps = {
6868
| 'fire'
6969
| 'licorice'
7070
| 'ash'
71+
| 'ai'
7172
/**
7273
* In inverse color mode the background and text/icon colors are inverted
7374
*/
@@ -139,7 +140,8 @@ const propTypes: PropValidators<PropKeys> = {
139140
'crimson',
140141
'fire',
141142
'licorice',
142-
'ash'
143+
'ash',
144+
'ai'
143145
]),
144146
hasInverseColor: PropTypes.bool,
145147
showBorder: PropTypes.oneOf(['auto', 'always', 'never']),

packages/ui-avatar/src/Avatar/styles.ts

Lines changed: 107 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -51,44 +51,97 @@ const generateStyle = (
5151
const { loaded, size, color, hasInverseColor, shape, src, showBorder } =
5252
params
5353

54+
// NOTE: this is needed due to design changes. The size of the component is calculated from "em" which means it is
55+
// tied to the fontSize. The font sizes changed for the icons, which meant that the container (component) size would've
56+
// changed too without additional calculations
57+
const calcNewScaler = (
58+
originalFontSize: number,
59+
newFontSize: number,
60+
originalScaler: number
61+
) => {
62+
return `${(originalFontSize * originalScaler) / newFontSize}em`
63+
}
64+
5465
const sizeStyles = {
5566
auto: {
5667
fontSize: 'inherit',
57-
borderWidth: componentTheme.borderWidthSmall
68+
borderWidth: componentTheme.borderWidthSmall,
69+
width: '2.5em',
70+
height: '2.5em'
5871
},
5972
'xx-small': {
60-
fontSize: '0.5rem',
61-
borderWidth: componentTheme.borderWidthSmall
73+
fontSize: '0.625rem',
74+
borderWidth: componentTheme.borderWidthSmall,
75+
width: calcNewScaler(0.5, 0.625, shape === 'circle' ? 2.5 : 3),
76+
height: calcNewScaler(0.5, 0.625, 2.5)
6277
},
6378
'x-small': {
64-
fontSize: '0.75rem',
65-
borderWidth: componentTheme.borderWidthSmall
79+
fontSize: '0.875rem',
80+
borderWidth: componentTheme.borderWidthSmall,
81+
width: calcNewScaler(0.75, 0.875, shape === 'circle' ? 2.5 : 3),
82+
height: calcNewScaler(0.75, 0.875, 2.5)
6683
},
6784
small: {
68-
fontSize: '1rem',
69-
borderWidth: componentTheme.borderWidthSmall
85+
fontSize: '1.25rem',
86+
borderWidth: componentTheme.borderWidthSmall,
87+
width: calcNewScaler(1, 1.25, shape === 'circle' ? 2.5 : 3),
88+
height: calcNewScaler(1, 1.25, 2.5)
7089
},
7190
medium: {
72-
fontSize: '1.25rem',
73-
borderWidth: componentTheme.borderWidthMedium
91+
fontSize: '1.5rem',
92+
borderWidth: componentTheme.borderWidthMedium,
93+
width: calcNewScaler(1.25, 1.5, shape === 'circle' ? 2.5 : 3),
94+
height: calcNewScaler(1.25, 1.5, 2.5)
7495
},
7596
large: {
76-
fontSize: '1.5rem',
77-
borderWidth: componentTheme.borderWidthMedium
97+
fontSize: '1.75rem',
98+
borderWidth: componentTheme.borderWidthMedium,
99+
width: calcNewScaler(1.5, 1.75, shape === 'circle' ? 2.5 : 3),
100+
height: calcNewScaler(1.5, 1.75, 2.5)
78101
},
79102
'x-large': {
80-
fontSize: '1.75rem',
81-
borderWidth: componentTheme.borderWidthMedium
103+
fontSize: '2rem',
104+
borderWidth: componentTheme.borderWidthMedium,
105+
width: calcNewScaler(1.75, 2, shape === 'circle' ? 2.5 : 3),
106+
height: calcNewScaler(1.75, 2, 2.5)
82107
},
83108
'xx-large': {
84-
fontSize: '2rem',
85-
borderWidth: componentTheme.borderWidthMedium
109+
fontSize: '2.25rem',
110+
borderWidth: componentTheme.borderWidthMedium,
111+
width: calcNewScaler(2, 2.25, shape === 'circle' ? 2.5 : 3),
112+
height: calcNewScaler(2, 2.25, 2.5)
86113
}
87114
}
88115

89-
const variantStyles = {
116+
const initialSizeStyles = {
117+
auto: {
118+
fontSize: 'inherit'
119+
},
120+
'xx-small': {
121+
fontSize: '0.5rem'
122+
},
123+
'x-small': {
124+
fontSize: '0.75rem'
125+
},
126+
small: {
127+
fontSize: '1rem'
128+
},
129+
medium: {
130+
fontSize: '1.25rem'
131+
},
132+
large: {
133+
fontSize: '1.5rem'
134+
},
135+
'x-large': {
136+
fontSize: '1.75rem'
137+
},
138+
'xx-large': {
139+
fontSize: '2rem'
140+
}
141+
}
142+
143+
const shapeStyles = {
90144
circle: {
91-
width: '2.5em',
92145
position: 'relative',
93146
borderRadius: '100%',
94147
overflow: 'hidden'
@@ -105,34 +158,54 @@ const generateStyle = (
105158
crimson: componentTheme.colorCrimson,
106159
fire: componentTheme.colorFire,
107160
licorice: componentTheme.colorLicorice,
108-
ash: componentTheme.colorAsh
161+
ash: componentTheme.colorAsh,
162+
ai: `
163+
linear-gradient(to bottom, ${componentTheme.aiTopGradientColor} 0%, ${componentTheme.aiBottomGradientColor} 100%) padding-box,
164+
linear-gradient(to bottom right, ${componentTheme.aiTopGradientColor} 0%, ${componentTheme.aiBottomGradientColor} 100%) border-box`
109165
}
110166

111-
const backgroundColor = hasInverseColor
112-
? colorVariants[color!]
113-
: componentTheme.background
167+
const background = () => {
168+
if (color === 'ai') {
169+
return {
170+
background: `
171+
linear-gradient(to bottom, ${componentTheme.aiTopGradientColor} 0%, ${componentTheme.aiBottomGradientColor} 100%) padding-box,
172+
linear-gradient(to bottom right, ${componentTheme.aiTopGradientColor} 0%, ${componentTheme.aiBottomGradientColor} 100%) border-box`,
173+
border: 'solid transparent'
174+
}
175+
}
176+
return hasInverseColor
177+
? {
178+
backgroundColor: colorVariants[color!],
179+
backgroundClip: 'content-box'
180+
}
181+
: {
182+
backgroundColor: componentTheme.background,
183+
backgroundClip: 'content-box'
184+
}
185+
}
114186

115-
const contentColor = hasInverseColor
116-
? componentTheme.background
117-
: colorVariants[color!]
187+
const contentColor = () => {
188+
if (color === 'ai') {
189+
return componentTheme.aiFontColor
190+
}
191+
return hasInverseColor ? componentTheme.background : colorVariants[color!]
192+
}
118193

119194
return {
120195
avatar: {
121196
label: 'avatar',
122-
height: '2.5em',
123197
boxSizing: 'border-box',
124-
backgroundColor: backgroundColor,
198+
borderStyle: 'solid',
199+
borderColor: componentTheme.borderColor,
200+
...background(),
125201
backgroundPosition: 'center',
126202
backgroundSize: 'cover',
127-
backgroundClip: 'content-box',
128203
backgroundRepeat: 'no-repeat',
129204
overflow: 'hidden',
130205
lineHeight: 0,
131206
textAlign: 'center',
132-
borderStyle: 'solid',
133-
borderColor: componentTheme.borderColor,
134207
...sizeStyles[size!],
135-
...variantStyles[shape!],
208+
...shapeStyles[shape!],
136209
...(loaded
137210
? {
138211
backgroundImage: `url('${src}')`,
@@ -155,11 +228,12 @@ const generateStyle = (
155228
},
156229
initials: {
157230
label: 'avatar__initials',
158-
color: contentColor,
231+
color: contentColor(),
159232
lineHeight: '2.375em',
160233
fontFamily: componentTheme.fontFamily,
161234
fontWeight: componentTheme.fontWeight,
162-
letterSpacing: '0.0313em'
235+
letterSpacing: '0.0313em',
236+
...initialSizeStyles[size!]
163237
},
164238
loadImage: {
165239
label: 'avatar__loadImage',
@@ -174,7 +248,7 @@ const generateStyle = (
174248
width: '100%',
175249

176250
svg: {
177-
fill: contentColor,
251+
fill: contentColor(),
178252
height: '1em',
179253
width: '1em'
180254
}

packages/ui-avatar/src/Avatar/theme.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ const generateComponentTheme = (theme: Theme): AvatarTheme => {
5252
colorCrimson: colors?.contrasts?.red4570,
5353
colorFire: colors?.contrasts?.orange4570,
5454
colorLicorice: colors?.contrasts?.grey125125,
55-
colorAsh: colors?.contrasts?.grey4570
55+
colorAsh: colors?.contrasts?.grey4570,
56+
57+
aiTopGradientColor: colors?.contrasts?.violet4570,
58+
aiBottomGradientColor: colors?.contrasts?.sea4570,
59+
aiFontColor: colors?.contrasts?.white1010
5660
}
5761

5862
return {

0 commit comments

Comments
 (0)