@instructure/ui-avatar 8.39.1-snapshot-2 → 8.40.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.
- package/CHANGELOG.md +1 -9
- package/es/Avatar/__new-tests__/Avatar.test.js +312 -0
- package/lib/Avatar/__new-tests__/Avatar.test.js +315 -0
- package/package.json +16 -13
- package/src/Avatar/__new-tests__/Avatar.test.tsx +285 -0
- package/tsconfig.build.json +3 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Avatar/__new-tests__/Avatar.test.d.ts +2 -0
- package/types/Avatar/__new-tests__/Avatar.test.d.ts.map +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-avatar",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.40.0",
|
|
4
4
|
"description": "An image or letters that represents a user.",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"module": "./es/index.js",
|
|
@@ -24,21 +24,24 @@
|
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@babel/runtime": "^7.22.6",
|
|
27
|
-
"@instructure/console": "8.
|
|
28
|
-
"@instructure/emotion": "8.
|
|
29
|
-
"@instructure/shared-types": "8.
|
|
30
|
-
"@instructure/ui-icons": "8.
|
|
31
|
-
"@instructure/ui-react-utils": "8.
|
|
32
|
-
"@instructure/ui-testable": "8.
|
|
33
|
-
"@instructure/ui-view": "8.
|
|
27
|
+
"@instructure/console": "8.40.0",
|
|
28
|
+
"@instructure/emotion": "8.40.0",
|
|
29
|
+
"@instructure/shared-types": "8.40.0",
|
|
30
|
+
"@instructure/ui-icons": "8.40.0",
|
|
31
|
+
"@instructure/ui-react-utils": "8.40.0",
|
|
32
|
+
"@instructure/ui-testable": "8.40.0",
|
|
33
|
+
"@instructure/ui-view": "8.40.0",
|
|
34
34
|
"prop-types": "^15.8.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@instructure/ui-
|
|
38
|
-
"@instructure/ui-
|
|
39
|
-
"@instructure/ui-
|
|
40
|
-
"@instructure/ui-test-
|
|
41
|
-
"@instructure/ui-
|
|
37
|
+
"@instructure/ui-axe-check": "8.40.0",
|
|
38
|
+
"@instructure/ui-babel-preset": "8.40.0",
|
|
39
|
+
"@instructure/ui-color-utils": "8.40.0",
|
|
40
|
+
"@instructure/ui-test-locator": "8.40.0",
|
|
41
|
+
"@instructure/ui-test-utils": "8.40.0",
|
|
42
|
+
"@instructure/ui-themes": "8.40.0",
|
|
43
|
+
"@testing-library/jest-dom": "^5.17.0",
|
|
44
|
+
"@testing-library/react": "^14.0.0"
|
|
42
45
|
},
|
|
43
46
|
"peerDependencies": {
|
|
44
47
|
"react": ">=16.8 <=18"
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The MIT License (MIT)
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2015 - present Instructure, Inc.
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
* furnished to do so, subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
* copies or substantial portions of the Software.
|
|
15
|
+
*
|
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
* SOFTWARE.
|
|
23
|
+
*/
|
|
24
|
+
import React from 'react'
|
|
25
|
+
import { fireEvent, render, screen } from '@testing-library/react'
|
|
26
|
+
import { runAxeCheck } from '@instructure/ui-axe-check'
|
|
27
|
+
|
|
28
|
+
import '@testing-library/jest-dom/extend-expect'
|
|
29
|
+
import Avatar from '../index'
|
|
30
|
+
import { IconGroupLine } from '@instructure/ui-icons'
|
|
31
|
+
|
|
32
|
+
describe('<Avatar />', () => {
|
|
33
|
+
describe('for a11y', () => {
|
|
34
|
+
it('should be accessible', async () => {
|
|
35
|
+
const { container } = render(<Avatar name="Jessica Jones" />)
|
|
36
|
+
const axeCheck = await runAxeCheck(container)
|
|
37
|
+
expect(axeCheck).toBe(true)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('initials should have aria-hidden=true', async () => {
|
|
41
|
+
render(<Avatar name="Jessica Jones" />)
|
|
42
|
+
const initials = screen.getByText('JJ')
|
|
43
|
+
expect(initials).toHaveAttribute('aria-hidden', 'true')
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
describe('with the default props', () => {
|
|
48
|
+
it('should display as a circle', async () => {
|
|
49
|
+
const { container } = render(<Avatar name="Avatar Name" />)
|
|
50
|
+
const avatarImg = container.querySelector('span[name="Avatar Name"]')
|
|
51
|
+
expect(avatarImg).toHaveAttribute('shape', 'circle')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('should render initials', async () => {
|
|
55
|
+
render(<Avatar name="Avatar Name" />)
|
|
56
|
+
const avatarWithInitials = await screen.findByText('AN')
|
|
57
|
+
expect(avatarWithInitials).toBeVisible()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('should have border and no box-shadow', async () => {
|
|
61
|
+
const { container } = render(<Avatar name="Avatar Name" />)
|
|
62
|
+
const element = container.querySelector('span')
|
|
63
|
+
expect(element).not.toHaveStyle('border-width: 0px')
|
|
64
|
+
const containerStyle = element && getComputedStyle(element)
|
|
65
|
+
expect(containerStyle?.boxShadow).toBe('')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('should display the initials in brand color', async () => {
|
|
69
|
+
render(<Avatar name="Jessica Jones" />)
|
|
70
|
+
const initials = screen.getByText('JJ')
|
|
71
|
+
expect(getComputedStyle(initials).color).toBe('rgb(3, 116, 181)')
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('should return the underlying component', async () => {
|
|
75
|
+
const elementRef = jest.fn()
|
|
76
|
+
const { container } = render(
|
|
77
|
+
<Avatar name="Avatar Name" elementRef={elementRef} />
|
|
78
|
+
)
|
|
79
|
+
expect(elementRef).toHaveBeenCalledWith(container.firstChild)
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
describe('when the renderIcon prop is provided', () => {
|
|
84
|
+
it('should display an svg passed', async () => {
|
|
85
|
+
const SomeIcon = () => (
|
|
86
|
+
<svg>
|
|
87
|
+
<circle cx="25" cy="75" r="20" />
|
|
88
|
+
</svg>
|
|
89
|
+
)
|
|
90
|
+
const { container } = render(
|
|
91
|
+
<Avatar name="avatar name" renderIcon={SomeIcon}>
|
|
92
|
+
hello
|
|
93
|
+
</Avatar>
|
|
94
|
+
)
|
|
95
|
+
const avatarSvg = container.querySelector('svg')
|
|
96
|
+
expect(avatarSvg).toBeInTheDocument()
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('should display an InstUI icon passed', async () => {
|
|
100
|
+
const { container } = render(
|
|
101
|
+
<Avatar name="avatar name" renderIcon={<IconGroupLine />}>
|
|
102
|
+
hello
|
|
103
|
+
</Avatar>
|
|
104
|
+
)
|
|
105
|
+
const avatarSvg = container.querySelector('svg')
|
|
106
|
+
expect(avatarSvg).toBeInTheDocument()
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('should display correctly when an icon renderer is passed', async () => {
|
|
110
|
+
const { container } = render(
|
|
111
|
+
<Avatar name="Jessica Jones" renderIcon={() => <IconGroupLine />}>
|
|
112
|
+
Hello World
|
|
113
|
+
</Avatar>
|
|
114
|
+
)
|
|
115
|
+
const avatarSvg = container.querySelector('svg')
|
|
116
|
+
expect(avatarSvg).toBeInTheDocument()
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
describe('when an image src url is provided', () => {
|
|
121
|
+
// eslint-disable-next-line max-len
|
|
122
|
+
const src =
|
|
123
|
+
'data:image/gif;base64,R0lGODlhFAAUAJEAAP/9/fYQEPytrflWViH5BAAAAAAALAAAAAAUABQAQAJKhI+pGe09lnhBnEETfodatVHNh1BR+ZzH9LAOCYrVYpiAfWWJOxrC/5MASbyZT4d6AUIBlUYGoR1FsAXUuTN5YhxAEYbrpKRkQwEAOw=='
|
|
124
|
+
|
|
125
|
+
it('should display the image url provided', async () => {
|
|
126
|
+
const { container } = render(<Avatar name="avatar name" src={src} />)
|
|
127
|
+
const avatarImg = container.querySelector('img')
|
|
128
|
+
expect(avatarImg).toHaveAttribute('src', src)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it('should display the image even if an icon is provided', async () => {
|
|
132
|
+
const { container } = render(
|
|
133
|
+
<Avatar name="avatar name" src={src} renderIcon={<IconGroupLine />} />
|
|
134
|
+
)
|
|
135
|
+
const avatarImg = container.querySelector('img')
|
|
136
|
+
expect(avatarImg).toHaveAttribute('src', src)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('should call onImageLoaded once the image loads', async () => {
|
|
140
|
+
const onImageLoaded = jest.fn()
|
|
141
|
+
const { container } = render(
|
|
142
|
+
<Avatar name="Avatar Name" onImageLoaded={onImageLoaded} />
|
|
143
|
+
)
|
|
144
|
+
const avatarImg = container.querySelector('img')
|
|
145
|
+
if (avatarImg) {
|
|
146
|
+
fireEvent.load(avatarImg)
|
|
147
|
+
}
|
|
148
|
+
expect(onImageLoaded).toHaveBeenCalled()
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('should have box-shadow instead of border', async () => {
|
|
152
|
+
const { container } = render(<Avatar name="Avatar Name" src={src} />)
|
|
153
|
+
const element = container.querySelector('span')
|
|
154
|
+
const avatarImg = container.querySelector('img')
|
|
155
|
+
if (avatarImg) {
|
|
156
|
+
fireEvent.load(avatarImg)
|
|
157
|
+
}
|
|
158
|
+
expect(element).toHaveStyle('border-width: 0px')
|
|
159
|
+
const containerStyle = element && window.getComputedStyle(element)
|
|
160
|
+
expect(containerStyle?.boxShadow).not.toBe('')
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
describe('when shape is set to "rectangle"', () => {
|
|
165
|
+
it('should display as a rectangle', async () => {
|
|
166
|
+
const { container } = render(
|
|
167
|
+
<Avatar name="Avatar Name" shape="rectangle" />
|
|
168
|
+
)
|
|
169
|
+
const avatarImg = container.querySelector('span[name="Avatar Name"]')
|
|
170
|
+
expect(avatarImg).toHaveAttribute('shape', 'rectangle')
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
describe('when the color is set to "shamrock"', () => {
|
|
175
|
+
it('should display the initials in green (shamrock)', async () => {
|
|
176
|
+
render(<Avatar name="Jessica Jones" color="shamrock" />)
|
|
177
|
+
const initials = screen.getByText('JJ')
|
|
178
|
+
expect(getComputedStyle(initials).color).toBe('rgb(11, 135, 75)')
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
it('should display the icon in green (shamrock)', async () => {
|
|
182
|
+
const { container } = render(
|
|
183
|
+
<Avatar
|
|
184
|
+
name="Jessica Jones"
|
|
185
|
+
renderIcon={<IconGroupLine />}
|
|
186
|
+
color="fire"
|
|
187
|
+
>
|
|
188
|
+
Hello World
|
|
189
|
+
</Avatar>
|
|
190
|
+
)
|
|
191
|
+
const avatarSvg = container.querySelector('svg')
|
|
192
|
+
expect(avatarSvg).toHaveStyle({ fill: '#FC5E13' })
|
|
193
|
+
})
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
describe('when "hasInverseColor" is set', () => {
|
|
197
|
+
describe('with initials', () => {
|
|
198
|
+
it('should display the background in the color', async () => {
|
|
199
|
+
render(<Avatar name="Jessica Jones" color="shamrock" hasInverseColor />)
|
|
200
|
+
const initials = screen.getByText('JJ')
|
|
201
|
+
expect(initials.parentNode).toHaveStyle({
|
|
202
|
+
backgroundColor: 'rgb(11, 135, 75)'
|
|
203
|
+
})
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
it('should display the initials in white', async () => {
|
|
207
|
+
render(<Avatar name="Jessica Jones" color="shamrock" hasInverseColor />)
|
|
208
|
+
const initials = screen.getByText('JJ')
|
|
209
|
+
expect(initials).toHaveStyle({ color: 'rgb(255, 255, 255)' })
|
|
210
|
+
})
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
describe('with icon', () => {
|
|
214
|
+
it('should display the background in the color', async () => {
|
|
215
|
+
const { container } = render(
|
|
216
|
+
<Avatar
|
|
217
|
+
name="Jessica Jones"
|
|
218
|
+
color="shamrock"
|
|
219
|
+
hasInverseColor
|
|
220
|
+
renderIcon={<IconGroupLine />}
|
|
221
|
+
/>
|
|
222
|
+
)
|
|
223
|
+
const element = container.querySelector('span')
|
|
224
|
+
expect(element).toHaveStyle({ backgroundColor: 'rgb(11, 135, 75)' })
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
it('should display the icon in white', async () => {
|
|
228
|
+
const { container } = render(
|
|
229
|
+
<Avatar
|
|
230
|
+
name="Jessica Jones"
|
|
231
|
+
renderIcon={<IconGroupLine />}
|
|
232
|
+
hasInverseColor
|
|
233
|
+
color="fire"
|
|
234
|
+
>
|
|
235
|
+
Hello World
|
|
236
|
+
</Avatar>
|
|
237
|
+
)
|
|
238
|
+
const avatarSvg = container.querySelector('svg')
|
|
239
|
+
expect(avatarSvg).toHaveStyle({ fill: '#FFFFFF' })
|
|
240
|
+
})
|
|
241
|
+
})
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
describe('when the user name has no spaces', () => {
|
|
245
|
+
it('should render a single initial', async () => {
|
|
246
|
+
render(<Avatar name="Jessica" />)
|
|
247
|
+
const initials = screen.getByText('J')
|
|
248
|
+
expect(initials).toBeInTheDocument()
|
|
249
|
+
})
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
describe('when the user name has leading spaces', () => {
|
|
253
|
+
it('should skip them', async () => {
|
|
254
|
+
render(<Avatar name=" Jessica Jones" />)
|
|
255
|
+
const initials = screen.getByText('JJ')
|
|
256
|
+
expect(initials).toBeInTheDocument()
|
|
257
|
+
})
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
describe('when the user name is empty', () => {
|
|
261
|
+
it('should render', async () => {
|
|
262
|
+
const { container } = render(<Avatar name="" />)
|
|
263
|
+
const initials = container.querySelector('[class$="-avatar__initials"]')
|
|
264
|
+
expect(initials).toBeInTheDocument()
|
|
265
|
+
expect(initials).toHaveTextContent('')
|
|
266
|
+
})
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
describe('when alt text is provided', () => {
|
|
270
|
+
it('should render the text as an aria-label attribute', async () => {
|
|
271
|
+
render(<Avatar name="Jessica Jones" alt="This is a test" />)
|
|
272
|
+
const initials = screen.getByText('JJ')
|
|
273
|
+
expect(initials.parentNode).toHaveAttribute(
|
|
274
|
+
'aria-label',
|
|
275
|
+
'This is a test'
|
|
276
|
+
)
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
it('should set the role attribute to img', async () => {
|
|
280
|
+
render(<Avatar name="Jessica Jones" alt="This is a test" />)
|
|
281
|
+
const initials = screen.getByText('JJ')
|
|
282
|
+
expect(initials.parentNode).toHaveAttribute('role', 'img')
|
|
283
|
+
})
|
|
284
|
+
})
|
|
285
|
+
})
|