@pie-lib/config-ui 11.30.3-next.2 → 11.30.3-next.205

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 (123) hide show
  1. package/CHANGELOG.md +19 -67
  2. package/lib/alert-dialog.js +35 -42
  3. package/lib/alert-dialog.js.map +1 -1
  4. package/lib/checkbox.js +56 -71
  5. package/lib/checkbox.js.map +1 -1
  6. package/lib/choice-configuration/feedback-menu.js +29 -64
  7. package/lib/choice-configuration/feedback-menu.js.map +1 -1
  8. package/lib/choice-configuration/index.js +202 -262
  9. package/lib/choice-configuration/index.js.map +1 -1
  10. package/lib/choice-utils.js +6 -18
  11. package/lib/choice-utils.js.map +1 -1
  12. package/lib/feedback-config/feedback-selector.js +79 -115
  13. package/lib/feedback-config/feedback-selector.js.map +1 -1
  14. package/lib/feedback-config/group.js +26 -40
  15. package/lib/feedback-config/group.js.map +1 -1
  16. package/lib/feedback-config/index.js +47 -90
  17. package/lib/feedback-config/index.js.map +1 -1
  18. package/lib/form-section.js +31 -33
  19. package/lib/form-section.js.map +1 -1
  20. package/lib/help.js +39 -80
  21. package/lib/help.js.map +1 -1
  22. package/lib/index.js +1 -31
  23. package/lib/index.js.map +1 -1
  24. package/lib/input.js +21 -54
  25. package/lib/input.js.map +1 -1
  26. package/lib/inputs.js +61 -95
  27. package/lib/inputs.js.map +1 -1
  28. package/lib/langs.js +58 -101
  29. package/lib/langs.js.map +1 -1
  30. package/lib/layout/config-layout.js +40 -70
  31. package/lib/layout/config-layout.js.map +1 -1
  32. package/lib/layout/index.js +0 -3
  33. package/lib/layout/index.js.map +1 -1
  34. package/lib/layout/layout-contents.js +72 -103
  35. package/lib/layout/layout-contents.js.map +1 -1
  36. package/lib/layout/settings-box.js +27 -56
  37. package/lib/layout/settings-box.js.map +1 -1
  38. package/lib/mui-box/index.js +41 -57
  39. package/lib/mui-box/index.js.map +1 -1
  40. package/lib/number-text-field-custom.js +79 -161
  41. package/lib/number-text-field-custom.js.map +1 -1
  42. package/lib/number-text-field.js +80 -114
  43. package/lib/number-text-field.js.map +1 -1
  44. package/lib/radio-with-label.js +30 -31
  45. package/lib/radio-with-label.js.map +1 -1
  46. package/lib/settings/display-size.js +16 -32
  47. package/lib/settings/display-size.js.map +1 -1
  48. package/lib/settings/index.js +14 -47
  49. package/lib/settings/index.js.map +1 -1
  50. package/lib/settings/panel.js +159 -229
  51. package/lib/settings/panel.js.map +1 -1
  52. package/lib/settings/settings-radio-label.js +28 -30
  53. package/lib/settings/settings-radio-label.js.map +1 -1
  54. package/lib/settings/toggle.js +35 -46
  55. package/lib/settings/toggle.js.map +1 -1
  56. package/lib/tabs/index.js +22 -57
  57. package/lib/tabs/index.js.map +1 -1
  58. package/lib/tags-input/index.js +50 -99
  59. package/lib/tags-input/index.js.map +1 -1
  60. package/lib/two-choice.js +46 -90
  61. package/lib/two-choice.js.map +1 -1
  62. package/lib/with-stateful-model.js +8 -31
  63. package/lib/with-stateful-model.js.map +1 -1
  64. package/package.json +12 -20
  65. package/src/__tests__/alert-dialog.test.jsx +283 -0
  66. package/src/__tests__/checkbox.test.jsx +249 -0
  67. package/src/__tests__/form-section.test.jsx +334 -0
  68. package/src/__tests__/help.test.jsx +184 -0
  69. package/src/__tests__/input.test.jsx +192 -0
  70. package/src/__tests__/langs.test.jsx +435 -15
  71. package/src/__tests__/number-text-field-custom.test.jsx +438 -0
  72. package/src/__tests__/number-text-field.test.jsx +295 -102
  73. package/src/__tests__/radio-with-label.test.jsx +259 -0
  74. package/src/__tests__/settings-panel.test.js +66 -83
  75. package/src/__tests__/settings.test.jsx +515 -0
  76. package/src/__tests__/tabs.test.jsx +193 -0
  77. package/src/__tests__/two-choice.test.js +104 -18
  78. package/src/__tests__/with-stateful-model.test.jsx +145 -0
  79. package/src/alert-dialog.jsx +21 -19
  80. package/src/checkbox.jsx +42 -46
  81. package/src/choice-configuration/__tests__/feedback-menu.test.jsx +157 -4
  82. package/src/choice-configuration/__tests__/index.test.jsx +198 -56
  83. package/src/choice-configuration/feedback-menu.jsx +6 -6
  84. package/src/choice-configuration/index.jsx +201 -203
  85. package/src/feedback-config/__tests__/feedback-config.test.jsx +130 -60
  86. package/src/feedback-config/__tests__/feedback-selector.test.jsx +81 -44
  87. package/src/feedback-config/feedback-selector.jsx +50 -55
  88. package/src/feedback-config/group.jsx +21 -22
  89. package/src/feedback-config/index.jsx +27 -29
  90. package/src/form-section.jsx +26 -18
  91. package/src/help.jsx +20 -28
  92. package/src/input.jsx +1 -1
  93. package/src/inputs.jsx +34 -50
  94. package/src/langs.jsx +41 -46
  95. package/src/layout/__tests__/config.layout.test.jsx +55 -38
  96. package/src/layout/config-layout.jsx +38 -32
  97. package/src/layout/layout-contents.jsx +38 -39
  98. package/src/layout/settings-box.jsx +16 -19
  99. package/src/mui-box/index.jsx +35 -43
  100. package/src/number-text-field-custom.jsx +30 -36
  101. package/src/number-text-field.jsx +45 -29
  102. package/src/radio-with-label.jsx +25 -13
  103. package/src/settings/display-size.jsx +12 -11
  104. package/src/settings/panel.jsx +97 -91
  105. package/src/settings/settings-radio-label.jsx +25 -13
  106. package/src/settings/toggle.jsx +30 -29
  107. package/src/tabs/index.jsx +8 -8
  108. package/src/tags-input/__tests__/index.test.jsx +88 -37
  109. package/src/tags-input/index.jsx +35 -38
  110. package/src/two-choice.jsx +15 -19
  111. package/esm/index.css +0 -847
  112. package/esm/index.js +0 -213950
  113. package/esm/index.js.map +0 -1
  114. package/esm/package.json +0 -3
  115. package/src/__tests__/__snapshots__/langs.test.jsx.snap +0 -32
  116. package/src/__tests__/__snapshots__/settings-panel.test.js.snap +0 -115
  117. package/src/__tests__/__snapshots__/two-choice.test.js.snap +0 -171
  118. package/src/choice-configuration/__tests__/__snapshots__/feedback-menu.test.jsx.snap +0 -51
  119. package/src/choice-configuration/__tests__/__snapshots__/index.test.jsx.snap +0 -519
  120. package/src/feedback-config/__tests__/__snapshots__/feedback-config.test.jsx.snap +0 -27
  121. package/src/feedback-config/__tests__/__snapshots__/feedback-selector.test.jsx.snap +0 -38
  122. package/src/layout/__tests__/__snapshots__/config.layout.test.jsx.snap +0 -59
  123. package/src/tags-input/__tests__/__snapshots__/index.test.jsx.snap +0 -170
@@ -0,0 +1,259 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import RadioWithLabel from '../radio-with-label';
5
+
6
+ describe('RadioWithLabel Component', () => {
7
+ const onChange = jest.fn();
8
+
9
+ beforeEach(() => {
10
+ onChange.mockClear();
11
+ });
12
+
13
+ describe('Rendering', () => {
14
+ it('should render radio button with label', () => {
15
+ render(
16
+ <RadioWithLabel
17
+ label="Option 1"
18
+ value="option1"
19
+ checked={false}
20
+ onChange={onChange}
21
+ />,
22
+ );
23
+
24
+ expect(screen.getByText('Option 1')).toBeInTheDocument();
25
+ expect(screen.getByRole('radio')).toBeInTheDocument();
26
+ });
27
+
28
+ it('should render checked radio button', () => {
29
+ render(
30
+ <RadioWithLabel
31
+ label="Selected"
32
+ value="selected"
33
+ checked={true}
34
+ onChange={onChange}
35
+ />,
36
+ );
37
+
38
+ expect(screen.getByRole('radio')).toBeChecked();
39
+ });
40
+
41
+ it('should render unchecked radio button', () => {
42
+ render(
43
+ <RadioWithLabel
44
+ label="Unselected"
45
+ value="unselected"
46
+ checked={false}
47
+ onChange={onChange}
48
+ />,
49
+ );
50
+
51
+ expect(screen.getByRole('radio')).not.toBeChecked();
52
+ });
53
+ });
54
+
55
+ describe('User interaction', () => {
56
+ it('should call onChange when radio button is clicked', async () => {
57
+ const user = userEvent.setup();
58
+ render(
59
+ <RadioWithLabel
60
+ label="Option"
61
+ value="option"
62
+ checked={false}
63
+ onChange={onChange}
64
+ />,
65
+ );
66
+
67
+ const radio = screen.getByRole('radio');
68
+ await user.click(radio);
69
+
70
+ expect(onChange).toHaveBeenCalled();
71
+ });
72
+
73
+ it('should call onChange when label is clicked', async () => {
74
+ const user = userEvent.setup();
75
+ render(
76
+ <RadioWithLabel
77
+ label="Click me"
78
+ value="test"
79
+ checked={false}
80
+ onChange={onChange}
81
+ />,
82
+ );
83
+
84
+ const label = screen.getByText('Click me');
85
+ await user.click(label);
86
+
87
+ expect(onChange).toHaveBeenCalled();
88
+ });
89
+ });
90
+
91
+ describe('Props', () => {
92
+ it('should accept different value types', () => {
93
+ const { container: stringContainer } = render(
94
+ <RadioWithLabel
95
+ label="String value"
96
+ value="string"
97
+ checked={false}
98
+ onChange={onChange}
99
+ />,
100
+ );
101
+
102
+ const { container: numberContainer } = render(
103
+ <RadioWithLabel
104
+ label="Number value"
105
+ value={123}
106
+ checked={false}
107
+ onChange={onChange}
108
+ />,
109
+ );
110
+
111
+ expect(stringContainer.querySelector('input[type="radio"]')).toBeInTheDocument();
112
+ expect(numberContainer.querySelector('input[type="radio"]')).toBeInTheDocument();
113
+ });
114
+
115
+ it('should display different labels', () => {
116
+ render(
117
+ <>
118
+ <RadioWithLabel
119
+ label="Label A"
120
+ value="a"
121
+ checked={false}
122
+ onChange={onChange}
123
+ />
124
+ <RadioWithLabel
125
+ label="Label B"
126
+ value="b"
127
+ checked={false}
128
+ onChange={onChange}
129
+ />
130
+ </>,
131
+ );
132
+
133
+ expect(screen.getByText('Label A')).toBeInTheDocument();
134
+ expect(screen.getByText('Label B')).toBeInTheDocument();
135
+ });
136
+ });
137
+
138
+ describe('Radio button group behavior', () => {
139
+ it('should allow multiple radio buttons to be rendered', () => {
140
+ render(
141
+ <>
142
+ <RadioWithLabel
143
+ label="Option 1"
144
+ value="opt1"
145
+ checked={true}
146
+ onChange={onChange}
147
+ />
148
+ <RadioWithLabel
149
+ label="Option 2"
150
+ value="opt2"
151
+ checked={false}
152
+ onChange={onChange}
153
+ />
154
+ <RadioWithLabel
155
+ label="Option 3"
156
+ value="opt3"
157
+ checked={false}
158
+ onChange={onChange}
159
+ />
160
+ </>,
161
+ );
162
+
163
+ const radios = screen.getAllByRole('radio');
164
+ expect(radios).toHaveLength(3);
165
+ expect(radios[0]).toBeChecked();
166
+ expect(radios[1]).not.toBeChecked();
167
+ expect(radios[2]).not.toBeChecked();
168
+ });
169
+
170
+ it('should handle independent onChange callbacks for multiple radios', async () => {
171
+ const user = userEvent.setup();
172
+ const onChange1 = jest.fn();
173
+ const onChange2 = jest.fn();
174
+ const onChange3 = jest.fn();
175
+
176
+ render(
177
+ <>
178
+ <RadioWithLabel
179
+ label="Option 1"
180
+ value="opt1"
181
+ checked={true}
182
+ onChange={onChange1}
183
+ />
184
+ <RadioWithLabel
185
+ label="Option 2"
186
+ value="opt2"
187
+ checked={false}
188
+ onChange={onChange2}
189
+ />
190
+ <RadioWithLabel
191
+ label="Option 3"
192
+ value="opt3"
193
+ checked={false}
194
+ onChange={onChange3}
195
+ />
196
+ </>,
197
+ );
198
+
199
+ const radios = screen.getAllByRole('radio');
200
+
201
+ await user.click(radios[1]);
202
+ expect(onChange2).toHaveBeenCalled();
203
+ expect(onChange1).not.toHaveBeenCalled();
204
+ expect(onChange3).not.toHaveBeenCalled();
205
+
206
+ onChange2.mockClear();
207
+
208
+ await user.click(radios[2]);
209
+ expect(onChange3).toHaveBeenCalled();
210
+ expect(onChange1).not.toHaveBeenCalled();
211
+ expect(onChange2).not.toHaveBeenCalled();
212
+ });
213
+ });
214
+
215
+ describe('Styling', () => {
216
+ it('should render with correct styling classes', () => {
217
+ const { container } = render(
218
+ <RadioWithLabel
219
+ label="Styled"
220
+ value="styled"
221
+ checked={false}
222
+ onChange={onChange}
223
+ />,
224
+ );
225
+
226
+ expect(container.querySelector('[class*="MuiFormControlLabel"]')).toBeInTheDocument();
227
+ expect(container.querySelector('[class*="MuiRadio"]')).toBeInTheDocument();
228
+ });
229
+ });
230
+
231
+ describe('Edge cases', () => {
232
+ it('should handle empty string label', () => {
233
+ render(
234
+ <RadioWithLabel
235
+ label=""
236
+ value="empty"
237
+ checked={false}
238
+ onChange={onChange}
239
+ />,
240
+ );
241
+
242
+ expect(screen.getByRole('radio')).toBeInTheDocument();
243
+ });
244
+
245
+ it('should handle long labels', () => {
246
+ const longLabel = 'This is a very long label that should wrap properly and not break the layout';
247
+ render(
248
+ <RadioWithLabel
249
+ label={longLabel}
250
+ value="long"
251
+ checked={false}
252
+ onChange={onChange}
253
+ />,
254
+ );
255
+
256
+ expect(screen.getByText(longLabel)).toBeInTheDocument();
257
+ });
258
+ });
259
+ });
@@ -1,54 +1,42 @@
1
1
  import React from 'react';
2
- import { shallow } from 'enzyme';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import { Panel } from '../settings/panel';
4
4
  import { toggle, radio, dropdown, numberField, numberFields } from '../settings';
5
5
 
6
6
  describe('Settings Panel', () => {
7
- let w;
8
- let onChange = jest.fn();
9
- let configure = {
10
- orientationLabel: 'Orientation',
11
-
12
- settingsOrientation: true,
13
- editChoiceLabel: false,
14
- };
15
- let model = {
16
- choiceAreaLayout: 'vertical',
17
- };
18
-
19
- let groups = ({ configure }) => ({
20
- 'Group 1': {
21
- choiceAreaLayout: configure.settingsOrientation && {
22
- type: 'radio',
23
- label: configure.orientationLabel,
24
- choices: [
25
- { label: 'opt1', value: 'opt1' },
26
- { label: 'opt2', value: 'opt2' },
27
- ],
28
- equationEditor: dropdown('Dropdown', ['geometry', 'advanced-algebra', 'statistics', 'miscellaneous']),
29
- graph: numberFields('Graph Display Size', {
30
- domain: {
31
- label: 'Domain',
32
- suffix: 'px',
33
- },
34
- range: {
35
- label: 'Range',
36
- suffix: 'px',
37
- },
38
- width: {
39
- label: 'Width',
40
- suffix: 'px',
41
- min: 50,
42
- max: 250,
43
- },
44
- }),
7
+ let onChange;
8
+ let configure;
9
+ let model;
10
+ let groups;
11
+
12
+ beforeEach(() => {
13
+ onChange = jest.fn();
14
+ configure = {
15
+ orientationLabel: 'Orientation',
16
+ settingsOrientation: true,
17
+ editChoiceLabel: false,
18
+ };
19
+ model = {
20
+ choiceAreaLayout: 'vertical',
21
+ };
22
+
23
+ groups = ({ configure }) => ({
24
+ 'Group 1': {
25
+ choiceAreaLayout: configure.settingsOrientation && {
26
+ type: 'radio',
27
+ label: configure.orientationLabel,
28
+ choices: [
29
+ { label: 'opt1', value: 'opt1' },
30
+ { label: 'opt2', value: 'opt2' },
31
+ ],
32
+ },
33
+ editChoiceLabel: { type: 'toggle', label: 'Edit choice label', isConfigProperty: true },
45
34
  },
46
- editChoiceLabel: { type: 'toggle', label: 'Edit choice label', isConfigProperty: true },
47
- },
35
+ });
48
36
  });
49
37
 
50
- const wrapper = (extras) => {
51
- return shallow(
38
+ const renderComponent = (extras = {}) => {
39
+ return render(
52
40
  <Panel
53
41
  model={model}
54
42
  configuration={configure}
@@ -60,58 +48,53 @@ describe('Settings Panel', () => {
60
48
  );
61
49
  };
62
50
 
63
- describe('snapshot', () => {
64
- it('renders', () => {
65
- w = wrapper();
51
+ describe('rendering', () => {
52
+ it('renders settings panel', () => {
53
+ renderComponent();
66
54
 
67
- expect(w).toMatchSnapshot();
55
+ expect(screen.getByText('Group 1')).toBeInTheDocument();
68
56
  });
69
57
 
70
- it('does not render radio buttons', () => {
71
- w = wrapper({
72
- groups: groups({
73
- configure: {
74
- ...configure,
75
- settingsOrientation: false,
76
- },
77
- }),
78
- });
58
+ it('renders toggle settings', () => {
59
+ renderComponent();
79
60
 
80
- expect(w).toMatchSnapshot();
61
+ // Toggle components render with Switch role in MUI v5
62
+ const toggles = screen.getAllByRole('switch');
63
+ expect(toggles.length).toBeGreaterThan(0);
81
64
  });
82
- });
83
65
 
84
- describe('logic', () => {
85
- describe('onChange gets called', () => {
86
- it('updates model props', () => {
87
- w.instance().change('test', false);
88
-
89
- expect(onChange).toBeCalledWith(
90
- {
91
- ...model,
92
- test: false,
93
- },
94
- 'test',
95
- );
96
- });
66
+ it('conditionally renders radio buttons based on configuration', () => {
67
+ renderComponent();
68
+
69
+ // Should render radio when settingsOrientation is true
70
+ expect(screen.getByText('Orientation')).toBeInTheDocument();
71
+ });
97
72
 
98
- it('updates configuration props', () => {
99
- w.instance().change('test.test', true, true);
100
-
101
- expect(onChange).toBeCalledWith(
102
- {
103
- ...configure,
104
- test: {
105
- test: true,
106
- },
107
- },
108
- 'test.test',
109
- );
73
+ it('does not render radio buttons when disabled in configuration', () => {
74
+ const disabledGroups = groups({
75
+ configure: {
76
+ ...configure,
77
+ settingsOrientation: false,
78
+ },
110
79
  });
80
+
81
+ render(
82
+ <Panel
83
+ model={model}
84
+ configuration={{ ...configure, settingsOrientation: false }}
85
+ onChangeModel={onChange}
86
+ onChangeConfiguration={onChange}
87
+ groups={disabledGroups}
88
+ />,
89
+ );
90
+
91
+ // Should not render radio when settingsOrientation is false
92
+ expect(screen.queryByText('Orientation')).not.toBeInTheDocument();
111
93
  });
112
94
  });
113
95
  });
114
96
 
97
+ // Utility function tests - these are simple unit tests that don't need RTL
115
98
  describe('toggle', () => {
116
99
  it('returns a toggle type object', () => {
117
100
  const setting = toggle('Label');