@moontra/moonui 2.0.8 → 2.0.10
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/package.json +9 -2
- package/src/__tests__/use-intersection-observer.test.tsx +216 -0
- package/src/__tests__/use-local-storage.test.tsx +174 -0
- package/src/__tests__/use-pro-access.test.tsx +183 -0
- package/src/components/ui/__tests__/accordion.test.tsx +571 -0
- package/src/components/ui/__tests__/alert.test.tsx +484 -0
- package/src/components/ui/__tests__/aspect-ratio.test.tsx +492 -0
- package/src/components/ui/__tests__/avatar.test.tsx +382 -0
- package/src/components/ui/__tests__/badge.test.tsx +364 -0
- package/src/components/ui/__tests__/breadcrumb.test.tsx +687 -0
- package/src/components/ui/__tests__/button.test.tsx +91 -0
- package/src/components/ui/__tests__/card.test.tsx +104 -0
- package/src/components/ui/__tests__/checkbox.test.tsx +591 -0
- package/src/components/ui/__tests__/collapsible.test.tsx +592 -0
- package/src/components/ui/__tests__/color-picker.test.tsx +365 -0
- package/src/components/ui/__tests__/command.test.tsx +677 -0
- package/src/components/ui/__tests__/data-table.test.tsx +256 -0
- package/src/components/ui/__tests__/date-picker.test.tsx +320 -0
- package/src/components/ui/__tests__/dialog.test.tsx +764 -0
- package/src/components/ui/__tests__/input.test.tsx +318 -0
- package/src/components/ui/__tests__/label.test.tsx +103 -0
- package/src/components/ui/__tests__/popover.test.tsx +637 -0
- package/src/components/ui/__tests__/progress.test.tsx +382 -0
- package/src/components/ui/__tests__/radio-group.test.tsx +555 -0
- package/src/components/ui/__tests__/select.test.tsx +705 -0
- package/src/components/ui/__tests__/skeleton.test.tsx +253 -0
- package/src/components/ui/__tests__/slider.test.tsx +493 -0
- package/src/components/ui/__tests__/switch.test.tsx +372 -0
- package/src/components/ui/__tests__/table.test.tsx +824 -0
- package/src/components/ui/__tests__/tabs.test.tsx +887 -0
- package/src/components/ui/__tests__/toast.test.tsx +458 -0
- package/src/components/ui/__tests__/tooltip.test.tsx +583 -0
- package/src/components/ui/accordion.tsx +63 -0
- package/src/components/ui/alert.tsx +130 -0
- package/src/components/ui/aspect-ratio.tsx +72 -0
- package/src/components/ui/avatar.tsx +135 -0
- package/src/components/ui/badge.tsx +225 -0
- package/src/components/ui/breadcrumb.tsx +207 -0
- package/src/components/ui/button.stories.tsx +162 -0
- package/src/components/ui/button.tsx +221 -0
- package/src/components/ui/calendar.tsx +262 -0
- package/src/components/ui/card.stories.tsx +208 -0
- package/src/components/ui/card.tsx +141 -0
- package/src/components/ui/checkbox.tsx +256 -0
- package/src/components/ui/collapsible.tsx +129 -0
- package/src/components/ui/color-picker.tsx +664 -0
- package/src/components/ui/command.tsx +218 -0
- package/src/components/ui/data-table.stories.tsx +509 -0
- package/src/components/ui/data-table.tsx +623 -0
- package/src/components/ui/date-picker.stories.tsx +321 -0
- package/src/components/ui/date-picker.tsx +603 -0
- package/src/components/ui/dialog.tsx +332 -0
- package/src/components/ui/dropdown-menu.tsx +200 -0
- package/src/components/ui/file-upload.tsx +400 -0
- package/src/components/ui/github-stars.tsx +201 -0
- package/src/components/ui/index.ts +12 -0
- package/src/components/ui/input.stories.tsx +255 -0
- package/src/components/ui/input.tsx +219 -0
- package/src/components/ui/label.tsx +26 -0
- package/src/components/ui/locked-component.tsx +215 -0
- package/src/components/ui/moon-logo.tsx +97 -0
- package/src/components/ui/pagination.tsx +116 -0
- package/src/components/ui/popover.tsx +183 -0
- package/src/components/ui/progress.tsx +182 -0
- package/src/components/ui/radio-group.tsx +243 -0
- package/src/components/ui/select.tsx +273 -0
- package/src/components/ui/separator.tsx +140 -0
- package/src/components/ui/simple-editor.tsx +652 -0
- package/src/components/ui/skeleton.tsx +351 -0
- package/src/components/ui/slider.tsx +351 -0
- package/src/components/ui/switch.tsx +83 -0
- package/src/components/ui/table.tsx +322 -0
- package/src/components/ui/tabs.tsx +195 -0
- package/src/components/ui/textarea.tsx +46 -0
- package/src/components/ui/toast.tsx +313 -0
- package/src/components/ui/toggle.tsx +47 -0
- package/src/components/ui/tooltip.tsx +152 -0
- package/src/docs/theme-system.md +1194 -0
- package/src/index.tsx +39 -0
- package/src/lib/micro-interactions.ts +255 -0
- package/src/lib/theme.tsx +398 -0
- package/src/lib/utils.ts +69 -0
- package/src/styles/design-system.css +365 -0
- package/src/styles/index.css +4 -0
- package/src/styles/tailwind.css +6 -0
- package/src/styles/tokens.css +453 -0
- package/src/use-intersection-observer.tsx +154 -0
- package/src/use-local-storage.tsx +71 -0
- package/src/use-paddle.ts +138 -0
- package/src/use-performance-optimizer.ts +379 -0
- package/src/use-pro-access.ts +141 -0
- package/src/use-scroll-animation.ts +221 -0
- package/src/use-subscription.ts +37 -0
- package/src/use-toast.ts +32 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import '@testing-library/jest-dom'
|
|
4
|
+
import { Avatar, AvatarImage, AvatarFallback, AvatarGroup } from '../avatar'
|
|
5
|
+
|
|
6
|
+
describe('Avatar Component', () => {
|
|
7
|
+
describe('Avatar', () => {
|
|
8
|
+
it('renders correctly with default props', () => {
|
|
9
|
+
render(
|
|
10
|
+
<Avatar>
|
|
11
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
12
|
+
</Avatar>
|
|
13
|
+
)
|
|
14
|
+
const avatar = screen.getByText('JD').parentElement
|
|
15
|
+
expect(avatar).toBeInTheDocument()
|
|
16
|
+
expect(avatar).toHaveClass('relative')
|
|
17
|
+
expect(avatar).toHaveClass('flex')
|
|
18
|
+
expect(avatar).toHaveClass('shrink-0')
|
|
19
|
+
expect(avatar).toHaveClass('overflow-hidden')
|
|
20
|
+
expect(avatar).toHaveClass('h-10')
|
|
21
|
+
expect(avatar).toHaveClass('w-10')
|
|
22
|
+
expect(avatar).toHaveClass('rounded-full')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('applies custom className', () => {
|
|
26
|
+
render(
|
|
27
|
+
<Avatar className="custom-avatar">
|
|
28
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
29
|
+
</Avatar>
|
|
30
|
+
)
|
|
31
|
+
const avatar = screen.getByText('JD').parentElement
|
|
32
|
+
expect(avatar).toHaveClass('custom-avatar')
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('forwards ref correctly', () => {
|
|
36
|
+
const ref = React.createRef<HTMLSpanElement>()
|
|
37
|
+
render(
|
|
38
|
+
<Avatar ref={ref}>
|
|
39
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
40
|
+
</Avatar>
|
|
41
|
+
)
|
|
42
|
+
expect(ref.current).toBeInstanceOf(HTMLSpanElement)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
describe('Sizes', () => {
|
|
46
|
+
it('renders xs size correctly', () => {
|
|
47
|
+
render(
|
|
48
|
+
<Avatar size="xs">
|
|
49
|
+
<AvatarFallback>XS</AvatarFallback>
|
|
50
|
+
</Avatar>
|
|
51
|
+
)
|
|
52
|
+
const avatar = screen.getByText('XS').parentElement
|
|
53
|
+
expect(avatar).toHaveClass('h-6')
|
|
54
|
+
expect(avatar).toHaveClass('w-6')
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('renders sm size correctly', () => {
|
|
58
|
+
render(
|
|
59
|
+
<Avatar size="sm">
|
|
60
|
+
<AvatarFallback>SM</AvatarFallback>
|
|
61
|
+
</Avatar>
|
|
62
|
+
)
|
|
63
|
+
const avatar = screen.getByText('SM').parentElement
|
|
64
|
+
expect(avatar).toHaveClass('h-8')
|
|
65
|
+
expect(avatar).toHaveClass('w-8')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('renders md size correctly', () => {
|
|
69
|
+
render(
|
|
70
|
+
<Avatar size="md">
|
|
71
|
+
<AvatarFallback>MD</AvatarFallback>
|
|
72
|
+
</Avatar>
|
|
73
|
+
)
|
|
74
|
+
const avatar = screen.getByText('MD').parentElement
|
|
75
|
+
expect(avatar).toHaveClass('h-10')
|
|
76
|
+
expect(avatar).toHaveClass('w-10')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('renders lg size correctly', () => {
|
|
80
|
+
render(
|
|
81
|
+
<Avatar size="lg">
|
|
82
|
+
<AvatarFallback>LG</AvatarFallback>
|
|
83
|
+
</Avatar>
|
|
84
|
+
)
|
|
85
|
+
const avatar = screen.getByText('LG').parentElement
|
|
86
|
+
expect(avatar).toHaveClass('h-12')
|
|
87
|
+
expect(avatar).toHaveClass('w-12')
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('renders xl size correctly', () => {
|
|
91
|
+
render(
|
|
92
|
+
<Avatar size="xl">
|
|
93
|
+
<AvatarFallback>XL</AvatarFallback>
|
|
94
|
+
</Avatar>
|
|
95
|
+
)
|
|
96
|
+
const avatar = screen.getByText('XL').parentElement
|
|
97
|
+
expect(avatar).toHaveClass('h-16')
|
|
98
|
+
expect(avatar).toHaveClass('w-16')
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('renders 2xl size correctly', () => {
|
|
102
|
+
render(
|
|
103
|
+
<Avatar size="2xl">
|
|
104
|
+
<AvatarFallback>2XL</AvatarFallback>
|
|
105
|
+
</Avatar>
|
|
106
|
+
)
|
|
107
|
+
const avatar = screen.getByText('2XL').parentElement
|
|
108
|
+
expect(avatar).toHaveClass('h-20')
|
|
109
|
+
expect(avatar).toHaveClass('w-20')
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
describe('Radius', () => {
|
|
114
|
+
it('renders default radius correctly', () => {
|
|
115
|
+
render(
|
|
116
|
+
<Avatar radius="default">
|
|
117
|
+
<AvatarFallback>DF</AvatarFallback>
|
|
118
|
+
</Avatar>
|
|
119
|
+
)
|
|
120
|
+
const avatar = screen.getByText('DF').parentElement
|
|
121
|
+
expect(avatar).toHaveClass('rounded-full')
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('renders sm radius correctly', () => {
|
|
125
|
+
render(
|
|
126
|
+
<Avatar radius="sm">
|
|
127
|
+
<AvatarFallback>SM</AvatarFallback>
|
|
128
|
+
</Avatar>
|
|
129
|
+
)
|
|
130
|
+
const avatar = screen.getByText('SM').parentElement
|
|
131
|
+
expect(avatar).toHaveClass('rounded-md')
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it('renders lg radius correctly', () => {
|
|
135
|
+
render(
|
|
136
|
+
<Avatar radius="lg">
|
|
137
|
+
<AvatarFallback>LG</AvatarFallback>
|
|
138
|
+
</Avatar>
|
|
139
|
+
)
|
|
140
|
+
const avatar = screen.getByText('LG').parentElement
|
|
141
|
+
expect(avatar).toHaveClass('rounded-xl')
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('renders full radius correctly', () => {
|
|
145
|
+
render(
|
|
146
|
+
<Avatar radius="full">
|
|
147
|
+
<AvatarFallback>FL</AvatarFallback>
|
|
148
|
+
</Avatar>
|
|
149
|
+
)
|
|
150
|
+
const avatar = screen.getByText('FL').parentElement
|
|
151
|
+
expect(avatar).toHaveClass('rounded-full')
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
it('renders none radius correctly', () => {
|
|
155
|
+
render(
|
|
156
|
+
<Avatar radius="none">
|
|
157
|
+
<AvatarFallback>NO</AvatarFallback>
|
|
158
|
+
</Avatar>
|
|
159
|
+
)
|
|
160
|
+
const avatar = screen.getByText('NO').parentElement
|
|
161
|
+
expect(avatar).toHaveClass('rounded-none')
|
|
162
|
+
})
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
describe('Variants', () => {
|
|
166
|
+
it('renders default variant correctly', () => {
|
|
167
|
+
render(
|
|
168
|
+
<Avatar variant="default">
|
|
169
|
+
<AvatarFallback>DF</AvatarFallback>
|
|
170
|
+
</Avatar>
|
|
171
|
+
)
|
|
172
|
+
const avatar = screen.getByText('DF').parentElement
|
|
173
|
+
expect(avatar).toBeInTheDocument()
|
|
174
|
+
// Default variant has no additional classes
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it('renders ring variant correctly', () => {
|
|
178
|
+
render(
|
|
179
|
+
<Avatar variant="ring">
|
|
180
|
+
<AvatarFallback>RG</AvatarFallback>
|
|
181
|
+
</Avatar>
|
|
182
|
+
)
|
|
183
|
+
const avatar = screen.getByText('RG').parentElement
|
|
184
|
+
expect(avatar).toHaveClass('ring-2')
|
|
185
|
+
expect(avatar).toHaveClass('ring-gray-300')
|
|
186
|
+
expect(avatar).toHaveClass('dark:ring-gray-600')
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
it('renders ringOffset variant correctly', () => {
|
|
190
|
+
render(
|
|
191
|
+
<Avatar variant="ringOffset">
|
|
192
|
+
<AvatarFallback>RO</AvatarFallback>
|
|
193
|
+
</Avatar>
|
|
194
|
+
)
|
|
195
|
+
const avatar = screen.getByText('RO').parentElement
|
|
196
|
+
expect(avatar).toHaveClass('ring-2')
|
|
197
|
+
expect(avatar).toHaveClass('ring-gray-300')
|
|
198
|
+
expect(avatar).toHaveClass('dark:ring-gray-600')
|
|
199
|
+
expect(avatar).toHaveClass('ring-offset-2')
|
|
200
|
+
expect(avatar).toHaveClass('ring-offset-background')
|
|
201
|
+
expect(avatar).toHaveClass('dark:ring-offset-gray-950')
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
it('renders border variant correctly', () => {
|
|
205
|
+
render(
|
|
206
|
+
<Avatar variant="border">
|
|
207
|
+
<AvatarFallback>BD</AvatarFallback>
|
|
208
|
+
</Avatar>
|
|
209
|
+
)
|
|
210
|
+
const avatar = screen.getByText('BD').parentElement
|
|
211
|
+
expect(avatar).toHaveClass('border-2')
|
|
212
|
+
expect(avatar).toHaveClass('border-gray-200')
|
|
213
|
+
expect(avatar).toHaveClass('dark:border-gray-800')
|
|
214
|
+
})
|
|
215
|
+
})
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
describe('AvatarImage', () => {
|
|
219
|
+
it('renders image correctly', () => {
|
|
220
|
+
render(
|
|
221
|
+
<Avatar>
|
|
222
|
+
<AvatarImage src="/test-image.jpg" alt="Test User" />
|
|
223
|
+
<AvatarFallback>TU</AvatarFallback>
|
|
224
|
+
</Avatar>
|
|
225
|
+
)
|
|
226
|
+
// AvatarImage falls back to AvatarFallback when image fails to load in test environment
|
|
227
|
+
const fallback = screen.getByText('TU')
|
|
228
|
+
expect(fallback).toBeInTheDocument()
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
it('applies custom className to image', () => {
|
|
232
|
+
render(
|
|
233
|
+
<Avatar>
|
|
234
|
+
<AvatarImage src="/test.jpg" className="custom-image" />
|
|
235
|
+
<AvatarFallback>TU</AvatarFallback>
|
|
236
|
+
</Avatar>
|
|
237
|
+
)
|
|
238
|
+
// AvatarImage falls back to AvatarFallback when image fails to load in test environment
|
|
239
|
+
const fallback = screen.getByText('TU')
|
|
240
|
+
expect(fallback).toBeInTheDocument()
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
it('forwards ref correctly', () => {
|
|
244
|
+
const ref = React.createRef<HTMLImageElement>()
|
|
245
|
+
render(
|
|
246
|
+
<Avatar>
|
|
247
|
+
<AvatarImage ref={ref} src="/test.jpg" />
|
|
248
|
+
<AvatarFallback>TU</AvatarFallback>
|
|
249
|
+
</Avatar>
|
|
250
|
+
)
|
|
251
|
+
// In test environment, ref may be null due to image loading behavior
|
|
252
|
+
expect(ref.current).toBeDefined()
|
|
253
|
+
})
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
describe('AvatarFallback', () => {
|
|
257
|
+
it('renders fallback correctly', () => {
|
|
258
|
+
render(
|
|
259
|
+
<Avatar>
|
|
260
|
+
<AvatarFallback>FB</AvatarFallback>
|
|
261
|
+
</Avatar>
|
|
262
|
+
)
|
|
263
|
+
const fallback = screen.getByText('FB')
|
|
264
|
+
expect(fallback).toBeInTheDocument()
|
|
265
|
+
expect(fallback).toHaveClass('flex')
|
|
266
|
+
expect(fallback).toHaveClass('h-full')
|
|
267
|
+
expect(fallback).toHaveClass('w-full')
|
|
268
|
+
expect(fallback).toHaveClass('items-center')
|
|
269
|
+
expect(fallback).toHaveClass('justify-center')
|
|
270
|
+
expect(fallback).toHaveClass('bg-muted')
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
it('applies custom className to fallback', () => {
|
|
274
|
+
render(
|
|
275
|
+
<Avatar>
|
|
276
|
+
<AvatarFallback className="custom-fallback">FB</AvatarFallback>
|
|
277
|
+
</Avatar>
|
|
278
|
+
)
|
|
279
|
+
const fallback = screen.getByText('FB')
|
|
280
|
+
expect(fallback).toHaveClass('custom-fallback')
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
it('forwards ref correctly', () => {
|
|
284
|
+
const ref = React.createRef<HTMLSpanElement>()
|
|
285
|
+
render(
|
|
286
|
+
<Avatar>
|
|
287
|
+
<AvatarFallback ref={ref}>FB</AvatarFallback>
|
|
288
|
+
</Avatar>
|
|
289
|
+
)
|
|
290
|
+
expect(ref.current).toBeInstanceOf(HTMLSpanElement)
|
|
291
|
+
})
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
describe('AvatarGroup', () => {
|
|
295
|
+
const mockAvatars = [
|
|
296
|
+
<Avatar key="1"><AvatarFallback>A1</AvatarFallback></Avatar>,
|
|
297
|
+
<Avatar key="2"><AvatarFallback>A2</AvatarFallback></Avatar>,
|
|
298
|
+
<Avatar key="3"><AvatarFallback>A3</AvatarFallback></Avatar>,
|
|
299
|
+
<Avatar key="4"><AvatarFallback>A4</AvatarFallback></Avatar>,
|
|
300
|
+
<Avatar key="5"><AvatarFallback>A5</AvatarFallback></Avatar>,
|
|
301
|
+
]
|
|
302
|
+
|
|
303
|
+
it('renders all avatars when no limit is set', () => {
|
|
304
|
+
render(<AvatarGroup avatars={mockAvatars} />)
|
|
305
|
+
expect(screen.getByText('A1')).toBeInTheDocument()
|
|
306
|
+
expect(screen.getByText('A2')).toBeInTheDocument()
|
|
307
|
+
expect(screen.getByText('A3')).toBeInTheDocument()
|
|
308
|
+
expect(screen.getByText('A4')).toBeInTheDocument()
|
|
309
|
+
expect(screen.getByText('A5')).toBeInTheDocument()
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
it('limits avatars when limit is set', () => {
|
|
313
|
+
render(<AvatarGroup avatars={mockAvatars} limit={3} />)
|
|
314
|
+
expect(screen.getByText('A1')).toBeInTheDocument()
|
|
315
|
+
expect(screen.getByText('A2')).toBeInTheDocument()
|
|
316
|
+
expect(screen.getByText('A3')).toBeInTheDocument()
|
|
317
|
+
expect(screen.queryByText('A4')).not.toBeInTheDocument()
|
|
318
|
+
expect(screen.queryByText('A5')).not.toBeInTheDocument()
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
it('shows remaining count when limit is exceeded', () => {
|
|
322
|
+
render(<AvatarGroup avatars={mockAvatars} limit={3} />)
|
|
323
|
+
expect(screen.getByText('+2')).toBeInTheDocument()
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
it('applies custom className', () => {
|
|
327
|
+
render(<AvatarGroup avatars={mockAvatars} className="custom-group" />)
|
|
328
|
+
const group = screen.getByText('A1').closest('.custom-group')
|
|
329
|
+
expect(group).toBeInTheDocument()
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
it('forwards ref correctly', () => {
|
|
333
|
+
const ref = React.createRef<HTMLDivElement>()
|
|
334
|
+
render(<AvatarGroup ref={ref} avatars={mockAvatars} />)
|
|
335
|
+
expect(ref.current).toBeInstanceOf(HTMLDivElement)
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
it('applies custom overlap offset', () => {
|
|
339
|
+
render(<AvatarGroup avatars={mockAvatars} overlapOffset={-12} />)
|
|
340
|
+
// This test verifies the component renders without error with custom offset
|
|
341
|
+
expect(screen.getByText('A1')).toBeInTheDocument()
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
it('handles empty avatars array', () => {
|
|
345
|
+
render(<AvatarGroup avatars={[]} data-testid="avatar-group" />)
|
|
346
|
+
const group = screen.getByTestId('avatar-group')
|
|
347
|
+
expect(group).toBeInTheDocument()
|
|
348
|
+
expect(group).toHaveClass('flex')
|
|
349
|
+
expect(group).toHaveClass('items-center')
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
it('handles single avatar', () => {
|
|
353
|
+
const singleAvatar = [<Avatar key="1"><AvatarFallback>SA</AvatarFallback></Avatar>]
|
|
354
|
+
render(<AvatarGroup avatars={singleAvatar} />)
|
|
355
|
+
expect(screen.getByText('SA')).toBeInTheDocument()
|
|
356
|
+
expect(screen.queryByText('+')).not.toBeInTheDocument()
|
|
357
|
+
})
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
describe('Complex Combinations', () => {
|
|
361
|
+
it('renders avatar with image and fallback', () => {
|
|
362
|
+
render(
|
|
363
|
+
<Avatar size="lg" variant="ring" radius="sm">
|
|
364
|
+
<AvatarImage src="/test.jpg" alt="Test" />
|
|
365
|
+
<AvatarFallback>TU</AvatarFallback>
|
|
366
|
+
</Avatar>
|
|
367
|
+
)
|
|
368
|
+
const avatar = screen.getByText('TU').parentElement
|
|
369
|
+
expect(avatar).toHaveClass('h-12')
|
|
370
|
+
expect(avatar).toHaveClass('w-12')
|
|
371
|
+
expect(avatar).toHaveClass('ring-2')
|
|
372
|
+
expect(avatar).toHaveClass('rounded-md')
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
it('maintains displayName for all components', () => {
|
|
376
|
+
expect(Avatar.displayName).toBeDefined()
|
|
377
|
+
expect(AvatarImage.displayName).toBeDefined()
|
|
378
|
+
expect(AvatarFallback.displayName).toBeDefined()
|
|
379
|
+
expect(AvatarGroup.displayName).toBe('AvatarGroup')
|
|
380
|
+
})
|
|
381
|
+
})
|
|
382
|
+
})
|