@adyen/eslint-plugin-bento 2.14.0 → 2.16.0

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 (19) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/package.json +1 -1
  3. package/rules/deprecation-bento-timeline-item-variant-prop/README.md +13 -5
  4. package/rules/deprecation-bento-timeline-item-variant-prop/__tests__/deprecation-bento-timeline-item-variant-prop.vue +2 -2
  5. package/rules/deprecation-bento-timeline-item-variant-prop/deprecation-bento-timeline-item-variant-prop.integration.test.ts +6 -2
  6. package/rules/deprecation-bento-timeline-item-variant-prop/deprecation-bento-timeline-item-variant-prop.js +61 -12
  7. package/rules/deprecation-bento-timeline-item-variant-prop/deprecation-bento-timeline-item-variant-prop.test.ts +87 -12
  8. package/rules/deprecation-components-error-prop/README.md +143 -7
  9. package/rules/deprecation-components-error-prop/__tests__/eslint.config.js +1 -1
  10. package/rules/deprecation-components-error-prop/deprecation-components-error-prop.integration.test.ts +14 -10
  11. package/rules/deprecation-components-error-prop/deprecation-components-error-prop.js +20 -30
  12. package/rules/deprecation-components-error-prop/deprecation-components-error-prop.test.ts +69 -36
  13. package/rules/deprecation-components-has-error-prop/README.md +107 -6
  14. package/rules/deprecation-components-has-error-prop/deprecation-components-has-error-prop.integration.test.ts +10 -2
  15. package/rules/deprecation-components-has-error-prop/deprecation-components-has-error-prop.js +18 -24
  16. package/rules/deprecation-components-has-error-prop/deprecation-components-has-error-prop.test.ts +58 -69
  17. package/rules/deprecation-components-input-emit/README.md +170 -3
  18. package/rules/deprecation-components-input-emit/deprecation-components-input-emit.integration.test.ts +9 -1
  19. package/rules/deprecation-components-input-emit/deprecation-components-input-emit.js +9 -1
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Description
4
4
 
5
- The `input` emit in the following components is deprecated:
5
+ The `@input` event listener in the following components is deprecated:
6
6
 
7
7
  - `bento-date-picker`
8
8
  - `bento-date-range-picker`
@@ -21,11 +21,28 @@ The `input` emit in the following components is deprecated:
21
21
  - `bento-selection-card-group`
22
22
  - `bento-textarea`
23
23
 
24
- Please use `update:model-value` instead.
24
+ Please use `@update:model-value` instead.
25
+
26
+ | Deprecated event | Replacement event | Autofix available |
27
+ | ---------------- | --------------------- | -------------------------- |
28
+ | `@input` | `@update:model-value` | Yes (opt-in via `autofix`) |
29
+
30
+ > **⚠️ Caveat — `v-model` combined with `@input`**
31
+ >
32
+ > Bento Vue 2 components emit **both** `input` (deprecated) and `update:model-value` on every value change for backward
33
+ > compatibility. In Vue 2, `v-model` internally listens to `@input`. If you autofix `@input` to `@update:model-value`
34
+ > while keeping `v-model`, you end up with `v-model` listening to `@input` **and** an explicit `@update:model-value`
35
+ > handler — both of which fire on every change. This causes race conditions because the handler may read the model value
36
+ > before `v-model`'s `@input` listener has propagated the update.
37
+ >
38
+ > In this case, **do not rely on autofix alone**. You must also replace `v-model` with an explicit `:model-value`
39
+ > binding so that a single `@update:model-value` handler controls both the model update and any side effects. See the
40
+ > [Migration Examples](#migration-examples) below.
25
41
 
26
42
  ## Rule Details
27
43
 
28
- This rule reports usages of the deprecated item.
44
+ This rule reports usages of the deprecated `@input` event and can optionally autofix them to `@update:model-value`.
45
+ Autofix is disabled by default and can be enabled with the `autofix` option.
29
46
 
30
47
  ### ❌ Incorrect
31
48
 
@@ -93,6 +110,18 @@ This rule reports usages of the deprecated item.
93
110
  <bento-textarea @input="handler" />
94
111
  ```
95
112
 
113
+ ```html
114
+ <!-- v-on:input directive syntax is also reported -->
115
+ <bento-input-field v-on:input="handler" />
116
+ ```
117
+
118
+ ```html
119
+ <!-- ⚠️ v-model + @input — autofix alone is NOT safe -->
120
+ <bento-input-field v-model="email" @input="onEmailChange" />
121
+
122
+ <bento-dropdown v-model="country" @input="onCountryChange" :items="items" />
123
+ ```
124
+
96
125
  ### ✅ Correct
97
126
 
98
127
  ```html
@@ -158,3 +187,141 @@ This rule reports usages of the deprecated item.
158
187
  ```html
159
188
  <bento-textarea @update:model-value="handler" />
160
189
  ```
190
+
191
+ ```html
192
+ <!-- v-model without a separate handler — no change needed -->
193
+ <bento-input-field v-model="email" />
194
+ ```
195
+
196
+ ```html
197
+ <!-- v-model + @input migrated: split v-model into explicit binding + handler -->
198
+ <bento-input-field :model-value="email" @update:model-value="onEmailChange" />
199
+
200
+ <bento-dropdown :model-value="country" @update:model-value="onCountryChange" :items="items" />
201
+ ```
202
+
203
+ ## Migration Examples
204
+
205
+ If `v-model` is used alongside `@input`, you must also replace `v-model` with `:model-value` — see Case 2. Otherwise,
206
+ renaming `@input` to `@update:model-value` is sufficient — see Cases 1 and 3.
207
+
208
+ ### Case 1 — standalone `@input` (safe to autofix)
209
+
210
+ The simplest case: `@input` is used without `v-model`. Rename it to `@update:model-value`.
211
+
212
+ #### Before
213
+
214
+ ```html
215
+ <template>
216
+ <bento-dropdown @input="onSelect" :items="countries" label="Country" />
217
+ </template>
218
+
219
+ <script setup lang="ts">
220
+ const onSelect = (value: string) => {
221
+ console.log('Selected:', value);
222
+ };
223
+ </script>
224
+ ```
225
+
226
+ #### After
227
+
228
+ ```html
229
+ <template>
230
+ <bento-dropdown @update:model-value="onSelect" :items="countries" label="Country" />
231
+ </template>
232
+
233
+ <script setup lang="ts">
234
+ const onSelect = (value: string) => {
235
+ console.log('Selected:', value);
236
+ };
237
+ </script>
238
+ ```
239
+
240
+ ### Case 2 — `v-model` + `@input` (autofix NOT safe — requires manual split)
241
+
242
+ When `v-model` is used alongside `@input`, autofix alone will cause a dual-emission race condition. You must replace
243
+ `v-model` with an explicit `:model-value` binding and merge the update logic into a single `@update:model-value`
244
+ handler.
245
+
246
+ #### Before — `v-model` + `@input`
247
+
248
+ ```html
249
+ <template>
250
+ <bento-dropdown v-model="country" @input="onCountryChange" :items="countries" label="Country" />
251
+ </template>
252
+
253
+ <script setup lang="ts">
254
+ const country = ref('');
255
+
256
+ const onCountryChange = (value: string) => {
257
+ fetchCities(value);
258
+ };
259
+ </script>
260
+ ```
261
+
262
+ #### ❌ Broken — after autofix only (dual-emission race condition)
263
+
264
+ ```html
265
+ <template>
266
+ <!-- v-model internally listens to @input, while @update:model-value listens to the new event.
267
+ The component emits BOTH events on every change, causing a race condition:
268
+ onCountryChange may read `country` before v-model's @input handler has updated it. -->
269
+ <bento-dropdown v-model="country" @update:model-value="onCountryChange" :items="countries" label="Country" />
270
+ </template>
271
+ ```
272
+
273
+ #### ✅ Correct — split `v-model` and merge handlers
274
+
275
+ Replace `v-model` with `:model-value` and merge the update logic into one handler:
276
+
277
+ ```html
278
+ <template>
279
+ <bento-dropdown :model-value="country" @update:model-value="onCountryChange" :items="countries" label="Country" />
280
+ </template>
281
+
282
+ <script setup lang="ts">
283
+ const country = ref('');
284
+
285
+ const onCountryChange = (value: string) => {
286
+ country.value = value;
287
+ fetchCities(value);
288
+ };
289
+ </script>
290
+ ```
291
+
292
+ ### Case 3 — explicit `:model-value` + `@input` (safe to autofix)
293
+
294
+ When `:model-value` is already used instead of `v-model`, there is no dual-emission conflict. Rename `@input` to
295
+ `@update:model-value`.
296
+
297
+ #### Before — `:model-value` + `@input`
298
+
299
+ ```html
300
+ <template>
301
+ <bento-checkbox-group :model-value="selected" @input="onSelect" :items="items" label="Toppings" />
302
+ </template>
303
+
304
+ <script setup lang="ts">
305
+ const selected = ref([]);
306
+
307
+ const onSelect = (value: string[]) => {
308
+ selected.value = value;
309
+ };
310
+ </script>
311
+ ```
312
+
313
+ #### After — rename to `@update:model-value`
314
+
315
+ ```html
316
+ <template>
317
+ <bento-checkbox-group :model-value="selected" @update:model-value="onSelect" :items="items" label="Toppings" />
318
+ </template>
319
+
320
+ <script setup lang="ts">
321
+ const selected = ref([]);
322
+
323
+ const onSelect = (value: string[]) => {
324
+ selected.value = value;
325
+ };
326
+ </script>
327
+ ```
@@ -25,7 +25,15 @@ describe('@adyen/bento/deprecation-components-input-emit', () => {
25
25
  severity: 1,
26
26
 
27
27
  messageId: 'deprecation',
28
- message: `The "input" emit is deprecated. Please use "update:model-value" instead.`,
28
+ message: `The \`input\` emit is deprecated. Please use \`update:model-value\` instead.
29
+
30
+ Be wary of undesired side effects and race conditions if \`v-model\` is used in conjunction with \`@input\`.
31
+
32
+ Incorrect:
33
+ <bento-component v-model="text" @input="onInput" />
34
+
35
+ Correct:
36
+ <bento-component :model-value="text" @update:model-value="onInput" />`,
29
37
 
30
38
  fix: expect.objectContaining({
31
39
  text: expect.stringContaining('update:model-value'),
@@ -19,7 +19,15 @@ module.exports = {
19
19
  recommended: true,
20
20
  },
21
21
  messages: {
22
- deprecation: `The "input" emit is deprecated. Please use "update:model-value" instead.`,
22
+ deprecation: `The \`input\` emit is deprecated. Please use \`update:model-value\` instead.
23
+
24
+ Be wary of undesired side effects and race conditions if \`v-model\` is used in conjunction with \`@input\`.
25
+
26
+ Incorrect:
27
+ <bento-component v-model="text" @input="onInput" />
28
+
29
+ Correct:
30
+ <bento-component :model-value="text" @update:model-value="onInput" />`,
23
31
  },
24
32
  fixable: 'code',
25
33
  schema: [