@wireweave/ux-rules 1.0.0 → 1.1.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/README.md +192 -8
- package/dist/index.cjs +1355 -175
- package/dist/index.d.cts +158 -2
- package/dist/index.d.ts +158 -2
- package/dist/index.js +1308 -175
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -44,14 +44,20 @@ const issues = getUXIssues(doc);
|
|
|
44
44
|
|
|
45
45
|
## Rule Categories
|
|
46
46
|
|
|
47
|
-
| Category | Description |
|
|
48
|
-
|
|
49
|
-
| `accessibility` | Screen reader support, labels, alt text |
|
|
50
|
-
| `form` | Form UX patterns, input types, validation |
|
|
51
|
-
| `usability` | General usability (empty containers, CTA, loading states) |
|
|
52
|
-
| `touch-target` | Touch target sizes for mobile |
|
|
53
|
-
| `navigation` | Navigation patterns (item count, active states) |
|
|
54
|
-
| `consistency` | Consistent styling across components |
|
|
47
|
+
| Category | Rules | Description |
|
|
48
|
+
|----------|-------|-------------|
|
|
49
|
+
| `accessibility` | 5 | Screen reader support, labels, alt text |
|
|
50
|
+
| `form` | 4 | Form UX patterns, input types, validation |
|
|
51
|
+
| `usability` | 10 | General usability (empty containers, CTA, loading states, cognitive load) |
|
|
52
|
+
| `touch-target` | 5 | Touch target sizes for mobile (WCAG 2.5.5) |
|
|
53
|
+
| `navigation` | 5 | Navigation patterns (item count, active states) |
|
|
54
|
+
| `consistency` | 4 | Consistent styling across components |
|
|
55
|
+
| `content` | 6 | Text quality, placeholder detection, title requirements |
|
|
56
|
+
| `data-display` | 6 | Tables, lists, empty states, pagination |
|
|
57
|
+
| `feedback` | 6 | Spinners, progress bars, toasts, alerts |
|
|
58
|
+
| `interaction` | 8 | Interactive elements need actions defined |
|
|
59
|
+
|
|
60
|
+
**Total: 59 rules**
|
|
55
61
|
|
|
56
62
|
## API
|
|
57
63
|
|
|
@@ -90,6 +96,184 @@ Formats validation result as human-readable string.
|
|
|
90
96
|
| `warning` | Should fix | -3 |
|
|
91
97
|
| `info` | Consider improving | -1 |
|
|
92
98
|
|
|
99
|
+
**Score Formula:** `100 - (errors × 10 + warnings × 3 + info × 1)`
|
|
100
|
+
|
|
101
|
+
## All Rules
|
|
102
|
+
|
|
103
|
+
<details>
|
|
104
|
+
<summary><strong>Accessibility (5 rules)</strong></summary>
|
|
105
|
+
|
|
106
|
+
| Rule ID | Severity | Description |
|
|
107
|
+
|---------|----------|-------------|
|
|
108
|
+
| `a11y-input-label` | error/warning | Input fields must have labels |
|
|
109
|
+
| `a11y-image-alt` | warning | Images should have alt text |
|
|
110
|
+
| `a11y-icon-button-label` | error | Icon-only buttons need accessible text |
|
|
111
|
+
| `a11y-link-text` | warning | Links should have descriptive text |
|
|
112
|
+
| `a11y-heading-hierarchy` | warning | Heading levels should be sequential |
|
|
113
|
+
|
|
114
|
+
</details>
|
|
115
|
+
|
|
116
|
+
<details>
|
|
117
|
+
<summary><strong>Form (4 rules)</strong></summary>
|
|
118
|
+
|
|
119
|
+
| Rule ID | Severity | Description |
|
|
120
|
+
|---------|----------|-------------|
|
|
121
|
+
| `form-submit-button` | warning | Forms with inputs need submit button |
|
|
122
|
+
| `form-required-indicator` | info | Required fields should be marked |
|
|
123
|
+
| `form-password-confirm` | info | Registration forms may need password confirmation |
|
|
124
|
+
| `form-input-type` | warning | Use appropriate input types (email, tel, etc.) |
|
|
125
|
+
|
|
126
|
+
</details>
|
|
127
|
+
|
|
128
|
+
<details>
|
|
129
|
+
<summary><strong>Usability (10 rules)</strong></summary>
|
|
130
|
+
|
|
131
|
+
| Rule ID | Severity | Description |
|
|
132
|
+
|---------|----------|-------------|
|
|
133
|
+
| `usability-empty-container` | warning | Avoid empty containers |
|
|
134
|
+
| `usability-clear-cta` | info | Pages should have primary button (CTA) |
|
|
135
|
+
| `usability-loading-states` | info | Async buttons may need loading state |
|
|
136
|
+
| `usability-destructive-confirm` | warning | Destructive actions need danger styling |
|
|
137
|
+
| `usability-modal-close` | warning | Modals need close mechanism |
|
|
138
|
+
| `usability-nesting-depth` | warning | Avoid excessive nesting (max 6 levels) |
|
|
139
|
+
| `usability-too-many-buttons` | warning | Max 5 buttons per container |
|
|
140
|
+
| `usability-too-many-form-fields` | info | Max 10 form fields |
|
|
141
|
+
| `usability-page-complexity` | info | Max 50 elements per page |
|
|
142
|
+
| `usability-drawer-width` | info | Drawers should have width |
|
|
143
|
+
|
|
144
|
+
</details>
|
|
145
|
+
|
|
146
|
+
<details>
|
|
147
|
+
<summary><strong>Touch Target (5 rules)</strong></summary>
|
|
148
|
+
|
|
149
|
+
| Rule ID | Severity | Description |
|
|
150
|
+
|---------|----------|-------------|
|
|
151
|
+
| `touch-button-size` | warning | Button minimum 44px (WCAG AAA) |
|
|
152
|
+
| `touch-icon-button-size` | warning | Icon buttons need adequate padding |
|
|
153
|
+
| `touch-checkbox-radio-size` | info | Checkbox/Radio should have labels |
|
|
154
|
+
| `touch-link-spacing` | info | Adjacent links need spacing |
|
|
155
|
+
| `touch-avatar-size` | info | Clickable avatars should be 44px+ |
|
|
156
|
+
|
|
157
|
+
</details>
|
|
158
|
+
|
|
159
|
+
<details>
|
|
160
|
+
<summary><strong>Navigation (5 rules)</strong></summary>
|
|
161
|
+
|
|
162
|
+
| Rule ID | Severity | Description |
|
|
163
|
+
|---------|----------|-------------|
|
|
164
|
+
| `nav-item-count` | warning | Max 7 navigation items (Miller's Law) |
|
|
165
|
+
| `nav-active-state` | info | Navigation should show active state |
|
|
166
|
+
| `nav-breadcrumb-home` | info | Breadcrumb should start with home |
|
|
167
|
+
| `nav-tab-count` | warning | Max 5 tabs |
|
|
168
|
+
| `nav-dropdown-items` | warning | Dropdown must have items |
|
|
169
|
+
|
|
170
|
+
</details>
|
|
171
|
+
|
|
172
|
+
<details>
|
|
173
|
+
<summary><strong>Consistency (4 rules)</strong></summary>
|
|
174
|
+
|
|
175
|
+
| Rule ID | Severity | Description |
|
|
176
|
+
|---------|----------|-------------|
|
|
177
|
+
| `consistency-button-styles` | info | Consistent button styles in container |
|
|
178
|
+
| `consistency-spacing` | info | Consistent gap values |
|
|
179
|
+
| `consistency-card-styling` | info | Sibling cards should match |
|
|
180
|
+
| `consistency-alert-variants` | warning | Alert variant should match content |
|
|
181
|
+
|
|
182
|
+
</details>
|
|
183
|
+
|
|
184
|
+
<details>
|
|
185
|
+
<summary><strong>Content (6 rules)</strong></summary>
|
|
186
|
+
|
|
187
|
+
| Rule ID | Severity | Description |
|
|
188
|
+
|---------|----------|-------------|
|
|
189
|
+
| `content-empty-text` | warning | Avoid empty/placeholder text |
|
|
190
|
+
| `content-button-text-length` | info | Button text max 25 characters |
|
|
191
|
+
| `content-title-length` | info | Title max 60 characters |
|
|
192
|
+
| `content-page-title` | warning | Pages should have title |
|
|
193
|
+
| `content-link-text` | error | Links must have text |
|
|
194
|
+
| `content-no-placeholder` | warning | Replace placeholder content |
|
|
195
|
+
|
|
196
|
+
</details>
|
|
197
|
+
|
|
198
|
+
<details>
|
|
199
|
+
<summary><strong>Data Display (6 rules)</strong></summary>
|
|
200
|
+
|
|
201
|
+
| Rule ID | Severity | Description |
|
|
202
|
+
|---------|----------|-------------|
|
|
203
|
+
| `data-table-header` | warning | Tables need headers |
|
|
204
|
+
| `data-list-empty-state` | info | Lists should have empty state |
|
|
205
|
+
| `data-table-empty-state` | info | Tables should have empty state |
|
|
206
|
+
| `data-list-pagination` | info | Long lists (20+) need pagination |
|
|
207
|
+
| `data-table-columns` | warning | Max 8 table columns |
|
|
208
|
+
| `data-card-grid` | info | Card grids should be consistent |
|
|
209
|
+
|
|
210
|
+
</details>
|
|
211
|
+
|
|
212
|
+
<details>
|
|
213
|
+
<summary><strong>Feedback (6 rules)</strong></summary>
|
|
214
|
+
|
|
215
|
+
| Rule ID | Severity | Description |
|
|
216
|
+
|---------|----------|-------------|
|
|
217
|
+
| `feedback-spinner-context` | info | Spinners should have context text |
|
|
218
|
+
| `feedback-progress-value` | info | Progress should show value |
|
|
219
|
+
| `feedback-toast-duration` | info | Toast duration 2-10 seconds |
|
|
220
|
+
| `feedback-alert-dismissible` | info | Non-critical alerts should be dismissible |
|
|
221
|
+
| `feedback-tooltip-length` | info | Tooltip max 100 characters |
|
|
222
|
+
| `feedback-form-errors` | info | Forms should handle errors |
|
|
223
|
+
|
|
224
|
+
</details>
|
|
225
|
+
|
|
226
|
+
<details>
|
|
227
|
+
<summary><strong>Interaction (8 rules)</strong></summary>
|
|
228
|
+
|
|
229
|
+
| Rule ID | Severity | Description |
|
|
230
|
+
|---------|----------|-------------|
|
|
231
|
+
| `interaction-button-action` | warning | Buttons need onClick/action/href |
|
|
232
|
+
| `interaction-link-destination` | warning | Links need href/to destination |
|
|
233
|
+
| `interaction-form-submit` | warning | Forms need onSubmit/action |
|
|
234
|
+
| `interaction-tab-target` | warning | Tabs need target/value |
|
|
235
|
+
| `interaction-menu-action` | warning | Menu items need action |
|
|
236
|
+
| `interaction-card-action` | info | Clickable cards need action |
|
|
237
|
+
| `interaction-icon-button-action` | warning | Icon buttons need action |
|
|
238
|
+
| `interaction-modal-close` | info | Modals need close mechanism |
|
|
239
|
+
|
|
240
|
+
</details>
|
|
241
|
+
|
|
242
|
+
## Custom Rules
|
|
243
|
+
|
|
244
|
+
Create custom rules using the exported types and utilities:
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
import { validateUX, UXRule, getNodeText, containsAnyWord } from '@wireweave/ux-rules';
|
|
248
|
+
|
|
249
|
+
const myRule: UXRule = {
|
|
250
|
+
id: 'custom-no-click-here',
|
|
251
|
+
category: 'accessibility',
|
|
252
|
+
severity: 'warning',
|
|
253
|
+
name: 'Avoid "click here" text',
|
|
254
|
+
description: 'Link text should be descriptive',
|
|
255
|
+
appliesTo: ['Button', 'Link'],
|
|
256
|
+
check: (node, context) => {
|
|
257
|
+
const text = getNodeText(node).toLowerCase();
|
|
258
|
+
if (containsAnyWord(text, ['click here', 'click me'])) {
|
|
259
|
+
return {
|
|
260
|
+
ruleId: 'custom-no-click-here',
|
|
261
|
+
category: 'accessibility',
|
|
262
|
+
severity: 'warning',
|
|
263
|
+
message: 'Avoid generic "click here" text',
|
|
264
|
+
description: 'Use descriptive text that indicates the action',
|
|
265
|
+
suggestion: 'Replace with descriptive action text',
|
|
266
|
+
path: context.path,
|
|
267
|
+
nodeType: node.type,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
return null;
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const result = validateUX(doc, { customRules: [myRule] });
|
|
275
|
+
```
|
|
276
|
+
|
|
93
277
|
## Related Packages
|
|
94
278
|
|
|
95
279
|
- [@wireweave/core](https://www.npmjs.com/package/@wireweave/core) - Core parser and renderer
|