@adyen/eslint-plugin-bento 2.21.0 → 2.23.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.
- package/CHANGELOG.md +26 -0
- package/configs/vue-recommended.js +1 -0
- package/configs/vue-strict.js +2 -1
- package/package.json +3 -3
- package/rules/deprecation-filter-bar-deprecated-props/README.md +7 -0
- package/rules/deprecation-filter-bar-deprecated-props/__tests__/deprecation-filter-bar-deprecated-props.vue +14 -0
- package/rules/deprecation-filter-bar-deprecated-props/deprecation-filter-bar-deprecated-props.js +22 -22
- package/rules/deprecation-filter-bar-deprecated-props/deprecation-filter-bar-deprecated-props.test.ts +89 -18
- package/rules/deprecation-tag-default-slot/deprecation-tag-default-slot.test.ts +18 -0
- package/utils/component-slot-migration.js +22 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.23.0 (2026-08-17)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- updated `deprecation-filter-bar-deprecated-props` rule to check also for configs with enums ([5259ab283](https://github.com/Adyen/bento/commit/5259ab283))
|
|
8
|
+
|
|
9
|
+
### Miscellaneous Chores
|
|
10
|
+
|
|
11
|
+
- enabled strict `@adyen/eslint-plugin-bento` plugin ESLint rules to enforce deprecations ([974a8e49e](https://github.com/Adyen/bento/commit/974a8e49e))
|
|
12
|
+
|
|
13
|
+
### ❤️ Thank You
|
|
14
|
+
|
|
15
|
+
- daver
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## 2.22.0 (2026-07-29)
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
- removed autofix from `deprecation-filter-bar-values` eslint ([b1a22af27](https://github.com/Adyen/bento/commit/b1a22af27))
|
|
23
|
+
|
|
24
|
+
### ❤️ Thank You
|
|
25
|
+
|
|
26
|
+
- erice
|
|
27
|
+
|
|
28
|
+
|
|
3
29
|
## 2.21.0 (2026-07-21)
|
|
4
30
|
|
|
5
31
|
This was a version bump only for eslint to align it with other projects, there were no code changes.
|
package/configs/vue-strict.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @type {import('eslint').Linter.Config[]} */
|
|
1
2
|
module.exports = [
|
|
2
3
|
{
|
|
3
4
|
name: '@bento/adyen/strict',
|
|
@@ -12,7 +13,7 @@ module.exports = [
|
|
|
12
13
|
},
|
|
13
14
|
rules: {
|
|
14
15
|
'@adyen/bento/deprecation-bento-data-grid-cell-action-menu-item-handler': 'error',
|
|
15
|
-
'@adyen/bento/deprecation-bento-date-range-picker-has-actions-prop': 'error',
|
|
16
|
+
'@adyen/bento/deprecation-bento-date-range-picker-has-actions-prop': ['error', { action: 'remove' }],
|
|
16
17
|
'@adyen/bento/deprecation-input-filter-dropdown-options': 'error',
|
|
17
18
|
'@adyen/bento/deprecation-bento-dropdown-size-prop': 'error',
|
|
18
19
|
'@adyen/bento/deprecation-bento-timeline-item-variant-prop': 'error',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adyen/eslint-plugin-bento",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.23.0",
|
|
4
4
|
"description": "Adyen Bento ESLint rules",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"@types/eslint": "9.6.1",
|
|
31
31
|
"@types/estree": "1.0.6",
|
|
32
32
|
"@types/node": "24.9.0",
|
|
33
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
34
|
-
"@typescript-eslint/parser": "8.
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "8.61.0",
|
|
34
|
+
"@typescript-eslint/parser": "8.61.0",
|
|
35
35
|
"@vitest/eslint-plugin": "1.1.25",
|
|
36
36
|
"@vitest/coverage-v8": "3.2.6",
|
|
37
37
|
"eslint": "9.39.0",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
:config="[
|
|
15
15
|
{
|
|
16
16
|
field: 'inline',
|
|
17
|
+
label: 'Inline',
|
|
17
18
|
type: 'BentoSelectFilter',
|
|
18
19
|
options: { messages: {} },
|
|
19
20
|
},
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
const configWithValue = [
|
|
28
29
|
{
|
|
29
30
|
field: 'name',
|
|
31
|
+
label: 'Name',
|
|
30
32
|
type: 'BentoInputFilter',
|
|
31
33
|
value: 'test',
|
|
32
34
|
},
|
|
@@ -36,6 +38,7 @@
|
|
|
36
38
|
const configWithOptions = [
|
|
37
39
|
{
|
|
38
40
|
field: 'status',
|
|
41
|
+
label: 'Status',
|
|
39
42
|
type: 'BentoSelectFilter',
|
|
40
43
|
options: {
|
|
41
44
|
messages: {},
|
|
@@ -46,3 +49,14 @@
|
|
|
46
49
|
},
|
|
47
50
|
];
|
|
48
51
|
</script>
|
|
52
|
+
|
|
53
|
+
<script>
|
|
54
|
+
export const parseBinaryOperation = operation => ({
|
|
55
|
+
field: operation.left.name,
|
|
56
|
+
operator: operation.type,
|
|
57
|
+
category: operation.left.type,
|
|
58
|
+
type: parseOperationValueType(operation.right.type),
|
|
59
|
+
value: parseOperationValue(operation),
|
|
60
|
+
key: getUniqueId(),
|
|
61
|
+
});
|
|
62
|
+
</script>
|
package/rules/deprecation-filter-bar-deprecated-props/deprecation-filter-bar-deprecated-props.js
CHANGED
|
@@ -20,6 +20,16 @@ function getStaticPropertyName(prop) {
|
|
|
20
20
|
return prop.key.type === 'Identifier' ? prop.key.name : prop.key.type === 'Literal' ? String(prop.key.value) : null;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
function isBentoFilterItemType(node) {
|
|
24
|
+
return (
|
|
25
|
+
node?.type === 'MemberExpression' &&
|
|
26
|
+
!node.computed &&
|
|
27
|
+
node.object.type === 'Identifier' &&
|
|
28
|
+
node.object.name === 'BentoFilterItemType' &&
|
|
29
|
+
node.property.type === 'Identifier'
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
/** @type {RuleModule} */
|
|
24
34
|
module.exports = {
|
|
25
35
|
meta: {
|
|
@@ -85,7 +95,13 @@ module.exports = {
|
|
|
85
95
|
}
|
|
86
96
|
|
|
87
97
|
// Only check objects that look like filter config items (BentoFilterModel)
|
|
88
|
-
const
|
|
98
|
+
const filterType = propertyMap.type?.value;
|
|
99
|
+
const isFilterConfig =
|
|
100
|
+
propertyMap.field &&
|
|
101
|
+
((filterType?.type === 'Literal' &&
|
|
102
|
+
typeof filterType.value === 'string' &&
|
|
103
|
+
filterType.value.endsWith('Filter')) ||
|
|
104
|
+
isBentoFilterItemType(filterType));
|
|
89
105
|
if (!isFilterConfig) {
|
|
90
106
|
return;
|
|
91
107
|
}
|
|
@@ -95,11 +111,6 @@ module.exports = {
|
|
|
95
111
|
context.report({
|
|
96
112
|
node: propertyMap.value.key,
|
|
97
113
|
messageId: 'deprecationConfigValue',
|
|
98
|
-
...(autofix && {
|
|
99
|
-
fix(fixer) {
|
|
100
|
-
return removeProperty(fixer, node, propertyMap.value);
|
|
101
|
-
},
|
|
102
|
-
}),
|
|
103
114
|
});
|
|
104
115
|
}
|
|
105
116
|
|
|
@@ -144,11 +155,6 @@ module.exports = {
|
|
|
144
155
|
context.report({
|
|
145
156
|
node,
|
|
146
157
|
messageId: 'deprecationValue',
|
|
147
|
-
...(autofix && {
|
|
148
|
-
fix(fixer) {
|
|
149
|
-
return fixer.remove(node);
|
|
150
|
-
},
|
|
151
|
-
}),
|
|
152
158
|
});
|
|
153
159
|
},
|
|
154
160
|
// Direct "value" prop on bento-filter-bar (dynamic)
|
|
@@ -158,25 +164,19 @@ module.exports = {
|
|
|
158
164
|
context.report({
|
|
159
165
|
node,
|
|
160
166
|
messageId: 'deprecationValue',
|
|
161
|
-
...(autofix && {
|
|
162
|
-
fix(fixer) {
|
|
163
|
-
return fixer.remove(node);
|
|
164
|
-
},
|
|
165
|
-
}),
|
|
166
167
|
});
|
|
167
168
|
},
|
|
168
|
-
//
|
|
169
|
+
// Bare v-model binds to "value" in Vue 2; v-model:value does the same in Vue 3
|
|
169
170
|
[`VElement[name="bento-filter-bar"] > VStartTag > VAttribute[directive=true][key.name.name="model"]`](
|
|
170
171
|
node
|
|
171
172
|
) {
|
|
173
|
+
if (node.key.argument && node.key.argument.name !== 'value') {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
172
177
|
context.report({
|
|
173
178
|
node,
|
|
174
179
|
messageId: 'deprecationValue',
|
|
175
|
-
...(autofix && {
|
|
176
|
-
fix(fixer) {
|
|
177
|
-
return fixer.remove(node);
|
|
178
|
-
},
|
|
179
|
-
}),
|
|
180
180
|
});
|
|
181
181
|
},
|
|
182
182
|
...objectVisitor,
|
|
@@ -26,6 +26,15 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
26
26
|
</template>
|
|
27
27
|
`,
|
|
28
28
|
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Valid: Vue 3 filter-values v-model on bento-filter-bar',
|
|
31
|
+
filename: 'test.vue',
|
|
32
|
+
code: `
|
|
33
|
+
<template>
|
|
34
|
+
<bento-filter-bar :config="config" v-model:filter-values="filterValues" />
|
|
35
|
+
</template>
|
|
36
|
+
`,
|
|
37
|
+
},
|
|
29
38
|
{
|
|
30
39
|
name: 'Valid: filter config item without deprecated value property',
|
|
31
40
|
filename: 'test.vue',
|
|
@@ -97,6 +106,43 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
97
106
|
<template><div /></template>
|
|
98
107
|
`,
|
|
99
108
|
},
|
|
109
|
+
{
|
|
110
|
+
name: 'Valid: unrelated binary operation object with field, type, and value properties',
|
|
111
|
+
filename: 'test.vue',
|
|
112
|
+
code: `
|
|
113
|
+
<script>
|
|
114
|
+
export const parseBinaryOperation = operation => ({
|
|
115
|
+
field: operation.left.name,
|
|
116
|
+
operator: operation.type,
|
|
117
|
+
category: operation.left.type,
|
|
118
|
+
type: parseOperationValueType(operation.right.type),
|
|
119
|
+
value: parseOperationValue(operation),
|
|
120
|
+
key: getUniqueId(),
|
|
121
|
+
});
|
|
122
|
+
</script>
|
|
123
|
+
<template><div /></template>
|
|
124
|
+
`,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'Valid: unrelated object with a non-filter string type',
|
|
128
|
+
filename: 'test.vue',
|
|
129
|
+
code: `
|
|
130
|
+
<script setup>
|
|
131
|
+
const operation = { field: 'name', type: 'BinaryOperation', value: 'test' };
|
|
132
|
+
</script>
|
|
133
|
+
<template><div /></template>
|
|
134
|
+
`,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'Valid: unrelated enum member with a similar name',
|
|
138
|
+
filename: 'test.vue',
|
|
139
|
+
code: `
|
|
140
|
+
<script setup>
|
|
141
|
+
const config = [{ field: 'name', type: OtherFilterItemType.INPUT, value: 'test' }];
|
|
142
|
+
</script>
|
|
143
|
+
<template><bento-filter-bar :config="config" /></template>
|
|
144
|
+
`,
|
|
145
|
+
},
|
|
100
146
|
{
|
|
101
147
|
name: 'Valid: unrelated object with value property (no false positive)',
|
|
102
148
|
filename: 'test.vue',
|
|
@@ -128,9 +174,15 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
128
174
|
code: `<template><bento-filter-bar v-model="filters" /></template>`,
|
|
129
175
|
errors: [{ messageId: 'deprecationValue' }],
|
|
130
176
|
},
|
|
177
|
+
{
|
|
178
|
+
name: 'Invalid: Vue 3 value v-model on bento-filter-bar',
|
|
179
|
+
filename: 'test.vue',
|
|
180
|
+
code: `<template><bento-filter-bar v-model:value="filters" /></template>`,
|
|
181
|
+
errors: [{ messageId: 'deprecationValue' }],
|
|
182
|
+
},
|
|
131
183
|
// "value" inside filter config items (script)
|
|
132
184
|
{
|
|
133
|
-
name: 'Invalid: value property in filter config item
|
|
185
|
+
name: 'Invalid: value property in filter config item without a label',
|
|
134
186
|
filename: 'test.vue',
|
|
135
187
|
code: `
|
|
136
188
|
<script setup>
|
|
@@ -144,13 +196,28 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
144
196
|
`,
|
|
145
197
|
errors: [{ messageId: 'deprecationConfigValue' }],
|
|
146
198
|
},
|
|
199
|
+
{
|
|
200
|
+
name: 'Invalid: value property in BentoFilterItemType enum config item',
|
|
201
|
+
filename: 'test.vue',
|
|
202
|
+
code: `
|
|
203
|
+
<script setup>
|
|
204
|
+
const config = [{
|
|
205
|
+
field: 'name',
|
|
206
|
+
type: BentoFilterItemType.INPUT,
|
|
207
|
+
value: 'test',
|
|
208
|
+
}];
|
|
209
|
+
</script>
|
|
210
|
+
<template><bento-filter-bar :config="config" /></template>
|
|
211
|
+
`,
|
|
212
|
+
errors: [{ messageId: 'deprecationConfigValue' }],
|
|
213
|
+
},
|
|
147
214
|
// "value" inside filter config items (inline template)
|
|
148
215
|
{
|
|
149
216
|
name: 'Invalid: value property in filter config item (inline template)',
|
|
150
217
|
filename: 'test.vue',
|
|
151
218
|
code: `
|
|
152
219
|
<template>
|
|
153
|
-
<bento-filter-bar :config="[{ field: 'name', type: 'BentoInputFilter', value: 'test' }]" />
|
|
220
|
+
<bento-filter-bar :config="[{ field: 'name', label: 'Name', type: 'BentoInputFilter', value: 'test' }]" />
|
|
154
221
|
</template>
|
|
155
222
|
`,
|
|
156
223
|
errors: [{ messageId: 'deprecationConfigValue' }],
|
|
@@ -163,6 +230,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
163
230
|
<script setup>
|
|
164
231
|
const config = [{
|
|
165
232
|
field: 'status',
|
|
233
|
+
label: 'Status',
|
|
166
234
|
type: 'BentoSelectFilter',
|
|
167
235
|
options: { messages: { en: { persistentButtonLabelPartiallySelected: 'x' } }, listboxItems: [] },
|
|
168
236
|
}];
|
|
@@ -179,6 +247,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
179
247
|
<script setup>
|
|
180
248
|
const config = [{
|
|
181
249
|
field: 'status',
|
|
250
|
+
label: 'Status',
|
|
182
251
|
type: 'BentoSelectFilter',
|
|
183
252
|
options: { messagesPersistentButtonLabelPartiallySelectedKey: 'customKey', listboxItems: [] },
|
|
184
253
|
}];
|
|
@@ -200,6 +269,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
200
269
|
<script setup>
|
|
201
270
|
const config = [{
|
|
202
271
|
field: 'status',
|
|
272
|
+
label: 'Status',
|
|
203
273
|
type: 'BentoSelectFilter',
|
|
204
274
|
options: { messagesPersistentButtonLabelAllSelectedKey: 'customKey', listboxItems: [] },
|
|
205
275
|
}];
|
|
@@ -218,6 +288,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
218
288
|
<script setup>
|
|
219
289
|
const config = [{
|
|
220
290
|
field: 'status',
|
|
291
|
+
label: 'Status',
|
|
221
292
|
type: 'BentoSelectFilter',
|
|
222
293
|
options: {
|
|
223
294
|
messages: {},
|
|
@@ -246,6 +317,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
246
317
|
<script setup>
|
|
247
318
|
const config = [{
|
|
248
319
|
field: 'status',
|
|
320
|
+
label: 'Status',
|
|
249
321
|
type: 'BentoSelectFilter',
|
|
250
322
|
options: { 'messages': {} },
|
|
251
323
|
}];
|
|
@@ -262,6 +334,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
262
334
|
<script setup>
|
|
263
335
|
const filters = [{
|
|
264
336
|
field: 'name',
|
|
337
|
+
label: 'Name',
|
|
265
338
|
type: 'BentoInputFilter',
|
|
266
339
|
value: 'test',
|
|
267
340
|
}];
|
|
@@ -278,6 +351,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
278
351
|
<script setup>
|
|
279
352
|
const filters = [{
|
|
280
353
|
field: 'status',
|
|
354
|
+
label: 'Status',
|
|
281
355
|
type: 'BentoSelectFilter',
|
|
282
356
|
options: { messages: {}, listboxItems: [] },
|
|
283
357
|
}];
|
|
@@ -294,6 +368,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
294
368
|
<template>
|
|
295
369
|
<bento-filter-bar :config="[{
|
|
296
370
|
field: 'status',
|
|
371
|
+
label: 'Status',
|
|
297
372
|
type: 'BentoSelectFilter',
|
|
298
373
|
options: { messages: {}, listboxItems: [] },
|
|
299
374
|
}]" />
|
|
@@ -310,6 +385,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
310
385
|
const defaults = {};
|
|
311
386
|
const config = [{
|
|
312
387
|
field: 'status',
|
|
388
|
+
label: 'Status',
|
|
313
389
|
type: 'BentoSelectFilter',
|
|
314
390
|
options: { ...defaults, messages: {} },
|
|
315
391
|
}];
|
|
@@ -335,52 +411,45 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
335
411
|
],
|
|
336
412
|
invalid: [
|
|
337
413
|
{
|
|
338
|
-
name: 'Autofix:
|
|
414
|
+
name: 'Autofix: preserves static value prop on bento-filter-bar',
|
|
339
415
|
filename: 'test.vue',
|
|
340
416
|
options: [{ autofix: true }],
|
|
341
417
|
code: `<template><bento-filter-bar value="val" /></template>`,
|
|
342
|
-
output:
|
|
418
|
+
output: null,
|
|
343
419
|
errors: [{ messageId: 'deprecationValue' }],
|
|
344
420
|
},
|
|
345
421
|
{
|
|
346
|
-
name: 'Autofix:
|
|
422
|
+
name: 'Autofix: preserves dynamic value prop on bento-filter-bar',
|
|
347
423
|
filename: 'test.vue',
|
|
348
424
|
options: [{ autofix: true }],
|
|
349
425
|
code: `<template><bento-filter-bar :value="filters" /></template>`,
|
|
350
|
-
output:
|
|
426
|
+
output: null,
|
|
351
427
|
errors: [{ messageId: 'deprecationValue' }],
|
|
352
428
|
},
|
|
353
429
|
{
|
|
354
|
-
name: 'Autofix:
|
|
430
|
+
name: 'Autofix: preserves v-model on bento-filter-bar',
|
|
355
431
|
filename: 'test.vue',
|
|
356
432
|
options: [{ autofix: true }],
|
|
357
433
|
code: `<template><bento-filter-bar v-model="filters" /></template>`,
|
|
358
|
-
output:
|
|
434
|
+
output: null,
|
|
359
435
|
errors: [{ messageId: 'deprecationValue' }],
|
|
360
436
|
},
|
|
361
437
|
{
|
|
362
|
-
name: 'Autofix:
|
|
438
|
+
name: 'Autofix: preserves value on filter config item',
|
|
363
439
|
filename: 'test.vue',
|
|
364
440
|
options: [{ autofix: true }],
|
|
365
441
|
code: `
|
|
366
442
|
<script setup>
|
|
367
443
|
const config = [{
|
|
368
444
|
field: 'name',
|
|
445
|
+
label: 'Name',
|
|
369
446
|
type: 'BentoInputFilter',
|
|
370
447
|
value: 'test',
|
|
371
448
|
}];
|
|
372
449
|
</script>
|
|
373
450
|
<template><bento-filter-bar :config="config" /></template>
|
|
374
451
|
`,
|
|
375
|
-
output:
|
|
376
|
-
<script setup>
|
|
377
|
-
const config = [{
|
|
378
|
-
field: 'name',
|
|
379
|
-
type: 'BentoInputFilter',
|
|
380
|
-
}];
|
|
381
|
-
</script>
|
|
382
|
-
<template><bento-filter-bar :config="config" /></template>
|
|
383
|
-
`,
|
|
452
|
+
output: null,
|
|
384
453
|
errors: [{ messageId: 'deprecationConfigValue' }],
|
|
385
454
|
},
|
|
386
455
|
{
|
|
@@ -391,6 +460,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
391
460
|
<script setup>
|
|
392
461
|
const config = [{
|
|
393
462
|
field: 'status',
|
|
463
|
+
label: 'Status',
|
|
394
464
|
type: 'BentoSelectFilter',
|
|
395
465
|
options: { messages: {}, listboxItems: [] },
|
|
396
466
|
}];
|
|
@@ -401,6 +471,7 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
401
471
|
<script setup>
|
|
402
472
|
const config = [{
|
|
403
473
|
field: 'status',
|
|
474
|
+
label: 'Status',
|
|
404
475
|
type: 'BentoSelectFilter',
|
|
405
476
|
options: { listboxItems: [] },
|
|
406
477
|
}];
|
|
@@ -42,6 +42,24 @@ describe('@adyen/bento/deprecation-tag-default-slot should suggest the usage of
|
|
|
42
42
|
<bento-tag :label="thisIsMyVariableWithText" variant="blue" />
|
|
43
43
|
`,
|
|
44
44
|
},
|
|
45
|
+
{
|
|
46
|
+
name: 'BentoTag with named "icon" slot',
|
|
47
|
+
filename: 'test.vue',
|
|
48
|
+
code: `
|
|
49
|
+
<template>
|
|
50
|
+
<bento-tag
|
|
51
|
+
v-if="errorCounter != null"
|
|
52
|
+
class="b-tabs__tab-error-counter"
|
|
53
|
+
variant="red"
|
|
54
|
+
:label="errorCounter"
|
|
55
|
+
>
|
|
56
|
+
<template #icon>
|
|
57
|
+
<cross-circle-fill-icon aria-hidden="true" />
|
|
58
|
+
</template>
|
|
59
|
+
</bento-tag>
|
|
60
|
+
</template>
|
|
61
|
+
`,
|
|
62
|
+
},
|
|
45
63
|
],
|
|
46
64
|
invalid: [
|
|
47
65
|
{
|
|
@@ -6,6 +6,7 @@ const j = require('jscodeshift');
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
+
* @typedef {import('vue-eslint-parser').AST.VElement} VElement
|
|
9
10
|
* @typedef {import('vue-eslint-parser').AST.VText} VText
|
|
10
11
|
* @typedef {import('vue-eslint-parser').AST.VExpressionContainer} VExpressionContainer
|
|
11
12
|
*/
|
|
@@ -26,10 +27,23 @@ module.exports = {
|
|
|
26
27
|
*/
|
|
27
28
|
componentSlotMigration({ propertyName, context, template, alwaysExpression = false }) {
|
|
28
29
|
return node => {
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* @param {VElement | VText | VExpressionContainer} child
|
|
32
|
+
* @returns {boolean}
|
|
33
|
+
*/
|
|
34
|
+
function isNamedSlot(child) {
|
|
35
|
+
return (
|
|
36
|
+
child.type === 'VElement' &&
|
|
37
|
+
child.name === 'template' &&
|
|
38
|
+
child.startTag.attributes.some(
|
|
39
|
+
attribute => attribute.directive && attribute.key.name.name === 'slot'
|
|
40
|
+
)
|
|
41
|
+
);
|
|
31
42
|
}
|
|
32
43
|
|
|
44
|
+
// Named slots are not default slot content and should not trigger migration.
|
|
45
|
+
const contentNodes = node.children.filter(child => !isNamedSlot(child));
|
|
46
|
+
|
|
33
47
|
// Turned true if one of the children is an expression
|
|
34
48
|
let hasExpression = false;
|
|
35
49
|
|
|
@@ -72,7 +86,11 @@ module.exports = {
|
|
|
72
86
|
|
|
73
87
|
// Remove empty nodes
|
|
74
88
|
/** @type { Array<VText | VExpressionContainer> } */
|
|
75
|
-
const filteredNodes =
|
|
89
|
+
const filteredNodes = contentNodes.filter(removeEmptyVTextNodes);
|
|
90
|
+
|
|
91
|
+
if (!filteredNodes.length) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
76
94
|
|
|
77
95
|
// Get all content and concat
|
|
78
96
|
const slotContent = (() => {
|
|
@@ -80,7 +98,7 @@ module.exports = {
|
|
|
80
98
|
return transformNodeToText(filteredNodes[0])?.trim();
|
|
81
99
|
}
|
|
82
100
|
|
|
83
|
-
const content =
|
|
101
|
+
const content = contentNodes
|
|
84
102
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
85
103
|
.map((/** @type {VText | VExpressionContainer} */ node) => transformNodeToText(node, true))
|
|
86
104
|
.join('')
|