@pie-lib/config-ui 13.0.4-next.3 → 13.0.4-next.30

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.
Files changed (190) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +11 -0
  2. package/dist/alert-dialog.d.ts +44 -0
  3. package/dist/alert-dialog.js +47 -0
  4. package/dist/checkbox.d.ts +34 -0
  5. package/dist/checkbox.js +57 -0
  6. package/dist/choice-configuration/feedback-menu.d.ts +32 -0
  7. package/dist/choice-configuration/feedback-menu.js +85 -0
  8. package/dist/choice-configuration/index.d.ts +62 -0
  9. package/dist/choice-configuration/index.js +240 -0
  10. package/dist/choice-utils.d.ts +21 -0
  11. package/dist/choice-utils.js +15 -0
  12. package/dist/feedback-config/feedback-selector.d.ts +33 -0
  13. package/dist/feedback-config/feedback-selector.js +92 -0
  14. package/dist/feedback-config/group.d.ts +21 -0
  15. package/dist/feedback-config/group.js +33 -0
  16. package/dist/feedback-config/index.d.ts +48 -0
  17. package/dist/feedback-config/index.js +96 -0
  18. package/dist/form-section.d.ts +25 -0
  19. package/dist/form-section.js +25 -0
  20. package/dist/fraction-to-number.d.ts +7 -0
  21. package/dist/fraction-to-number.js +9 -0
  22. package/dist/help.d.ts +41 -0
  23. package/dist/help.js +61 -0
  24. package/dist/index.d.ts +31 -0
  25. package/dist/index.js +34 -0
  26. package/dist/input.d.ts +29 -0
  27. package/dist/input.js +65 -0
  28. package/dist/inputs.d.ts +63 -0
  29. package/dist/inputs.js +70 -0
  30. package/dist/langs.d.ts +41 -0
  31. package/dist/langs.js +76 -0
  32. package/dist/layout/config-layout.d.ts +10 -0
  33. package/dist/layout/config-layout.js +75 -0
  34. package/dist/layout/index.d.ts +11 -0
  35. package/dist/layout/index.js +10 -0
  36. package/dist/layout/layout-contents.d.ts +21 -0
  37. package/dist/layout/layout-contents.js +70 -0
  38. package/dist/layout/settings-box.d.ts +19 -0
  39. package/dist/layout/settings-box.js +31 -0
  40. package/dist/mui-box/index.d.ts +21 -0
  41. package/dist/mui-box/index.js +47 -0
  42. package/dist/node_modules/.bun/@babel_runtime@7.29.7/node_modules/@babel/runtime/helpers/esm/extends.js +12 -0
  43. package/dist/node_modules/.bun/@babel_runtime@7.29.7/node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +7 -0
  44. package/dist/node_modules/.bun/@babel_runtime@7.29.7/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js +12 -0
  45. package/dist/node_modules/.bun/@babel_runtime@7.29.7/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js +8 -0
  46. package/dist/node_modules/.bun/react-measure@2.5.2_6dbf9a050bc9aadb/node_modules/react-measure/dist/index.esm.js +122 -0
  47. package/dist/node_modules/.bun/resize-observer-polyfill@1.5.1/node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js +276 -0
  48. package/dist/number-text-field-custom.d.ts +51 -0
  49. package/dist/number-text-field-custom.js +192 -0
  50. package/dist/number-text-field.d.ts +47 -0
  51. package/dist/number-text-field.js +122 -0
  52. package/dist/radio-with-label.d.ts +25 -0
  53. package/dist/radio-with-label.js +27 -0
  54. package/dist/settings/display-size.d.ts +26 -0
  55. package/dist/settings/display-size.js +45 -0
  56. package/dist/settings/index.d.ts +45 -0
  57. package/dist/settings/index.js +63 -0
  58. package/dist/settings/panel.d.ts +27 -0
  59. package/dist/settings/panel.js +201 -0
  60. package/dist/settings/settings-radio-label.d.ts +25 -0
  61. package/dist/settings/settings-radio-label.js +29 -0
  62. package/dist/settings/toggle.d.ts +25 -0
  63. package/dist/settings/toggle.js +33 -0
  64. package/dist/tabs/index.d.ts +22 -0
  65. package/dist/tabs/index.js +39 -0
  66. package/dist/tags-input/index.d.ts +21 -0
  67. package/dist/tags-input/index.js +83 -0
  68. package/dist/two-choice.d.ts +43 -0
  69. package/dist/two-choice.js +79 -0
  70. package/dist/with-stateful-model.d.ts +42 -0
  71. package/dist/with-stateful-model.js +32 -0
  72. package/package.json +33 -19
  73. package/CHANGELOG.json +0 -32
  74. package/CHANGELOG.md +0 -2419
  75. package/LICENSE.md +0 -5
  76. package/lib/alert-dialog.js +0 -68
  77. package/lib/alert-dialog.js.map +0 -1
  78. package/lib/checkbox.js +0 -84
  79. package/lib/checkbox.js.map +0 -1
  80. package/lib/choice-configuration/feedback-menu.js +0 -129
  81. package/lib/choice-configuration/feedback-menu.js.map +0 -1
  82. package/lib/choice-configuration/index.js +0 -381
  83. package/lib/choice-configuration/index.js.map +0 -1
  84. package/lib/choice-utils.js +0 -42
  85. package/lib/choice-utils.js.map +0 -1
  86. package/lib/feedback-config/feedback-selector.js +0 -155
  87. package/lib/feedback-config/feedback-selector.js.map +0 -1
  88. package/lib/feedback-config/group.js +0 -61
  89. package/lib/feedback-config/group.js.map +0 -1
  90. package/lib/feedback-config/index.js +0 -146
  91. package/lib/feedback-config/index.js.map +0 -1
  92. package/lib/form-section.js +0 -44
  93. package/lib/form-section.js.map +0 -1
  94. package/lib/help.js +0 -106
  95. package/lib/help.js.map +0 -1
  96. package/lib/index.js +0 -186
  97. package/lib/index.js.map +0 -1
  98. package/lib/input.js +0 -106
  99. package/lib/input.js.map +0 -1
  100. package/lib/inputs.js +0 -105
  101. package/lib/inputs.js.map +0 -1
  102. package/lib/langs.js +0 -136
  103. package/lib/langs.js.map +0 -1
  104. package/lib/layout/config-layout.js +0 -137
  105. package/lib/layout/config-layout.js.map +0 -1
  106. package/lib/layout/index.js +0 -21
  107. package/lib/layout/index.js.map +0 -1
  108. package/lib/layout/layout-contents.js +0 -160
  109. package/lib/layout/layout-contents.js.map +0 -1
  110. package/lib/layout/settings-box.js +0 -57
  111. package/lib/layout/settings-box.js.map +0 -1
  112. package/lib/mui-box/index.js +0 -63
  113. package/lib/mui-box/index.js.map +0 -1
  114. package/lib/number-text-field-custom.js +0 -376
  115. package/lib/number-text-field-custom.js.map +0 -1
  116. package/lib/number-text-field.js +0 -229
  117. package/lib/number-text-field.js.map +0 -1
  118. package/lib/radio-with-label.js +0 -48
  119. package/lib/radio-with-label.js.map +0 -1
  120. package/lib/settings/display-size.js +0 -61
  121. package/lib/settings/display-size.js.map +0 -1
  122. package/lib/settings/index.js +0 -110
  123. package/lib/settings/index.js.map +0 -1
  124. package/lib/settings/panel.js +0 -392
  125. package/lib/settings/panel.js.map +0 -1
  126. package/lib/settings/settings-radio-label.js +0 -51
  127. package/lib/settings/settings-radio-label.js.map +0 -1
  128. package/lib/settings/toggle.js +0 -63
  129. package/lib/settings/toggle.js.map +0 -1
  130. package/lib/tabs/index.js +0 -75
  131. package/lib/tabs/index.js.map +0 -1
  132. package/lib/tags-input/index.js +0 -149
  133. package/lib/tags-input/index.js.map +0 -1
  134. package/lib/two-choice.js +0 -136
  135. package/lib/two-choice.js.map +0 -1
  136. package/lib/with-stateful-model.js +0 -61
  137. package/lib/with-stateful-model.js.map +0 -1
  138. package/src/__tests__/alert-dialog.test.jsx +0 -183
  139. package/src/__tests__/checkbox.test.jsx +0 -152
  140. package/src/__tests__/choice-utils.test.js +0 -12
  141. package/src/__tests__/form-section.test.jsx +0 -328
  142. package/src/__tests__/help.test.jsx +0 -184
  143. package/src/__tests__/input.test.jsx +0 -156
  144. package/src/__tests__/langs.test.jsx +0 -376
  145. package/src/__tests__/number-text-field-custom.test.jsx +0 -255
  146. package/src/__tests__/number-text-field.test.jsx +0 -263
  147. package/src/__tests__/radio-with-label.test.jsx +0 -155
  148. package/src/__tests__/settings-panel.test.js +0 -187
  149. package/src/__tests__/settings.test.jsx +0 -452
  150. package/src/__tests__/tabs.test.jsx +0 -188
  151. package/src/__tests__/two-choice.test.js +0 -110
  152. package/src/__tests__/with-stateful-model.test.jsx +0 -139
  153. package/src/alert-dialog.jsx +0 -75
  154. package/src/checkbox.jsx +0 -61
  155. package/src/choice-configuration/__tests__/feedback-menu.test.jsx +0 -151
  156. package/src/choice-configuration/__tests__/index.test.jsx +0 -234
  157. package/src/choice-configuration/feedback-menu.jsx +0 -96
  158. package/src/choice-configuration/index.jsx +0 -357
  159. package/src/choice-utils.js +0 -30
  160. package/src/feedback-config/__tests__/feedback-config.test.jsx +0 -141
  161. package/src/feedback-config/__tests__/feedback-selector.test.jsx +0 -97
  162. package/src/feedback-config/feedback-selector.jsx +0 -112
  163. package/src/feedback-config/group.jsx +0 -51
  164. package/src/feedback-config/index.jsx +0 -111
  165. package/src/form-section.jsx +0 -31
  166. package/src/help.jsx +0 -79
  167. package/src/index.js +0 -55
  168. package/src/input.jsx +0 -72
  169. package/src/inputs.jsx +0 -69
  170. package/src/langs.jsx +0 -111
  171. package/src/layout/__tests__/config.layout.test.jsx +0 -59
  172. package/src/layout/__tests__/layout-content.test.jsx +0 -3
  173. package/src/layout/config-layout.jsx +0 -103
  174. package/src/layout/index.js +0 -4
  175. package/src/layout/layout-contents.jsx +0 -117
  176. package/src/layout/settings-box.jsx +0 -32
  177. package/src/mui-box/index.jsx +0 -56
  178. package/src/number-text-field-custom.jsx +0 -333
  179. package/src/number-text-field.jsx +0 -215
  180. package/src/radio-with-label.jsx +0 -30
  181. package/src/settings/display-size.jsx +0 -53
  182. package/src/settings/index.js +0 -83
  183. package/src/settings/panel.jsx +0 -333
  184. package/src/settings/settings-radio-label.jsx +0 -32
  185. package/src/settings/toggle.jsx +0 -46
  186. package/src/tabs/index.jsx +0 -47
  187. package/src/tags-input/__tests__/index.test.jsx +0 -113
  188. package/src/tags-input/index.jsx +0 -116
  189. package/src/two-choice.jsx +0 -90
  190. package/src/with-stateful-model.jsx +0 -36
@@ -1,376 +0,0 @@
1
- import { render, screen } from '@testing-library/react';
2
- import userEvent from '@testing-library/user-event';
3
- import React from 'react';
4
- import { Langs, LanguageControls } from '../langs';
5
-
6
- describe('Langs Component', () => {
7
- let onChange;
8
- const renderComponent = (extras = {}) => {
9
- const defaults = {
10
- uid: '1',
11
- onChange,
12
- langs: ['en-US', 'es-ES'],
13
- selected: 'en-US',
14
- };
15
- const props = { ...defaults, ...extras };
16
- return render(<Langs {...props} />);
17
- };
18
-
19
- beforeEach(() => {
20
- onChange = jest.fn();
21
- });
22
-
23
- describe('rendering', () => {
24
- it('renders language selector with options', () => {
25
- renderComponent();
26
-
27
- // Select should be present
28
- const select = screen.getByRole('combobox');
29
- expect(select).toBeInTheDocument();
30
-
31
- // Should show selected value - MUI Select displays value as text content
32
- expect(select).toHaveTextContent('en-US');
33
- });
34
-
35
- it('renders with custom label', () => {
36
- renderComponent({ label: 'Choose Language' });
37
- expect(screen.getByText('Choose Language')).toBeInTheDocument();
38
- });
39
-
40
- it('renders all language options', () => {
41
- const { container } = renderComponent({
42
- langs: ['en-US', 'es-ES', 'fr-FR', 'de-DE'],
43
- });
44
-
45
- const select = screen.getByRole('combobox');
46
- expect(select).toBeInTheDocument();
47
- });
48
-
49
- it('renders with multiple languages', () => {
50
- const langs = ['en-US', 'es-ES', 'fr-FR', 'pt-BR'];
51
- renderComponent({ langs });
52
-
53
- const select = screen.getByRole('combobox');
54
- expect(select).toHaveTextContent('en-US');
55
- });
56
-
57
- it('renders FormControl with proper structure', () => {
58
- const { container } = renderComponent();
59
-
60
- expect(container.querySelector('[class*="MuiFormControl"]')).toBeInTheDocument();
61
- });
62
- });
63
-
64
- describe('user interactions', () => {
65
- it('calls onChange when user selects a language', async () => {
66
- const user = userEvent.setup();
67
- renderComponent();
68
-
69
- const select = screen.getByRole('combobox');
70
-
71
- // Open the select and choose es-ES
72
- await user.click(select);
73
- await user.click(screen.getByRole('option', { name: 'es-ES' }));
74
-
75
- expect(onChange).toHaveBeenCalledWith('es-ES');
76
- });
77
-
78
- it('calls onChange with correct value', async () => {
79
- const user = userEvent.setup();
80
- renderComponent({ selected: 'es-ES' });
81
-
82
- const select = screen.getByRole('combobox');
83
-
84
- await user.click(select);
85
- await user.click(screen.getByRole('option', { name: 'en-US' }));
86
-
87
- expect(onChange).toHaveBeenCalledWith('en-US');
88
- });
89
-
90
- it('opens dropdown on click', async () => {
91
- const user = userEvent.setup();
92
- renderComponent({
93
- langs: ['en-US', 'es-ES', 'fr-FR'],
94
- });
95
-
96
- const select = screen.getByRole('combobox');
97
- await user.click(select);
98
-
99
- expect(screen.getByRole('option', { name: 'en-US' })).toBeInTheDocument();
100
- expect(screen.getByRole('option', { name: 'es-ES' })).toBeInTheDocument();
101
- expect(screen.getByRole('option', { name: 'fr-FR' })).toBeInTheDocument();
102
- });
103
-
104
- it('does not call onChange if no onChange prop provided', async () => {
105
- const user = userEvent.setup();
106
- const { container } = render(<Langs uid="1" langs={['en-US', 'es-ES']} selected="en-US" />);
107
-
108
- const select = screen.getByRole('combobox');
109
- await user.click(select);
110
- await user.click(screen.getByRole('option', { name: 'es-ES' }));
111
-
112
- // Should not throw any error
113
- expect(select).toBeInTheDocument();
114
- });
115
- });
116
-
117
- describe('props handling', () => {
118
- it('accepts custom uid', () => {
119
- const customUid = 'custom-uid-123';
120
- const { container } = renderComponent({ uid: customUid });
121
-
122
- const input = container.querySelector(`#${customUid}`);
123
- expect(input).toBeInTheDocument();
124
- });
125
-
126
- it('generates random uid if not provided', () => {
127
- const { container } = render(<Langs onChange={onChange} langs={['en-US', 'es-ES']} selected="en-US" />);
128
-
129
- const select = screen.getByRole('combobox');
130
- expect(select).toBeInTheDocument();
131
- });
132
-
133
- it('handles empty label', () => {
134
- renderComponent({ label: '' });
135
-
136
- const select = screen.getByRole('combobox');
137
- expect(select).toBeInTheDocument();
138
- });
139
-
140
- it('handles very long label', () => {
141
- const longLabel = 'Choose the language you would like to use for editing this content';
142
- renderComponent({ label: longLabel });
143
-
144
- expect(screen.getByText(longLabel)).toBeInTheDocument();
145
- });
146
- });
147
-
148
- describe('value updates', () => {
149
- it('updates selected value when prop changes', () => {
150
- const { rerender } = renderComponent({ selected: 'en-US' });
151
-
152
- let select = screen.getByRole('combobox');
153
- expect(select).toHaveTextContent('en-US');
154
-
155
- rerender(<Langs uid="1" onChange={onChange} langs={['en-US', 'es-ES']} selected="es-ES" />);
156
-
157
- select = screen.getByRole('combobox');
158
- expect(select).toHaveTextContent('es-ES');
159
- });
160
-
161
- it('maintains state when language options change', async () => {
162
- const user = userEvent.setup();
163
- const { rerender } = renderComponent({
164
- langs: ['en-US', 'es-ES'],
165
- selected: 'en-US',
166
- });
167
-
168
- rerender(<Langs uid="1" onChange={onChange} langs={['en-US', 'es-ES', 'fr-FR']} selected="en-US" />);
169
-
170
- const select = screen.getByRole('combobox');
171
- expect(select).toHaveTextContent('en-US');
172
- });
173
- });
174
-
175
- describe('keyboard navigation', () => {
176
- it('opens dropdown with keyboard', async () => {
177
- const user = userEvent.setup();
178
- renderComponent({
179
- langs: ['en-US', 'es-ES'],
180
- });
181
-
182
- const select = screen.getByRole('combobox');
183
- select.focus();
184
-
185
- await user.keyboard(' ');
186
-
187
- expect(screen.getByRole('option', { name: 'en-US' })).toBeInTheDocument();
188
- });
189
- });
190
-
191
- describe('accessibility', () => {
192
- it('has proper label association', () => {
193
- renderComponent({ label: 'Select Language' });
194
-
195
- const select = screen.getByRole('combobox');
196
- expect(select).toBeInTheDocument();
197
- });
198
-
199
- it('renders options with proper roles', async () => {
200
- const user = userEvent.setup();
201
- renderComponent({
202
- langs: ['en-US', 'es-ES', 'fr-FR'],
203
- });
204
-
205
- const select = screen.getByRole('combobox');
206
- await user.click(select);
207
-
208
- const options = screen.getAllByRole('option');
209
- expect(options.length).toBe(3);
210
- });
211
- });
212
- });
213
-
214
- describe('LanguageControls Component', () => {
215
- const defaultProps = {
216
- langs: ['en-US', 'es-ES', 'fr-FR'],
217
- activeLang: 'en-US',
218
- defaultLang: 'en-US',
219
- onActiveLangChange: jest.fn(),
220
- onDefaultLangChange: jest.fn(),
221
- };
222
-
223
- beforeEach(() => {
224
- jest.clearAllMocks();
225
- });
226
-
227
- describe('rendering', () => {
228
- it('renders both language selectors', () => {
229
- render(<LanguageControls {...defaultProps} />);
230
-
231
- expect(screen.getByText('Choose language to edit')).toBeInTheDocument();
232
- expect(screen.getByText('Default language')).toBeInTheDocument();
233
- });
234
-
235
- it('renders with correct initial values', () => {
236
- render(<LanguageControls {...defaultProps} />);
237
-
238
- const selects = screen.getAllByRole('combobox');
239
- expect(selects).toHaveLength(2);
240
- });
241
-
242
- it('applies custom className', () => {
243
- const { container } = render(<LanguageControls {...defaultProps} className="custom-class" />);
244
-
245
- expect(container.querySelector('.custom-class')).toBeInTheDocument();
246
- });
247
- });
248
-
249
- describe('user interactions', () => {
250
- it('calls onActiveLangChange when active language is changed', async () => {
251
- const user = userEvent.setup();
252
- const onActiveLangChange = jest.fn();
253
-
254
- render(<LanguageControls {...defaultProps} activeLang="en-US" onActiveLangChange={onActiveLangChange} />);
255
-
256
- const selects = screen.getAllByRole('combobox');
257
- const activeSelect = selects[0];
258
-
259
- await user.click(activeSelect);
260
- await user.click(screen.getByRole('option', { name: 'es-ES' }));
261
-
262
- expect(onActiveLangChange).toHaveBeenCalledWith('es-ES');
263
- });
264
-
265
- it('calls onDefaultLangChange when default language is changed', async () => {
266
- const user = userEvent.setup();
267
- const onDefaultLangChange = jest.fn();
268
-
269
- render(<LanguageControls {...defaultProps} defaultLang="en-US" onDefaultLangChange={onDefaultLangChange} />);
270
-
271
- const selects = screen.getAllByRole('combobox');
272
- const defaultSelect = selects[1];
273
-
274
- await user.click(defaultSelect);
275
- await user.click(screen.getByRole('option', { name: 'fr-FR' }));
276
-
277
- expect(onDefaultLangChange).toHaveBeenCalledWith('fr-FR');
278
- });
279
-
280
- it('handles independent language changes', async () => {
281
- const user = userEvent.setup();
282
- const onActiveLangChange = jest.fn();
283
- const onDefaultLangChange = jest.fn();
284
-
285
- render(
286
- <LanguageControls
287
- {...defaultProps}
288
- activeLang="en-US"
289
- defaultLang="en-US"
290
- onActiveLangChange={onActiveLangChange}
291
- onDefaultLangChange={onDefaultLangChange}
292
- />,
293
- );
294
-
295
- const selects = screen.getAllByRole('combobox');
296
-
297
- // Change active language
298
- await user.click(selects[0]);
299
- await user.click(screen.getByRole('option', { name: 'es-ES' }));
300
-
301
- expect(onActiveLangChange).toHaveBeenCalledWith('es-ES');
302
- expect(onDefaultLangChange).not.toHaveBeenCalled();
303
- });
304
- });
305
-
306
- describe('props handling', () => {
307
- it('displays correct language options', async () => {
308
- const user = userEvent.setup();
309
- render(<LanguageControls {...defaultProps} langs={['en-US', 'es-ES', 'fr-FR', 'de-DE']} />);
310
-
311
- const selects = screen.getAllByRole('combobox');
312
- await user.click(selects[0]);
313
-
314
- expect(screen.getByRole('option', { name: 'en-US' })).toBeInTheDocument();
315
- expect(screen.getByRole('option', { name: 'es-ES' })).toBeInTheDocument();
316
- expect(screen.getByRole('option', { name: 'fr-FR' })).toBeInTheDocument();
317
- expect(screen.getByRole('option', { name: 'de-DE' })).toBeInTheDocument();
318
- });
319
-
320
- it('maintains different active and default languages', async () => {
321
- const user = userEvent.setup();
322
- render(<LanguageControls {...defaultProps} activeLang="es-ES" defaultLang="en-US" />);
323
-
324
- const selects = screen.getAllByRole('combobox');
325
- expect(selects[0]).toHaveTextContent('es-ES');
326
- expect(selects[1]).toHaveTextContent('en-US');
327
- });
328
- });
329
-
330
- describe('updates', () => {
331
- it('updates when activeLang prop changes', () => {
332
- const { rerender } = render(<LanguageControls {...defaultProps} activeLang="en-US" />);
333
-
334
- let selects = screen.getAllByRole('combobox');
335
- expect(selects[0]).toHaveTextContent('en-US');
336
-
337
- rerender(<LanguageControls {...defaultProps} activeLang="es-ES" />);
338
-
339
- selects = screen.getAllByRole('combobox');
340
- expect(selects[0]).toHaveTextContent('es-ES');
341
- });
342
-
343
- it('updates when defaultLang prop changes', () => {
344
- const { rerender } = render(<LanguageControls {...defaultProps} defaultLang="en-US" />);
345
-
346
- let selects = screen.getAllByRole('combobox');
347
- expect(selects[1]).toHaveTextContent('en-US');
348
-
349
- rerender(<LanguageControls {...defaultProps} defaultLang="fr-FR" />);
350
-
351
- selects = screen.getAllByRole('combobox');
352
- expect(selects[1]).toHaveTextContent('fr-FR');
353
- });
354
-
355
- it('updates when langs prop changes', async () => {
356
- const user = userEvent.setup();
357
- const { rerender } = render(<LanguageControls {...defaultProps} langs={['en-US', 'es-ES']} />);
358
-
359
- rerender(<LanguageControls {...defaultProps} langs={['en-US', 'es-ES', 'fr-FR']} />);
360
-
361
- const selects = screen.getAllByRole('combobox');
362
- await user.click(selects[0]);
363
-
364
- expect(screen.getByRole('option', { name: 'fr-FR' })).toBeInTheDocument();
365
- });
366
- });
367
-
368
- describe('accessibility', () => {
369
- it('has proper semantic structure', () => {
370
- const { container } = render(<LanguageControls {...defaultProps} />);
371
-
372
- const selects = screen.getAllByRole('combobox');
373
- expect(selects.length).toBe(2);
374
- });
375
- });
376
- });
@@ -1,255 +0,0 @@
1
- import React from 'react';
2
- import { fireEvent, render, screen, waitFor } from '@testing-library/react';
3
- import userEvent from '@testing-library/user-event';
4
- import { NumberTextFieldCustom } from '../number-text-field-custom';
5
-
6
- describe('NumberTextFieldCustom', () => {
7
- const defaultProps = {
8
- value: 1,
9
- onChange: jest.fn(),
10
- };
11
-
12
- beforeEach(() => {
13
- jest.clearAllMocks();
14
- });
15
-
16
- describe('rendering', () => {
17
- it('renders input field', () => {
18
- render(<NumberTextFieldCustom {...defaultProps} />);
19
- const input = screen.getByRole('spinbutton');
20
- expect(input).toBeInTheDocument();
21
- });
22
-
23
- it('renders with custom label', () => {
24
- render(<NumberTextFieldCustom {...defaultProps} label="Custom Label" />);
25
- expect(screen.getByLabelText('Custom Label')).toBeInTheDocument();
26
- });
27
-
28
- it('renders add and remove buttons', () => {
29
- render(<NumberTextFieldCustom {...defaultProps} />);
30
- const buttons = screen.getAllByRole('button');
31
- expect(buttons.length).toBeGreaterThanOrEqual(2);
32
- });
33
-
34
- it('renders with custom className', () => {
35
- const { container } = render(<NumberTextFieldCustom {...defaultProps} className="custom-class" />);
36
- expect(container.querySelector('.custom-class')).toBeInTheDocument();
37
- });
38
-
39
- it('renders with custom inputClassName', () => {
40
- const { container } = render(<NumberTextFieldCustom {...defaultProps} inputClassName="input-class" />);
41
- expect(container.querySelector('.input-class')).toBeInTheDocument();
42
- });
43
-
44
- it('renders as disabled when disabled prop is true', () => {
45
- render(<NumberTextFieldCustom {...defaultProps} disabled={true} />);
46
- const input = screen.getByRole('spinbutton');
47
- expect(input).toBeDisabled();
48
- });
49
-
50
- it('renders with error styling when error is true', () => {
51
- render(<NumberTextFieldCustom {...defaultProps} error={true} />);
52
- const input = screen.getByRole('spinbutton');
53
- expect(input).toHaveAttribute('aria-invalid', 'true');
54
- });
55
-
56
- it('renders helper text when provided', () => {
57
- render(<NumberTextFieldCustom {...defaultProps} helperText="This is a helper text" />);
58
- expect(screen.getByText('This is a helper text')).toBeInTheDocument();
59
- });
60
-
61
- it('renders with different variant', () => {
62
- render(<NumberTextFieldCustom {...defaultProps} variant="outlined" />);
63
- const input = screen.getByRole('spinbutton');
64
- expect(input).toBeInTheDocument();
65
- });
66
-
67
- it('renders with text alignment', () => {
68
- const { container } = render(<NumberTextFieldCustom {...defaultProps} textAlign="left" />);
69
- expect(container.querySelector('input')).toBeInTheDocument();
70
- });
71
- });
72
-
73
- describe('custom values', () => {
74
- it('accepts custom values array', () => {
75
- render(<NumberTextFieldCustom {...defaultProps} customValues={['small', 'medium', 'large']} value="medium" />);
76
- const input = screen.getByRole('spinbutton');
77
- expect(input).toBeInTheDocument();
78
- });
79
-
80
- it('handles empty custom values array', () => {
81
- render(<NumberTextFieldCustom {...defaultProps} customValues={[]} value={5} />);
82
- const input = screen.getByRole('spinbutton');
83
- expect(input).toHaveValue(5);
84
- });
85
-
86
- it('displays custom value when selected', () => {
87
- render(<NumberTextFieldCustom {...defaultProps} customValues={['auto', 'fixed', 'dynamic']} value="fixed" />);
88
- const input = screen.getByRole('spinbutton');
89
- expect(input).toBeInTheDocument();
90
- });
91
- });
92
-
93
- describe('step functionality', () => {
94
- it('uses default step of 1', () => {
95
- const onChange = jest.fn();
96
- render(<NumberTextFieldCustom {...defaultProps} value={5} onChange={onChange} />);
97
- expect(screen.getByRole('spinbutton')).toBeInTheDocument();
98
- });
99
-
100
- it('uses custom step value', () => {
101
- const onChange = jest.fn();
102
- render(<NumberTextFieldCustom {...defaultProps} value={5} step={0.5} onChange={onChange} />);
103
- expect(screen.getByRole('spinbutton')).toBeInTheDocument();
104
- });
105
-
106
- it('increments value by step with add button', async () => {
107
- const user = userEvent.setup();
108
- const onChange = jest.fn();
109
- render(<NumberTextFieldCustom {...defaultProps} value={5} step={2} onChange={onChange} />);
110
-
111
- const buttons = screen.getAllByRole('button');
112
- const addButton = buttons.find((btn) => btn.querySelector('[data-testid], svg'));
113
-
114
- if (addButton) {
115
- await user.click(addButton);
116
- }
117
- });
118
-
119
- it('decrements value by step with remove button', async () => {
120
- const user = userEvent.setup();
121
- const onChange = jest.fn();
122
- render(<NumberTextFieldCustom {...defaultProps} value={5} step={1} onChange={onChange} />);
123
-
124
- const buttons = screen.getAllByRole('button');
125
- const removeButton = buttons[0];
126
-
127
- if (removeButton) {
128
- await user.click(removeButton);
129
- }
130
- });
131
- });
132
-
133
- describe('min/max constraints', () => {
134
- it('clamps value to min', async () => {
135
- const user = userEvent.setup();
136
- render(<NumberTextFieldCustom {...defaultProps} value={0} min={1} max={10} />);
137
-
138
- const input = screen.getByRole('spinbutton');
139
- fireEvent.blur(input);
140
-
141
- await waitFor(() => {
142
- expect(input).toHaveValue(1);
143
- });
144
- });
145
-
146
- it('clamps value to max', async () => {
147
- const user = userEvent.setup();
148
- render(<NumberTextFieldCustom {...defaultProps} value={15} min={1} max={10} />);
149
-
150
- const input = screen.getByRole('spinbutton');
151
- fireEvent.blur(input);
152
-
153
- await waitFor(() => {
154
- expect(input).toHaveValue(10);
155
- });
156
- });
157
-
158
- it('handles only min constraint', () => {
159
- render(<NumberTextFieldCustom {...defaultProps} value={5} min={3} />);
160
- expect(screen.getByRole('spinbutton')).toHaveValue(5);
161
- });
162
-
163
- it('handles only max constraint', () => {
164
- render(<NumberTextFieldCustom {...defaultProps} value={5} max={10} />);
165
- expect(screen.getByRole('spinbutton')).toHaveValue(5);
166
- });
167
- });
168
-
169
- describe('props updates', () => {
170
- it('updates value when prop changes', () => {
171
- const { rerender } = render(<NumberTextFieldCustom {...defaultProps} value={5} />);
172
-
173
- let input = screen.getByRole('spinbutton');
174
- expect(input).toHaveValue(5);
175
-
176
- rerender(<NumberTextFieldCustom {...defaultProps} value={8} />);
177
-
178
- input = screen.getByRole('spinbutton');
179
- expect(input).toHaveValue(8);
180
- });
181
-
182
- it('updates when label changes', () => {
183
- const { rerender } = render(<NumberTextFieldCustom {...defaultProps} label="Old Label" />);
184
-
185
- expect(screen.getByLabelText('Old Label')).toBeInTheDocument();
186
-
187
- rerender(<NumberTextFieldCustom {...defaultProps} label="New Label" />);
188
-
189
- expect(screen.getByLabelText('New Label')).toBeInTheDocument();
190
- });
191
-
192
- it('updates constraints when min/max props change', () => {
193
- const { rerender } = render(<NumberTextFieldCustom {...defaultProps} value={5} min={1} max={10} />);
194
-
195
- rerender(<NumberTextFieldCustom {...defaultProps} value={5} min={1} max={8} />);
196
-
197
- expect(screen.getByRole('spinbutton')).toBeInTheDocument();
198
- });
199
- });
200
-
201
- describe('text alignment', () => {
202
- it('renders with center alignment (default)', () => {
203
- render(<NumberTextFieldCustom {...defaultProps} value={5} />);
204
- expect(screen.getByRole('spinbutton')).toBeInTheDocument();
205
- });
206
-
207
- it('renders with custom left alignment', () => {
208
- render(<NumberTextFieldCustom {...defaultProps} value={5} textAlign="left" />);
209
- expect(screen.getByRole('spinbutton')).toBeInTheDocument();
210
- });
211
-
212
- it('renders with right alignment', () => {
213
- render(<NumberTextFieldCustom {...defaultProps} value={5} textAlign="right" />);
214
- expect(screen.getByRole('spinbutton')).toBeInTheDocument();
215
- });
216
- });
217
-
218
- describe('type property', () => {
219
- it('renders as number type by default', () => {
220
- const { container } = render(<NumberTextFieldCustom {...defaultProps} value={5} />);
221
- const input = container.querySelector('input[type="number"]');
222
- expect(input).toBeInTheDocument();
223
- });
224
-
225
- it('can render with custom type', () => {
226
- const { container } = render(<NumberTextFieldCustom {...defaultProps} value={5} type="text" />);
227
- const input = container.querySelector('input');
228
- expect(input).toBeInTheDocument();
229
- });
230
- });
231
-
232
- describe('accessibility', () => {
233
- it('renders as a spinbutton', () => {
234
- render(<NumberTextFieldCustom {...defaultProps} />);
235
- expect(screen.getByRole('spinbutton')).toBeInTheDocument();
236
- });
237
-
238
- it('has proper label association', () => {
239
- render(<NumberTextFieldCustom {...defaultProps} label="Price" />);
240
- expect(screen.getByLabelText('Price')).toBeInTheDocument();
241
- });
242
-
243
- it('supports keyboard navigation', async () => {
244
- const user = userEvent.setup();
245
- render(<NumberTextFieldCustom {...defaultProps} value={5} />);
246
-
247
- const input = screen.getByRole('spinbutton');
248
- input.focus();
249
- expect(input).toHaveFocus();
250
-
251
- await user.keyboard('{ArrowUp}');
252
- expect(input).toHaveFocus();
253
- });
254
- });
255
- });