@yuktishaalaa/yuktai 4.4.0 → 4.4.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 +325 -314
- package/dist/index.d.mts +9 -14
- package/dist/index.d.ts +9 -14
- package/dist/index.js +59 -64
- package/dist/index.mjs +28 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,99 +1,92 @@
|
|
|
1
1
|
# @yuktishaalaa/yuktai
|
|
2
2
|
|
|
3
|
-
> Universal
|
|
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
|
[](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
|
|
6
6
|
[](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
|
|
7
7
|
[](./LICENSE)
|
|
8
8
|
[](https://nodejs.org)
|
|
9
|
+
[](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
|
-
|
|
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 → [aksharatantra.vercel.app](https://aksharatantra.vercel.app)
|
|
25
14
|
|
|
26
15
|
---
|
|
27
16
|
|
|
28
|
-
##
|
|
17
|
+
## The story
|
|
29
18
|
|
|
30
|
-
|
|
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
|
-
|
|
36
|
-
```bash
|
|
37
|
-
npm i @yuktishaalaa/yuktai --legacy-peer-deps
|
|
38
|
-
```
|
|
21
|
+
I wanted something without any of those barriers.
|
|
39
22
|
|
|
40
|
-
|
|
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
|
-
|
|
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
|
|
29
|
+
## What's inside
|
|
52
30
|
|
|
53
|
-
|
|
31
|
+
Five modules ship in the single npm package:
|
|
54
32
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
41
|
+
Plus 7 custom SVG icons, a voice + chat assistant, and a growing icon library.
|
|
67
42
|
|
|
68
43
|
---
|
|
69
44
|
|
|
70
|
-
##
|
|
45
|
+
## What's new
|
|
71
46
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
78
|
+
### Older Next.js (13, 14, 15)
|
|
79
|
+
```bash
|
|
80
|
+
npm install @yuktishaalaa/yuktai
|
|
81
|
+
```
|
|
86
82
|
|
|
87
|
-
|
|
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
|
-
##
|
|
87
|
+
## Quick start
|
|
95
88
|
|
|
96
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
141
|
+
## Module 1 — Accessibility Engine
|
|
164
142
|
|
|
165
|
-
|
|
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
|
-
|
|
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
|
-
|
|
181
|
-
<script setup lang="ts">
|
|
182
|
-
import YuktAIWrapper from "@yuktishaalaa/yuktai/vue";
|
|
183
|
-
</script>
|
|
147
|
+
### Features (16)
|
|
184
148
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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
|
-
|
|
159
|
+
### Direct API
|
|
195
160
|
|
|
196
161
|
```ts
|
|
197
|
-
import
|
|
162
|
+
import { wcagPlugin } from "@yuktishaalaa/yuktai";
|
|
198
163
|
|
|
199
|
-
|
|
200
|
-
|
|
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
|
-
##
|
|
182
|
+
## Module 2 — YuktaiGrid ⭐
|
|
207
183
|
|
|
208
|
-
|
|
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
|
-
|
|
211
|
-
import { YuktAIModule } from "@yuktishaalaa/yuktai/angular";
|
|
186
|
+
### Usage
|
|
212
187
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
})
|
|
217
|
-
export class AppModule {}
|
|
218
|
-
```
|
|
188
|
+
```tsx
|
|
189
|
+
"use client";
|
|
190
|
+
import { YuktaiGrid } from "@yuktishaalaa/yuktai";
|
|
219
191
|
|
|
220
|
-
|
|
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
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
-
|
|
215
|
+
### Grid features (12)
|
|
229
216
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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
|
-
|
|
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
|
-
|
|
232
|
+
Here's the pattern with a Next.js API proxy that also solves CORS.
|
|
250
233
|
|
|
251
|
-
|
|
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
|
-
|
|
236
|
+
```ts
|
|
237
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
257
238
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
239
|
+
let cachedData: any[] | null = null;
|
|
240
|
+
let cacheTime = 0;
|
|
241
|
+
const TTL_MS = 60_000;
|
|
261
242
|
|
|
262
|
-
|
|
243
|
+
async function fetchAll(): Promise<any[]> {
|
|
244
|
+
const now = Date.now();
|
|
245
|
+
if (cachedData && now - cacheTime < TTL_MS) return cachedData;
|
|
263
246
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
-
**
|
|
275
|
+
**Page — call the paginated API and disable the grid's built-in pagination:**
|
|
272
276
|
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
-
##
|
|
300
|
+
## Module 3 — In-Tab RAG (Ask This Page)
|
|
282
301
|
|
|
283
|
-
|
|
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
|
-
|
|
304
|
+
### Features (11)
|
|
286
305
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
|
|
293
|
-
<!-- your content -->
|
|
294
|
-
</yuktai-a11y>
|
|
295
|
-
```
|
|
316
|
+
### What I learned
|
|
296
317
|
|
|
297
|
-
|
|
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
|
-
|
|
300
|
-
import "@yuktishaalaa/yuktai/web-component";
|
|
320
|
+
---
|
|
301
321
|
|
|
302
|
-
|
|
303
|
-
<yuktai-a11y position="left">
|
|
304
|
-
<App />
|
|
305
|
-
</yuktai-a11y>
|
|
306
|
-
```
|
|
322
|
+
## Module 4 — Autonomous AI Agent
|
|
307
323
|
|
|
308
|
-
|
|
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
|
-
|
|
311
|
-
plugins: [vue({
|
|
312
|
-
template: {
|
|
313
|
-
compilerOptions: {
|
|
314
|
-
isCustomElement: (tag) => tag === "yuktai-a11y",
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
})]
|
|
318
|
-
```
|
|
326
|
+
### Features (13)
|
|
319
327
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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
|
-
##
|
|
343
|
+
## Module 5 — Vibe Coder
|
|
334
344
|
|
|
335
|
-
|
|
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
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
-
|
|
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
|
-
|
|
357
|
-
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Voice + Chat Assistant
|
|
358
362
|
|
|
359
|
-
|
|
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
|
-
|
|
364
|
-
|
|
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
|
-
|
|
367
|
-
|
|
373
|
+
Chrome + Edge give the best voice recognition. Firefox needs a flag. iOS Safari is limited.
|
|
374
|
+
|
|
375
|
+
---
|
|
368
376
|
|
|
369
|
-
|
|
370
|
-
const modal = document.querySelector("#my-modal") as HTMLElement;
|
|
371
|
-
wcagPlugin.trapFocus(modal);
|
|
377
|
+
## Icon library
|
|
372
378
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
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
|
-
##
|
|
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,
|
|
388
|
-
darkMode: false,
|
|
389
|
-
reduceMotion: false,
|
|
390
|
-
largeTargets: false,
|
|
391
|
-
speechEnabled: false,
|
|
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,
|
|
394
|
-
showPreferencePanel: true,
|
|
395
|
-
showSkipLinks: true,
|
|
396
|
-
showAuditBadge: false, //
|
|
397
|
-
fontSizeMultiplier: 1,
|
|
398
|
-
timeoutWarning: 0, // seconds
|
|
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
|
|
456
|
+
| Beyond WCAG | SpeechSynthesis, visual alerts, keyboard cheatsheet, audit score, colour-blind modes, dyslexia font |
|
|
429
457
|
|
|
430
458
|
---
|
|
431
459
|
|
|
432
|
-
##
|
|
460
|
+
## Design principles
|
|
433
461
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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
|
-
##
|
|
469
|
+
## Compatibility
|
|
453
470
|
|
|
454
|
-
|
|
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
|
-
|
|
458
|
-
|
|
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
|
-
|
|
486
|
+
### Browsers
|
|
487
|
+
Chrome 90+ · Firefox 90+ · Safari 15+ · Edge 90+ · Samsung Internet 14+
|
|
462
488
|
|
|
463
489
|
---
|
|
464
490
|
|
|
465
|
-
##
|
|
491
|
+
## Roadmap
|
|
466
492
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
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
|
-
##
|
|
500
|
+
## Links
|
|
475
501
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
514
|
+
Free forever. Open source.
|