@moontra/moonui 2.0.7 → 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 +26 -19
- 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,365 @@
|
|
|
1
|
+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
2
|
+
import { ColorPicker, SimpleColorPicker, GradientPicker } from '../color-picker';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
|
|
5
|
+
describe('ColorPicker Components', () => {
|
|
6
|
+
describe('ColorPicker', () => {
|
|
7
|
+
it('renders correctly with default props', () => {
|
|
8
|
+
const mockOnChange = jest.fn();
|
|
9
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
10
|
+
|
|
11
|
+
expect(screen.getByRole('button')).toBeInTheDocument();
|
|
12
|
+
expect(screen.getByText('#ffffff')).toBeInTheDocument();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('displays selected color', () => {
|
|
16
|
+
const mockOnChange = jest.fn();
|
|
17
|
+
render(<ColorPicker color="#ff0000" onColorChange={mockOnChange} />);
|
|
18
|
+
|
|
19
|
+
expect(screen.getByText('#ff0000')).toBeInTheDocument();
|
|
20
|
+
const colorDisplay = screen.getByTestId('color-display');
|
|
21
|
+
expect(colorDisplay).toHaveStyle('background-color: #ff0000');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('opens color picker when button is clicked', async () => {
|
|
25
|
+
const mockOnChange = jest.fn();
|
|
26
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
27
|
+
|
|
28
|
+
const button = screen.getByRole('button');
|
|
29
|
+
fireEvent.click(button);
|
|
30
|
+
|
|
31
|
+
await waitFor(() => {
|
|
32
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('calls onColorChange when color is selected', async () => {
|
|
37
|
+
const mockOnChange = jest.fn();
|
|
38
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
39
|
+
|
|
40
|
+
const button = screen.getByRole('button');
|
|
41
|
+
fireEvent.click(button);
|
|
42
|
+
|
|
43
|
+
await waitFor(() => {
|
|
44
|
+
const colorArea = screen.getByTestId('color-area');
|
|
45
|
+
fireEvent.click(colorArea);
|
|
46
|
+
expect(mockOnChange).toHaveBeenCalled();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('handles HSL color format', () => {
|
|
51
|
+
const mockOnChange = jest.fn();
|
|
52
|
+
render(<ColorPicker color="hsl(120, 100%, 50%)" onColorChange={mockOnChange} />);
|
|
53
|
+
|
|
54
|
+
expect(screen.getByText('hsl(120, 100%, 50%)')).toBeInTheDocument();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('handles RGB color format', () => {
|
|
58
|
+
const mockOnChange = jest.fn();
|
|
59
|
+
render(<ColorPicker color="rgb(255, 0, 0)" onColorChange={mockOnChange} />);
|
|
60
|
+
|
|
61
|
+
expect(screen.getByText('rgb(255, 0, 0)')).toBeInTheDocument();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('handles alpha channel', async () => {
|
|
65
|
+
const mockOnChange = jest.fn();
|
|
66
|
+
render(<ColorPicker color="rgba(255, 0, 0, 0.5)" onColorChange={mockOnChange} />);
|
|
67
|
+
|
|
68
|
+
const button = screen.getByRole('button');
|
|
69
|
+
fireEvent.click(button);
|
|
70
|
+
|
|
71
|
+
await waitFor(() => {
|
|
72
|
+
expect(screen.getByText('Opacity')).toBeInTheDocument();
|
|
73
|
+
const opacitySlider = screen.getByTestId('opacity-slider');
|
|
74
|
+
expect(opacitySlider).toBeInTheDocument();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('shows eyedropper tool when available', async () => {
|
|
79
|
+
// Mock the EyeDropper API
|
|
80
|
+
Object.defineProperty(window, 'EyeDropper', {
|
|
81
|
+
value: class MockEyeDropper {
|
|
82
|
+
async open() {
|
|
83
|
+
return { sRGBHex: '#ff0000' };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const mockOnChange = jest.fn();
|
|
89
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
90
|
+
|
|
91
|
+
const button = screen.getByRole('button');
|
|
92
|
+
fireEvent.click(button);
|
|
93
|
+
|
|
94
|
+
await waitFor(() => {
|
|
95
|
+
expect(screen.getByText('Eyedropper')).toBeInTheDocument();
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('handles disabled state', () => {
|
|
100
|
+
const mockOnChange = jest.fn();
|
|
101
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} disabled />);
|
|
102
|
+
|
|
103
|
+
const button = screen.getByRole('button');
|
|
104
|
+
expect(button).toBeDisabled();
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('SimpleColorPicker', () => {
|
|
109
|
+
it('renders correctly with preset colors', () => {
|
|
110
|
+
const mockOnChange = jest.fn();
|
|
111
|
+
render(<SimpleColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
112
|
+
|
|
113
|
+
expect(screen.getByRole('button')).toBeInTheDocument();
|
|
114
|
+
|
|
115
|
+
// Check for preset color buttons
|
|
116
|
+
const colorButtons = screen.getAllByRole('button');
|
|
117
|
+
expect(colorButtons.length).toBeGreaterThan(1);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('displays selected color', () => {
|
|
121
|
+
const mockOnChange = jest.fn();
|
|
122
|
+
render(<SimpleColorPicker color="#ff0000" onColorChange={mockOnChange} />);
|
|
123
|
+
|
|
124
|
+
const selectedButton = screen.getByRole('button', { pressed: true });
|
|
125
|
+
expect(selectedButton).toHaveStyle('background-color: #ff0000');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('calls onColorChange when preset color is clicked', () => {
|
|
129
|
+
const mockOnChange = jest.fn();
|
|
130
|
+
render(<SimpleColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
131
|
+
|
|
132
|
+
const colorButtons = screen.getAllByRole('button');
|
|
133
|
+
fireEvent.click(colorButtons[1]); // Click second color button
|
|
134
|
+
|
|
135
|
+
expect(mockOnChange).toHaveBeenCalled();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('shows custom color input', () => {
|
|
139
|
+
const mockOnChange = jest.fn();
|
|
140
|
+
render(<SimpleColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
141
|
+
|
|
142
|
+
expect(screen.getByPlaceholderText('Enter color...')).toBeInTheDocument();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('handles custom color input', () => {
|
|
146
|
+
const mockOnChange = jest.fn();
|
|
147
|
+
render(<SimpleColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
148
|
+
|
|
149
|
+
const input = screen.getByPlaceholderText('Enter color...');
|
|
150
|
+
fireEvent.change(input, { target: { value: '#ff0000' } });
|
|
151
|
+
fireEvent.blur(input);
|
|
152
|
+
|
|
153
|
+
expect(mockOnChange).toHaveBeenCalledWith('#ff0000');
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('GradientPicker', () => {
|
|
158
|
+
it('renders correctly with default gradient', () => {
|
|
159
|
+
const mockOnChange = jest.fn();
|
|
160
|
+
render(<GradientPicker gradient="linear-gradient(to right, #ff0000, #0000ff)" onGradientChange={mockOnChange} />);
|
|
161
|
+
|
|
162
|
+
expect(screen.getByRole('button')).toBeInTheDocument();
|
|
163
|
+
expect(screen.getByText('linear-gradient(to right, #ff0000, #0000ff)')).toBeInTheDocument();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('opens gradient picker when button is clicked', async () => {
|
|
167
|
+
const mockOnChange = jest.fn();
|
|
168
|
+
render(<GradientPicker gradient="linear-gradient(to right, #ff0000, #0000ff)" onGradientChange={mockOnChange} />);
|
|
169
|
+
|
|
170
|
+
const button = screen.getByRole('button');
|
|
171
|
+
fireEvent.click(button);
|
|
172
|
+
|
|
173
|
+
await waitFor(() => {
|
|
174
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('shows gradient type selector', async () => {
|
|
179
|
+
const mockOnChange = jest.fn();
|
|
180
|
+
render(<GradientPicker gradient="linear-gradient(to right, #ff0000, #0000ff)" onGradientChange={mockOnChange} />);
|
|
181
|
+
|
|
182
|
+
const button = screen.getByRole('button');
|
|
183
|
+
fireEvent.click(button);
|
|
184
|
+
|
|
185
|
+
await waitFor(() => {
|
|
186
|
+
expect(screen.getByText('Linear')).toBeInTheDocument();
|
|
187
|
+
expect(screen.getByText('Radial')).toBeInTheDocument();
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it('shows color stops', async () => {
|
|
192
|
+
const mockOnChange = jest.fn();
|
|
193
|
+
render(<GradientPicker gradient="linear-gradient(to right, #ff0000, #0000ff)" onGradientChange={mockOnChange} />);
|
|
194
|
+
|
|
195
|
+
const button = screen.getByRole('button');
|
|
196
|
+
fireEvent.click(button);
|
|
197
|
+
|
|
198
|
+
await waitFor(() => {
|
|
199
|
+
expect(screen.getByText('Color Stops')).toBeInTheDocument();
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('allows adding color stops', async () => {
|
|
204
|
+
const mockOnChange = jest.fn();
|
|
205
|
+
render(<GradientPicker gradient="linear-gradient(to right, #ff0000, #0000ff)" onGradientChange={mockOnChange} />);
|
|
206
|
+
|
|
207
|
+
const button = screen.getByRole('button');
|
|
208
|
+
fireEvent.click(button);
|
|
209
|
+
|
|
210
|
+
await waitFor(() => {
|
|
211
|
+
const addButton = screen.getByText('Add Stop');
|
|
212
|
+
fireEvent.click(addButton);
|
|
213
|
+
expect(mockOnChange).toHaveBeenCalled();
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('handles gradient direction change', async () => {
|
|
218
|
+
const mockOnChange = jest.fn();
|
|
219
|
+
render(<GradientPicker gradient="linear-gradient(to right, #ff0000, #0000ff)" onGradientChange={mockOnChange} />);
|
|
220
|
+
|
|
221
|
+
const button = screen.getByRole('button');
|
|
222
|
+
fireEvent.click(button);
|
|
223
|
+
|
|
224
|
+
await waitFor(() => {
|
|
225
|
+
const directionSelect = screen.getByText('to right');
|
|
226
|
+
fireEvent.click(directionSelect);
|
|
227
|
+
|
|
228
|
+
const toBottomOption = screen.getByText('to bottom');
|
|
229
|
+
fireEvent.click(toBottomOption);
|
|
230
|
+
|
|
231
|
+
expect(mockOnChange).toHaveBeenCalled();
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
describe('Common functionality', () => {
|
|
237
|
+
it('handles keyboard navigation', async () => {
|
|
238
|
+
const mockOnChange = jest.fn();
|
|
239
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
240
|
+
|
|
241
|
+
const button = screen.getByRole('button');
|
|
242
|
+
fireEvent.keyDown(button, { key: 'Enter' });
|
|
243
|
+
|
|
244
|
+
await waitFor(() => {
|
|
245
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('closes picker when clicking outside', async () => {
|
|
250
|
+
const mockOnChange = jest.fn();
|
|
251
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
252
|
+
|
|
253
|
+
const button = screen.getByRole('button');
|
|
254
|
+
fireEvent.click(button);
|
|
255
|
+
|
|
256
|
+
await waitFor(() => {
|
|
257
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
fireEvent.click(document.body);
|
|
261
|
+
|
|
262
|
+
await waitFor(() => {
|
|
263
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it('handles ESC key to close picker', async () => {
|
|
268
|
+
const mockOnChange = jest.fn();
|
|
269
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
270
|
+
|
|
271
|
+
const button = screen.getByRole('button');
|
|
272
|
+
fireEvent.click(button);
|
|
273
|
+
|
|
274
|
+
await waitFor(() => {
|
|
275
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
fireEvent.keyDown(document, { key: 'Escape' });
|
|
279
|
+
|
|
280
|
+
await waitFor(() => {
|
|
281
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('applies custom className', () => {
|
|
286
|
+
const mockOnChange = jest.fn();
|
|
287
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} className="custom-class" />);
|
|
288
|
+
|
|
289
|
+
const button = screen.getByRole('button');
|
|
290
|
+
expect(button).toHaveClass('custom-class');
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
describe('Accessibility', () => {
|
|
295
|
+
it('has proper ARIA attributes', () => {
|
|
296
|
+
const mockOnChange = jest.fn();
|
|
297
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
298
|
+
|
|
299
|
+
const button = screen.getByRole('button');
|
|
300
|
+
expect(button).toHaveAttribute('aria-haspopup', 'dialog');
|
|
301
|
+
expect(button).toHaveAttribute('aria-expanded', 'false');
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('updates aria-expanded when picker is open', async () => {
|
|
305
|
+
const mockOnChange = jest.fn();
|
|
306
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
307
|
+
|
|
308
|
+
const button = screen.getByRole('button');
|
|
309
|
+
fireEvent.click(button);
|
|
310
|
+
|
|
311
|
+
await waitFor(() => {
|
|
312
|
+
expect(button).toHaveAttribute('aria-expanded', 'true');
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it('has proper labels for screen readers', () => {
|
|
317
|
+
const mockOnChange = jest.fn();
|
|
318
|
+
render(<ColorPicker color="#ffffff" onColorChange={mockOnChange} />);
|
|
319
|
+
|
|
320
|
+
const button = screen.getByRole('button');
|
|
321
|
+
expect(button).toHaveAttribute('aria-label', 'Open color picker');
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('provides color value to screen readers', () => {
|
|
325
|
+
const mockOnChange = jest.fn();
|
|
326
|
+
render(<ColorPicker color="#ff0000" onColorChange={mockOnChange} />);
|
|
327
|
+
|
|
328
|
+
const button = screen.getByRole('button');
|
|
329
|
+
expect(button).toHaveAttribute('aria-describedby');
|
|
330
|
+
expect(screen.getByText('#ff0000')).toBeInTheDocument();
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
describe('Form integration', () => {
|
|
335
|
+
it('works with form validation', () => {
|
|
336
|
+
const mockOnChange = jest.fn();
|
|
337
|
+
|
|
338
|
+
render(
|
|
339
|
+
<form>
|
|
340
|
+
<ColorPicker color="#ffffff" onColorChange={mockOnChange} required />
|
|
341
|
+
</form>
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
const button = screen.getByRole('button');
|
|
345
|
+
expect(button).toBeValid();
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it('handles form reset', () => {
|
|
349
|
+
const mockOnChange = jest.fn();
|
|
350
|
+
|
|
351
|
+
render(
|
|
352
|
+
<form>
|
|
353
|
+
<ColorPicker color="#ff0000" onColorChange={mockOnChange} />
|
|
354
|
+
<button type="reset">Reset</button>
|
|
355
|
+
</form>
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
const resetButton = screen.getByText('Reset');
|
|
359
|
+
fireEvent.click(resetButton);
|
|
360
|
+
|
|
361
|
+
// Form reset should trigger appropriate behavior
|
|
362
|
+
expect(screen.getAllByRole('button')).toHaveLength(2);
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
});
|