@yuktishaalaa/yuktai 4.4.0 → 4.5.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 CHANGED
@@ -1,99 +1,92 @@
1
1
  # @yuktishaalaa/yuktai
2
2
 
3
- > Universal runtime accessibility plugin — automatically fixes WCAG 2.2 violations on every page, for every user, with zero configuration.
3
+ > Universal Next.js plugin for accessibility, AI, and data. One install brings WCAG 2.2 auto-fix, in-browser RAG, an AI agent, code generation, and an accessible data grid with voice + chat — zero API keys, zero cost, works offline.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@yuktishaalaa/yuktai)](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
6
6
  [![downloads](https://img.shields.io/npm/dm/@yuktishaalaa/yuktai)](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
7
7
  [![license](https://img.shields.io/badge/license-ISC-brightgreen)](./LICENSE)
8
8
  [![node](https://img.shields.io/badge/node-%3E%3D18-blue)](https://nodejs.org)
9
+ [![Next.js](https://img.shields.io/badge/Next.js-16%2B-black)](https://nextjs.org)
9
10
 
10
- ---
11
-
12
- ## What's new in v2.0.0
11
+ **7,000+ developers** already installed yuktai. Built entirely in free time by [Sandeep Miriyala](https://github.com/sandeepmiriyala03) with help from Claude, GPT, and Gemini.
13
12
 
14
- - ✅ Built-in SpeechSynthesis — browser speaks on focus, zero install
15
- - ✅ Visual alerts — sliding banner for deaf users, no audio needed
16
- - ✅ Keyboard navigation — arrow keys, Escape, focus trap, no AT needed
17
- - ✅ Skip links — multi-target (main, nav, search), always visible on mobile
18
- - ✅ Preference panel — blind / deaf / motor / colour blind presets
19
- - ✅ Persistent preferences — saved to localStorage across pages
20
- - ✅ WCAG 2.2 — focus appearance, target size 44×44px, timeout warning
21
- - ✅ Audit score — 0–100 with issue breakdown (localhost dev only)
22
- - ✅ Dyslexia font — Atkinson Hyperlegible (research-backed)
23
- - ✅ React 17, 18, 19 supported
24
- - ✅ TypeScript declarations — full `index.d.ts` generated
13
+ Live demo → [https://aksharatantra.miriyala.in/staffdirectory](https://aksharatantra.miriyala.in/staffdirectory)
25
14
 
26
15
  ---
27
16
 
28
- ## Install
17
+ ## The story
29
18
 
30
- ### React 17 or 18
31
- ```bash
32
- npm i @yuktishaalaa/yuktai
33
- ```
19
+ I have been building web apps since 2013. In all those years the same things kept breaking on almost every website I touched. Missing ARIA labels. No keyboard navigation. Forms that senior citizens couldn't figure out. Data grids that broke on mobile. Accessibility tools that cost money. AI tools that needed API keys.
34
20
 
35
- ### React 19 or MUI v5 conflict
36
- ```bash
37
- npm i @yuktishaalaa/yuktai --legacy-peer-deps
38
- ```
21
+ I wanted something without any of those barriers.
39
22
 
40
- ### MUI v5 + React 19 permanent fix
41
- ```bash
42
- npm i @mui/material@6 @mui/icons-material@6 --legacy-peer-deps
43
- ```
23
+ Free. Open source. One install. Works on every device. No account. No key. No server.
44
24
 
45
- ### Requirements
46
- - Node.js 18 or higher
47
- - npm 8 or higher
25
+ So I built yuktai — one weekend and one late-night at a time. This README is the map of everything that shipped.
48
26
 
49
27
  ---
50
28
 
51
- ## What it does
29
+ ## What's inside
52
30
 
53
- 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:
31
+ Five modules ship in the single npm package:
54
32
 
55
- - Injects multi-target skip links — main content, navigation, search
56
- - Ensures `<html lang>` and `<title>` are present
57
- - Fixes `<meta viewport>` if it blocks user zoom
58
- - Watches for new DOM elements via `MutationObserver`
59
- - Applies user-controlled visual preferences — high contrast, dark mode, reduce motion, large targets, font scale, dyslexia font, colour blind simulation
60
- - Speaks focused elements aloud via browser SpeechSynthesis — zero install
61
- - Shows visual alert banners for deaf users — no audio dependency
62
- - Enforces keyboard navigation — arrow keys, Escape, focus trap in modals
63
- - Saves user preferences to localStorage across sessions
64
- - Shows accessibility audit score 0–100 in development
33
+ | Module | Features | What it does |
34
+ |---|---|---|
35
+ | **1. Accessibility Engine** | 16 | WCAG 2.2 auto-fix, speak on focus, colour-blind modes, dyslexia font, skip links |
36
+ | **2. YuktaiGrid** ⭐ NEW | 12 | Accessible data grid with 5 WCAG themes, search, sort, pagination, mobile card view |
37
+ | **3. In-Tab RAG** | 11 | Ask questions about any page — offline, no API |
38
+ | **4. Autonomous AI Agent** | 13 | Natural-language browser automation |
39
+ | **5. Vibe Coder** | 19 | Generate full Next.js projects from plain English |
65
40
 
66
- The floating ♿ button appears bottom-right. Click it, choose preferences, click **Apply settings**.
41
+ Plus 7 custom SVG icons, a voice + chat assistant, and a growing icon library.
67
42
 
68
43
  ---
69
44
 
70
- ## React
45
+ ## What's new
71
46
 
72
- ```tsx
73
- // src/App.tsx
74
- import { YuktAIWrapper } from "@yuktishaalaa/yuktai";
47
+ ### v4.1.2 — grid polish
48
+ - Search icon inside search input
49
+ - Empty-search-results state with "Clear search" action
50
+ - Attractive pagination with page numbers and ellipsis
51
+ - Better touch targets (36×36 min)
52
+ - ARIA `aria-current="page"` on active page
75
53
 
76
- export default function App() {
77
- return (
78
- <YuktAIWrapper position="left">
79
- <YourAppContent />
80
- </YuktAIWrapper>
81
- );
82
- }
54
+ ### v4.1.0 — 7 custom SVG icons
55
+ Zero external icon dependency. All icons: 24×24 viewBox, 2.5 stroke, `currentColor`, accessible.
56
+ - `SearchIcon`, `SortUpIcon`, `SortDownIcon`
57
+ - `ChevronLeftIcon`, `ChevronRightIcon`
58
+ - `CheckIcon`, `CloseIcon`
59
+
60
+ ### v4.0.0 — YuktaiGrid ships
61
+ Fully accessible data grid. 5 built-in themes. Mobile card view. Search + sort + pagination.
62
+
63
+ ### v3.0.0 — Voice + chat AI assistant
64
+ Floating chat panel. Voice input via Web Speech API. TTS for AI replies. Zero LLM download.
65
+
66
+ ### v2.0.0 — Accessibility engine
67
+ Auto-injects ARIA labels, `alt`, `role`, `tabindex`. MutationObserver watches for new elements.
68
+
69
+ ---
70
+
71
+ ## Install
72
+
73
+ ### Next.js 16 + React 19 (recommended)
74
+ ```bash
75
+ npm install @yuktishaalaa/yuktai --legacy-peer-deps
83
76
  ```
84
77
 
85
- **Props**
78
+ ### Older Next.js (13, 14, 15)
79
+ ```bash
80
+ npm install @yuktishaalaa/yuktai
81
+ ```
86
82
 
87
- | Prop | Type | Default | Description |
88
- |---|---|---|---|
89
- | `position` | `"left" \| "right"` | `"left"` | Side the FAB appears on |
90
- | `children` | `ReactNode` | required | Your app content |
83
+ Requirements: Node.js 18+, npm 8+, Next.js 13+.
91
84
 
92
85
  ---
93
86
 
94
- ## Next.js — App Router
87
+ ## Quick start
95
88
 
96
- **Step 1 — next.config.js**
89
+ ### Step 1 — `next.config.js`
97
90
 
98
91
  ```js
99
92
  const nextConfig = {
@@ -102,7 +95,7 @@ const nextConfig = {
102
95
  module.exports = nextConfig;
103
96
  ```
104
97
 
105
- **Step 2 — Create a client wrapper**
98
+ ### Step 2 — Client wrapper
106
99
 
107
100
  ```tsx
108
101
  // components/YuktaiClient.tsx
@@ -113,8 +106,6 @@ import { YuktAIWrapper } from "@yuktishaalaa/yuktai";
113
106
  export default function YuktaiClient({ children }: { children: ReactNode }) {
114
107
  const [mounted, setMounted] = useState(false);
115
108
  useEffect(() => setMounted(true), []);
116
-
117
- // Prevents React hydration mismatch error #418
118
109
  if (!mounted) return <>{children}</>;
119
110
 
120
111
  return (
@@ -125,7 +116,7 @@ export default function YuktaiClient({ children }: { children: ReactNode }) {
125
116
  }
126
117
  ```
127
118
 
128
- **Step 3 — app/layout.tsx**
119
+ ### Step 3 — `app/layout.tsx`
129
120
 
130
121
  ```tsx
131
122
  import YuktaiClient from "@/components/YuktaiClient";
@@ -143,259 +134,311 @@ export default function RootLayout({ children }: { children: React.ReactNode })
143
134
  }
144
135
  ```
145
136
 
146
- **Pages Router — pages/_app.tsx**
147
-
148
- ```tsx
149
- import { YuktAIWrapper } from "@yuktishaalaa/yuktai";
150
- import type { AppProps } from "next/app";
151
-
152
- export default function MyApp({ Component, pageProps }: AppProps) {
153
- return (
154
- <YuktAIWrapper position="left">
155
- <Component {...pageProps} />
156
- </YuktAIWrapper>
157
- );
158
- }
159
- ```
137
+ That's it. Three AI-powered buttons appear on every page. Click the ♿ button bottom-right to open the accessibility panel.
160
138
 
161
139
  ---
162
140
 
163
- ## Vue 3 / Nuxt 3
141
+ ## Module 1 — Accessibility Engine
164
142
 
165
- ```vue
166
- <!-- App.vue -->
167
- <script setup lang="ts">
168
- import YuktAIWrapper from "@yuktishaalaa/yuktai/vue";
169
- </script>
143
+ Scans every element and injects missing accessibility attributes automatically.
170
144
 
171
- <template>
172
- <YuktAIWrapper position="left">
173
- <RouterView />
174
- </YuktAIWrapper>
175
- </template>
176
- ```
177
-
178
- **Nuxt 3 — app.vue**
145
+ Covers: headings, images, forms, tables, lists, landmarks, ARIA widgets. Watches for new DOM elements via `MutationObserver`.
179
146
 
180
- ```vue
181
- <script setup lang="ts">
182
- import YuktAIWrapper from "@yuktishaalaa/yuktai/vue";
183
- </script>
147
+ ### Features (16)
184
148
 
185
- <template>
186
- <YuktAIWrapper position="left">
187
- <NuxtLayout>
188
- <NuxtPage />
189
- </NuxtLayout>
190
- </YuktAIWrapper>
191
- </template>
192
- ```
149
+ - WCAG 2.2 auto-fix — ARIA, roles, tabindex, scope, autocomplete
150
+ - Speak on focus — browser speech synthesis
151
+ - Voice control — say commands to navigate
152
+ - High contrast · Dark mode · Reduce motion · Large targets (44×44)
153
+ - Colour-blind modes — Deuteranopia, Protanopia, Tritanopia, Greyscale
154
+ - Dyslexia font — Atkinson Hyperlegible (research-backed)
155
+ - Local font picker, font scaling 80–130%
156
+ - Audit badge — WCAG score 0–100 (localhost only)
157
+ - Skip links, focus trap, preference persistence, reset
193
158
 
194
- **Nuxt 3 — client plugin** (`plugins/yuktai.client.ts`)
159
+ ### Direct API
195
160
 
196
161
  ```ts
197
- import YuktAIWrapper from "@yuktishaalaa/yuktai/vue";
162
+ import { wcagPlugin } from "@yuktishaalaa/yuktai";
198
163
 
199
- export default defineNuxtPlugin((nuxtApp) => {
200
- nuxtApp.vueApp.component("YuktAIWrapper", YuktAIWrapper);
164
+ // Apply fixes
165
+ const report = wcagPlugin.applyFixes({
166
+ enabled: true,
167
+ highContrast: false,
168
+ darkMode: false,
169
+ reduceMotion: false,
170
+ largeTargets: false,
171
+ speechEnabled: false,
172
+ colorBlindMode:"none",
173
+ autoFix: true,
201
174
  });
175
+
176
+ console.log(report.fixed); // number of fixes applied
177
+ console.log(report.score); // 0–100
202
178
  ```
203
179
 
204
180
  ---
205
181
 
206
- ## Angular
182
+ ## Module 2 — YuktaiGrid ⭐
207
183
 
208
- **app.module.ts**
184
+ An accessible data grid built for Next.js. Handles small tables and large datasets. Works with any API. Ships with the 5 accessibility themes.
209
185
 
210
- ```ts
211
- import { YuktAIModule } from "@yuktishaalaa/yuktai/angular";
186
+ ### Usage
212
187
 
213
- @NgModule({
214
- imports: [BrowserModule, YuktAIModule],
215
- bootstrap: [AppComponent],
216
- })
217
- export class AppModule {}
218
- ```
188
+ ```tsx
189
+ "use client";
190
+ import { YuktaiGrid } from "@yuktishaalaa/yuktai";
219
191
 
220
- **app.component.html**
192
+ const data = [
193
+ { id: 1, name: "Sandeep", role: "Developer", salary: 85000 },
194
+ { id: 2, name: "Priya", role: "Designer", salary: 90000 },
195
+ ];
221
196
 
222
- ```html
223
- <yuktai-a11y position="left">
224
- <router-outlet></router-outlet>
225
- </yuktai-a11y>
197
+ export default function EmployeesPage() {
198
+ return (
199
+ <YuktaiGrid
200
+ data={data}
201
+ columns={[
202
+ { key: "name", label: "Name", sortable: true },
203
+ { key: "role", label: "Role" },
204
+ { key: "salary", label: "Salary", type: "number", align: "right" },
205
+ ]}
206
+ theme="default" // default | high-contrast | dark | color-blind | dyslexia
207
+ search={true} // real-time filtering
208
+ view="auto" // auto (card on mobile) | table | card
209
+ pagination={{ pageSize: 10 }} // built-in client pagination
210
+ />
211
+ );
212
+ }
226
213
  ```
227
214
 
228
- **Angular 17+ standalone**
215
+ ### Grid features (12)
229
216
 
230
- ```ts
231
- import { YuktAIComponent } from "@yuktishaalaa/yuktai/angular";
232
-
233
- @Component({
234
- standalone: true,
235
- imports: [RouterOutlet, YuktAIComponent],
236
- template: `
237
- <yuktai-a11y position="left">
238
- <router-outlet />
239
- </yuktai-a11y>
240
- `,
241
- })
242
- export class AppComponent {}
243
- ```
217
+ - Search bar with icon and "Clear" action
218
+ - Sort — click column header (asc → desc → cleared)
219
+ - Pagination with page numbers and ellipsis
220
+ - Mobile card view (below 768px, no config needed)
221
+ - Loading, empty, and empty-search states
222
+ - 5 WCAG themes with 3-line switcher
223
+ - Row selection, custom render, `rowKey`
224
+ - Keyboard navigation
225
+ - ARIA `role="grid"`, `aria-sort`, `aria-current`
226
+ - 44×44 touch targets
244
227
 
245
- ---
228
+ ### Handling large datasets (100K, 200K, 300K rows)
246
229
 
247
- ## Vanilla JavaScript
230
+ **Client-side pagination handles a few thousand rows well.** For anything larger, use **server-side pagination** — fetch only the page you need.
248
231
 
249
- **CDN — no install needed**
232
+ Here's the pattern with a Next.js API proxy that also solves CORS.
250
233
 
251
- ```html
252
- <!-- Add before </body> -->
253
- <script src="https://cdn.jsdelivr.net/npm/@yuktishaalaa/yuktai/vanilla/index.js"></script>
254
- ```
234
+ **`src/app/api/employees/route.ts`** — the proxy:
255
235
 
256
- **npm import**
236
+ ```ts
237
+ import { NextRequest, NextResponse } from "next/server";
257
238
 
258
- ```js
259
- import "@yuktishaalaa/yuktai/vanilla";
260
- ```
239
+ let cachedData: any[] | null = null;
240
+ let cacheTime = 0;
241
+ const TTL_MS = 60_000;
261
242
 
262
- **Configure position**
243
+ async function fetchAll(): Promise<any[]> {
244
+ const now = Date.now();
245
+ if (cachedData && now - cacheTime < TTL_MS) return cachedData;
263
246
 
264
- ```html
265
- <script>
266
- window.YUKTAI_CONFIG = { position: "right" };
267
- </script>
268
- <script src="cdn.../vanilla/index.js"></script>
247
+ const res = await fetch("https://your-api.com/employees", { cache: "no-store" });
248
+ const json = await res.json();
249
+ cachedData = Array.isArray(json) ? json : (json.employees ?? json.data ?? []);
250
+ cacheTime = now;
251
+ return cachedData;
252
+ }
253
+
254
+ export async function GET(req: NextRequest) {
255
+ const p = req.nextUrl.searchParams;
256
+ const page = Math.max(1, parseInt(p.get("page") || "1"));
257
+ const pageSize = Math.max(1, parseInt(p.get("pageSize") || "5000"));
258
+ const search = (p.get("search") || "").toLowerCase().trim();
259
+
260
+ const all = await fetchAll();
261
+ const filtered = search
262
+ ? all.filter(r => Object.values(r).some(v => String(v).toLowerCase().includes(search)))
263
+ : all;
264
+
265
+ const total = filtered.length;
266
+ const rows = filtered.slice((page - 1) * pageSize, page * pageSize);
267
+
268
+ return NextResponse.json({
269
+ rows,
270
+ pagination: { page, pageSize, totalRows: total, totalPages: Math.ceil(total / pageSize) },
271
+ });
272
+ }
269
273
  ```
270
274
 
271
- **Programmatic API**
275
+ **Page — call the paginated API and disable the grid's built-in pagination:**
272
276
 
273
- ```js
274
- window.yuktai.apply();
275
- window.yuktai.reset();
276
- window.yuktai.wcagPlugin.scan();
277
+ ```tsx
278
+ const [apiResp, setApiResp] = useState<any>(null);
279
+ const [currentPage, setPage] = useState(1);
280
+
281
+ useEffect(() => {
282
+ fetch(`/api/employees?page=${currentPage}&pageSize=5000`)
283
+ .then(r => r.json())
284
+ .then(setApiResp);
285
+ }, [currentPage]);
286
+
287
+ <YuktaiGrid
288
+ data={apiResp?.rows ?? []}
289
+ columns={columns}
290
+ search={false} // disable — we handle search server-side
291
+ pagination={false} // disable — we handle pagination server-side
292
+ loading={!apiResp}
293
+ />
277
294
  ```
278
295
 
296
+ Then render your own pagination bar backed by `apiResp.pagination`. This pattern works for 100K, 200K, 300K rows — the browser only ever holds 5,000 rows in memory.
297
+
279
298
  ---
280
299
 
281
- ## Web Component
300
+ ## Module 3 — In-Tab RAG (Ask This Page)
282
301
 
283
- Works in every framework and plain HTML — uses native Custom Elements.
302
+ Retrieval-Augmented Generation running entirely in the browser. Extracts semantic chunks from the current DOM, embeds them, finds the best match for the user's question, and answers — offline, no API key.
284
303
 
285
- **Plain HTML**
304
+ ### Features (11)
286
305
 
287
- ```html
288
- <script type="module"
289
- src="https://cdn.jsdelivr.net/npm/@yuktishaalaa/yuktai/web-component/index.js">
290
- </script>
306
+ - Ask any question about any page
307
+ - Gemini Nano on desktop Chrome — zero download, zero API
308
+ - Transformers.js on mobile — 30 MB one-time model load
309
+ - Auto engine detection and switching
310
+ - Works offline after first load
311
+ - q4 quantization on mobile (32-bit → 4-bit weights)
312
+ - `flan-t5-small` for full-sentence answers
313
+ - Cosine similarity semantic search
314
+ - Deduped DOM text extraction
291
315
 
292
- <yuktai-a11y position="left">
293
- <!-- your content -->
294
- </yuktai-a11y>
295
- ```
316
+ ### What I learned
296
317
 
297
- **Inside React**
318
+ The hardest part was mobile. Transformers.js kept crashing on iOS Safari with out-of-memory errors. Learning about quantization — same model, 75% smaller — fixed it. DistilBERT gives short useless spans; flan-t5-small gives real sentences. None of that was in any tutorial. Found on a Saturday by breaking things until something worked.
298
319
 
299
- ```tsx
300
- import "@yuktishaalaa/yuktai/web-component";
320
+ ---
301
321
 
302
- // @ts-ignore
303
- <yuktai-a11y position="left">
304
- <App />
305
- </yuktai-a11y>
306
- ```
322
+ ## Module 4 — Autonomous AI Agent
307
323
 
308
- **Inside Vue** — add to `vite.config.ts` first:
324
+ User types a goal in plain English. Yuktai reads the DOM, finds the right elements, plans steps, and highlights what to do.
309
325
 
310
- ```ts
311
- plugins: [vue({
312
- template: {
313
- compilerOptions: {
314
- isCustomElement: (tag) => tag === "yuktai-a11y",
315
- }
316
- }
317
- })]
318
- ```
326
+ ### Features (13)
319
327
 
320
- ```vue
321
- <script setup>
322
- import "@yuktishaalaa/yuktai/web-component";
323
- </script>
324
- <template>
325
- <yuktai-a11y position="left">
326
- <RouterView />
327
- </yuktai-a11y>
328
- </template>
329
- ```
328
+ - Plain-English goal input
329
+ - Reads full page DOM — 9 traversal strategies
330
+ - Scans all form fields — 11 label strategies
331
+ - Works on static HTML, React, WordPress, and old government portals
332
+ - Gemini Nano planning on desktop, Transformers.js on mobile
333
+ - Rule-based fallback if AI fails
334
+ - Highlights target field with teal outline
335
+ - Scrolls to relevant section by keyword
336
+ - Numbered step-by-step plan
337
+ - Handles iframes
338
+
339
+ The 11 label strategies came from real websites — old government portals put labels in the previous table cell, modern apps use `aria-label`, static pages use `placeholder`. Every strategy solved a problem I had actually hit.
330
340
 
331
341
  ---
332
342
 
333
- ## Direct engine API
343
+ ## Module 5 — Vibe Coder
334
344
 
335
- ```ts
336
- import { wcagPlugin } from "@yuktishaalaa/yuktai";
345
+ Type a business requirement. Yuktai generates a full Next.js 16 project as a downloadable ZIP.
337
346
 
338
- // Apply all WCAG rules
339
- const report = wcagPlugin.applyFixes({
340
- enabled: true,
341
- highContrast: false,
342
- darkMode: false,
343
- reduceMotion: false,
344
- largeTargets: false,
345
- speechEnabled: false,
346
- colorBlindMode:"none",
347
- autoFix: true,
348
- });
347
+ ### Features (19)
348
+
349
+ - Detects website type (12 types), pages needed (21 types), features (14 types)
350
+ - Detects theme colour (8), extracts site name
351
+ - Preview before generating
352
+ - Full Next.js 16 project — Tailwind + CSS Modules, TypeScript, mobile responsive
353
+ - Navbar, Footer, Home, About, Contact, Services, Pricing, Auth, Dashboard pages
354
+ - Downloads as ZIP · `npm run dev` works immediately
355
+ - Pure templates — no AI writes the code
349
356
 
350
- console.log(report.fixed); // number of fixes applied
351
- console.log(report.scanned); // number of nodes scanned
352
- console.log(report.renderTime); // time in ms
353
- console.log(report.score); // accessibility score 0–100
354
- console.log(report.details); // array of A11yFix objects
357
+ No AI writes a single line. Pure template engineering. Same reusable-utility thinking from 2013 jQuery — now generating entire Next.js projects.
355
358
 
356
- // Scan only — no DOM changes
357
- const violations = wcagPlugin.scan();
359
+ ---
360
+
361
+ ## Voice + Chat Assistant
358
362
 
359
- // Announce to screen readers + visual alert + speech
360
- wcagPlugin.announce("Form submitted successfully", "success");
361
- wcagPlugin.announce("Email is required", "error");
363
+ A floating 🤖 button bottom-right opens a chat panel. Voice in via Web Speech API. TTS out via SpeechSynthesis. Intent parsing runs locally — no LLM, no API.
362
364
 
363
- // Browser speech — zero install
364
- wcagPlugin.speak("Welcome to the dashboard");
365
+ Understands:
366
+ - "highest salary" → analyzes visible grid rows
367
+ - "how many employees" → counts
368
+ - "average age" → calculates
369
+ - "who is Sandeep" → looks up
370
+ - "search for developer" → filters grid
371
+ - "sort by salary descending" → sorts
365
372
 
366
- // Visual alert for deaf users
367
- wcagPlugin.showVisualAlert("Settings saved", "success");
373
+ Chrome + Edge give the best voice recognition. Firefox needs a flag. iOS Safari is limited.
374
+
375
+ ---
368
376
 
369
- // Focus trap for modals
370
- const modal = document.querySelector("#my-modal") as HTMLElement;
371
- wcagPlugin.trapFocus(modal);
377
+ ## Icon library
372
378
 
373
- // Auto-fix new DOM elements
374
- wcagPlugin.startObserver({ enabled: true, autoFix: true });
375
- wcagPlugin.stopObserver();
379
+ 7 custom SVG icons. Zero external dependency.
380
+
381
+ ```tsx
382
+ import {
383
+ SearchIcon,
384
+ SortUpIcon,
385
+ SortDownIcon,
386
+ ChevronLeftIcon,
387
+ ChevronRightIcon,
388
+ CheckIcon,
389
+ CloseIcon,
390
+ } from "@yuktishaalaa/yuktai";
391
+
392
+ <SearchIcon size={20} />
393
+ <SortUpIcon size={20} color="#0D9488" />
394
+ <CheckIcon size={20} color="#10b981" label="Task complete" />
395
+ <CloseIcon size={20} color="#dc2626" />
396
+ <ChevronLeftIcon size={24} label="Previous" />
397
+ <ChevronRightIcon size={24} label="Next" />
376
398
  ```
377
399
 
400
+ Props: `size` (default 20), `color` (default `currentColor`), `strokeWidth` (default 2.5), `label` (adds ARIA — decorative if omitted).
401
+
378
402
  ---
379
403
 
380
- ## A11yConfig options
404
+ ## Gemini Nano (Chrome 147+)
405
+
406
+ - Plain-English mode — rewrites complex text
407
+ - Summarise page — 3-sentence summary
408
+ - Smart ARIA labels — AI generates labels
409
+ - Translate page — 18 languages
410
+ - Chrome 147+ standalone globals (`window.LanguageModel`)
411
+ - Fallback to old `window.ai` namespace
412
+
413
+ Chrome 147 silently removed `window.ai` and moved everything to standalone globals. Debugged for an evening before finding it in the release notes.
414
+
415
+ ---
416
+
417
+ ## Technical (17 features)
418
+
419
+ Zero API keys · Zero cost · Zero telemetry · Works on all browsers · Works on mobile (Android + iOS) · Works offline after first load · PWA compatible · Next.js 16 compatible · React 19 compatible · TypeScript throughout · SSR safe (no window errors) · Escape closes all panels · Each panel closes others · `data-yuktai-panel` — never reads own UI · Three stacked FAB buttons · Mobile full-screen panels · Tablet responsive · `showRag`, `showAgent`, `position` props.
420
+
421
+ ---
422
+
423
+ ## Configuration
381
424
 
382
425
  ```ts
383
426
  import { wcagPlugin, A11yConfig } from "@yuktishaalaa/yuktai";
384
427
 
385
428
  const config: A11yConfig = {
386
429
  enabled: true, // required
387
- highContrast: false, // increase contrast
388
- darkMode: false, // invert colours
389
- reduceMotion: false, // disable animations
390
- largeTargets: false, // 44×44px minimum touch targets
391
- speechEnabled: false, // speak focused elements aloud
430
+ highContrast: false,
431
+ darkMode: false,
432
+ reduceMotion: false,
433
+ largeTargets: false,
434
+ speechEnabled: false,
392
435
  colorBlindMode: "none", // none | deuteranopia | protanopia | tritanopia | achromatopsia
393
- autoFix: true, // MutationObserver watches for new elements
394
- showPreferencePanel: true, // floating ♿ button + panel
395
- showSkipLinks: true, // multi-target skip links
396
- showAuditBadge: false, // score badge — dev only (localhost)
397
- fontSizeMultiplier: 1, // font scale multiplier
398
- timeoutWarning: 0, // seconds before session timeout warning (0 = off)
436
+ autoFix: true,
437
+ showPreferencePanel: true,
438
+ showSkipLinks: true,
439
+ showAuditBadge: false, // dev only (localhost)
440
+ fontSizeMultiplier: 1,
441
+ timeoutWarning: 0, // seconds (0 = off)
399
442
  };
400
443
 
401
444
  await wcagPlugin.execute(config);
@@ -403,21 +446,6 @@ await wcagPlugin.execute(config);
403
446
 
404
447
  ---
405
448
 
406
- ## HTML elements covered
407
-
408
- - **Headings** — `h1` through `h6`
409
- - **Text** — `p`, `span`, `abbr`, `mark`, `time`, `meter`, `progress`, all inline elements
410
- - **Images & media** — `img`, `area`, `svg`, `canvas`, `video`, `audio`, `iframe`, `object`, `embed`, `figure`
411
- - **Interactive** — `button`, `a`, clickable `div` / `span`
412
- - **Forms** — `input` (all types), `select`, `textarea`, `fieldset`, `label`
413
- - **Tables** — `table`, `th`, `td`, `caption`
414
- - **Lists** — `ul`, `ol`, `dl`, `li`, `dt`, `dd`
415
- - **Landmarks** — `nav`, `header`, `footer`, `main`, `aside`, `section`, `article`, `details`, `summary`, `dialog`
416
- - **Document** — `html`, `head`, `meta viewport`, `body`
417
- - **ARIA widgets** — `role=tab`, `alert`, `tooltip`, `menu`, `listbox`, `slider`, `checkbox`, `combobox`, `grid`, `tree`, `spinbutton`
418
-
419
- ---
420
-
421
449
  ## WCAG coverage
422
450
 
423
451
  | Standard | Criteria covered |
@@ -425,79 +453,62 @@ await wcagPlugin.execute(config);
425
453
  | WCAG 2.0 | 19 criteria |
426
454
  | WCAG 2.1 | 7 criteria |
427
455
  | WCAG 2.2 | 3 criteria (focus appearance, target size, timeout) |
428
- | Beyond WCAG | SpeechSynthesis, visual alerts, keyboard cheatsheet, audit score, colour blind modes, dyslexia font |
456
+ | Beyond WCAG | SpeechSynthesis, visual alerts, keyboard cheatsheet, audit score, colour-blind modes, dyslexia font |
429
457
 
430
458
  ---
431
459
 
432
- ## Accessibility features — no screen reader software needed
460
+ ## Design principles
433
461
 
434
- | Feature | Who it helps | How |
435
- |---|---|---|
436
- | SpeechSynthesis | Blind users without screen reader | Browser reads focused element aloud |
437
- | Visual alerts | Deaf users | Sliding banner — no audio |
438
- | Skip links | All keyboard users | Jump to main, nav, search |
439
- | Focus trap | Keyboard users | Tab stays inside modals |
440
- | Arrow key nav | Keyboard users | Navigate menus, tabs, listbox |
441
- | Keyboard cheatsheet | All users | Press Alt+A |
442
- | Colour blind modes | Colour blind users | Deuteranopia, protanopia, tritanopia, greyscale |
443
- | High contrast | Low vision users | Filter-based contrast boost |
444
- | Dark mode | Light sensitivity | Invert + hue rotate |
445
- | Large targets | Motor impaired | 44×44px minimum |
446
- | Timeout warning | Motor impaired | Warning before session expires |
447
- | Dyslexia font | Dyslexia users | Atkinson Hyperlegible |
448
- | Reduce motion | Vestibular disorder | Disables all animations |
462
+ - **Zero id attributes** — no injected node ever gets an `id`. Tracked via module-level JavaScript references. Never collides with host app ids.
463
+ - **Zero API keys** — runs entirely in the browser. No external calls, no telemetry, no cost.
464
+ - **Zero framework lock-in** — `core/renderer.ts` has no framework imports. Works in Node.js, browsers, and test environments.
465
+ - **Honest limits** — client-side grid pagination works for a few thousand rows. Beyond that, use server-side pagination (pattern shown above).
449
466
 
450
467
  ---
451
468
 
452
- ## The report
469
+ ## Compatibility
453
470
 
454
- After clicking **Apply settings**, the panel shows:
471
+ ### Next.js versions
472
+ | Version | Supported |
473
+ |---|---|
474
+ | Next.js 16 | ✅ |
475
+ | Next.js 15 | ✅ |
476
+ | Next.js 14 | ✅ |
477
+ | Next.js 13 | ✅ |
455
478
 
456
- ```
457
- ✓ 12 fixes · 534 nodes · 1.2ms · Score: 88/100
458
- ✓ 0 fixes needed · 534 nodes clean · 0.8ms · Score: 100/100
459
- ```
479
+ ### React versions
480
+ | Version | Supported | Install flag |
481
+ |---|---|---|
482
+ | React 19 | ✅ | `--legacy-peer-deps` |
483
+ | React 18 | ✅ | none |
484
+ | React 17 | ✅ | none |
460
485
 
461
- > **Note:** A score of 100/100 means yuktai found no issues it could automatically detect and fix. Automated scanning covers a significant portion of WCAG criteria but cannot substitute for manual testing and real user feedback. We recommend combining yuktai with periodic manual audits for comprehensive accessibility coverage.
486
+ ### Browsers
487
+ Chrome 90+ · Firefox 90+ · Safari 15+ · Edge 90+ · Samsung Internet 14+
462
488
 
463
489
  ---
464
490
 
465
- ## Design principles
491
+ ## Roadmap
466
492
 
467
- - **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.
468
- - **Zero API keys** — runs entirely in the browser. No external calls, no telemetry, no cost.
469
- - **Zero framework lock-in** — `core/renderer.ts` has no framework imports. Works in Node.js, browsers, and test environments.
470
- - **One engine, many adapters** — all adapters import from `core/renderer.ts`. WCAG logic written once.
493
+ Shipped: v4.1.2 (grid polish)
494
+ Next: v4.2.0 — Voice search inside `YuktaiGrid` (mic button + Web Speech API)
495
+ After that: v4.3.0 — AI Summary button, TTS row reader
496
+ Long term: v5.0.0 — WebLLM + WebMCP + multimodal
471
497
 
472
498
  ---
473
499
 
474
- ## Browser support
500
+ ## Links
475
501
 
476
- | Browser | Supported |
477
- |---|---|
478
- | Chrome 90+ | ✅ |
479
- | Firefox 90+ | ✅ |
480
- | Safari 15+ | ✅ |
481
- | Edge 90+ | ✅ |
482
- | Samsung Internet 14+ | ✅ |
502
+ - npm — [@yuktishaalaa/yuktai](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
503
+ - GitHub — [sandeepmiriyala03/yuktai](https://github.com/sandeepmiriyala03/yuktai)
504
+ - Live demo — [aksharatantra.vercel.app](https://aksharatantra.vercel.app)
483
505
 
484
506
  ---
485
507
 
486
- ## Framework compatibility
487
-
488
- | Framework | Version | Supported |
489
- |---|---|---|
490
- | React | 17, 18, 19 | ✅ |
491
- | Next.js | 13, 14, 15 | ✅ |
492
- | Vue | 3+ | ✅ |
493
- | Nuxt | 3+ | ✅ |
494
- | Angular | 15+ | ✅ |
495
- | Remix | Any | ✅ |
496
- | Astro | Any | ✅ |
497
- | Vanilla JS | ES2020+ | ✅ |
508
+ ## License
498
509
 
499
- ---
510
+ ISC © Sandeep Miriyala — [Yuktishaalaa AI Lab](https://github.com/sandeepmiriyala03)
500
511
 
501
- ## License
512
+ Built in free time. With help from Claude, GPT, and Gemini for learning — but every line written, every bug fixed, every decision made by me.
502
513
 
503
- ISC © Sandeep Miriyala — [Yuktishaalaa AI Lab]
514
+ Free forever. Open source.