@yuktishaalaa/yuktai 4.5.0 → 4.6.1
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 +272 -2
- package/dist/index.d.mts +6 -5
- package/dist/index.d.ts +6 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
# @yuktishaalaa/yuktai
|
|
2
5
|
|
|
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
|
|
6
|
+
> 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 Agentic AI + WebMCP — zero API keys, zero cost, works offline.
|
|
4
7
|
|
|
5
8
|
[](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
|
|
9
|
+
|
|
6
10
|
[](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
|
|
11
|
+
|
|
7
12
|
[](./LICENSE)
|
|
13
|
+
|
|
8
14
|
[](https://nodejs.org)
|
|
15
|
+
|
|
9
16
|
[](https://nextjs.org)
|
|
10
17
|
|
|
11
18
|
**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.
|
|
@@ -31,39 +38,89 @@ So I built yuktai — one weekend and one late-night at a time. This README is t
|
|
|
31
38
|
Five modules ship in the single npm package:
|
|
32
39
|
|
|
33
40
|
| Module | Features | What it does |
|
|
41
|
+
|
|
34
42
|
|---|---|---|
|
|
43
|
+
|
|
35
44
|
| **1. Accessibility Engine** | 16 | WCAG 2.2 auto-fix, speak on focus, colour-blind modes, dyslexia font, skip links |
|
|
45
|
+
|
|
36
46
|
| **2. YuktaiGrid** ⭐ NEW | 12 | Accessible data grid with 5 WCAG themes, search, sort, pagination, mobile card view |
|
|
47
|
+
|
|
37
48
|
| **3. In-Tab RAG** | 11 | Ask questions about any page — offline, no API |
|
|
49
|
+
|
|
38
50
|
| **4. Autonomous AI Agent** | 13 | Natural-language browser automation |
|
|
51
|
+
|
|
39
52
|
| **5. Vibe Coder** | 19 | Generate full Next.js projects from plain English |
|
|
40
53
|
|
|
41
|
-
Plus 7 custom SVG icons, a voice + chat assistant
|
|
54
|
+
Plus Grid Assistant capabilities, Grid Agent tools, WebMCP integration, 7 custom SVG icons, and a voice + chat assistant.
|
|
42
55
|
|
|
43
56
|
---
|
|
44
57
|
|
|
45
58
|
## What's new
|
|
46
59
|
|
|
60
|
+
v4.5.0 — Agentic AI + WebMCP for YuktaiGrid
|
|
61
|
+
YuktaiGrid now exposes grid operations as reusable tools for Agentic AI and WebMCP.
|
|
62
|
+
|
|
63
|
+
Shared Grid Tools layer for agent and WebMCP execution
|
|
64
|
+
|
|
65
|
+
Search grid rows
|
|
66
|
+
|
|
67
|
+
Count grid rows
|
|
68
|
+
|
|
69
|
+
Get grid columns
|
|
70
|
+
|
|
71
|
+
Get a row by ID
|
|
72
|
+
|
|
73
|
+
Highlight rows
|
|
74
|
+
|
|
75
|
+
Select a row
|
|
76
|
+
|
|
77
|
+
Open a row
|
|
78
|
+
|
|
79
|
+
WebMCP tool registration through document.modelContext
|
|
80
|
+
|
|
81
|
+
useYuktaiGridAgent for programmatic agent tool execution
|
|
82
|
+
|
|
83
|
+
Designed around the flow: User → Agent → WebMCP → YuktaiGrid → Data
|
|
84
|
+
|
|
85
|
+
v4.4.1
|
|
86
|
+
Previous published YuktAI release.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
**## What's new
|
|
91
|
+
|
|
47
92
|
### v4.1.2 — grid polish
|
|
93
|
+
|
|
48
94
|
- Search icon inside search input
|
|
95
|
+
|
|
49
96
|
- Empty-search-results state with "Clear search" action
|
|
97
|
+
|
|
50
98
|
- Attractive pagination with page numbers and ellipsis
|
|
99
|
+
|
|
51
100
|
- Better touch targets (36×36 min)
|
|
101
|
+
|
|
52
102
|
- ARIA `aria-current="page"` on active page
|
|
53
103
|
|
|
54
104
|
### v4.1.0 — 7 custom SVG icons
|
|
105
|
+
|
|
55
106
|
Zero external icon dependency. All icons: 24×24 viewBox, 2.5 stroke, `currentColor`, accessible.
|
|
107
|
+
|
|
56
108
|
- `SearchIcon`, `SortUpIcon`, `SortDownIcon`
|
|
109
|
+
|
|
57
110
|
- `ChevronLeftIcon`, `ChevronRightIcon`
|
|
111
|
+
|
|
58
112
|
- `CheckIcon`, `CloseIcon`
|
|
59
113
|
|
|
60
114
|
### v4.0.0 — YuktaiGrid ships
|
|
115
|
+
|
|
61
116
|
Fully accessible data grid. 5 built-in themes. Mobile card view. Search + sort + pagination.
|
|
62
117
|
|
|
63
118
|
### v3.0.0 — Voice + chat AI assistant
|
|
119
|
+
|
|
64
120
|
Floating chat panel. Voice input via Web Speech API. TTS for AI replies. Zero LLM download.
|
|
65
121
|
|
|
66
122
|
### v2.0.0 — Accessibility engine
|
|
123
|
+
|
|
67
124
|
Auto-injects ARIA labels, `alt`, `role`, `tabindex`. MutationObserver watches for new elements.
|
|
68
125
|
|
|
69
126
|
---
|
|
@@ -71,13 +128,19 @@ Auto-injects ARIA labels, `alt`, `role`, `tabindex`. MutationObserver watches fo
|
|
|
71
128
|
## Install
|
|
72
129
|
|
|
73
130
|
### Next.js 16 + React 19 (recommended)
|
|
131
|
+
|
|
74
132
|
```bash
|
|
133
|
+
|
|
75
134
|
npm install @yuktishaalaa/yuktai --legacy-peer-deps
|
|
135
|
+
|
|
76
136
|
```
|
|
77
137
|
|
|
78
138
|
### Older Next.js (13, 14, 15)
|
|
139
|
+
|
|
79
140
|
```bash
|
|
141
|
+
|
|
80
142
|
npm install @yuktishaalaa/yuktai
|
|
143
|
+
|
|
81
144
|
```
|
|
82
145
|
|
|
83
146
|
Requirements: Node.js 18+, npm 8+, Next.js 13+.
|
|
@@ -89,49 +152,79 @@ Requirements: Node.js 18+, npm 8+, Next.js 13+.
|
|
|
89
152
|
### Step 1 — `next.config.js`
|
|
90
153
|
|
|
91
154
|
```js
|
|
155
|
+
|
|
92
156
|
const nextConfig = {
|
|
157
|
+
|
|
93
158
|
transpilePackages: ["@yuktishaalaa/yuktai"],
|
|
159
|
+
|
|
94
160
|
};
|
|
161
|
+
|
|
95
162
|
module.exports = nextConfig;
|
|
163
|
+
|
|
96
164
|
```
|
|
97
165
|
|
|
98
166
|
### Step 2 — Client wrapper
|
|
99
167
|
|
|
100
168
|
```tsx
|
|
169
|
+
|
|
101
170
|
// components/YuktaiClient.tsx
|
|
171
|
+
|
|
102
172
|
"use client";
|
|
173
|
+
|
|
103
174
|
import { useState, useEffect, type ReactNode } from "react";
|
|
175
|
+
|
|
104
176
|
import { YuktAIWrapper } from "@yuktishaalaa/yuktai";
|
|
105
177
|
|
|
106
178
|
export default function YuktaiClient({ children }: { children: ReactNode }) {
|
|
179
|
+
|
|
107
180
|
const [mounted, setMounted] = useState(false);
|
|
181
|
+
|
|
108
182
|
useEffect(() => setMounted(true), []);
|
|
183
|
+
|
|
109
184
|
if (!mounted) return <>{children}</>;
|
|
110
185
|
|
|
111
186
|
return (
|
|
187
|
+
|
|
112
188
|
<YuktAIWrapper position="left">
|
|
189
|
+
|
|
113
190
|
{children}
|
|
191
|
+
|
|
114
192
|
</YuktAIWrapper>
|
|
193
|
+
|
|
115
194
|
);
|
|
195
|
+
|
|
116
196
|
}
|
|
197
|
+
|
|
117
198
|
```
|
|
118
199
|
|
|
119
200
|
### Step 3 — `app/layout.tsx`
|
|
120
201
|
|
|
121
202
|
```tsx
|
|
203
|
+
|
|
122
204
|
import YuktaiClient from "@/components/YuktaiClient";
|
|
123
205
|
|
|
124
206
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
207
|
+
|
|
125
208
|
return (
|
|
209
|
+
|
|
126
210
|
<html lang="en">
|
|
211
|
+
|
|
127
212
|
<body>
|
|
213
|
+
|
|
128
214
|
<YuktaiClient>
|
|
215
|
+
|
|
129
216
|
<main>{children}</main>
|
|
217
|
+
|
|
130
218
|
</YuktaiClient>
|
|
219
|
+
|
|
131
220
|
</body>
|
|
221
|
+
|
|
132
222
|
</html>
|
|
223
|
+
|
|
133
224
|
);
|
|
225
|
+
|
|
134
226
|
}
|
|
227
|
+
|
|
135
228
|
```
|
|
136
229
|
|
|
137
230
|
That's it. Three AI-powered buttons appear on every page. Click the ♿ button bottom-right to open the accessibility panel.
|
|
@@ -147,34 +240,55 @@ Covers: headings, images, forms, tables, lists, landmarks, ARIA widgets. Watches
|
|
|
147
240
|
### Features (16)
|
|
148
241
|
|
|
149
242
|
- WCAG 2.2 auto-fix — ARIA, roles, tabindex, scope, autocomplete
|
|
243
|
+
|
|
150
244
|
- Speak on focus — browser speech synthesis
|
|
245
|
+
|
|
151
246
|
- Voice control — say commands to navigate
|
|
247
|
+
|
|
152
248
|
- High contrast · Dark mode · Reduce motion · Large targets (44×44)
|
|
249
|
+
|
|
153
250
|
- Colour-blind modes — Deuteranopia, Protanopia, Tritanopia, Greyscale
|
|
251
|
+
|
|
154
252
|
- Dyslexia font — Atkinson Hyperlegible (research-backed)
|
|
253
|
+
|
|
155
254
|
- Local font picker, font scaling 80–130%
|
|
255
|
+
|
|
156
256
|
- Audit badge — WCAG score 0–100 (localhost only)
|
|
257
|
+
|
|
157
258
|
- Skip links, focus trap, preference persistence, reset
|
|
158
259
|
|
|
159
260
|
### Direct API
|
|
160
261
|
|
|
161
262
|
```ts
|
|
263
|
+
|
|
162
264
|
import { wcagPlugin } from "@yuktishaalaa/yuktai";
|
|
163
265
|
|
|
164
266
|
// Apply fixes
|
|
267
|
+
|
|
165
268
|
const report = wcagPlugin.applyFixes({
|
|
269
|
+
|
|
166
270
|
enabled: true,
|
|
271
|
+
|
|
167
272
|
highContrast: false,
|
|
273
|
+
|
|
168
274
|
darkMode: false,
|
|
275
|
+
|
|
169
276
|
reduceMotion: false,
|
|
277
|
+
|
|
170
278
|
largeTargets: false,
|
|
279
|
+
|
|
171
280
|
speechEnabled: false,
|
|
281
|
+
|
|
172
282
|
colorBlindMode:"none",
|
|
283
|
+
|
|
173
284
|
autoFix: true,
|
|
285
|
+
|
|
174
286
|
});
|
|
175
287
|
|
|
176
288
|
console.log(report.fixed); // number of fixes applied
|
|
289
|
+
|
|
177
290
|
console.log(report.score); // 0–100
|
|
291
|
+
|
|
178
292
|
```
|
|
179
293
|
|
|
180
294
|
---
|
|
@@ -186,43 +300,73 @@ An accessible data grid built for Next.js. Handles small tables and large datase
|
|
|
186
300
|
### Usage
|
|
187
301
|
|
|
188
302
|
```tsx
|
|
303
|
+
|
|
189
304
|
"use client";
|
|
305
|
+
|
|
190
306
|
import { YuktaiGrid } from "@yuktishaalaa/yuktai";
|
|
191
307
|
|
|
192
308
|
const data = [
|
|
309
|
+
|
|
193
310
|
{ id: 1, name: "Sandeep", role: "Developer", salary: 85000 },
|
|
311
|
+
|
|
194
312
|
{ id: 2, name: "Priya", role: "Designer", salary: 90000 },
|
|
313
|
+
|
|
195
314
|
];
|
|
196
315
|
|
|
197
316
|
export default function EmployeesPage() {
|
|
317
|
+
|
|
198
318
|
return (
|
|
319
|
+
|
|
199
320
|
<YuktaiGrid
|
|
321
|
+
|
|
200
322
|
data={data}
|
|
323
|
+
|
|
201
324
|
columns={[
|
|
325
|
+
|
|
202
326
|
{ key: "name", label: "Name", sortable: true },
|
|
327
|
+
|
|
203
328
|
{ key: "role", label: "Role" },
|
|
329
|
+
|
|
204
330
|
{ key: "salary", label: "Salary", type: "number", align: "right" },
|
|
331
|
+
|
|
205
332
|
]}
|
|
333
|
+
|
|
206
334
|
theme="default" // default | high-contrast | dark | color-blind | dyslexia
|
|
335
|
+
|
|
207
336
|
search={true} // real-time filtering
|
|
337
|
+
|
|
208
338
|
view="auto" // auto (card on mobile) | table | card
|
|
339
|
+
|
|
209
340
|
pagination={{ pageSize: 10 }} // built-in client pagination
|
|
341
|
+
|
|
210
342
|
/>
|
|
343
|
+
|
|
211
344
|
);
|
|
345
|
+
|
|
212
346
|
}
|
|
347
|
+
|
|
213
348
|
```
|
|
214
349
|
|
|
215
350
|
### Grid features (12)
|
|
216
351
|
|
|
217
352
|
- Search bar with icon and "Clear" action
|
|
353
|
+
|
|
218
354
|
- Sort — click column header (asc → desc → cleared)
|
|
355
|
+
|
|
219
356
|
- Pagination with page numbers and ellipsis
|
|
357
|
+
|
|
220
358
|
- Mobile card view (below 768px, no config needed)
|
|
359
|
+
|
|
221
360
|
- Loading, empty, and empty-search states
|
|
361
|
+
|
|
222
362
|
- 5 WCAG themes with 3-line switcher
|
|
363
|
+
|
|
223
364
|
- Row selection, custom render, `rowKey`
|
|
365
|
+
|
|
224
366
|
- Keyboard navigation
|
|
367
|
+
|
|
225
368
|
- ARIA `role="grid"`, `aria-sort`, `aria-current`
|
|
369
|
+
|
|
226
370
|
- 44×44 touch targets
|
|
227
371
|
|
|
228
372
|
### Handling large datasets (100K, 200K, 300K rows)
|
|
@@ -234,63 +378,99 @@ Here's the pattern with a Next.js API proxy that also solves CORS.
|
|
|
234
378
|
**`src/app/api/employees/route.ts`** — the proxy:
|
|
235
379
|
|
|
236
380
|
```ts
|
|
381
|
+
|
|
237
382
|
import { NextRequest, NextResponse } from "next/server";
|
|
238
383
|
|
|
239
384
|
let cachedData: any[] | null = null;
|
|
385
|
+
|
|
240
386
|
let cacheTime = 0;
|
|
387
|
+
|
|
241
388
|
const TTL_MS = 60_000;
|
|
242
389
|
|
|
243
390
|
async function fetchAll(): Promise<any[]> {
|
|
391
|
+
|
|
244
392
|
const now = Date.now();
|
|
393
|
+
|
|
245
394
|
if (cachedData && now - cacheTime < TTL_MS) return cachedData;
|
|
246
395
|
|
|
247
396
|
const res = await fetch("https://your-api.com/employees", { cache: "no-store" });
|
|
397
|
+
|
|
248
398
|
const json = await res.json();
|
|
399
|
+
|
|
249
400
|
cachedData = Array.isArray(json) ? json : (json.employees ?? json.data ?? []);
|
|
401
|
+
|
|
250
402
|
cacheTime = now;
|
|
403
|
+
|
|
251
404
|
return cachedData;
|
|
405
|
+
|
|
252
406
|
}
|
|
253
407
|
|
|
254
408
|
export async function GET(req: NextRequest) {
|
|
409
|
+
|
|
255
410
|
const p = req.nextUrl.searchParams;
|
|
411
|
+
|
|
256
412
|
const page = Math.max(1, parseInt(p.get("page") || "1"));
|
|
413
|
+
|
|
257
414
|
const pageSize = Math.max(1, parseInt(p.get("pageSize") || "5000"));
|
|
415
|
+
|
|
258
416
|
const search = (p.get("search") || "").toLowerCase().trim();
|
|
259
417
|
|
|
260
418
|
const all = await fetchAll();
|
|
419
|
+
|
|
261
420
|
const filtered = search
|
|
421
|
+
|
|
262
422
|
? all.filter(r => Object.values(r).some(v => String(v).toLowerCase().includes(search)))
|
|
423
|
+
|
|
263
424
|
: all;
|
|
264
425
|
|
|
265
426
|
const total = filtered.length;
|
|
427
|
+
|
|
266
428
|
const rows = filtered.slice((page - 1) * pageSize, page * pageSize);
|
|
267
429
|
|
|
268
430
|
return NextResponse.json({
|
|
431
|
+
|
|
269
432
|
rows,
|
|
433
|
+
|
|
270
434
|
pagination: { page, pageSize, totalRows: total, totalPages: Math.ceil(total / pageSize) },
|
|
435
|
+
|
|
271
436
|
});
|
|
437
|
+
|
|
272
438
|
}
|
|
439
|
+
|
|
273
440
|
```
|
|
274
441
|
|
|
275
442
|
**Page — call the paginated API and disable the grid's built-in pagination:**
|
|
276
443
|
|
|
277
444
|
```tsx
|
|
445
|
+
|
|
278
446
|
const [apiResp, setApiResp] = useState<any>(null);
|
|
447
|
+
|
|
279
448
|
const [currentPage, setPage] = useState(1);
|
|
280
449
|
|
|
281
450
|
useEffect(() => {
|
|
451
|
+
|
|
282
452
|
fetch(`/api/employees?page=${currentPage}&pageSize=5000`)
|
|
453
|
+
|
|
283
454
|
.then(r => r.json())
|
|
455
|
+
|
|
284
456
|
.then(setApiResp);
|
|
457
|
+
|
|
285
458
|
}, [currentPage]);
|
|
286
459
|
|
|
287
460
|
<YuktaiGrid
|
|
461
|
+
|
|
288
462
|
data={apiResp?.rows ?? []}
|
|
463
|
+
|
|
289
464
|
columns={columns}
|
|
465
|
+
|
|
290
466
|
search={false} // disable — we handle search server-side
|
|
467
|
+
|
|
291
468
|
pagination={false} // disable — we handle pagination server-side
|
|
469
|
+
|
|
292
470
|
loading={!apiResp}
|
|
471
|
+
|
|
293
472
|
/>
|
|
473
|
+
|
|
294
474
|
```
|
|
295
475
|
|
|
296
476
|
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.
|
|
@@ -304,13 +484,21 @@ Retrieval-Augmented Generation running entirely in the browser. Extracts semanti
|
|
|
304
484
|
### Features (11)
|
|
305
485
|
|
|
306
486
|
- Ask any question about any page
|
|
487
|
+
|
|
307
488
|
- Gemini Nano on desktop Chrome — zero download, zero API
|
|
489
|
+
|
|
308
490
|
- Transformers.js on mobile — 30 MB one-time model load
|
|
491
|
+
|
|
309
492
|
- Auto engine detection and switching
|
|
493
|
+
|
|
310
494
|
- Works offline after first load
|
|
495
|
+
|
|
311
496
|
- q4 quantization on mobile (32-bit → 4-bit weights)
|
|
497
|
+
|
|
312
498
|
- `flan-t5-small` for full-sentence answers
|
|
499
|
+
|
|
313
500
|
- Cosine similarity semantic search
|
|
501
|
+
|
|
314
502
|
- Deduped DOM text extraction
|
|
315
503
|
|
|
316
504
|
### What I learned
|
|
@@ -326,14 +514,23 @@ User types a goal in plain English. Yuktai reads the DOM, finds the right elemen
|
|
|
326
514
|
### Features (13)
|
|
327
515
|
|
|
328
516
|
- Plain-English goal input
|
|
517
|
+
|
|
329
518
|
- Reads full page DOM — 9 traversal strategies
|
|
519
|
+
|
|
330
520
|
- Scans all form fields — 11 label strategies
|
|
521
|
+
|
|
331
522
|
- Works on static HTML, React, WordPress, and old government portals
|
|
523
|
+
|
|
332
524
|
- Gemini Nano planning on desktop, Transformers.js on mobile
|
|
525
|
+
|
|
333
526
|
- Rule-based fallback if AI fails
|
|
527
|
+
|
|
334
528
|
- Highlights target field with teal outline
|
|
529
|
+
|
|
335
530
|
- Scrolls to relevant section by keyword
|
|
531
|
+
|
|
336
532
|
- Numbered step-by-step plan
|
|
533
|
+
|
|
337
534
|
- Handles iframes
|
|
338
535
|
|
|
339
536
|
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.
|
|
@@ -347,11 +544,17 @@ Type a business requirement. Yuktai generates a full Next.js 16 project as a dow
|
|
|
347
544
|
### Features (19)
|
|
348
545
|
|
|
349
546
|
- Detects website type (12 types), pages needed (21 types), features (14 types)
|
|
547
|
+
|
|
350
548
|
- Detects theme colour (8), extracts site name
|
|
549
|
+
|
|
351
550
|
- Preview before generating
|
|
551
|
+
|
|
352
552
|
- Full Next.js 16 project — Tailwind + CSS Modules, TypeScript, mobile responsive
|
|
553
|
+
|
|
353
554
|
- Navbar, Footer, Home, About, Contact, Services, Pricing, Auth, Dashboard pages
|
|
555
|
+
|
|
354
556
|
- Downloads as ZIP · `npm run dev` works immediately
|
|
557
|
+
|
|
355
558
|
- Pure templates — no AI writes the code
|
|
356
559
|
|
|
357
560
|
No AI writes a single line. Pure template engineering. Same reusable-utility thinking from 2013 jQuery — now generating entire Next.js projects.
|
|
@@ -363,11 +566,17 @@ No AI writes a single line. Pure template engineering. Same reusable-utility thi
|
|
|
363
566
|
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.
|
|
364
567
|
|
|
365
568
|
Understands:
|
|
569
|
+
|
|
366
570
|
- "highest salary" → analyzes visible grid rows
|
|
571
|
+
|
|
367
572
|
- "how many employees" → counts
|
|
573
|
+
|
|
368
574
|
- "average age" → calculates
|
|
575
|
+
|
|
369
576
|
- "who is Sandeep" → looks up
|
|
577
|
+
|
|
370
578
|
- "search for developer" → filters grid
|
|
579
|
+
|
|
371
580
|
- "sort by salary descending" → sorts
|
|
372
581
|
|
|
373
582
|
Chrome + Edge give the best voice recognition. Firefox needs a flag. iOS Safari is limited.
|
|
@@ -379,22 +588,37 @@ Chrome + Edge give the best voice recognition. Firefox needs a flag. iOS Safari
|
|
|
379
588
|
7 custom SVG icons. Zero external dependency.
|
|
380
589
|
|
|
381
590
|
```tsx
|
|
591
|
+
|
|
382
592
|
import {
|
|
593
|
+
|
|
383
594
|
SearchIcon,
|
|
595
|
+
|
|
384
596
|
SortUpIcon,
|
|
597
|
+
|
|
385
598
|
SortDownIcon,
|
|
599
|
+
|
|
386
600
|
ChevronLeftIcon,
|
|
601
|
+
|
|
387
602
|
ChevronRightIcon,
|
|
603
|
+
|
|
388
604
|
CheckIcon,
|
|
605
|
+
|
|
389
606
|
CloseIcon,
|
|
607
|
+
|
|
390
608
|
} from "@yuktishaalaa/yuktai";
|
|
391
609
|
|
|
392
610
|
<SearchIcon size={20} />
|
|
611
|
+
|
|
393
612
|
<SortUpIcon size={20} color="#0D9488" />
|
|
613
|
+
|
|
394
614
|
<CheckIcon size={20} color="#10b981" label="Task complete" />
|
|
615
|
+
|
|
395
616
|
<CloseIcon size={20} color="#dc2626" />
|
|
617
|
+
|
|
396
618
|
<ChevronLeftIcon size={24} label="Previous" />
|
|
619
|
+
|
|
397
620
|
<ChevronRightIcon size={24} label="Next" />
|
|
621
|
+
|
|
398
622
|
```
|
|
399
623
|
|
|
400
624
|
Props: `size` (default 20), `color` (default `currentColor`), `strokeWidth` (default 2.5), `label` (adds ARIA — decorative if omitted).
|
|
@@ -404,10 +628,15 @@ Props: `size` (default 20), `color` (default `currentColor`), `strokeWidth` (def
|
|
|
404
628
|
## Gemini Nano (Chrome 147+)
|
|
405
629
|
|
|
406
630
|
- Plain-English mode — rewrites complex text
|
|
631
|
+
|
|
407
632
|
- Summarise page — 3-sentence summary
|
|
633
|
+
|
|
408
634
|
- Smart ARIA labels — AI generates labels
|
|
635
|
+
|
|
409
636
|
- Translate page — 18 languages
|
|
637
|
+
|
|
410
638
|
- Chrome 147+ standalone globals (`window.LanguageModel`)
|
|
639
|
+
|
|
411
640
|
- Fallback to old `window.ai` namespace
|
|
412
641
|
|
|
413
642
|
Chrome 147 silently removed `window.ai` and moved everything to standalone globals. Debugged for an evening before finding it in the release notes.
|
|
@@ -423,25 +652,41 @@ Zero API keys · Zero cost · Zero telemetry · Works on all browsers · Works o
|
|
|
423
652
|
## Configuration
|
|
424
653
|
|
|
425
654
|
```ts
|
|
655
|
+
|
|
426
656
|
import { wcagPlugin, A11yConfig } from "@yuktishaalaa/yuktai";
|
|
427
657
|
|
|
428
658
|
const config: A11yConfig = {
|
|
659
|
+
|
|
429
660
|
enabled: true, // required
|
|
661
|
+
|
|
430
662
|
highContrast: false,
|
|
663
|
+
|
|
431
664
|
darkMode: false,
|
|
665
|
+
|
|
432
666
|
reduceMotion: false,
|
|
667
|
+
|
|
433
668
|
largeTargets: false,
|
|
669
|
+
|
|
434
670
|
speechEnabled: false,
|
|
671
|
+
|
|
435
672
|
colorBlindMode: "none", // none | deuteranopia | protanopia | tritanopia | achromatopsia
|
|
673
|
+
|
|
436
674
|
autoFix: true,
|
|
675
|
+
|
|
437
676
|
showPreferencePanel: true,
|
|
677
|
+
|
|
438
678
|
showSkipLinks: true,
|
|
679
|
+
|
|
439
680
|
showAuditBadge: false, // dev only (localhost)
|
|
681
|
+
|
|
440
682
|
fontSizeMultiplier: 1,
|
|
683
|
+
|
|
441
684
|
timeoutWarning: 0, // seconds (0 = off)
|
|
685
|
+
|
|
442
686
|
};
|
|
443
687
|
|
|
444
688
|
await wcagPlugin.execute(config);
|
|
689
|
+
|
|
445
690
|
```
|
|
446
691
|
|
|
447
692
|
---
|
|
@@ -449,10 +694,15 @@ await wcagPlugin.execute(config);
|
|
|
449
694
|
## WCAG coverage
|
|
450
695
|
|
|
451
696
|
| Standard | Criteria covered |
|
|
697
|
+
|
|
452
698
|
|---|---|
|
|
699
|
+
|
|
453
700
|
| WCAG 2.0 | 19 criteria |
|
|
701
|
+
|
|
454
702
|
| WCAG 2.1 | 7 criteria |
|
|
703
|
+
|
|
455
704
|
| WCAG 2.2 | 3 criteria (focus appearance, target size, timeout) |
|
|
705
|
+
|
|
456
706
|
| Beyond WCAG | SpeechSynthesis, visual alerts, keyboard cheatsheet, audit score, colour-blind modes, dyslexia font |
|
|
457
707
|
|
|
458
708
|
---
|
|
@@ -460,8 +710,11 @@ await wcagPlugin.execute(config);
|
|
|
460
710
|
## Design principles
|
|
461
711
|
|
|
462
712
|
- **Zero id attributes** — no injected node ever gets an `id`. Tracked via module-level JavaScript references. Never collides with host app ids.
|
|
713
|
+
|
|
463
714
|
- **Zero API keys** — runs entirely in the browser. No external calls, no telemetry, no cost.
|
|
715
|
+
|
|
464
716
|
- **Zero framework lock-in** — `core/renderer.ts` has no framework imports. Works in Node.js, browsers, and test environments.
|
|
717
|
+
|
|
465
718
|
- **Honest limits** — client-side grid pagination works for a few thousand rows. Beyond that, use server-side pagination (pattern shown above).
|
|
466
719
|
|
|
467
720
|
---
|
|
@@ -469,21 +722,33 @@ await wcagPlugin.execute(config);
|
|
|
469
722
|
## Compatibility
|
|
470
723
|
|
|
471
724
|
### Next.js versions
|
|
725
|
+
|
|
472
726
|
| Version | Supported |
|
|
727
|
+
|
|
473
728
|
|---|---|
|
|
729
|
+
|
|
474
730
|
| Next.js 16 | ✅ |
|
|
731
|
+
|
|
475
732
|
| Next.js 15 | ✅ |
|
|
733
|
+
|
|
476
734
|
| Next.js 14 | ✅ |
|
|
735
|
+
|
|
477
736
|
| Next.js 13 | ✅ |
|
|
478
737
|
|
|
479
738
|
### React versions
|
|
739
|
+
|
|
480
740
|
| Version | Supported | Install flag |
|
|
741
|
+
|
|
481
742
|
|---|---|---|
|
|
743
|
+
|
|
482
744
|
| React 19 | ✅ | `--legacy-peer-deps` |
|
|
745
|
+
|
|
483
746
|
| React 18 | ✅ | none |
|
|
747
|
+
|
|
484
748
|
| React 17 | ✅ | none |
|
|
485
749
|
|
|
486
750
|
### Browsers
|
|
751
|
+
|
|
487
752
|
Chrome 90+ · Firefox 90+ · Safari 15+ · Edge 90+ · Samsung Internet 14+
|
|
488
753
|
|
|
489
754
|
---
|
|
@@ -491,8 +756,11 @@ Chrome 90+ · Firefox 90+ · Safari 15+ · Edge 90+ · Samsung Internet 14+
|
|
|
491
756
|
## Roadmap
|
|
492
757
|
|
|
493
758
|
Shipped: v4.1.2 (grid polish)
|
|
759
|
+
|
|
494
760
|
Next: v4.2.0 — Voice search inside `YuktaiGrid` (mic button + Web Speech API)
|
|
761
|
+
|
|
495
762
|
After that: v4.3.0 — AI Summary button, TTS row reader
|
|
763
|
+
|
|
496
764
|
Long term: v5.0.0 — WebLLM + WebMCP + multimodal
|
|
497
765
|
|
|
498
766
|
---
|
|
@@ -500,7 +768,9 @@ Long term: v5.0.0 — WebLLM + WebMCP + multimodal
|
|
|
500
768
|
## Links
|
|
501
769
|
|
|
502
770
|
- npm — [@yuktishaalaa/yuktai](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
|
|
771
|
+
|
|
503
772
|
- GitHub — [sandeepmiriyala03/yuktai](https://github.com/sandeepmiriyala03/yuktai)
|
|
773
|
+
|
|
504
774
|
- Live demo — [aksharatantra.vercel.app](https://aksharatantra.vercel.app)
|
|
505
775
|
|
|
506
776
|
---
|
package/dist/index.d.mts
CHANGED
|
@@ -295,13 +295,14 @@ declare global {
|
|
|
295
295
|
};
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
|
+
type WebMCPColumn = {
|
|
299
|
+
key: string;
|
|
300
|
+
label: string;
|
|
301
|
+
type?: "text" | "number" | "date";
|
|
302
|
+
};
|
|
298
303
|
type YuktaiGridWebMCPProps<T> = {
|
|
299
304
|
data: T[];
|
|
300
|
-
columns:
|
|
301
|
-
key: string;
|
|
302
|
-
label: string;
|
|
303
|
-
type?: "text" | "number" | "date";
|
|
304
|
-
}[];
|
|
305
|
+
columns: WebMCPColumn[];
|
|
305
306
|
name?: string;
|
|
306
307
|
onSelectRow?: (id: string) => void;
|
|
307
308
|
onHighlightRows?: (ids: string[]) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -295,13 +295,14 @@ declare global {
|
|
|
295
295
|
};
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
|
+
type WebMCPColumn = {
|
|
299
|
+
key: string;
|
|
300
|
+
label: string;
|
|
301
|
+
type?: "text" | "number" | "date";
|
|
302
|
+
};
|
|
298
303
|
type YuktaiGridWebMCPProps<T> = {
|
|
299
304
|
data: T[];
|
|
300
|
-
columns:
|
|
301
|
-
key: string;
|
|
302
|
-
label: string;
|
|
303
|
-
type?: "text" | "number" | "date";
|
|
304
|
-
}[];
|
|
305
|
+
columns: WebMCPColumn[];
|
|
305
306
|
name?: string;
|
|
306
307
|
onSelectRow?: (id: string) => void;
|
|
307
308
|
onHighlightRows?: (ids: string[]) => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuktishaalaa/yuktai",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.1",
|
|
4
4
|
"description": "Universal runtime accessibility plugin — auto-fixes WCAG 2.2 violations with on-device AI features. Zero API keys.",
|
|
5
5
|
"author": "Sandeep Miriyala — Yuktishaalaa AI Lab",
|
|
6
6
|
"license": "ISC",
|