@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,492 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import '@testing-library/jest-dom'
|
|
4
|
+
import { AspectRatio } from '../aspect-ratio'
|
|
5
|
+
|
|
6
|
+
describe('AspectRatio Component', () => {
|
|
7
|
+
describe('Basic Rendering', () => {
|
|
8
|
+
it('renders correctly with default props', () => {
|
|
9
|
+
render(
|
|
10
|
+
<AspectRatio data-testid="aspect-ratio">
|
|
11
|
+
<div>Test Content</div>
|
|
12
|
+
</AspectRatio>
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
16
|
+
expect(aspectRatio).toBeInTheDocument()
|
|
17
|
+
expect(screen.getByText('Test Content')).toBeInTheDocument()
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('applies custom className', () => {
|
|
21
|
+
render(
|
|
22
|
+
<AspectRatio className="custom-aspect-ratio" data-testid="aspect-ratio">
|
|
23
|
+
<div>Content</div>
|
|
24
|
+
</AspectRatio>
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
28
|
+
expect(aspectRatio).toHaveClass('custom-aspect-ratio')
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('forwards ref correctly', () => {
|
|
32
|
+
const ref = React.createRef<HTMLDivElement>()
|
|
33
|
+
render(
|
|
34
|
+
<AspectRatio ref={ref} data-testid="aspect-ratio">
|
|
35
|
+
<div>Content</div>
|
|
36
|
+
</AspectRatio>
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
expect(ref.current).toBeInstanceOf(HTMLDivElement)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('maintains displayName', () => {
|
|
43
|
+
expect(AspectRatio.displayName).toBe('AspectRatio')
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
describe('Variants', () => {
|
|
48
|
+
it('renders default variant correctly', () => {
|
|
49
|
+
render(
|
|
50
|
+
<AspectRatio variant="default" data-testid="aspect-ratio">
|
|
51
|
+
<div>Content</div>
|
|
52
|
+
</AspectRatio>
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
56
|
+
expect(aspectRatio).toHaveClass('rounded-md')
|
|
57
|
+
expect(aspectRatio).toHaveClass('bg-muted/10')
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('renders ghost variant correctly', () => {
|
|
61
|
+
render(
|
|
62
|
+
<AspectRatio variant="ghost" data-testid="aspect-ratio">
|
|
63
|
+
<div>Content</div>
|
|
64
|
+
</AspectRatio>
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
68
|
+
expect(aspectRatio).toHaveClass('bg-transparent')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('renders outline variant correctly', () => {
|
|
72
|
+
render(
|
|
73
|
+
<AspectRatio variant="outline" data-testid="aspect-ratio">
|
|
74
|
+
<div>Content</div>
|
|
75
|
+
</AspectRatio>
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
79
|
+
expect(aspectRatio).toHaveClass('rounded-md')
|
|
80
|
+
expect(aspectRatio).toHaveClass('border')
|
|
81
|
+
expect(aspectRatio).toHaveClass('border-border')
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('renders card variant correctly', () => {
|
|
85
|
+
render(
|
|
86
|
+
<AspectRatio variant="card" data-testid="aspect-ratio">
|
|
87
|
+
<div>Content</div>
|
|
88
|
+
</AspectRatio>
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
92
|
+
expect(aspectRatio).toHaveClass('rounded-md')
|
|
93
|
+
expect(aspectRatio).toHaveClass('bg-card')
|
|
94
|
+
expect(aspectRatio).toHaveClass('shadow-sm')
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('uses default variant as default', () => {
|
|
98
|
+
render(
|
|
99
|
+
<AspectRatio data-testid="aspect-ratio">
|
|
100
|
+
<div>Content</div>
|
|
101
|
+
</AspectRatio>
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
105
|
+
expect(aspectRatio).toHaveClass('rounded-md')
|
|
106
|
+
expect(aspectRatio).toHaveClass('bg-muted/10')
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
describe('Radius', () => {
|
|
111
|
+
it('renders none radius correctly', () => {
|
|
112
|
+
render(
|
|
113
|
+
<AspectRatio radius="none" data-testid="aspect-ratio">
|
|
114
|
+
<div>Content</div>
|
|
115
|
+
</AspectRatio>
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
119
|
+
expect(aspectRatio).toHaveClass('rounded-none')
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('renders sm radius correctly', () => {
|
|
123
|
+
render(
|
|
124
|
+
<AspectRatio radius="sm" data-testid="aspect-ratio">
|
|
125
|
+
<div>Content</div>
|
|
126
|
+
</AspectRatio>
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
130
|
+
expect(aspectRatio).toHaveClass('rounded-sm')
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('renders md radius correctly', () => {
|
|
134
|
+
render(
|
|
135
|
+
<AspectRatio radius="md" data-testid="aspect-ratio">
|
|
136
|
+
<div>Content</div>
|
|
137
|
+
</AspectRatio>
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
141
|
+
expect(aspectRatio).toHaveClass('rounded-md')
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('renders lg radius correctly', () => {
|
|
145
|
+
render(
|
|
146
|
+
<AspectRatio radius="lg" data-testid="aspect-ratio">
|
|
147
|
+
<div>Content</div>
|
|
148
|
+
</AspectRatio>
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
152
|
+
expect(aspectRatio).toHaveClass('rounded-lg')
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
it('renders full radius correctly', () => {
|
|
156
|
+
render(
|
|
157
|
+
<AspectRatio radius="full" data-testid="aspect-ratio">
|
|
158
|
+
<div>Content</div>
|
|
159
|
+
</AspectRatio>
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
163
|
+
expect(aspectRatio).toHaveClass('rounded-full')
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
it('radius overrides variant radius', () => {
|
|
167
|
+
render(
|
|
168
|
+
<AspectRatio variant="default" radius="lg" data-testid="aspect-ratio">
|
|
169
|
+
<div>Content</div>
|
|
170
|
+
</AspectRatio>
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
174
|
+
expect(aspectRatio).toHaveClass('rounded-lg')
|
|
175
|
+
expect(aspectRatio).not.toHaveClass('rounded-md')
|
|
176
|
+
})
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
describe('Ratio Calculations', () => {
|
|
180
|
+
it('applies default ratio (16/9)', () => {
|
|
181
|
+
render(
|
|
182
|
+
<AspectRatio data-testid="aspect-ratio">
|
|
183
|
+
<div>Content</div>
|
|
184
|
+
</AspectRatio>
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
188
|
+
const expectedPadding = `${(1 / (16 / 9)) * 100}%`
|
|
189
|
+
expect(aspectRatio).toHaveStyle(`padding-bottom: ${expectedPadding}`)
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it('applies custom ratio (4/3)', () => {
|
|
193
|
+
render(
|
|
194
|
+
<AspectRatio ratio={4 / 3} data-testid="aspect-ratio">
|
|
195
|
+
<div>Content</div>
|
|
196
|
+
</AspectRatio>
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
200
|
+
const expectedPadding = `${(1 / (4 / 3)) * 100}%`
|
|
201
|
+
expect(aspectRatio).toHaveStyle(`padding-bottom: ${expectedPadding}`)
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
it('applies square ratio (1/1)', () => {
|
|
205
|
+
render(
|
|
206
|
+
<AspectRatio ratio={1} data-testid="aspect-ratio">
|
|
207
|
+
<div>Content</div>
|
|
208
|
+
</AspectRatio>
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
212
|
+
expect(aspectRatio).toHaveStyle('padding-bottom: 100%')
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
it('applies wide ratio (21/9)', () => {
|
|
216
|
+
render(
|
|
217
|
+
<AspectRatio ratio={21 / 9} data-testid="aspect-ratio">
|
|
218
|
+
<div>Content</div>
|
|
219
|
+
</AspectRatio>
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
223
|
+
const expectedPadding = `${(1 / (21 / 9)) * 100}%`
|
|
224
|
+
expect(aspectRatio).toHaveStyle(`padding-bottom: ${expectedPadding}`)
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
it('applies portrait ratio (9/16)', () => {
|
|
228
|
+
render(
|
|
229
|
+
<AspectRatio ratio={9 / 16} data-testid="aspect-ratio">
|
|
230
|
+
<div>Content</div>
|
|
231
|
+
</AspectRatio>
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
235
|
+
const expectedPadding = `${(1 / (9 / 16)) * 100}%`
|
|
236
|
+
expect(aspectRatio).toHaveStyle(`padding-bottom: ${expectedPadding}`)
|
|
237
|
+
})
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
describe('Styling and Layout', () => {
|
|
241
|
+
it('has correct base styling', () => {
|
|
242
|
+
render(
|
|
243
|
+
<AspectRatio data-testid="aspect-ratio">
|
|
244
|
+
<div>Content</div>
|
|
245
|
+
</AspectRatio>
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
249
|
+
expect(aspectRatio).toHaveClass('relative')
|
|
250
|
+
expect(aspectRatio).toHaveClass('overflow-hidden')
|
|
251
|
+
expect(aspectRatio).toHaveStyle('position: relative')
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
it('renders content wrapper with correct positioning', () => {
|
|
255
|
+
render(
|
|
256
|
+
<AspectRatio data-testid="aspect-ratio">
|
|
257
|
+
<div data-testid="content">Content</div>
|
|
258
|
+
</AspectRatio>
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
262
|
+
const contentWrapper = aspectRatio.querySelector('div')
|
|
263
|
+
expect(contentWrapper).toHaveClass('absolute')
|
|
264
|
+
expect(contentWrapper).toHaveClass('inset-0')
|
|
265
|
+
expect(screen.getByTestId('content')).toBeInTheDocument()
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
it('applies custom style prop', () => {
|
|
269
|
+
render(
|
|
270
|
+
<AspectRatio style={{ backgroundColor: 'red' }} data-testid="aspect-ratio">
|
|
271
|
+
<div>Content</div>
|
|
272
|
+
</AspectRatio>
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
276
|
+
expect(aspectRatio).toHaveStyle('background-color: rgb(255, 0, 0)')
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
it('merges custom style with ratio style', () => {
|
|
280
|
+
render(
|
|
281
|
+
<AspectRatio
|
|
282
|
+
ratio={2}
|
|
283
|
+
style={{ backgroundColor: 'blue', border: '1px solid red' }}
|
|
284
|
+
data-testid="aspect-ratio"
|
|
285
|
+
>
|
|
286
|
+
<div>Content</div>
|
|
287
|
+
</AspectRatio>
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
291
|
+
expect(aspectRatio).toHaveStyle('background-color: rgb(0, 0, 255)')
|
|
292
|
+
expect(aspectRatio).toHaveStyle('border: 1px solid red')
|
|
293
|
+
expect(aspectRatio).toHaveStyle('padding-bottom: 50%')
|
|
294
|
+
})
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
describe('Content Rendering', () => {
|
|
298
|
+
it('renders single child correctly', () => {
|
|
299
|
+
render(
|
|
300
|
+
<AspectRatio data-testid="aspect-ratio">
|
|
301
|
+
<img src="test.jpg" alt="Test" />
|
|
302
|
+
</AspectRatio>
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
const image = screen.getByAltText('Test')
|
|
306
|
+
expect(image).toBeInTheDocument()
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
it('renders multiple children correctly', () => {
|
|
310
|
+
render(
|
|
311
|
+
<AspectRatio data-testid="aspect-ratio">
|
|
312
|
+
<div>Child 1</div>
|
|
313
|
+
<div>Child 2</div>
|
|
314
|
+
<span>Child 3</span>
|
|
315
|
+
</AspectRatio>
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
expect(screen.getByText('Child 1')).toBeInTheDocument()
|
|
319
|
+
expect(screen.getByText('Child 2')).toBeInTheDocument()
|
|
320
|
+
expect(screen.getByText('Child 3')).toBeInTheDocument()
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
it('renders complex nested content', () => {
|
|
324
|
+
render(
|
|
325
|
+
<AspectRatio data-testid="aspect-ratio">
|
|
326
|
+
<div>
|
|
327
|
+
<h2>Title</h2>
|
|
328
|
+
<p>Description</p>
|
|
329
|
+
<button>Action</button>
|
|
330
|
+
</div>
|
|
331
|
+
</AspectRatio>
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
expect(screen.getByText('Title')).toBeInTheDocument()
|
|
335
|
+
expect(screen.getByText('Description')).toBeInTheDocument()
|
|
336
|
+
expect(screen.getByText('Action')).toBeInTheDocument()
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
it('handles empty content gracefully', () => {
|
|
340
|
+
render(<AspectRatio data-testid="aspect-ratio" />)
|
|
341
|
+
|
|
342
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
343
|
+
expect(aspectRatio).toBeInTheDocument()
|
|
344
|
+
|
|
345
|
+
const contentWrapper = aspectRatio.querySelector('div')
|
|
346
|
+
expect(contentWrapper).toBeInTheDocument()
|
|
347
|
+
expect(contentWrapper).toBeEmptyDOMElement()
|
|
348
|
+
})
|
|
349
|
+
})
|
|
350
|
+
|
|
351
|
+
describe('Complex Combinations', () => {
|
|
352
|
+
it('renders with all props correctly', () => {
|
|
353
|
+
render(
|
|
354
|
+
<AspectRatio
|
|
355
|
+
variant="card"
|
|
356
|
+
radius="lg"
|
|
357
|
+
ratio={4 / 3}
|
|
358
|
+
className="custom-class"
|
|
359
|
+
style={{ border: '2px solid blue' }}
|
|
360
|
+
data-testid="aspect-ratio"
|
|
361
|
+
>
|
|
362
|
+
<div>Complex Content</div>
|
|
363
|
+
</AspectRatio>
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
367
|
+
expect(aspectRatio).toHaveClass('bg-card')
|
|
368
|
+
expect(aspectRatio).toHaveClass('shadow-sm')
|
|
369
|
+
expect(aspectRatio).toHaveClass('rounded-lg')
|
|
370
|
+
expect(aspectRatio).toHaveClass('custom-class')
|
|
371
|
+
expect(aspectRatio).toHaveStyle('border: 2px solid blue')
|
|
372
|
+
expect(aspectRatio).toHaveStyle('padding-bottom: 75%')
|
|
373
|
+
expect(screen.getByText('Complex Content')).toBeInTheDocument()
|
|
374
|
+
})
|
|
375
|
+
|
|
376
|
+
it('works with image content', () => {
|
|
377
|
+
render(
|
|
378
|
+
<AspectRatio variant="outline" ratio={16 / 9} data-testid="aspect-ratio">
|
|
379
|
+
<img
|
|
380
|
+
src="https://example.com/image.jpg"
|
|
381
|
+
alt="Test Image"
|
|
382
|
+
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
|
383
|
+
/>
|
|
384
|
+
</AspectRatio>
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
388
|
+
expect(aspectRatio).toHaveClass('border')
|
|
389
|
+
expect(aspectRatio).toHaveStyle('padding-bottom: 56.25%')
|
|
390
|
+
|
|
391
|
+
const image = screen.getByAltText('Test Image')
|
|
392
|
+
expect(image).toHaveStyle('width: 100%')
|
|
393
|
+
expect(image).toHaveStyle('height: 100%')
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
it('works with video content', () => {
|
|
397
|
+
render(
|
|
398
|
+
<AspectRatio variant="card" ratio={16 / 9} data-testid="aspect-ratio">
|
|
399
|
+
<video controls style={{ width: '100%', height: '100%' }}>
|
|
400
|
+
<source src="video.mp4" type="video/mp4" />
|
|
401
|
+
</video>
|
|
402
|
+
</AspectRatio>
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
406
|
+
expect(aspectRatio).toHaveClass('bg-card')
|
|
407
|
+
|
|
408
|
+
const video = aspectRatio.querySelector('video')
|
|
409
|
+
expect(video).toBeInTheDocument()
|
|
410
|
+
expect(video).toHaveAttribute('controls')
|
|
411
|
+
})
|
|
412
|
+
})
|
|
413
|
+
|
|
414
|
+
describe('Edge Cases', () => {
|
|
415
|
+
it('passes through HTML attributes', () => {
|
|
416
|
+
render(
|
|
417
|
+
<AspectRatio id="custom-id" data-custom="value" data-testid="aspect-ratio">
|
|
418
|
+
<div>Content</div>
|
|
419
|
+
</AspectRatio>
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
423
|
+
expect(aspectRatio).toHaveAttribute('id', 'custom-id')
|
|
424
|
+
expect(aspectRatio).toHaveAttribute('data-custom', 'value')
|
|
425
|
+
})
|
|
426
|
+
|
|
427
|
+
it('handles zero ratio gracefully', () => {
|
|
428
|
+
render(
|
|
429
|
+
<AspectRatio ratio={0} data-testid="aspect-ratio">
|
|
430
|
+
<div>Content</div>
|
|
431
|
+
</AspectRatio>
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
435
|
+
expect(aspectRatio).toHaveStyle('padding-bottom: Infinity%')
|
|
436
|
+
})
|
|
437
|
+
|
|
438
|
+
it('handles very small ratio', () => {
|
|
439
|
+
render(
|
|
440
|
+
<AspectRatio ratio={0.1} data-testid="aspect-ratio">
|
|
441
|
+
<div>Content</div>
|
|
442
|
+
</AspectRatio>
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
446
|
+
expect(aspectRatio).toHaveStyle('padding-bottom: 1000%')
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
it('handles very large ratio', () => {
|
|
450
|
+
render(
|
|
451
|
+
<AspectRatio ratio={100} data-testid="aspect-ratio">
|
|
452
|
+
<div>Content</div>
|
|
453
|
+
</AspectRatio>
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
457
|
+
expect(aspectRatio).toHaveStyle('padding-bottom: 1%')
|
|
458
|
+
})
|
|
459
|
+
|
|
460
|
+
it('handles negative ratio', () => {
|
|
461
|
+
render(
|
|
462
|
+
<AspectRatio ratio={-1} data-testid="aspect-ratio">
|
|
463
|
+
<div>Content</div>
|
|
464
|
+
</AspectRatio>
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
const aspectRatio = screen.getByTestId('aspect-ratio')
|
|
468
|
+
expect(aspectRatio).toHaveStyle('padding-bottom: -100%')
|
|
469
|
+
})
|
|
470
|
+
|
|
471
|
+
it('handles common aspect ratios', () => {
|
|
472
|
+
const commonRatios = [
|
|
473
|
+
{ ratio: 16 / 9, expected: '56.25%' },
|
|
474
|
+
{ ratio: 4 / 3, expected: '75%' },
|
|
475
|
+
{ ratio: 3 / 2, expected: '66.66666666666666%' },
|
|
476
|
+
{ ratio: 1 / 1, expected: '100%' },
|
|
477
|
+
{ ratio: 2 / 1, expected: '50%' },
|
|
478
|
+
]
|
|
479
|
+
|
|
480
|
+
commonRatios.forEach(({ ratio, expected }, index) => {
|
|
481
|
+
render(
|
|
482
|
+
<AspectRatio ratio={ratio} data-testid={`aspect-ratio-${index}`}>
|
|
483
|
+
<div>Content {index}</div>
|
|
484
|
+
</AspectRatio>
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
const aspectRatio = screen.getByTestId(`aspect-ratio-${index}`)
|
|
488
|
+
expect(aspectRatio).toHaveStyle(`padding-bottom: ${expected}`)
|
|
489
|
+
})
|
|
490
|
+
})
|
|
491
|
+
})
|
|
492
|
+
})
|