@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.
- package/CHANGELOG.md +1 -0
- package/README.md +754 -0
- package/build/index.d.ts +99 -0
- package/build/index.js +79 -0
- package/build/rules/accordion/no-nested-accordion.d.ts +5 -0
- package/build/rules/accordion/no-nested-accordion.js +37 -0
- package/build/rules/badge/badge-corner-placement-rules.d.ts +5 -0
- package/build/rules/badge/badge-corner-placement-rules.js +76 -0
- package/build/rules/badge/badge-no-inline-in-interactive.d.ts +5 -0
- package/build/rules/badge/badge-no-inline-in-interactive.js +67 -0
- package/build/rules/button/button-no-text-requires-tooltip.d.ts +5 -0
- package/build/rules/button/button-no-text-requires-tooltip.js +59 -0
- package/build/rules/button/button-single-icon-attribute.d.ts +5 -0
- package/build/rules/button/button-single-icon-attribute.js +35 -0
- package/build/rules/button/button-type-required.d.ts +5 -0
- package/build/rules/button/button-type-required.js +45 -0
- package/build/rules/close-button/close-button-text-required.d.ts +5 -0
- package/build/rules/close-button/close-button-text-required.js +40 -0
- package/build/rules/content/text-or-children-required.d.ts +5 -0
- package/build/rules/content/text-or-children-required.js +49 -0
- package/build/rules/form/form-label-required.d.ts +5 -0
- package/build/rules/form/form-label-required.js +47 -0
- package/build/rules/form/form-validation-message-required.d.ts +5 -0
- package/build/rules/form/form-validation-message-required.js +93 -0
- package/build/rules/header/header-burger-menu-label-required.d.ts +5 -0
- package/build/rules/header/header-burger-menu-label-required.js +32 -0
- package/build/rules/icon/prefer-icon-attribute.d.ts +5 -0
- package/build/rules/icon/prefer-icon-attribute.js +67 -0
- package/build/rules/input/input-file-type-validation.d.ts +5 -0
- package/build/rules/input/input-file-type-validation.js +52 -0
- package/build/rules/input/input-type-required.d.ts +5 -0
- package/build/rules/input/input-type-required.js +40 -0
- package/build/rules/link/link-external-security.d.ts +5 -0
- package/build/rules/link/link-external-security.js +50 -0
- package/build/rules/navigation/navigation-item-back-button-text-required.d.ts +5 -0
- package/build/rules/navigation/navigation-item-back-button-text-required.js +32 -0
- package/build/rules/select/custom-select-tags-remove-text-required.d.ts +5 -0
- package/build/rules/select/custom-select-tags-remove-text-required.js +35 -0
- package/build/rules/select/select-requires-options.d.ts +5 -0
- package/build/rules/select/select-requires-options.js +44 -0
- package/build/rules/tag/tag-removable-remove-button-required.d.ts +5 -0
- package/build/rules/tag/tag-removable-remove-button-required.js +35 -0
- package/build/rules/tooltip/no-interactive-tooltip-content.d.ts +5 -0
- package/build/rules/tooltip/no-interactive-tooltip-content.js +47 -0
- package/build/rules/tooltip/tooltip-requires-interactive-parent.d.ts +5 -0
- package/build/rules/tooltip/tooltip-requires-interactive-parent.js +47 -0
- package/build/shared/utils.d.ts +5 -0
- package/build/shared/utils.js +61 -0
- 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
|
+
```
|