@moontra/moonui 2.0.8 → 2.0.9
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,493 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen, fireEvent } from '@testing-library/react'
|
|
3
|
+
import { Slider } from '../slider'
|
|
4
|
+
|
|
5
|
+
describe('Slider Component', () => {
|
|
6
|
+
describe('Basic Rendering', () => {
|
|
7
|
+
it('renders correctly with default props', () => {
|
|
8
|
+
render(<Slider data-testid="slider" />)
|
|
9
|
+
|
|
10
|
+
const slider = screen.getByTestId('slider')
|
|
11
|
+
expect(slider).toBeInTheDocument()
|
|
12
|
+
expect(slider).toHaveClass('w-full')
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('applies custom className', () => {
|
|
16
|
+
render(<Slider className="custom-slider" data-testid="slider" />)
|
|
17
|
+
|
|
18
|
+
const sliderContainer = screen.getByTestId('slider').children[0] as HTMLElement
|
|
19
|
+
expect(sliderContainer).toHaveClass('custom-slider')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('renders with default value', () => {
|
|
23
|
+
render(<Slider defaultValue={[25]} data-testid="slider" />)
|
|
24
|
+
|
|
25
|
+
const thumb = screen.getByRole('slider')
|
|
26
|
+
expect(thumb).toHaveAttribute('aria-valuenow', '25')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('renders with controlled value', () => {
|
|
30
|
+
render(<Slider value={[50]} data-testid="slider" />)
|
|
31
|
+
|
|
32
|
+
const thumb = screen.getByRole('slider')
|
|
33
|
+
expect(thumb).toHaveAttribute('aria-valuenow', '50')
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
describe('Size Variants', () => {
|
|
38
|
+
it('renders sm size correctly', () => {
|
|
39
|
+
render(<Slider size="sm" data-testid="slider" />)
|
|
40
|
+
|
|
41
|
+
const sliderContainer = screen.getByTestId('slider').children[0] as HTMLElement
|
|
42
|
+
expect(sliderContainer).toHaveClass('h-5')
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('renders default size correctly', () => {
|
|
46
|
+
render(<Slider size="default" data-testid="slider" />)
|
|
47
|
+
|
|
48
|
+
const sliderContainer = screen.getByTestId('slider').children[0] as HTMLElement
|
|
49
|
+
expect(sliderContainer).toHaveClass('h-6')
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('renders md size correctly', () => {
|
|
53
|
+
render(<Slider size="md" data-testid="slider" />)
|
|
54
|
+
|
|
55
|
+
const sliderContainer = screen.getByTestId('slider').children[0] as HTMLElement
|
|
56
|
+
expect(sliderContainer).toHaveClass('h-8')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('renders lg size correctly', () => {
|
|
60
|
+
render(<Slider size="lg" data-testid="slider" />)
|
|
61
|
+
|
|
62
|
+
const sliderContainer = screen.getByTestId('slider').children[0] as HTMLElement
|
|
63
|
+
expect(sliderContainer).toHaveClass('h-10')
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
describe('Track Variants', () => {
|
|
68
|
+
it('renders default track variant correctly', () => {
|
|
69
|
+
render(<Slider trackVariant="default" data-testid="slider" />)
|
|
70
|
+
|
|
71
|
+
const track = screen.getByTestId('slider').querySelector('.bg-muted')
|
|
72
|
+
expect(track).toBeInTheDocument()
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('renders primary track variant correctly', () => {
|
|
76
|
+
render(<Slider trackVariant="primary" data-testid="slider" />)
|
|
77
|
+
|
|
78
|
+
const track = screen.getByTestId('slider').querySelector('.bg-primary\\/20')
|
|
79
|
+
expect(track).toBeInTheDocument()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('renders secondary track variant correctly', () => {
|
|
83
|
+
render(<Slider trackVariant="secondary" data-testid="slider" />)
|
|
84
|
+
|
|
85
|
+
const track = screen.getByTestId('slider').querySelector('.bg-secondary\\/20')
|
|
86
|
+
expect(track).toBeInTheDocument()
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('renders success track variant correctly', () => {
|
|
90
|
+
render(<Slider trackVariant="success" data-testid="slider" />)
|
|
91
|
+
|
|
92
|
+
const track = screen.getByTestId('slider').querySelector('.bg-success\\/20')
|
|
93
|
+
expect(track).toBeInTheDocument()
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('renders error track variant correctly', () => {
|
|
97
|
+
render(<Slider trackVariant="error" data-testid="slider" />)
|
|
98
|
+
|
|
99
|
+
const track = screen.getByTestId('slider').querySelector('.bg-error\\/20')
|
|
100
|
+
expect(track).toBeInTheDocument()
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
describe('Range Variants', () => {
|
|
105
|
+
it('renders default range variant correctly', () => {
|
|
106
|
+
render(<Slider rangeVariant="default" data-testid="slider" />)
|
|
107
|
+
|
|
108
|
+
const range = screen.getByTestId('slider').querySelector('.bg-foreground')
|
|
109
|
+
expect(range).toBeInTheDocument()
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('renders primary range variant correctly', () => {
|
|
113
|
+
render(<Slider rangeVariant="primary" data-testid="slider" />)
|
|
114
|
+
|
|
115
|
+
const range = screen.getByTestId('slider').querySelector('.bg-primary')
|
|
116
|
+
expect(range).toBeInTheDocument()
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('renders success range variant correctly', () => {
|
|
120
|
+
render(<Slider rangeVariant="success" data-testid="slider" />)
|
|
121
|
+
|
|
122
|
+
const range = screen.getByTestId('slider').querySelector('.bg-success')
|
|
123
|
+
expect(range).toBeInTheDocument()
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('renders error range variant correctly', () => {
|
|
127
|
+
render(<Slider rangeVariant="error" data-testid="slider" />)
|
|
128
|
+
|
|
129
|
+
const range = screen.getByTestId('slider').querySelector('.bg-error')
|
|
130
|
+
expect(range).toBeInTheDocument()
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
describe('Thumb Variants', () => {
|
|
135
|
+
it('renders default thumb variant correctly', () => {
|
|
136
|
+
render(<Slider thumbVariant="default" data-testid="slider" />)
|
|
137
|
+
|
|
138
|
+
const thumb = screen.getByRole('slider')
|
|
139
|
+
expect(thumb).toHaveClass('border-foreground')
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
it('renders primary thumb variant correctly', () => {
|
|
143
|
+
render(<Slider thumbVariant="primary" data-testid="slider" />)
|
|
144
|
+
|
|
145
|
+
const thumb = screen.getByRole('slider')
|
|
146
|
+
expect(thumb).toHaveClass('border-primary')
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('renders success thumb variant correctly', () => {
|
|
150
|
+
render(<Slider thumbVariant="success" data-testid="slider" />)
|
|
151
|
+
|
|
152
|
+
const thumb = screen.getByRole('slider')
|
|
153
|
+
expect(thumb).toHaveClass('border-success')
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('renders error thumb variant correctly', () => {
|
|
157
|
+
render(<Slider thumbVariant="error" data-testid="slider" />)
|
|
158
|
+
|
|
159
|
+
const thumb = screen.getByRole('slider')
|
|
160
|
+
expect(thumb).toHaveClass('border-error')
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
describe('Thumb Sizes', () => {
|
|
165
|
+
it('renders sm thumb size correctly', () => {
|
|
166
|
+
render(<Slider thumbSize="sm" data-testid="slider" />)
|
|
167
|
+
|
|
168
|
+
const thumb = screen.getByRole('slider')
|
|
169
|
+
expect(thumb).toHaveClass('h-3', 'w-3')
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('renders default thumb size correctly', () => {
|
|
173
|
+
render(<Slider thumbSize="default" data-testid="slider" />)
|
|
174
|
+
|
|
175
|
+
const thumb = screen.getByRole('slider')
|
|
176
|
+
expect(thumb).toHaveClass('h-4', 'w-4')
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
it('renders md thumb size correctly', () => {
|
|
180
|
+
render(<Slider thumbSize="md" data-testid="slider" />)
|
|
181
|
+
|
|
182
|
+
const thumb = screen.getByRole('slider')
|
|
183
|
+
expect(thumb).toHaveClass('h-5', 'w-5')
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it('renders lg thumb size correctly', () => {
|
|
187
|
+
render(<Slider thumbSize="lg" data-testid="slider" />)
|
|
188
|
+
|
|
189
|
+
const thumb = screen.getByRole('slider')
|
|
190
|
+
expect(thumb).toHaveClass('h-6', 'w-6')
|
|
191
|
+
})
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
describe('Value Label', () => {
|
|
195
|
+
it('does not show value label by default', () => {
|
|
196
|
+
render(<Slider defaultValue={[25]} data-testid="slider" />)
|
|
197
|
+
|
|
198
|
+
expect(screen.queryByText('25')).not.toBeInTheDocument()
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
it('shows value label when enabled', () => {
|
|
202
|
+
render(<Slider defaultValue={[25]} showValueLabel data-testid="slider" />)
|
|
203
|
+
|
|
204
|
+
expect(screen.getByText('25')).toBeInTheDocument()
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
it('applies custom value label className', () => {
|
|
208
|
+
render(
|
|
209
|
+
<Slider
|
|
210
|
+
defaultValue={[25]}
|
|
211
|
+
showValueLabel
|
|
212
|
+
valueLabelClassName="custom-label"
|
|
213
|
+
data-testid="slider"
|
|
214
|
+
/>
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
const label = screen.getByText('25').parentElement
|
|
218
|
+
expect(label).toHaveClass('custom-label')
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
it('formats value label with custom formatter', () => {
|
|
222
|
+
const formatter = (value: number) => `${value}%`
|
|
223
|
+
render(
|
|
224
|
+
<Slider
|
|
225
|
+
defaultValue={[25]}
|
|
226
|
+
showValueLabel
|
|
227
|
+
valueLabelFormat={formatter}
|
|
228
|
+
data-testid="slider"
|
|
229
|
+
/>
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
expect(screen.getByText('25%')).toBeInTheDocument()
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
it('shows range for multiple values', () => {
|
|
236
|
+
render(
|
|
237
|
+
<Slider
|
|
238
|
+
defaultValue={[25, 75]}
|
|
239
|
+
showValueLabel
|
|
240
|
+
data-testid="slider"
|
|
241
|
+
/>
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
expect(screen.getByText('25 - 75')).toBeInTheDocument()
|
|
245
|
+
})
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
describe('Props and Configuration', () => {
|
|
249
|
+
it('handles min and max values', () => {
|
|
250
|
+
render(<Slider min={10} max={90} defaultValue={[50]} data-testid="slider" />)
|
|
251
|
+
|
|
252
|
+
const thumb = screen.getByRole('slider')
|
|
253
|
+
expect(thumb).toHaveAttribute('aria-valuemin', '10')
|
|
254
|
+
expect(thumb).toHaveAttribute('aria-valuemax', '90')
|
|
255
|
+
expect(thumb).toHaveAttribute('aria-valuenow', '50')
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it('handles step value', () => {
|
|
259
|
+
render(<Slider step={5} defaultValue={[25]} data-testid="slider" />)
|
|
260
|
+
|
|
261
|
+
const thumb = screen.getByRole('slider')
|
|
262
|
+
expect(thumb).toHaveAttribute('aria-valuenow', '25')
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
it('handles multiple thumbs', () => {
|
|
266
|
+
render(<Slider defaultValue={[25, 75]} data-testid="slider" />)
|
|
267
|
+
|
|
268
|
+
const thumbs = screen.getAllByRole('slider')
|
|
269
|
+
expect(thumbs).toHaveLength(2)
|
|
270
|
+
expect(thumbs[0]).toHaveAttribute('aria-valuenow', '25')
|
|
271
|
+
expect(thumbs[1]).toHaveAttribute('aria-valuenow', '75')
|
|
272
|
+
})
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
describe('Disabled State', () => {
|
|
276
|
+
it('renders disabled state correctly', () => {
|
|
277
|
+
render(<Slider disabled data-testid="slider" />)
|
|
278
|
+
|
|
279
|
+
const sliderContainer = screen.getByTestId('slider').querySelector('[data-disabled]')
|
|
280
|
+
expect(sliderContainer).toHaveAttribute('data-disabled', 'true')
|
|
281
|
+
|
|
282
|
+
const thumb = screen.getByRole('slider')
|
|
283
|
+
expect(thumb).toHaveAttribute('aria-disabled', 'true')
|
|
284
|
+
expect(thumb).toHaveAttribute('tabIndex', '-1')
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
it('does not handle interactions when disabled', () => {
|
|
288
|
+
const onValueChange = jest.fn()
|
|
289
|
+
render(<Slider disabled onValueChange={onValueChange} data-testid="slider" />)
|
|
290
|
+
|
|
291
|
+
const thumb = screen.getByRole('slider')
|
|
292
|
+
fireEvent.mouseDown(thumb)
|
|
293
|
+
|
|
294
|
+
expect(onValueChange).not.toHaveBeenCalled()
|
|
295
|
+
})
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
describe('Event Handling', () => {
|
|
299
|
+
it('calls onValueChange when value changes', () => {
|
|
300
|
+
const onValueChange = jest.fn()
|
|
301
|
+
render(<Slider onValueChange={onValueChange} defaultValue={[25]} data-testid="slider" />)
|
|
302
|
+
|
|
303
|
+
const thumb = screen.getByRole('slider')
|
|
304
|
+
fireEvent.mouseDown(thumb)
|
|
305
|
+
|
|
306
|
+
// Simulate mouse move
|
|
307
|
+
fireEvent(document, new MouseEvent('mousemove', {
|
|
308
|
+
clientX: 100,
|
|
309
|
+
bubbles: true
|
|
310
|
+
}))
|
|
311
|
+
|
|
312
|
+
expect(onValueChange).toHaveBeenCalled()
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
it('handles track click', () => {
|
|
316
|
+
const onValueChange = jest.fn()
|
|
317
|
+
render(<Slider onValueChange={onValueChange} data-testid="slider" />)
|
|
318
|
+
|
|
319
|
+
const track = screen.getByTestId('slider').querySelector('.bg-muted')
|
|
320
|
+
if (track) {
|
|
321
|
+
fireEvent.click(track, { clientX: 50 })
|
|
322
|
+
expect(onValueChange).toHaveBeenCalled()
|
|
323
|
+
}
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
it('updates controlled value', () => {
|
|
327
|
+
const TestComponent = () => {
|
|
328
|
+
const [value, setValue] = React.useState([25])
|
|
329
|
+
return (
|
|
330
|
+
<div>
|
|
331
|
+
<Slider value={value} onValueChange={setValue} data-testid="slider" />
|
|
332
|
+
<span data-testid="current-value">{value[0]}</span>
|
|
333
|
+
</div>
|
|
334
|
+
)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
render(<TestComponent />)
|
|
338
|
+
|
|
339
|
+
expect(screen.getByTestId('current-value')).toHaveTextContent('25')
|
|
340
|
+
|
|
341
|
+
const thumb = screen.getByRole('slider')
|
|
342
|
+
expect(thumb).toHaveAttribute('aria-valuenow', '25')
|
|
343
|
+
})
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
describe('Accessibility', () => {
|
|
347
|
+
it('has proper ARIA attributes', () => {
|
|
348
|
+
render(<Slider defaultValue={[50]} min={0} max={100} data-testid="slider" />)
|
|
349
|
+
|
|
350
|
+
const thumb = screen.getByRole('slider')
|
|
351
|
+
expect(thumb).toHaveAttribute('role', 'slider')
|
|
352
|
+
expect(thumb).toHaveAttribute('aria-valuemin', '0')
|
|
353
|
+
expect(thumb).toHaveAttribute('aria-valuemax', '100')
|
|
354
|
+
expect(thumb).toHaveAttribute('aria-valuenow', '50')
|
|
355
|
+
expect(thumb).toHaveAttribute('tabIndex', '0')
|
|
356
|
+
})
|
|
357
|
+
|
|
358
|
+
it('has proper aria-label for multiple thumbs', () => {
|
|
359
|
+
render(<Slider defaultValue={[25, 75]} data-testid="slider" />)
|
|
360
|
+
|
|
361
|
+
const thumbs = screen.getAllByRole('slider')
|
|
362
|
+
expect(thumbs[0]).toHaveAttribute('aria-label', 'Thumb 1')
|
|
363
|
+
expect(thumbs[1]).toHaveAttribute('aria-label', 'Thumb 2')
|
|
364
|
+
})
|
|
365
|
+
|
|
366
|
+
it('handles keyboard navigation', () => {
|
|
367
|
+
render(<Slider defaultValue={[50]} data-testid="slider" />)
|
|
368
|
+
|
|
369
|
+
const thumb = screen.getByRole('slider')
|
|
370
|
+
expect(thumb).toHaveAttribute('tabIndex', '0')
|
|
371
|
+
|
|
372
|
+
thumb.focus()
|
|
373
|
+
expect(thumb).toHaveFocus()
|
|
374
|
+
})
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
describe('Ref Forwarding', () => {
|
|
378
|
+
it('forwards ref correctly', () => {
|
|
379
|
+
const ref = React.createRef<HTMLDivElement>()
|
|
380
|
+
render(<Slider ref={ref} data-testid="slider" />)
|
|
381
|
+
|
|
382
|
+
expect(ref.current).toBeInstanceOf(HTMLDivElement)
|
|
383
|
+
expect(ref.current).toBe(screen.getByTestId('slider'))
|
|
384
|
+
})
|
|
385
|
+
})
|
|
386
|
+
|
|
387
|
+
describe('DisplayName', () => {
|
|
388
|
+
it('maintains displayName', () => {
|
|
389
|
+
expect(Slider.displayName).toBe('Slider')
|
|
390
|
+
})
|
|
391
|
+
})
|
|
392
|
+
|
|
393
|
+
describe('HTML Attributes', () => {
|
|
394
|
+
it('passes through HTML attributes', () => {
|
|
395
|
+
render(
|
|
396
|
+
<Slider
|
|
397
|
+
data-testid="slider"
|
|
398
|
+
id="test-slider"
|
|
399
|
+
aria-describedby="slider-description"
|
|
400
|
+
/>
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
const slider = screen.getByTestId('slider')
|
|
404
|
+
expect(slider).toHaveAttribute('id', 'test-slider')
|
|
405
|
+
expect(slider).toHaveAttribute('aria-describedby', 'slider-description')
|
|
406
|
+
})
|
|
407
|
+
})
|
|
408
|
+
|
|
409
|
+
describe('Complex Combinations', () => {
|
|
410
|
+
it('renders with all variants and options', () => {
|
|
411
|
+
render(
|
|
412
|
+
<Slider
|
|
413
|
+
size="lg"
|
|
414
|
+
trackVariant="primary"
|
|
415
|
+
rangeVariant="success"
|
|
416
|
+
thumbVariant="error"
|
|
417
|
+
thumbSize="md"
|
|
418
|
+
showValueLabel
|
|
419
|
+
valueLabelFormat={(v) => `${v}px`}
|
|
420
|
+
min={0}
|
|
421
|
+
max={200}
|
|
422
|
+
step={10}
|
|
423
|
+
defaultValue={[50, 150]}
|
|
424
|
+
data-testid="slider"
|
|
425
|
+
/>
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
const slider = screen.getByTestId('slider')
|
|
429
|
+
expect(slider).toBeInTheDocument()
|
|
430
|
+
|
|
431
|
+
const thumbs = screen.getAllByRole('slider')
|
|
432
|
+
expect(thumbs).toHaveLength(2)
|
|
433
|
+
|
|
434
|
+
expect(screen.getByText('50px - 150px')).toBeInTheDocument()
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
it('handles variant inheritance correctly', () => {
|
|
438
|
+
render(<Slider thumbVariant="success" data-testid="slider" />)
|
|
439
|
+
|
|
440
|
+
// Track should inherit from thumb variant
|
|
441
|
+
const track = screen.getByTestId('slider').querySelector('.bg-success\\/20')
|
|
442
|
+
expect(track).toBeInTheDocument()
|
|
443
|
+
|
|
444
|
+
// Range should inherit from thumb variant
|
|
445
|
+
const range = screen.getByTestId('slider').querySelector('.bg-success')
|
|
446
|
+
expect(range).toBeInTheDocument()
|
|
447
|
+
|
|
448
|
+
// Thumb should use its own variant
|
|
449
|
+
const thumb = screen.getByRole('slider')
|
|
450
|
+
expect(thumb).toHaveClass('border-success')
|
|
451
|
+
})
|
|
452
|
+
})
|
|
453
|
+
|
|
454
|
+
describe('Edge Cases', () => {
|
|
455
|
+
it('handles empty defaultValue', () => {
|
|
456
|
+
render(<Slider defaultValue={[]} data-testid="slider" />)
|
|
457
|
+
|
|
458
|
+
const slider = screen.getByTestId('slider')
|
|
459
|
+
expect(slider).toBeInTheDocument()
|
|
460
|
+
})
|
|
461
|
+
|
|
462
|
+
it('handles undefined value', () => {
|
|
463
|
+
render(<Slider value={undefined} data-testid="slider" />)
|
|
464
|
+
|
|
465
|
+
const slider = screen.getByTestId('slider')
|
|
466
|
+
expect(slider).toBeInTheDocument()
|
|
467
|
+
})
|
|
468
|
+
|
|
469
|
+
it('handles extreme min/max values', () => {
|
|
470
|
+
render(<Slider min={-100} max={1000} defaultValue={[0]} data-testid="slider" />)
|
|
471
|
+
|
|
472
|
+
const thumb = screen.getByRole('slider')
|
|
473
|
+
expect(thumb).toHaveAttribute('aria-valuemin', '-100')
|
|
474
|
+
expect(thumb).toHaveAttribute('aria-valuemax', '1000')
|
|
475
|
+
})
|
|
476
|
+
|
|
477
|
+
it('handles very small step values', () => {
|
|
478
|
+
render(<Slider step={0.1} min={0} max={1} defaultValue={[0.5]} data-testid="slider" />)
|
|
479
|
+
|
|
480
|
+
const thumb = screen.getByRole('slider')
|
|
481
|
+
expect(thumb).toHaveAttribute('aria-valuenow', '0.5')
|
|
482
|
+
})
|
|
483
|
+
|
|
484
|
+
it('handles single value array', () => {
|
|
485
|
+
render(<Slider defaultValue={[42]} showValueLabel data-testid="slider" />)
|
|
486
|
+
|
|
487
|
+
expect(screen.getByText('42')).toBeInTheDocument()
|
|
488
|
+
|
|
489
|
+
const thumbs = screen.getAllByRole('slider')
|
|
490
|
+
expect(thumbs).toHaveLength(1)
|
|
491
|
+
})
|
|
492
|
+
})
|
|
493
|
+
})
|