@db-ux/core-eslint-plugin 0.0.0 → 4.4.2-eslint-plugin-28ea614

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 (49) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/README.md +754 -0
  3. package/build/index.d.ts +99 -0
  4. package/build/index.js +79 -0
  5. package/build/rules/accordion/no-nested-accordion.d.ts +5 -0
  6. package/build/rules/accordion/no-nested-accordion.js +37 -0
  7. package/build/rules/badge/badge-corner-placement-rules.d.ts +5 -0
  8. package/build/rules/badge/badge-corner-placement-rules.js +76 -0
  9. package/build/rules/badge/badge-no-inline-in-interactive.d.ts +5 -0
  10. package/build/rules/badge/badge-no-inline-in-interactive.js +67 -0
  11. package/build/rules/button/button-no-text-requires-tooltip.d.ts +5 -0
  12. package/build/rules/button/button-no-text-requires-tooltip.js +59 -0
  13. package/build/rules/button/button-single-icon-attribute.d.ts +5 -0
  14. package/build/rules/button/button-single-icon-attribute.js +35 -0
  15. package/build/rules/button/button-type-required.d.ts +5 -0
  16. package/build/rules/button/button-type-required.js +45 -0
  17. package/build/rules/close-button/close-button-text-required.d.ts +5 -0
  18. package/build/rules/close-button/close-button-text-required.js +40 -0
  19. package/build/rules/content/text-or-children-required.d.ts +5 -0
  20. package/build/rules/content/text-or-children-required.js +49 -0
  21. package/build/rules/form/form-label-required.d.ts +5 -0
  22. package/build/rules/form/form-label-required.js +47 -0
  23. package/build/rules/form/form-validation-message-required.d.ts +5 -0
  24. package/build/rules/form/form-validation-message-required.js +93 -0
  25. package/build/rules/header/header-burger-menu-label-required.d.ts +5 -0
  26. package/build/rules/header/header-burger-menu-label-required.js +32 -0
  27. package/build/rules/icon/prefer-icon-attribute.d.ts +5 -0
  28. package/build/rules/icon/prefer-icon-attribute.js +67 -0
  29. package/build/rules/input/input-file-type-validation.d.ts +5 -0
  30. package/build/rules/input/input-file-type-validation.js +52 -0
  31. package/build/rules/input/input-type-required.d.ts +5 -0
  32. package/build/rules/input/input-type-required.js +40 -0
  33. package/build/rules/link/link-external-security.d.ts +5 -0
  34. package/build/rules/link/link-external-security.js +50 -0
  35. package/build/rules/navigation/navigation-item-back-button-text-required.d.ts +5 -0
  36. package/build/rules/navigation/navigation-item-back-button-text-required.js +32 -0
  37. package/build/rules/select/custom-select-tags-remove-text-required.d.ts +5 -0
  38. package/build/rules/select/custom-select-tags-remove-text-required.js +35 -0
  39. package/build/rules/select/select-requires-options.d.ts +5 -0
  40. package/build/rules/select/select-requires-options.js +44 -0
  41. package/build/rules/tag/tag-removable-remove-button-required.d.ts +5 -0
  42. package/build/rules/tag/tag-removable-remove-button-required.js +35 -0
  43. package/build/rules/tooltip/no-interactive-tooltip-content.d.ts +5 -0
  44. package/build/rules/tooltip/no-interactive-tooltip-content.js +47 -0
  45. package/build/rules/tooltip/tooltip-requires-interactive-parent.d.ts +5 -0
  46. package/build/rules/tooltip/tooltip-requires-interactive-parent.js +47 -0
  47. package/build/shared/utils.d.ts +5 -0
  48. package/build/shared/utils.js +61 -0
  49. package/package.json +32 -1
package/README.md ADDED
@@ -0,0 +1,754 @@
1
+ # @db-ux/eslint-plugin
2
+
3
+ ESLint plugin to validate correct usage of DB UX Design System components across React, Vue, and Angular.
4
+
5
+ ## Installation
6
+
7
+ ```shell
8
+ npm install eslint @db-ux/eslint-plugin --save-dev
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Add to your ESLint config:
14
+
15
+ **ESLint 9+ (flat config):**
16
+
17
+ ```js
18
+ import dbUx from "@db-ux/eslint-plugin";
19
+
20
+ export default [
21
+ {
22
+ plugins: {
23
+ "db-ux": dbUx
24
+ },
25
+ rules: dbUx.configs.recommended.rules
26
+ }
27
+ ];
28
+ ```
29
+
30
+ **Or enable rules individually:**
31
+
32
+ ```js
33
+ import dbUx from "@db-ux/eslint-plugin";
34
+
35
+ export default [
36
+ {
37
+ plugins: {
38
+ "db-ux": dbUx
39
+ },
40
+ rules: {
41
+ "db-ux/button-no-text-requires-tooltip": "error"
42
+ }
43
+ }
44
+ ];
45
+ ```
46
+
47
+ ## Rules
48
+
49
+ ### `button-no-text-requires-tooltip`
50
+
51
+ Ensures that buttons with `noText` prop have both an `icon` (or `iconLeading`/`iconTrailing`) and a `DBTooltip` child.
52
+
53
+ **❌ Invalid:**
54
+
55
+ ```jsx
56
+ // React
57
+ <DBButton noText>Save</DBButton>
58
+ <DBButton icon="save" noText>Save</DBButton>
59
+
60
+ // Angular
61
+ <db-button [noText]="true">ABC</db-button>
62
+ <db-button icon="x" [noText]="true">ABC</db-button>
63
+
64
+ // Vue
65
+ <DBButton :noText="true">ABC</DBButton>
66
+ <DBButton icon="x" :noText="true">ABC</DBButton>
67
+ ```
68
+
69
+ **✅ Valid:**
70
+
71
+ ```jsx
72
+ // React
73
+ <DBButton icon="save" noText>
74
+ Save
75
+ <DBTooltip>Save document</DBTooltip>
76
+ </DBButton>
77
+
78
+ // Angular
79
+ <db-button icon="x_placeholder" [noText]="true">
80
+ ABC
81
+ <db-tooltip>ABC</db-tooltip>
82
+ </db-button>
83
+
84
+ // Vue
85
+ <DBButton icon="x_placeholder" :noText="true">
86
+ ABC
87
+ <DBTooltip>ABC</DBTooltip>
88
+ </DBButton>
89
+ ```
90
+
91
+ ## Supported Frameworks
92
+
93
+ - React (JSX/TSX)
94
+ - Vue (SFC)
95
+ - Angular (Templates)
96
+
97
+ The plugin automatically detects the framework based on file extension and parser.
98
+
99
+ ### `button-type-required`
100
+
101
+ Ensures that DBButton has an explicit `type` attribute (submit, button, or reset).
102
+
103
+ **❌ Invalid:**
104
+
105
+ ```jsx
106
+ <DBButton>Save</DBButton>
107
+ <db-button>Save</db-button>
108
+ ```
109
+
110
+ **✅ Valid:**
111
+
112
+ ```jsx
113
+ <DBButton type="button">Save</DBButton>
114
+ <DBButton type="submit">Submit</DBButton>
115
+ <DBButton type="reset">Reset</DBButton>
116
+ ```
117
+
118
+ ### `form-label-required`
119
+
120
+ Ensures that form components (DBInput, DBTextarea, DBSelect, DBCustomSelect, DBCheckbox, DBRadio, DBSwitch) have a `label` attribute for accessibility.
121
+
122
+ **❌ Invalid:**
123
+
124
+ ```jsx
125
+ // React
126
+ <DBInput />
127
+ <DBCheckbox />
128
+ <DBSelect />
129
+
130
+ // Angular
131
+ <db-input></db-input>
132
+ <db-checkbox></db-checkbox>
133
+
134
+ // Vue
135
+ <DBInput />
136
+ <DBCheckbox />
137
+ ```
138
+
139
+ **✅ Valid:**
140
+
141
+ ```jsx
142
+ // React
143
+ <DBInput label="Name" />
144
+ <DBCheckbox label="Accept terms" />
145
+ <DBSelect label="Country" />
146
+
147
+ // Angular
148
+ <db-input label="Name"></db-input>
149
+ <db-checkbox [label]="labelText"></db-checkbox>
150
+
151
+ // Vue
152
+ <DBInput :label="dynamicLabel" />
153
+ <DBCheckbox label="Accept terms" />
154
+ ```
155
+
156
+ ### `prefer-icon-attribute`
157
+
158
+ Prefer using the `icon` attribute over `<DBIcon>` child component for components that support icon attributes.
159
+
160
+ **❌ Invalid:**
161
+
162
+ ```jsx
163
+ // React
164
+ <DBButton><DBIcon icon="save" /></DBButton>
165
+ <DBInput><DBIcon icon="search" /></DBInput>
166
+
167
+ // Angular
168
+ <db-button><db-icon icon="save"></db-icon></db-button>
169
+
170
+ // Vue
171
+ <DBLink><DBIcon icon="external" /></DBLink>
172
+ ```
173
+
174
+ **✅ Valid:**
175
+
176
+ ```jsx
177
+ // React
178
+ <DBButton icon="save">Save</DBButton>
179
+ <DBInput icon="search" />
180
+
181
+ // Angular
182
+ <db-button icon="save">Save</db-button>
183
+
184
+ // Vue
185
+ <DBLink :icon="iconName">Link</DBLink>
186
+ ```
187
+
188
+ ### `text-or-children-required`
189
+
190
+ Ensures that components (DBAccordionItem, DBBadge, DBButton, DBLink, DBIcon, DBInfotext, DBNavigationItem, DBNotification) have either a `text` property or children content.
191
+
192
+ **❌ Invalid:**
193
+
194
+ ```jsx
195
+ // React
196
+ <DBButton />
197
+ <DBLink />
198
+ <DBBadge />
199
+
200
+ // Angular
201
+ <db-button></db-button>
202
+ <db-notification></db-notification>
203
+
204
+ // Vue
205
+ <DBIcon icon="test" />
206
+ ```
207
+
208
+ **✅ Valid:**
209
+
210
+ ```jsx
211
+ // React
212
+ <DBButton text="Save" />
213
+ <DBButton>Save</DBButton>
214
+ <DBLink>Click here</DBLink>
215
+
216
+ // Angular
217
+ <db-button text="Save"></db-button>
218
+ <db-button>Save</db-button>
219
+
220
+ // Vue
221
+ <DBBadge>New</DBBadge>
222
+ <DBIcon icon="test">Label</DBIcon>
223
+ ```
224
+
225
+ ### `no-interactive-tooltip-content`
226
+
227
+ Prevents interactive elements (buttons, links, inputs) inside DBTooltip. Use DBPopover for interactive content.
228
+
229
+ **❌ Invalid:**
230
+
231
+ ```jsx
232
+ // React
233
+ <DBTooltip><button>Click</button></DBTooltip>
234
+ <DBTooltip><DBButton>Action</DBButton></DBTooltip>
235
+ <DBTooltip><a href="#">Link</a></DBTooltip>
236
+
237
+ // Angular
238
+ <db-tooltip><button>Click</button></db-tooltip>
239
+ <db-tooltip><db-button>Action</db-button></db-tooltip>
240
+
241
+ // Vue
242
+ <DBTooltip><DBLink href="#">Link</DBLink></DBTooltip>
243
+ ```
244
+
245
+ **✅ Valid:**
246
+
247
+ ```jsx
248
+ // React
249
+ <DBTooltip>Simple text</DBTooltip>
250
+ <DBTooltip><span>Text with span</span></DBTooltip>
251
+ <DBTooltip><p>Paragraph</p></DBTooltip>
252
+
253
+ // For interactive content, use DBPopover:
254
+ <DBPopover><DBButton>Action</DBButton></DBPopover>
255
+ ```
256
+
257
+ ### `tooltip-requires-interactive-parent`
258
+
259
+ Ensures DBTooltip is a child of an interactive element for accessibility (users must be able to focus the parent).
260
+
261
+ **❌ Invalid:**
262
+
263
+ ```jsx
264
+ // React
265
+ <span>Show more<DBTooltip>XXX</DBTooltip></span>
266
+ <div>Text<DBTooltip>Info</DBTooltip></div>
267
+ <DBBadge>Badge<DBTooltip>Info</DBTooltip></DBBadge>
268
+
269
+ // Angular
270
+ <span>Show more<db-tooltip>XXX</db-tooltip></span>
271
+
272
+ // Vue
273
+ <div>Text<DBTooltip>Info</DBTooltip></div>
274
+ ```
275
+
276
+ **✅ Valid:**
277
+
278
+ ```jsx
279
+ // React
280
+ <button>Save<DBTooltip>Save document</DBTooltip></button>
281
+ <DBButton>Save<DBTooltip>Save document</DBTooltip></DBButton>
282
+ <a href="#">Link<DBTooltip>More info</DBTooltip></a>
283
+
284
+ // Angular
285
+ <db-button>Save<db-tooltip>Save document</db-tooltip></db-button>
286
+
287
+ // Vue
288
+ <DBLink href="#">Link<DBTooltip>More info</DBTooltip></DBLink>
289
+ ```
290
+
291
+ ### `no-nested-accordion`
292
+
293
+ Prevents nesting DBAccordion components inside each other as it confuses users.
294
+
295
+ **❌ Invalid:**
296
+
297
+ ```jsx
298
+ // React
299
+ <DBAccordion><DBAccordion>Nested</DBAccordion></DBAccordion>
300
+ <DBAccordion><DBAccordionItem><DBAccordion>Deep</DBAccordion></DBAccordionItem></DBAccordion>
301
+
302
+ // Angular
303
+ <db-accordion><db-accordion>Nested</db-accordion></db-accordion>
304
+
305
+ // Vue
306
+ <DBAccordion><div><DBAccordion>Nested</DBAccordion></div></DBAccordion>
307
+ ```
308
+
309
+ **✅ Valid:**
310
+
311
+ ```jsx
312
+ // React
313
+ <DBAccordion><DBAccordionItem>Item</DBAccordionItem></DBAccordion>
314
+ <div><DBAccordion>First</DBAccordion></div>
315
+ <DBAccordion>First</DBAccordion><DBAccordion>Second</DBAccordion>
316
+ ```
317
+
318
+ ### `badge-corner-placement-rules`
319
+
320
+ Ensures DBBadge with corner placement has max 3 characters and a label attribute for accessibility.
321
+
322
+ **❌ Invalid:**
323
+
324
+ ```jsx
325
+ // React
326
+ <DBBadge placement="corner-top-left">9999</DBBadge>
327
+ <DBBadge placement="corner-top-right" text="1234" />
328
+ <DBBadge placement="corner-top-left">99</DBBadge>
329
+
330
+ // Angular
331
+ <db-badge placement="corner-top-left">9999</db-badge>
332
+
333
+ // Vue
334
+ <DBBadge placement="corner-top-right">Long text</DBBadge>
335
+ ```
336
+
337
+ **✅ Valid:**
338
+
339
+ ```jsx
340
+ // React
341
+ <DBBadge>Long text is fine</DBBadge>
342
+ <DBBadge placement="inline">Long text</DBBadge>
343
+ <DBBadge placement="corner-top-left" label="New items">99+</DBBadge>
344
+ <DBBadge placement="corner-top-right" text="5" label="Notifications" />
345
+
346
+ // Auto-fix converts:
347
+ <DBBadge placement="corner-top-left">9999</DBBadge>
348
+ // to:
349
+ <DBBadge placement="corner-top-left" label="9999">999</DBBadge>
350
+ ```
351
+
352
+ ### `badge-no-inline-in-interactive`
353
+
354
+ Prevents DBBadge with inline placement inside interactive elements (DBButton, DBLink). Use corner placement instead.
355
+
356
+ **❌ Invalid:**
357
+
358
+ ```jsx
359
+ // React
360
+ <DBButton><DBBadge placement="inline">Badge</DBBadge>Button</DBButton>
361
+ <DBLink><DBBadge placement="inline">Badge</DBBadge>Link</DBLink>
362
+
363
+ // Angular
364
+ <db-button><db-badge placement="inline">Badge</db-badge>Button</db-button>
365
+
366
+ // Vue
367
+ <DBButton><DBBadge placement="inline">Badge</DBBadge>Button</DBButton>
368
+ ```
369
+
370
+ **✅ Valid:**
371
+
372
+ ```jsx
373
+ // React
374
+ <DBBadge placement="inline">Badge</DBBadge>
375
+ <DBButton><DBBadge placement="corner-top-right" label="New">5</DBBadge>Button</DBButton>
376
+ <DBLink><DBBadge placement="corner-top-left" label="Count">3</DBBadge>Link</DBLink>
377
+
378
+ // Auto-fix converts:
379
+ <DBButton><DBBadge placement="inline">Badge</DBBadge>Button</DBButton>
380
+ // to:
381
+ <DBButton><DBBadge placement="corner-top-right">Badge</DBBadge>Button</DBButton>
382
+ ```
383
+
384
+ ### `button-single-icon-attribute`
385
+
386
+ Ensures DBButton uses only one icon attribute (icon, iconLeading, or iconTrailing).
387
+
388
+ **❌ Invalid:**
389
+
390
+ ```jsx
391
+ // React
392
+ <DBButton icon="save" iconLeading="save">Save</DBButton>
393
+ <DBButton icon="save" iconTrailing="arrow">Save</DBButton>
394
+ <DBButton iconLeading="save" iconTrailing="arrow">Save</DBButton>
395
+
396
+ // Angular
397
+ <db-button icon="save" [iconLeading]="iconName">Save</db-button>
398
+
399
+ // Vue
400
+ <DBButton icon="save" :iconTrailing="icon">Save</DBButton>
401
+ ```
402
+
403
+ **✅ Valid:**
404
+
405
+ ```jsx
406
+ // React
407
+ <DBButton icon="save">Save</DBButton>
408
+ <DBButton iconLeading="save">Save</DBButton>
409
+ <DBButton iconTrailing="arrow">Next</DBButton>
410
+
411
+ // Angular
412
+ <db-button icon="save">Save</db-button>
413
+ <db-button [iconLeading]="iconName">Save</db-button>
414
+
415
+ // Vue
416
+ <DBButton :iconTrailing="icon">Next</DBButton>
417
+ ```
418
+
419
+ ### `link-external-security`
420
+
421
+ Ensures external links have proper security attributes (target="\_blank" and referrerPolicy).
422
+
423
+ **❌ Invalid:**
424
+
425
+ ```jsx
426
+ // React
427
+ <DBLink content="external">External</DBLink>
428
+ <DBLink content="external" target="_blank">External</DBLink>
429
+ <DBLink target="_blank">External</DBLink>
430
+
431
+ // Angular
432
+ <db-link content="external">External</db-link>
433
+
434
+ // Vue
435
+ <DBLink content="external" :target="linkTarget">External</DBLink>
436
+ ```
437
+
438
+ **✅ Valid:**
439
+
440
+ ```jsx
441
+ // React
442
+ <DBLink href="#">Internal link</DBLink>
443
+ <DBLink content="external" target="_blank" referrerPolicy="no-referrer">External</DBLink>
444
+
445
+ // Angular
446
+ <db-link content="external" target="_blank" referrerPolicy="no-referrer">External</db-link>
447
+
448
+ // Vue
449
+ <DBLink content="external" target="_blank" :referrerPolicy="policy">External</DBLink>
450
+ ```
451
+
452
+ ### `select-requires-options`
453
+
454
+ Ensures DBSelect has either an options property or option children.
455
+
456
+ **❌ Invalid:**
457
+
458
+ ```jsx
459
+ // React
460
+ <DBSelect label="Country" />
461
+ <DBSelect label="Country"></DBSelect>
462
+
463
+ // Angular
464
+ <db-select label="Country"></db-select>
465
+
466
+ // Vue
467
+ <DBSelect label="Country" />
468
+ ```
469
+
470
+ **✅ Valid:**
471
+
472
+ ```jsx
473
+ // React
474
+ <DBSelect label="Country">
475
+ <option value="de">Germany</option>
476
+ <option value="us">USA</option>
477
+ </DBSelect>
478
+ <DBSelect label="Country" options={countryOptions} />
479
+
480
+ // Angular
481
+ <db-select label="Country">
482
+ <option value="de">Germany</option>
483
+ </db-select>
484
+ <db-select label="Country" [options]="options"></db-select>
485
+
486
+ // Vue
487
+ <DBSelect label="Country" :options="options" />
488
+ ```
489
+
490
+ ### `close-button-text-required`
491
+
492
+ Ensures components with close buttons have appropriate text attributes for accessibility.
493
+
494
+ **❌ Invalid:**
495
+
496
+ ```jsx
497
+ // React
498
+ <DBNotification>Message</DBNotification>
499
+ <DBDrawer>Content</DBDrawer>
500
+ <DBCustomSelect label="Select" />
501
+
502
+ // Angular
503
+ <db-notification>Message</db-notification>
504
+ <db-drawer>Content</db-drawer>
505
+
506
+ // Vue
507
+ <DBCustomSelect label="Select" />
508
+ ```
509
+
510
+ **✅ Valid:**
511
+
512
+ ```jsx
513
+ // React
514
+ <DBNotification closeButtonText="Close">Message</DBNotification>
515
+ <DBDrawer closeButtonText="Close drawer">Content</DBDrawer>
516
+ <DBCustomSelect mobileCloseButtonText="Close" label="Select" />
517
+
518
+ // Angular
519
+ <db-notification closeButtonText="Close">Message</db-notification>
520
+ <db-drawer [closeButtonText]="closeText">Content</db-drawer>
521
+
522
+ // Vue
523
+ <DBCustomSelect :mobileCloseButtonText="closeText" label="Select" />
524
+ ```
525
+
526
+ ### `header-burger-menu-label-required`
527
+
528
+ Ensures DBHeader has burgerMenuLabel attribute for accessibility.
529
+
530
+ **❌ Invalid:**
531
+
532
+ ```jsx
533
+ // React
534
+ <DBHeader>Content</DBHeader>
535
+ <DBHeader closeButtonText="Close">Content</DBHeader>
536
+
537
+ // Angular
538
+ <db-header>Content</db-header>
539
+
540
+ // Vue
541
+ <DBHeader>Content</DBHeader>
542
+ ```
543
+
544
+ **✅ Valid:**
545
+
546
+ ```jsx
547
+ // React
548
+ <DBHeader burgerMenuLabel="Menu">Content</DBHeader>
549
+ <DBHeader burgerMenuLabel="Open navigation">Content</DBHeader>
550
+
551
+ // Angular
552
+ <db-header burgerMenuLabel="Menu">Content</db-header>
553
+ <db-header [burgerMenuLabel]="menuLabel">Content</db-header>
554
+
555
+ // Vue
556
+ <DBHeader :burgerMenuLabel="label">Content</DBHeader>
557
+ ```
558
+
559
+ ### `navigation-item-back-button-text-required`
560
+
561
+ Ensures DBNavigationItem has backButtonText attribute for accessibility.
562
+
563
+ **❌ Invalid:**
564
+
565
+ ```jsx
566
+ // React
567
+ <DBNavigationItem>Item</DBNavigationItem>
568
+ <DBNavigationItem icon="home">Item</DBNavigationItem>
569
+
570
+ // Angular
571
+ <db-navigation-item>Item</db-navigation-item>
572
+
573
+ // Vue
574
+ <DBNavigationItem>Item</DBNavigationItem>
575
+ ```
576
+
577
+ **✅ Valid:**
578
+
579
+ ```jsx
580
+ // React
581
+ <DBNavigationItem backButtonText="Back">Item</DBNavigationItem>
582
+ <DBNavigationItem backButtonText="Go back">Item</DBNavigationItem>
583
+
584
+ // Angular
585
+ <db-navigation-item backButtonText="Back">Item</db-navigation-item>
586
+ <db-navigation-item [backButtonText]="backText">Item</db-navigation-item>
587
+
588
+ // Vue
589
+ <DBNavigationItem :backButtonText="text">Item</DBNavigationItem>
590
+ ```
591
+
592
+ ### `custom-select-tags-remove-text-required`
593
+
594
+ Ensures DBCustomSelect with selectedType="tag" has removeTagsTexts attribute for accessibility.
595
+
596
+ **❌ Invalid:**
597
+
598
+ ```jsx
599
+ // React
600
+ <DBCustomSelect label="Select" selectedType="tag" />
601
+ <DBCustomSelect label="Select" selectedType="tag" options={opts} />
602
+
603
+ // Angular
604
+ <db-custom-select label="Select" selectedType="tag"></db-custom-select>
605
+
606
+ // Vue
607
+ <DBCustomSelect label="Select" selectedType="tag" />
608
+ ```
609
+
610
+ **✅ Valid:**
611
+
612
+ ```jsx
613
+ // React
614
+ <DBCustomSelect label="Select" />
615
+ <DBCustomSelect label="Select" selectedType="text" />
616
+ <DBCustomSelect label="Select" selectedType="tag" removeTagsTexts={["Remove A", "Remove B"]} />
617
+
618
+ // Angular
619
+ <db-custom-select label="Select" selectedType="tag" removeTagsTexts="texts"></db-custom-select>
620
+
621
+ // Vue
622
+ <DBCustomSelect label="Select" selectedType="tag" :removeTagsTexts="texts" />
623
+ ```
624
+
625
+ ### `tag-removable-remove-button-required`
626
+
627
+ Ensures DBTag with behavior="removable" has removeButton attribute for accessibility.
628
+
629
+ **❌ Invalid:**
630
+
631
+ ```jsx
632
+ // React
633
+ <DBTag behavior="removable">Tag</DBTag>
634
+ <DBTag behavior="removable" semantic="successful">Tag</DBTag>
635
+
636
+ // Angular
637
+ <db-tag behavior="removable">Tag</db-tag>
638
+
639
+ // Vue
640
+ <DBTag behavior="removable">Tag</DBTag>
641
+ ```
642
+
643
+ **✅ Valid:**
644
+
645
+ ```jsx
646
+ // React
647
+ <DBTag>Tag</DBTag>
648
+ <DBTag behavior="static">Tag</DBTag>
649
+ <DBTag behavior="removable" removeButton="Remove">Tag</DBTag>
650
+
651
+ // Angular
652
+ <db-tag behavior="removable" removeButton="Remove">Tag</db-tag>
653
+
654
+ // Vue
655
+ <DBTag behavior="removable" :removeButton="removeText">Tag</DBTag>
656
+ ```
657
+
658
+ ### `form-validation-message-required`
659
+
660
+ Ensures form components with validation attributes have invalidMessage for user feedback.
661
+
662
+ **❌ Invalid:**
663
+
664
+ ```jsx
665
+ // React
666
+ <DBInput label="Name" required />
667
+ <DBTextarea label="Text" maxLength={100} />
668
+ <DBInput label="Age" min={18} />
669
+ <DBInput label="Email" pattern=".*@.*" />
670
+
671
+ // Angular
672
+ <db-input label="Name" required></db-input>
673
+
674
+ // Vue
675
+ <DBInput label="Score" :max="100" />
676
+ ```
677
+
678
+ **✅ Valid:**
679
+
680
+ ```jsx
681
+ // React
682
+ <DBInput label="Name" />
683
+ <DBInput label="Name" required invalidMessage="Required" />
684
+ <DBTextarea label="Text" maxLength={100} invalidMessage="Too long" />
685
+ <DBInput label="Age" min={18} invalidMessage="Must be 18+" />
686
+ <DBInput label="Email" pattern=".*@.*" invalidMessage="Invalid email" />
687
+
688
+ // Applies to: DBInput, DBTextarea, DBSelect, DBCustomSelect, DBCheckbox
689
+ // Checks: required, maxLength, minLength (Input/Textarea), min, max, pattern (Input only)
690
+ ```
691
+
692
+ ### `input-type-required`
693
+
694
+ Suggests adding type attribute to DBInput for better developer experience.
695
+
696
+ **❌ Invalid:**
697
+
698
+ ```jsx
699
+ // React
700
+ <DBInput label="Name" />
701
+ <DBInput label="Name" placeholder="Enter name" />
702
+
703
+ // Angular
704
+ <db-input label="Name"></db-input>
705
+
706
+ // Vue
707
+ <DBInput label="Name" />
708
+ ```
709
+
710
+ **✅ Valid:**
711
+
712
+ ```jsx
713
+ // React
714
+ <DBInput label="Name" type="text" />
715
+ <DBInput label="Email" type="email" />
716
+ <DBInput label="Password" type="password" />
717
+
718
+ // Auto-fix adds:
719
+ <DBInput label="Name" type="text" />
720
+ ```
721
+
722
+ ### `input-file-type-validation`
723
+
724
+ Ensures DBInput with type="file" has accept attribute, and validates file-only attributes.
725
+
726
+ **❌ Invalid:**
727
+
728
+ ```jsx
729
+ // React
730
+ <DBInput label="File" type="file" />
731
+ <DBInput label="Name" type="text" multiple />
732
+ <DBInput label="Name" type="text" accept=".pdf" />
733
+
734
+ // Angular
735
+ <db-input label="File" type="file"></db-input>
736
+
737
+ // Vue
738
+ <DBInput label="Email" type="email" accept=".pdf" multiple />
739
+ ```
740
+
741
+ **✅ Valid:**
742
+
743
+ ```jsx
744
+ // React
745
+ <DBInput label="Name" type="text" />
746
+ <DBInput label="File" type="file" accept=".pdf" />
747
+ <DBInput label="Files" type="file" accept="image/*" multiple />
748
+
749
+ // Angular
750
+ <db-input label="File" type="file" accept=".jpg"></db-input>
751
+
752
+ // Vue
753
+ <DBInput label="File" type="file" accept="image/*" :multiple="true" />
754
+ ```