@yuktishaalaa/yuktai 2.0.13 → 2.0.14

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 (2) hide show
  1. package/README.md +204 -37
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,31 +1,70 @@
1
1
  # @yuktishaalaa/yuktai
2
2
 
3
- > Universal runtime accessibility plugin — automatically fixes WCAG violations on every page, for every user, with zero configuration.
3
+ > Universal runtime accessibility plugin — automatically fixes WCAG 2.2 violations on every page, for every user, with zero configuration. No JAWS needed.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@yuktishaalaa/yuktai)](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
6
- [![license](https://img.shields.io/badge/license--brightgreen)](./LICENSE)
6
+ [![downloads](https://img.shields.io/npm/dm/@yuktishaalaa/yuktai)](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
7
+ [![license](https://img.shields.io/badge/license-ISC-brightgreen)](./LICENSE)
8
+ [![node](https://img.shields.io/badge/node-%3E%3D18-blue)](https://nodejs.org)
9
+
10
+ ---
11
+
12
+ ## What's new in v2.0.0
13
+
14
+ - ✅ No JAWS needed — works with NVDA, VoiceOver, TalkBack, Narrator
15
+ - ✅ Built-in SpeechSynthesis — browser speaks on focus, zero install
16
+ - ✅ Visual alerts — sliding banner for deaf users, no audio needed
17
+ - ✅ Keyboard navigation — arrow keys, Escape, focus trap, no AT needed
18
+ - ✅ Skip links — multi-target (main, nav, search), always visible on mobile
19
+ - ✅ Preference panel — blind / deaf / motor / colour blind presets
20
+ - ✅ Persistent preferences — saved to localStorage across pages
21
+ - ✅ WCAG 2.2 — focus appearance, target size 44×44px, timeout warning
22
+ - ✅ Audit score — 0–100 with issue breakdown (localhost dev only)
23
+ - ✅ Dyslexia font — Atkinson Hyperlegible (research-backed)
24
+ - ✅ React 17, 18, 19 supported
25
+ - ✅ TypeScript declarations — full `index.d.ts` generated
7
26
 
8
27
  ---
9
28
 
10
29
  ## Install
11
30
 
31
+ ### React 17 or 18
12
32
  ```bash
13
33
  npm i @yuktishaalaa/yuktai
14
34
  ```
15
35
 
36
+ ### React 19 or MUI v5 conflict
37
+ ```bash
38
+ npm i @yuktishaalaa/yuktai --legacy-peer-deps
39
+ ```
40
+
41
+ ### MUI v5 + React 19 permanent fix
42
+ ```bash
43
+ npm i @mui/material@6 @mui/icons-material@6 --legacy-peer-deps
44
+ ```
45
+
46
+ ### Requirements
47
+ - Node.js 18 or higher
48
+ - npm 8 or higher
49
+
16
50
  ---
17
51
 
18
52
  ## What it does
19
53
 
20
54
  yuktai scans every HTML element on the page and automatically injects missing accessibility attributes — `aria-label`, `alt`, `role`, `tabindex`, `scope`, `autocomplete`, `aria-required`, `aria-expanded`, and more. It also:
21
55
 
22
- - Injects a skip-to-content link
56
+ - Injects multi-target skip links — main content, navigation, search
23
57
  - Ensures `<html lang>` and `<title>` are present
24
58
  - Fixes `<meta viewport>` if it blocks user zoom
25
- - Watches for new DOM elements via `MutationObserver` and fixes them as they appear
26
- - Applies user-controlled visual preferences (high contrast, reduce motion, font scale, dyslexia font, colour-blind simulation)
59
+ - Watches for new DOM elements via `MutationObserver`
60
+ - Applies user-controlled visual preferences — high contrast, dark mode, reduce motion, large targets, font scale, dyslexia font, colour blind simulation
61
+ - Speaks focused elements aloud via browser SpeechSynthesis — zero install
62
+ - Shows visual alert banners for deaf users — no audio dependency
63
+ - Enforces keyboard navigation — arrow keys, Escape, focus trap in modals
64
+ - Saves user preferences to localStorage across sessions
65
+ - Shows accessibility audit score 0–100 in development
27
66
 
28
- The floating button appears bottom-left. Click it, enable settings, click **Apply settings**.
67
+ The floating ♿ button appears bottom-right. Click it, choose preferences, click **Apply settings**.
29
68
 
30
69
  ---
31
70
 
@@ -53,9 +92,9 @@ export default function App() {
53
92
 
54
93
  ---
55
94
 
56
- ## Next.js (App Router)
95
+ ## Next.js — App Router
57
96
 
58
- **Step 1 — next.config.js** (required)
97
+ **Step 1 — next.config.js**
59
98
 
60
99
  ```js
61
100
  const nextConfig = {
@@ -64,25 +103,48 @@ const nextConfig = {
64
103
  module.exports = nextConfig;
65
104
  ```
66
105
 
67
- **Step 2 — app/layout.tsx**
106
+ **Step 2 — Create a client wrapper**
68
107
 
69
108
  ```tsx
109
+ // components/YuktaiClient.tsx
110
+ "use client";
111
+ import { useState, useEffect, type ReactNode } from "react";
70
112
  import { YuktAIWrapper } from "@yuktishaalaa/yuktai";
71
113
 
114
+ export default function YuktaiClient({ children }: { children: ReactNode }) {
115
+ const [mounted, setMounted] = useState(false);
116
+ useEffect(() => setMounted(true), []);
117
+
118
+ // Prevents React hydration mismatch error #418
119
+ if (!mounted) return <>{children}</>;
120
+
121
+ return (
122
+ <YuktAIWrapper position="left">
123
+ {children}
124
+ </YuktAIWrapper>
125
+ );
126
+ }
127
+ ```
128
+
129
+ **Step 3 — app/layout.tsx**
130
+
131
+ ```tsx
132
+ import YuktaiClient from "@/components/YuktaiClient";
133
+
72
134
  export default function RootLayout({ children }: { children: React.ReactNode }) {
73
135
  return (
74
136
  <html lang="en">
75
137
  <body>
76
- <YuktAIWrapper position="left">
138
+ <YuktaiClient>
77
139
  <main>{children}</main>
78
- </YuktAIWrapper>
140
+ </YuktaiClient>
79
141
  </body>
80
142
  </html>
81
143
  );
82
144
  }
83
145
  ```
84
146
 
85
- **Pages Router** — use `pages/_app.tsx` instead:
147
+ **Pages Router — pages/_app.tsx**
86
148
 
87
149
  ```tsx
88
150
  import { YuktAIWrapper } from "@yuktishaalaa/yuktai";
@@ -210,16 +272,16 @@ import "@yuktishaalaa/yuktai/vanilla";
210
272
  **Programmatic API**
211
273
 
212
274
  ```js
213
- window.yuktai.apply(); // apply settings
214
- window.yuktai.reset(); // reset everything
215
- window.yuktai.wcagPlugin.scan(); // scan without fixing
275
+ window.yuktai.apply();
276
+ window.yuktai.reset();
277
+ window.yuktai.wcagPlugin.scan();
216
278
  ```
217
279
 
218
280
  ---
219
281
 
220
282
  ## Web Component
221
283
 
222
- Works in every framework and plain HTML — uses native Custom Elements with Shadow DOM.
284
+ Works in every framework and plain HTML — uses native Custom Elements.
223
285
 
224
286
  **Plain HTML**
225
287
 
@@ -272,36 +334,82 @@ import "@yuktishaalaa/yuktai/web-component";
272
334
  ## Direct engine API
273
335
 
274
336
  ```ts
275
- import { wcagPlugin } from "@yuktishaalaa/yuktai/core";
337
+ import { wcagPlugin } from "@yuktishaalaa/yuktai";
276
338
 
277
339
  // Apply all WCAG rules
278
- const report = wcagPlugin.applyFixes({ enabled: true });
279
- console.log(report.fixed); // fixes applied
280
- console.log(report.scanned); // nodes scanned
281
- console.log(report.renderTime); // ms
340
+ const report = wcagPlugin.applyFixes({
341
+ enabled: true,
342
+ highContrast: false,
343
+ darkMode: false,
344
+ reduceMotion: false,
345
+ largeTargets: false,
346
+ speechEnabled: false,
347
+ colorBlindMode:"none",
348
+ autoFix: true,
349
+ });
350
+
351
+ console.log(report.fixed); // number of fixes applied
352
+ console.log(report.scanned); // number of nodes scanned
353
+ console.log(report.renderTime); // time in ms
354
+ console.log(report.score); // accessibility score 0–100
355
+ console.log(report.details); // array of A11yFix objects
282
356
 
283
357
  // Scan only — no DOM changes
284
358
  const violations = wcagPlugin.scan();
285
359
 
286
- // Auto-fix new elements
360
+ // Announce to screen readers + visual alert + speech
361
+ wcagPlugin.announce("Form submitted successfully", "success");
362
+ wcagPlugin.announce("Email is required", "error");
363
+
364
+ // Browser speech — zero install
365
+ wcagPlugin.speak("Welcome to the dashboard");
366
+
367
+ // Visual alert for deaf users
368
+ wcagPlugin.showVisualAlert("Settings saved", "success");
369
+
370
+ // Focus trap for modals
371
+ const modal = document.querySelector("#my-modal") as HTMLElement;
372
+ wcagPlugin.trapFocus(modal);
373
+
374
+ // Auto-fix new DOM elements
287
375
  wcagPlugin.startObserver({ enabled: true, autoFix: true });
288
376
  wcagPlugin.stopObserver();
377
+ ```
289
378
 
290
- // Cleanup
291
- wcagPlugin.removeLiveRegion();
292
- wcagPlugin.removeColorBlindSvg();
379
+ ---
380
+
381
+ ## A11yConfig options
382
+
383
+ ```ts
384
+ import { wcagPlugin, A11yConfig } from "@yuktishaalaa/yuktai";
385
+
386
+ const config: A11yConfig = {
387
+ enabled: true, // required
388
+ highContrast: false, // increase contrast
389
+ darkMode: false, // invert colours
390
+ reduceMotion: false, // disable animations
391
+ largeTargets: false, // 44×44px minimum touch targets
392
+ speechEnabled: false, // speak focused elements aloud
393
+ colorBlindMode: "none", // none | deuteranopia | protanopia | tritanopia | achromatopsia
394
+ autoFix: true, // MutationObserver watches for new elements
395
+ showPreferencePanel: true, // floating ♿ button + panel
396
+ showSkipLinks: true, // multi-target skip links
397
+ showAuditBadge: false, // score badge — dev only (localhost)
398
+ fontSizeMultiplier: 1, // font scale multiplier
399
+ timeoutWarning: 0, // seconds before session timeout warning (0 = off)
400
+ };
401
+
402
+ await wcagPlugin.execute(config);
293
403
  ```
294
404
 
295
405
  ---
296
406
 
297
407
  ## HTML elements covered
298
408
 
299
- The engine covers every HTML element:
300
-
301
409
  - **Headings** — `h1` through `h6`
302
- - **Text** — `p`, `span`, `abbr`, `mark`, `time`, `meter`, `progress`, and all inline elements
410
+ - **Text** — `p`, `span`, `abbr`, `mark`, `time`, `meter`, `progress`, all inline elements
303
411
  - **Images & media** — `img`, `area`, `svg`, `canvas`, `video`, `audio`, `iframe`, `object`, `embed`, `figure`
304
- - **Interactive** — `button`, `a`, clickable `div`/`span`
412
+ - **Interactive** — `button`, `a`, clickable `div` / `span`
305
413
  - **Forms** — `input` (all types), `select`, `textarea`, `fieldset`, `label`
306
414
  - **Tables** — `table`, `th`, `td`, `caption`
307
415
  - **Lists** — `ul`, `ol`, `dl`, `li`, `dt`, `dd`
@@ -311,28 +419,87 @@ The engine covers every HTML element:
311
419
 
312
420
  ---
313
421
 
422
+ ## WCAG coverage
423
+
424
+ | Standard | Criteria covered |
425
+ |---|---|
426
+ | WCAG 2.0 | 19 criteria |
427
+ | WCAG 2.1 | 7 criteria |
428
+ | WCAG 2.2 | 3 criteria (focus appearance, target size, timeout) |
429
+ | Beyond WCAG | SpeechSynthesis, visual alerts, keyboard cheatsheet, audit score, colour blind modes, dyslexia font |
430
+
431
+ ---
432
+
433
+ ## Accessibility features — no screen reader software needed
434
+
435
+ | Feature | Who it helps | How |
436
+ |---|---|---|
437
+ | SpeechSynthesis | Blind users without screen reader | Browser reads focused element aloud |
438
+ | Visual alerts | Deaf users | Sliding banner — no audio |
439
+ | Skip links | All keyboard users | Jump to main, nav, search |
440
+ | Focus trap | Keyboard users | Tab stays inside modals |
441
+ | Arrow key nav | Keyboard users | Navigate menus, tabs, listbox |
442
+ | Keyboard cheatsheet | All users | Press Alt+A |
443
+ | Colour blind modes | Colour blind users | Deuteranopia, protanopia, tritanopia, greyscale |
444
+ | High contrast | Low vision users | Filter-based contrast boost |
445
+ | Dark mode | Light sensitivity | Invert + hue rotate |
446
+ | Large targets | Motor impaired | 44×44px minimum |
447
+ | Timeout warning | Motor impaired | Warning before session expires |
448
+ | Dyslexia font | Dyslexia users | Atkinson Hyperlegible |
449
+ | Reduce motion | Vestibular disorder | Disables all animations |
450
+
451
+ ---
452
+
314
453
  ## The report
315
454
 
316
455
  After clicking **Apply settings**, the panel shows:
317
456
 
318
457
  ```
319
- ✓ 12 fixes applied · 534 nodes · 1.2ms
320
- ✓ 0 fixes needed · 534 nodes clean · 0.8ms
458
+ ✓ 12 fixes · 534 nodes · 1.2ms · Score: 88/100
459
+ ✓ 0 fixes needed · 534 nodes clean · 0.8ms · Score: 100/100
321
460
  ```
322
461
 
323
- `0 fixes needed` is a passing result — it means the page is already accessible. The render time confirms the engine ran.
462
+ `Score: 100/100` means the page is fully accessible. `0 fixes needed` is a passing result — the page was already accessible before yuktai ran.
324
463
 
325
464
  ---
326
465
 
327
466
  ## Design principles
328
467
 
329
- - **Zero id attributes** — no injected node ever gets an `id`. All injected nodes are tracked via module-level JavaScript references. The plugin never collides with the host app's ids.
330
- - **Zero API keys** — the engine runs entirely in the browser. No external calls, no telemetry, no cost.
331
- - **Zero framework lock-in** — `core/renderer.ts` has no framework imports. It works in Node.js, browsers, and test environments.
332
- - **One engine, many adapters** — all adapters import from `core/renderer.ts`. The WCAG logic is written once.
468
+ - **Zero id attributes** — no injected node ever gets an `id`. All injected nodes tracked via module-level JavaScript references. Never collides with host app ids.
469
+ - **Zero API keys** — runs entirely in the browser. No external calls, no telemetry, no cost.
470
+ - **Zero framework lock-in** — `core/renderer.ts` has no framework imports. Works in Node.js, browsers, and test environments.
471
+ - **Zero JAWS dependency** — uses standard browser APIs. Works with NVDA, VoiceOver, TalkBack, Narrator — all free.
472
+ - **One engine, many adapters** — all adapters import from `core/renderer.ts`. WCAG logic written once.
473
+
474
+ ---
475
+
476
+ ## Browser support
477
+
478
+ | Browser | Supported |
479
+ |---|---|
480
+ | Chrome 90+ | ✅ |
481
+ | Firefox 90+ | ✅ |
482
+ | Safari 15+ | ✅ |
483
+ | Edge 90+ | ✅ |
484
+ | Samsung Internet 14+ | ✅ |
485
+
486
+ ---
487
+
488
+ ## Framework compatibility
489
+
490
+ | Framework | Version | Supported |
491
+ |---|---|---|
492
+ | React | 17, 18, 19 | ✅ |
493
+ | Next.js | 13, 14, 15 | ✅ |
494
+ | Vue | 3+ | ✅ |
495
+ | Nuxt | 3+ | ✅ |
496
+ | Angular | 15+ | ✅ |
497
+ | Remix | Any | ✅ |
498
+ | Astro | Any | ✅ |
499
+ | Vanilla JS | ES2020+ | ✅ |
333
500
 
334
501
  ---
335
502
 
336
503
  ## License
337
504
 
338
- yuktai contributors
505
+ ISC © Sandeep Miriyala — [Yuktishaalaa AI Lab]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuktishaalaa/yuktai",
3
- "version": "2.0.13",
3
+ "version": "2.0.14",
4
4
  "description": "Privacy-first, offline-first universal accessibility engine with WCAG auto-fix, OCR, voice, and Indic language AI support.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",