@coveord/plasma-mantine 55.7.2-next.21 → 55.7.2-next.23

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 (117) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/.turbo/turbo-test.log +53 -51
  3. package/__mocks__/@monaco-editor/react.tsx +1 -0
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/cjs/components/checkbox/CheckboxIcon.d.ts +7 -0
  6. package/dist/cjs/components/checkbox/CheckboxIcon.d.ts.map +1 -0
  7. package/dist/cjs/components/checkbox/CheckboxIcon.js +29 -0
  8. package/dist/cjs/components/checkbox/CheckboxIcon.js.map +1 -0
  9. package/dist/cjs/components/checkbox/index.d.ts +2 -0
  10. package/dist/cjs/components/checkbox/index.d.ts.map +1 -0
  11. package/dist/cjs/components/checkbox/index.js +8 -0
  12. package/dist/cjs/components/checkbox/index.js.map +1 -0
  13. package/dist/cjs/components/code-editor/CodeEditor.d.ts.map +1 -1
  14. package/dist/cjs/components/code-editor/CodeEditor.js +19 -21
  15. package/dist/cjs/components/code-editor/CodeEditor.js.map +1 -1
  16. package/dist/cjs/components/code-editor/CodeEditor.module.css +10 -6
  17. package/dist/cjs/components/collection/CollectionItem.d.ts.map +1 -1
  18. package/dist/cjs/components/collection/CollectionItem.js +9 -4
  19. package/dist/cjs/components/collection/CollectionItem.js.map +1 -1
  20. package/dist/cjs/components/index.d.ts +2 -0
  21. package/dist/cjs/components/index.d.ts.map +1 -1
  22. package/dist/cjs/components/index.js +2 -0
  23. package/dist/cjs/components/index.js.map +1 -1
  24. package/dist/cjs/components/loader/CircleLoader.d.ts +3 -0
  25. package/dist/cjs/components/loader/CircleLoader.d.ts.map +1 -0
  26. package/dist/cjs/components/loader/CircleLoader.js +32 -0
  27. package/dist/cjs/components/loader/CircleLoader.js.map +1 -0
  28. package/dist/cjs/components/loader/CircleLoader.module.css +29 -0
  29. package/dist/cjs/components/loader/index.d.ts +2 -0
  30. package/dist/cjs/components/loader/index.d.ts.map +1 -0
  31. package/dist/cjs/components/loader/index.js +8 -0
  32. package/dist/cjs/components/loader/index.js.map +1 -0
  33. package/dist/cjs/components/read-only/ReadOnlyInputStyles.js +2 -2
  34. package/dist/cjs/components/read-only/ReadOnlyInputStyles.js.map +1 -1
  35. package/dist/cjs/components/table/layouts/row-layout/RowLayout.module.css +1 -1
  36. package/dist/cjs/styles/Badge.module.css +2 -0
  37. package/dist/cjs/styles/Checkbox.module.css +41 -5
  38. package/dist/cjs/styles/CheckboxIndicator.module.css +8 -1
  39. package/dist/cjs/styles/Input.module.css +8 -2
  40. package/dist/cjs/styles/Pagination.module.css +10 -1
  41. package/dist/cjs/styles/Radio.module.css +30 -2
  42. package/dist/cjs/styles/ReadOnlyInput.module.css +7 -3
  43. package/dist/cjs/styles/Select.module.css +46 -0
  44. package/dist/cjs/theme/Theme.d.ts.map +1 -1
  45. package/dist/cjs/theme/Theme.js +16 -19
  46. package/dist/cjs/theme/Theme.js.map +1 -1
  47. package/dist/cjs/theme/plasmaCSSVariablesResolver.d.ts.map +1 -1
  48. package/dist/cjs/theme/plasmaCSSVariablesResolver.js +6 -1
  49. package/dist/cjs/theme/plasmaCSSVariablesResolver.js.map +1 -1
  50. package/dist/esm/components/checkbox/CheckboxIcon.d.ts +7 -0
  51. package/dist/esm/components/checkbox/CheckboxIcon.d.ts.map +1 -0
  52. package/dist/esm/components/checkbox/CheckboxIcon.js +16 -0
  53. package/dist/esm/components/checkbox/CheckboxIcon.js.map +1 -0
  54. package/dist/esm/components/checkbox/index.d.ts +2 -0
  55. package/dist/esm/components/checkbox/index.d.ts.map +1 -0
  56. package/dist/esm/components/checkbox/index.js +3 -0
  57. package/dist/esm/components/checkbox/index.js.map +1 -0
  58. package/dist/esm/components/code-editor/CodeEditor.d.ts.map +1 -1
  59. package/dist/esm/components/code-editor/CodeEditor.js +18 -19
  60. package/dist/esm/components/code-editor/CodeEditor.js.map +1 -1
  61. package/dist/esm/components/code-editor/CodeEditor.module.css +10 -6
  62. package/dist/esm/components/collection/CollectionItem.d.ts.map +1 -1
  63. package/dist/esm/components/collection/CollectionItem.js +5 -2
  64. package/dist/esm/components/collection/CollectionItem.js.map +1 -1
  65. package/dist/esm/components/index.d.ts +2 -0
  66. package/dist/esm/components/index.d.ts.map +1 -1
  67. package/dist/esm/components/index.js +2 -0
  68. package/dist/esm/components/index.js.map +1 -1
  69. package/dist/esm/components/loader/CircleLoader.d.ts +3 -0
  70. package/dist/esm/components/loader/CircleLoader.d.ts.map +1 -0
  71. package/dist/esm/components/loader/CircleLoader.js +13 -0
  72. package/dist/esm/components/loader/CircleLoader.js.map +1 -0
  73. package/dist/esm/components/loader/CircleLoader.module.css +29 -0
  74. package/dist/esm/components/loader/index.d.ts +2 -0
  75. package/dist/esm/components/loader/index.d.ts.map +1 -0
  76. package/dist/esm/components/loader/index.js +3 -0
  77. package/dist/esm/components/loader/index.js.map +1 -0
  78. package/dist/esm/components/read-only/ReadOnlyInputStyles.js +2 -2
  79. package/dist/esm/components/read-only/ReadOnlyInputStyles.js.map +1 -1
  80. package/dist/esm/components/table/layouts/row-layout/RowLayout.module.css +1 -1
  81. package/dist/esm/styles/Badge.module.css +2 -0
  82. package/dist/esm/styles/Checkbox.module.css +41 -5
  83. package/dist/esm/styles/CheckboxIndicator.module.css +8 -1
  84. package/dist/esm/styles/Input.module.css +8 -2
  85. package/dist/esm/styles/Pagination.module.css +10 -1
  86. package/dist/esm/styles/Radio.module.css +30 -2
  87. package/dist/esm/styles/ReadOnlyInput.module.css +7 -3
  88. package/dist/esm/styles/Select.module.css +46 -0
  89. package/dist/esm/theme/Theme.d.ts.map +1 -1
  90. package/dist/esm/theme/Theme.js +17 -20
  91. package/dist/esm/theme/Theme.js.map +1 -1
  92. package/dist/esm/theme/plasmaCSSVariablesResolver.d.ts.map +1 -1
  93. package/dist/esm/theme/plasmaCSSVariablesResolver.js +6 -1
  94. package/dist/esm/theme/plasmaCSSVariablesResolver.js.map +1 -1
  95. package/package.json +3 -3
  96. package/src/components/checkbox/CheckboxIcon.tsx +14 -0
  97. package/src/components/checkbox/index.ts +1 -0
  98. package/src/components/code-editor/CodeEditor.module.css +10 -6
  99. package/src/components/code-editor/CodeEditor.tsx +23 -26
  100. package/src/components/collection/CollectionItem.tsx +9 -3
  101. package/src/components/collection/__tests__/Collection.spec.tsx +140 -44
  102. package/src/components/index.ts +2 -0
  103. package/src/components/loader/CircleLoader.module.css +29 -0
  104. package/src/components/loader/CircleLoader.tsx +8 -0
  105. package/src/components/loader/index.ts +1 -0
  106. package/src/components/read-only/ReadOnlyInputStyles.ts +2 -2
  107. package/src/components/table/layouts/row-layout/RowLayout.module.css +1 -1
  108. package/src/styles/Badge.module.css +2 -0
  109. package/src/styles/Checkbox.module.css +41 -5
  110. package/src/styles/CheckboxIndicator.module.css +8 -1
  111. package/src/styles/Input.module.css +8 -2
  112. package/src/styles/Pagination.module.css +10 -1
  113. package/src/styles/Radio.module.css +30 -2
  114. package/src/styles/ReadOnlyInput.module.css +7 -3
  115. package/src/styles/Select.module.css +46 -0
  116. package/src/theme/Theme.tsx +9 -14
  117. package/src/theme/plasmaCSSVariablesResolver.ts +11 -1
@@ -13,21 +13,48 @@ describe('Collection', () => {
13
13
  });
14
14
  return (
15
15
  <Collection<string> newItem="" {...form.getInputProps('fruits')}>
16
- {(name) => <span data-testid="item">{name}</span>}
16
+ {(name) => <span>{name}</span>}
17
17
  </Collection>
18
18
  );
19
19
  };
20
20
 
21
21
  render(<Fixture />);
22
22
 
23
- const items = screen.getAllByTestId('item');
23
+ const items = screen.getAllByTestId(/item-/);
24
+ expect(items).toHaveLength(2);
25
+ expect(screen.queryByTestId('item-0')).toHaveTextContent('banana');
26
+ expect(screen.queryByTestId('item-1')).toHaveTextContent('orange');
27
+ expect(screen.getByTestId('item-0')).toBeInTheDocument();
28
+ expect(screen.getByTestId('item-1')).toBeInTheDocument();
29
+ });
30
+
31
+ it('renders one item for each initial values in the form with custom id', () => {
32
+ const getItemId = (item: string) => `id-${item}`;
33
+
34
+ const Fixture = () => {
35
+ const form = useForm({
36
+ initialValues: {fruits: ['banana', 'orange']},
37
+ enhanceGetInputProps: (payload) => ({...enhanceWithCollectionProps(payload, 'fruits')}),
38
+ });
39
+ return (
40
+ <Collection<string> getItemId={getItemId} newItem="" {...form.getInputProps('fruits')}>
41
+ {(name) => <span>{name}</span>}
42
+ </Collection>
43
+ );
44
+ };
45
+
46
+ render(<Fixture />);
47
+
48
+ const items = screen.getAllByTestId(/item-/);
24
49
  expect(items).toHaveLength(2);
25
50
  expect(items[0]).toHaveTextContent('banana');
26
51
  expect(items[1]).toHaveTextContent('orange');
52
+ expect(screen.getByTestId('item-id-orange')).toBeInTheDocument();
53
+ expect(screen.getByTestId('item-id-banana')).toBeInTheDocument();
27
54
  });
28
55
 
29
56
  it('removes the item when clicking on its remove button', async () => {
30
- const user = userEvent.setup({delay: null});
57
+ const user = userEvent.setup();
31
58
  const Fixture = () => {
32
59
  const form = useForm({
33
60
  initialValues: {fruits: ['banana', 'orange']},
@@ -36,7 +63,7 @@ describe('Collection', () => {
36
63
  return (
37
64
  <>
38
65
  <Collection newItem="" {...form.getInputProps('fruits')}>
39
- {(name) => <span data-testid="item">{name}</span>}
66
+ {(name) => <span>{name}</span>}
40
67
  </Collection>
41
68
  <div data-testid="form-state">{JSON.stringify(form.values)}</div>
42
69
  </>
@@ -44,21 +71,57 @@ describe('Collection', () => {
44
71
  };
45
72
 
46
73
  render(<Fixture />);
47
- let items = screen.getAllByTestId('item');
74
+ let items = screen.getAllByTestId(/item-/);
48
75
  expect(items).toHaveLength(2);
49
76
 
50
- const removeBanana = await within(items[0].parentElement).findByRole('button', {name: /remove/i});
77
+ const removeBanana = await within(screen.getByTestId('item-0')).findByRole('button', {name: /remove/i});
78
+ await user.click(removeBanana);
51
79
 
80
+ items = screen.getAllByTestId(/item-/);
81
+ expect(items).toHaveLength(1);
82
+ expect(items[0]).toHaveTextContent('orange');
83
+ expect(screen.queryByTestId('item-1')).not.toBeInTheDocument();
84
+ expect(screen.getByTestId('form-state')).toHaveTextContent('{"fruits":["orange"]}');
85
+ });
86
+
87
+ it('removes the item when clicking on its remove button with custom id', async () => {
88
+ const user = userEvent.setup();
89
+ const getItemId = (item: string) => `id-${item}`;
90
+
91
+ const Fixture = () => {
92
+ const form = useForm({
93
+ initialValues: {fruits: ['banana', 'orange']},
94
+ enhanceGetInputProps: (payload) => ({...enhanceWithCollectionProps(payload, 'fruits')}),
95
+ });
96
+ return (
97
+ <>
98
+ <Collection getItemId={getItemId} newItem="" {...form.getInputProps('fruits')}>
99
+ {(name) => <span>{name}</span>}
100
+ </Collection>
101
+ <div data-testid="form-state">{JSON.stringify(form.values)}</div>
102
+ </>
103
+ );
104
+ };
105
+
106
+ render(<Fixture />);
107
+ let items = screen.getAllByTestId(/item-/);
108
+ expect(items).toHaveLength(2);
109
+
110
+ const removeBanana = await within(screen.queryByTestId('item-id-banana')).findByRole('button', {
111
+ name: /remove/i,
112
+ });
52
113
  await user.click(removeBanana);
53
114
 
54
- items = screen.getAllByTestId('item');
55
- expect(screen.getAllByTestId('item')).toHaveLength(1);
115
+ items = screen.getAllByTestId(/item-/);
116
+ expect(items).toHaveLength(1);
56
117
  expect(items[0]).toHaveTextContent('orange');
118
+ expect(screen.getByTestId('item-id-orange')).toBeInTheDocument();
119
+ expect(screen.queryByTestId('item-id-banana')).not.toBeInTheDocument();
57
120
  expect(screen.getByTestId('form-state')).toHaveTextContent('{"fruits":["orange"]}');
58
121
  });
59
122
 
60
123
  it('calls the onRemoveItem function when clicking on a remove button', async () => {
61
- const user = userEvent.setup({delay: null});
124
+ const user = userEvent.setup();
62
125
  const onRemoveItemSpy = vi.fn();
63
126
  const Fixture = () => {
64
127
  const form = useForm({
@@ -67,29 +130,27 @@ describe('Collection', () => {
67
130
  });
68
131
  return (
69
132
  <Collection newItem="" {...form.getInputProps('fruits')} onRemoveItem={onRemoveItemSpy}>
70
- {(name) => <span data-testid="item">{name}</span>}
133
+ {(name) => <span>{name}</span>}
71
134
  </Collection>
72
135
  );
73
136
  };
74
137
 
75
138
  render(<Fixture />);
76
- let items = screen.getAllByTestId('item');
139
+ const items = screen.getAllByTestId(/item-/);
77
140
  expect(items).toHaveLength(2);
78
-
79
- const removeOrange = await within(items[1].parentElement).findByRole('button', {name: /remove/i});
141
+ const removeOrange = await within(screen.queryByTestId('item-1')).findByRole('button', {name: /remove/i});
80
142
  await user.click(removeOrange);
81
143
 
82
144
  expect(onRemoveItemSpy).toHaveBeenCalledWith(1);
83
145
 
84
- items = screen.getAllByTestId('item');
85
- const removeBanana = await within(items[0].parentElement).findByRole('button', {name: /remove/i});
146
+ const removeBanana = await within(screen.queryByTestId('item-0')).findByRole('button', {name: /remove/i});
86
147
  await user.click(removeBanana);
87
148
 
88
149
  expect(onRemoveItemSpy).toHaveBeenCalledWith(0);
89
150
  });
90
151
 
91
152
  it('does not render the remove button when disabled', async () => {
92
- const user = userEvent.setup({delay: null});
153
+ const user = userEvent.setup();
93
154
  const Fixture = () => {
94
155
  const [disabled, setDisabled] = useState(false);
95
156
  const form = useForm({
@@ -100,7 +161,7 @@ describe('Collection', () => {
100
161
  <>
101
162
  <button onClick={() => setDisabled(true)}>disable</button>
102
163
  <Collection newItem="" {...form.getInputProps('fruits')} disabled={disabled}>
103
- {(name) => <span data-testid="item">{name}</span>}
164
+ {(name) => <span>{name}</span>}
104
165
  </Collection>
105
166
  </>
106
167
  );
@@ -113,7 +174,7 @@ describe('Collection', () => {
113
174
  });
114
175
 
115
176
  it('adds a new item when clicking on the add button', async () => {
116
- const user = userEvent.setup({delay: null});
177
+ const user = userEvent.setup();
117
178
  const Fixture = () => {
118
179
  const form = useForm({
119
180
  initialValues: {fruits: ['banana', 'orange']},
@@ -122,7 +183,38 @@ describe('Collection', () => {
122
183
  return (
123
184
  <>
124
185
  <Collection newItem="new" {...form.getInputProps('fruits')}>
125
- {(name) => <span data-testid="item">{name}</span>}
186
+ {(name) => <span>{name}</span>}
187
+ </Collection>
188
+ <div data-testid="form-state">{JSON.stringify(form.values)}</div>
189
+ </>
190
+ );
191
+ };
192
+
193
+ render(<Fixture />);
194
+ const addItem = screen.getByRole('button', {name: /add/i});
195
+ await user.click(addItem);
196
+
197
+ const items = screen.getAllByTestId(/item-/);
198
+ expect(items).toHaveLength(3);
199
+ expect(items[0]).toHaveTextContent('banana');
200
+ expect(items[1]).toHaveTextContent('orange');
201
+ expect(items[2]).toHaveTextContent('new');
202
+ expect(screen.getByTestId('item-2')).toBeInTheDocument();
203
+ expect(screen.getByTestId('form-state')).toHaveTextContent('{"fruits":["banana","orange","new"]}');
204
+ });
205
+
206
+ it('adds a new item when clicking on the add button with custom id', async () => {
207
+ const user = userEvent.setup();
208
+ const getItemId = (item: string) => `id-${item}`;
209
+ const Fixture = () => {
210
+ const form = useForm({
211
+ initialValues: {fruits: ['banana', 'orange']},
212
+ enhanceGetInputProps: (payload) => ({...enhanceWithCollectionProps(payload, 'fruits')}),
213
+ });
214
+ return (
215
+ <>
216
+ <Collection getItemId={getItemId} newItem="new" {...form.getInputProps('fruits')}>
217
+ {(name) => <span>{name}</span>}
126
218
  </Collection>
127
219
  <div data-testid="form-state">{JSON.stringify(form.values)}</div>
128
220
  </>
@@ -133,11 +225,12 @@ describe('Collection', () => {
133
225
  const addItem = screen.getByRole('button', {name: /add/i});
134
226
  await user.click(addItem);
135
227
 
136
- const items = screen.getAllByTestId('item');
228
+ const items = screen.getAllByTestId(/item-/);
137
229
  expect(items).toHaveLength(3);
138
230
  expect(items[0]).toHaveTextContent('banana');
139
231
  expect(items[1]).toHaveTextContent('orange');
140
232
  expect(items[2]).toHaveTextContent('new');
233
+ expect(screen.getByTestId('item-id-new')).toBeInTheDocument();
141
234
  expect(screen.getByTestId('form-state')).toHaveTextContent('{"fruits":["banana","orange","new"]}');
142
235
  });
143
236
 
@@ -151,7 +244,7 @@ describe('Collection', () => {
151
244
  return (
152
245
  <>
153
246
  <Collection newItem="new" {...form.getInputProps('fruits')} allowAdd={allowAdd}>
154
- {(name) => <span data-testid="item">{name}</span>}
247
+ {(name) => <span>{name}</span>}
155
248
  </Collection>
156
249
  <div data-testid="form-state">{JSON.stringify(form.values)}</div>
157
250
  </>
@@ -175,8 +268,8 @@ describe('Collection', () => {
175
268
  enhanceGetInputProps: (payload) => ({...enhanceWithCollectionProps(payload, 'fruits')}),
176
269
  });
177
270
  return (
178
- <Collection data-testid="collection" {...form.getInputProps('fruits')} newItem="new" required>
179
- {(name) => <span data-testid="item">{name}</span>}
271
+ <Collection {...form.getInputProps('fruits')} newItem="new" required>
272
+ {(name) => <span>{name}</span>}
180
273
  </Collection>
181
274
  );
182
275
  };
@@ -185,7 +278,7 @@ describe('Collection', () => {
185
278
 
186
279
  expect(screen.queryByRole('button', {name: /remove/i})).not.toBeInTheDocument();
187
280
 
188
- const items = screen.getAllByTestId('item');
281
+ const items = screen.getAllByTestId(/item-/);
189
282
  expect(items).toHaveLength(1);
190
283
  expect(items[0]).toHaveTextContent('banana');
191
284
  });
@@ -197,8 +290,8 @@ describe('Collection', () => {
197
290
  enhanceGetInputProps: (payload) => ({...enhanceWithCollectionProps(payload, 'fruits')}),
198
291
  });
199
292
  return (
200
- <Collection data-testid="collection" {...form.getInputProps('fruits')} newItem="new" required>
201
- {(name) => <span data-testid="item">{name}</span>}
293
+ <Collection {...form.getInputProps('fruits')} newItem="new" required>
294
+ {(name) => <span>{name}</span>}
202
295
  </Collection>
203
296
  );
204
297
  };
@@ -209,22 +302,24 @@ describe('Collection', () => {
209
302
  const removeButtons = screen.queryAllByRole('button', {name: /remove/i});
210
303
  expect(removeButtons).toHaveLength(2);
211
304
 
212
- const items = screen.getAllByTestId('item');
305
+ const items = screen.getAllByTestId(/item-/);
213
306
  expect(items).toHaveLength(2);
214
307
  expect(items[0]).toHaveTextContent('banana');
215
308
  expect(items[1]).toHaveTextContent('orange');
309
+ expect(screen.getByTestId('item-0')).toBeInTheDocument();
310
+ expect(screen.getByTestId('item-1')).toBeInTheDocument();
216
311
  });
217
312
 
218
313
  it('not render the remove button after removing an item from a collection containing two items', async () => {
219
- const user = userEvent.setup({delay: null});
314
+ const user = userEvent.setup();
220
315
  const Fixture = () => {
221
316
  const form = useForm({
222
317
  initialValues: {fruits: ['banana', 'orange']},
223
318
  enhanceGetInputProps: (payload) => ({...enhanceWithCollectionProps(payload, 'fruits')}),
224
319
  });
225
320
  return (
226
- <Collection data-testid="collection" {...form.getInputProps('fruits')} newItem="new" required>
227
- {(name) => <span data-testid="item">{name}</span>}
321
+ <Collection {...form.getInputProps('fruits')} newItem="new" required>
322
+ {(name) => <span>{name}</span>}
228
323
  </Collection>
229
324
  );
230
325
  };
@@ -236,14 +331,18 @@ describe('Collection', () => {
236
331
  const removeButtons = screen.queryAllByRole('button', {name: /remove/i});
237
332
  expect(removeButtons).toHaveLength(2);
238
333
 
239
- const items = screen.getAllByTestId('item');
334
+ const items = screen.getAllByTestId(/item-/);
240
335
  expect(items).toHaveLength(2);
241
336
  expect(items[0]).toHaveTextContent('banana');
242
337
  expect(items[1]).toHaveTextContent('orange');
338
+ expect(screen.getByTestId('item-0')).toBeInTheDocument();
339
+ expect(screen.getByTestId('item-1')).toBeInTheDocument();
243
340
 
244
- await user.click(removeButtons[1]);
341
+ const removeOrange = await within(screen.queryByTestId('item-1')).findByRole('button', {name: /remove/i});
342
+ await user.click(removeOrange);
245
343
 
246
344
  expect(screen.queryByRole('button', {name: /remove/i})).not.toBeInTheDocument();
345
+ expect(screen.queryByTestId('item-1')).not.toBeInTheDocument();
247
346
  });
248
347
  });
249
348
 
@@ -257,7 +356,7 @@ describe('Collection', () => {
257
356
  return (
258
357
  <>
259
358
  <Collection newItem="new" {...form.getInputProps('fruits')} draggable>
260
- {(name) => <span data-testid="item">{name}</span>}
359
+ {(name) => <span>{name}</span>}
261
360
  </Collection>
262
361
  </>
263
362
  );
@@ -271,21 +370,15 @@ describe('Collection', () => {
271
370
 
272
371
  describe('when required is true', () => {
273
372
  it('not render the remove button after removing an item from a collection containing two items', async () => {
274
- const user = userEvent.setup({delay: null});
373
+ const user = userEvent.setup();
275
374
  const Fixture = () => {
276
375
  const form = useForm({
277
376
  initialValues: {fruits: ['banana', 'orange']},
278
377
  enhanceGetInputProps: (payload) => ({...enhanceWithCollectionProps(payload, 'fruits')}),
279
378
  });
280
379
  return (
281
- <Collection
282
- data-testid="collection"
283
- {...form.getInputProps('fruits')}
284
- newItem="new"
285
- required
286
- draggable
287
- >
288
- {(name) => <span data-testid="item">{name}</span>}
380
+ <Collection {...form.getInputProps('fruits')} newItem="new" required draggable>
381
+ {(name) => <span>{name}</span>}
289
382
  </Collection>
290
383
  );
291
384
  };
@@ -297,12 +390,15 @@ describe('Collection', () => {
297
390
  const removeButtons = screen.queryAllByRole('button', {name: /remove/i});
298
391
  expect(removeButtons).toHaveLength(2);
299
392
 
300
- const items = screen.getAllByTestId('item');
393
+ const items = screen.getAllByTestId(/item-/);
301
394
  expect(items).toHaveLength(2);
302
395
  expect(items[0]).toHaveTextContent('banana');
303
396
  expect(items[1]).toHaveTextContent('orange');
304
397
 
305
- await user.click(removeButtons[1]);
398
+ const removeOrange = await within(screen.queryByTestId('item-1')).findByRole('button', {
399
+ name: /remove/i,
400
+ });
401
+ await user.click(removeOrange);
306
402
 
307
403
  expect(screen.queryByRole('button', {name: /remove/i})).not.toBeInTheDocument();
308
404
  });
@@ -20,3 +20,5 @@ export * from './read-only';
20
20
  export * from './sticky-footer';
21
21
  export * from './table';
22
22
  export * from './child-form';
23
+ export * from './checkbox';
24
+ export * from './loader';
@@ -0,0 +1,29 @@
1
+ .root {
2
+ --loader-light-color: var(--mantine-primary-color-light);
3
+
4
+ display: inline-block;
5
+ width: var(--loader-size);
6
+ height: var(--loader-size);
7
+
8
+ &::after {
9
+ content: '';
10
+ display: block;
11
+ width: var(--loader-size);
12
+ height: var(--loader-size);
13
+ border-radius: 10000px;
14
+ border-width: calc(var(--loader-size) / 8);
15
+ border-style: solid;
16
+ border-color: var(--loader-light-color) var(--loader-light-color) var(--loader-light-color) var(--loader-color);
17
+ animation: circle-loader-animation 1.2s linear infinite;
18
+ }
19
+ }
20
+
21
+ @keyframes circle-loader-animation {
22
+ 0% {
23
+ transform: rotate(0deg);
24
+ }
25
+
26
+ 100% {
27
+ transform: rotate(360deg);
28
+ }
29
+ }
@@ -0,0 +1,8 @@
1
+ import {Box, MantineLoaderComponent} from '@mantine/core';
2
+ import cx from 'clsx';
3
+ import {forwardRef} from 'react';
4
+ import classes from './CircleLoader.module.css';
5
+
6
+ export const CircleLoader: MantineLoaderComponent = forwardRef(({className, ...others}, ref) => (
7
+ <Box component="span" className={cx(classes.root, className)} {...others} ref={ref} />
8
+ ));
@@ -0,0 +1 @@
1
+ export * from './CircleLoader';
@@ -2,8 +2,8 @@ import {type MantineTheme} from '@mantine/core';
2
2
 
3
3
  export const readOnlyInputStyles = (theme: MantineTheme) => ({
4
4
  wrapper: {
5
- '--input-bd': 'transparent',
6
- '--input-bg': theme.colors.gray[2],
5
+ '--input-bd': 'var(--mantine-color-default-border)',
6
+ '--input-bg': theme.colors.gray[1],
7
7
  '--input-color': theme.colors.gray[7],
8
8
  '--input-placeholder-color': theme.colors.gray[7],
9
9
  },
@@ -35,7 +35,7 @@
35
35
 
36
36
  &[data-selected='true'] {
37
37
  &[data-multi-selection='false'] {
38
- background-color: var(--mantine-color-gray-light);
38
+ background-color: var(--mantine-color-gray-light-hover);
39
39
  }
40
40
 
41
41
  &[data-multi-selection='true'] {
@@ -1,3 +1,5 @@
1
1
  .root {
2
+ --badge-fz-md: 12px;
3
+
2
4
  font-weight: 500;
3
5
  }
@@ -1,9 +1,45 @@
1
- .label {
2
- font-weight: 400;
1
+ /*
2
+ `readonly` state on checkboxes is not something that exists in Mantine.
3
+ So we are allowing ourselves some custom style to achieve the desired effect
4
+ */
5
+ .input {
6
+ @mixin light {
7
+ /* targets the default checkbox without overiding mantine's base rules */
8
+ &:not([data-indeterminate], :checked, [readonly], :disabled, [data-error='true']) {
9
+ border-color: var(--coveo-color-input-border);
10
+ }
11
+
12
+ /* mantine doesn't have a concept of readonly checkbox */
13
+ &[readonly] {
14
+ border-color: var(--mantine-color-default-border);
15
+ background-color: var(--coveo-color-bg-readonly);
16
+ color: var(--coveo-color-text-readonly);
17
+
18
+ & + .icon {
19
+ color: var(--coveo-color-text-readonly);
20
+ }
21
+ }
22
+
23
+ /* mantine hardcodes disabled styles so we need to write custom styles */
24
+ &:disabled {
25
+ border-color: var(--mantine-color-default-border);
26
+ background-color: var(--coveo-color-bg-disabled);
27
+ color: var(--coveo-color-text-disabled);
28
+
29
+ & + .icon {
30
+ color: var(--coveo-color-text-disabled);
31
+ }
32
+ }
33
+ }
3
34
  }
4
35
 
5
- .input {
6
- @mixin where-light {
7
- border-color: var(--coveo-color-input-border);
36
+ .labelWrapper {
37
+ @mixin light {
38
+ &[data-disabled] {
39
+ .label,
40
+ .description {
41
+ color: var(--coveo-color-text-disabled);
42
+ }
43
+ }
8
44
  }
9
45
  }
@@ -1,5 +1,12 @@
1
+ /*
2
+ `readonly` state on checkboxes is not something that exists in Mantine.
3
+ So we are allowing ourselves some custom style to achieve the desired effect
4
+ */
1
5
  .indicator {
2
6
  @mixin where-light {
3
- border-color: var(--coveo-color-input-border);
7
+ &[readonly] {
8
+ border-color: var(--coveo-color-input-border);
9
+ background-color: var(--checkbox-color);
10
+ }
4
11
  }
5
12
  }
@@ -10,10 +10,16 @@
10
10
  }
11
11
 
12
12
  &[data-disabled] {
13
- --input-section-color: var(--input-disabled-color);
13
+ > .section {
14
+ > svg {
15
+ color: var(--input-disabled-color);
16
+ }
17
+ }
14
18
  }
15
19
  }
16
20
 
17
21
  .section {
18
- color: var(--input-section-color);
22
+ > svg {
23
+ color: var(--mantine-color-gray-3);
24
+ }
19
25
  }
@@ -1,5 +1,14 @@
1
+ .root {
2
+ --pagination-active-bg: var(--mantine-primary-color-light);
3
+ --pagination-active-color: var(--mantine-primary-color-filled);
4
+ }
5
+
1
6
  .control {
2
7
  @mixin where-light {
3
- border-color: var(--coveo-color-input-border);
8
+ border-color: var(--mantine-color-default-border);
9
+ }
10
+
11
+ &[data-active] {
12
+ border: none;
4
13
  }
5
14
  }
@@ -1,10 +1,38 @@
1
1
  .labelWrapper {
2
2
  display: flex;
3
3
  align-items: flex-start;
4
+
5
+ @mixin light {
6
+ color: var(--coveo-color-title);
7
+
8
+ &[data-disabled] {
9
+ .label,
10
+ .description {
11
+ color: var(--coveo-color-text-disabled);
12
+ }
13
+ }
14
+ }
4
15
  }
5
16
 
6
17
  .radio {
7
- @mixin where-light {
8
- border-color: var(--coveo-color-input-border);
18
+ @mixin light {
19
+ &:not([data-disabled]) {
20
+ border-color: var(--coveo-color-input-border);
21
+ }
22
+
23
+ &:disabled {
24
+ background-color: var(--coveo-color-bg-disabled);
25
+ }
26
+
27
+ /* mantine hardcodes disabled styles so we need to write custom styles */
28
+ &[readonly] {
29
+ border-color: var(--mantine-color-default-border);
30
+ background-color: var(--coveo-color-bg-readonly);
31
+ color: var(--coveo-color-text-readonly);
32
+
33
+ & + .icon {
34
+ color: var(--coveo-color-text-readonly);
35
+ }
36
+ }
9
37
  }
10
38
  }
@@ -1,12 +1,16 @@
1
1
  .input {
2
2
  cursor: text;
3
3
 
4
- --input-bd: transparent;
5
- --input-bg: var(--mantine-color-dark-light);
4
+ --input-bd: var(--mantine-color-default-border);
5
+ --input-bg: var(--mantine-color-gray-1);
6
6
  --input-color: var(--mantine-color-text);
7
- --input-placeholder-color: var(--mantine-color-text);
7
+ --input-placeholder-color: var(--mantine-color-placeholder);
8
8
  }
9
9
 
10
10
  .section {
11
11
  --input-section-color: var(--mantine-color-text);
12
+
13
+ > svg {
14
+ color: var(--mantine-color-gray-3);
15
+ }
12
16
  }
@@ -0,0 +1,46 @@
1
+ .option {
2
+ @mixin light {
3
+ color: var(--coveo-color-title);
4
+ border-radius: var(--mantine-radius-sm);
5
+
6
+ @mixin hover {
7
+ &:not([data-combobox-disabled], [data-checked], [data-combobox-selected]) {
8
+ background-color: var(--mantine-color-default-hover);
9
+ }
10
+ }
11
+
12
+ &[data-combobox-disabled] {
13
+ opacity: 1;
14
+ color: var(--coveo-color-text-disabled);
15
+ }
16
+
17
+ &[data-combobox-active='true'] {
18
+ background-color: var(--mantine-primary-color-light);
19
+ color: var(--mantine-primary-color-filled);
20
+
21
+ + svg {
22
+ opacity: 1;
23
+ }
24
+ }
25
+
26
+ &[data-combobox-selected] {
27
+ background-color: var(--mantine-primary-color-filled);
28
+ color: white;
29
+ }
30
+ }
31
+ }
32
+
33
+ .groupLabel {
34
+ @mixin light {
35
+ color: var(--mantine-color-placeholder);
36
+ }
37
+ }
38
+
39
+ .input {
40
+ @mixin light {
41
+ &[data-disabled] {
42
+ --input-disabled-bg: var(--coveo-color-bg-disabled);
43
+ --input-bd: var(--mantine-color-default-border);
44
+ }
45
+ }
46
+ }