@yuktishaalaa/yuktai 5.2.0 → 5.3.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 +923 -738
- package/dist/chunk-RQKKMYGR.mjs +1 -0
- package/dist/icons.d.mts +201 -0
- package/dist/icons.d.ts +201 -0
- package/dist/icons.js +1 -0
- package/dist/icons.mjs +1 -0
- package/dist/index.d.mts +3 -34
- package/dist/index.d.ts +3 -34
- package/dist/index.js +59 -59
- package/dist/index.mjs +24 -24
- package/dist/renderer.global.js +18 -18
- package/package.json +120 -84
- package/vanilla/README.md +162 -0
- package/vanilla/index.js +6857 -0
- package/vanilla/index.min.js +543 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# yuktai — Vanilla JS
|
|
2
|
+
|
|
3
|
+
The whole yuktai 5.2 toolkit for plain HTML pages: one script file, no React, no build step, no API keys.
|
|
4
|
+
|
|
5
|
+
- **Data grid you can talk to**: search, sort, pagination, selection, CSV export, five WCAG themes, table/card views, Telugu UI, and keyboard navigation with ARIA grid roles.
|
|
6
|
+
- **Agents**: smart grid queries, BI answers, multi-step tasks, an anomaly finder, a grid assistant with custom rules and voice, and WebMCP.
|
|
7
|
+
- **Page tools**: Accessibility Copilot, QA report (15 WCAG checks), form review, design review, page Q&A and voice commands.
|
|
8
|
+
- **Accessibility engine**: WCAG auto-fixes, high contrast, dark mode, reduced motion, large targets, colour-blind filters, a dyslexia font, text size 80–130%, skip links and speak-on-focus.
|
|
9
|
+
|
|
10
|
+
The logic is bundled from this repo's `src/` (the same code as the npm package), so a question gets the same answer in React and in plain HTML. Only the React components and hooks are rewritten, in `vanilla/src/`.
|
|
11
|
+
|
|
12
|
+
## Use it
|
|
13
|
+
|
|
14
|
+
```html
|
|
15
|
+
<script>
|
|
16
|
+
window.YUKTAI_CONFIG = { position: "right", showPageTools: true } // optional
|
|
17
|
+
</script>
|
|
18
|
+
<script src="./index.js"></script> <!-- or index.min.js -->
|
|
19
|
+
|
|
20
|
+
<div id="staff"></div>
|
|
21
|
+
<script>
|
|
22
|
+
const grid = yuktai.renderGrid("#staff", {
|
|
23
|
+
data: rows,
|
|
24
|
+
rowKey: "id",
|
|
25
|
+
columns: [
|
|
26
|
+
{ key: "name", label: "Name" },
|
|
27
|
+
{ key: "salary", label: "Salary", type: "number" },
|
|
28
|
+
{ key: "joined", label: "Joined", type: "date" },
|
|
29
|
+
{ key: "status", label: "Status", type: "badge" },
|
|
30
|
+
],
|
|
31
|
+
agentic: true, // question bar: "salary over 1 lakh", "average salary by department"
|
|
32
|
+
ai: true, // assistant: custom rules → phrases → tools, with voice input
|
|
33
|
+
})
|
|
34
|
+
</script>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Open `index.html` in this folder to see every feature with working examples, including a Telugu grid.
|
|
38
|
+
|
|
39
|
+
## `YUKTAI_CONFIG` (floating buttons)
|
|
40
|
+
|
|
41
|
+
| Option | Default | Purpose |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| `position` | `"left"` | Side for the floating buttons: `"left"` or `"right"` |
|
|
44
|
+
| `primaryColor` | `#0f766e` | Accent colour (keep 4.5:1 against white) |
|
|
45
|
+
| `title` | `"Accessibility"` | Settings dialog title |
|
|
46
|
+
| `showPageTools` | `false` | Adds the 🛠 button that opens the six page tools |
|
|
47
|
+
| `defaultTab`, `voiceLang` | `"qa"`, `"en-IN"` | Settings for the page tools |
|
|
48
|
+
| `generate(q, ctx)`, `summarize(text)` | — | Optional hooks for your own model (Ask tab) |
|
|
49
|
+
| `config` | — | Engine overrides, for example `{ autoFix: false }` |
|
|
50
|
+
| `applyOnLoad` | `true` | Run the engine once on page load (restores saved settings) |
|
|
51
|
+
| `autoInit` | `true` | Set `false` to call `yuktai.init()` yourself |
|
|
52
|
+
|
|
53
|
+
`yuktai.open()`, `yuktai.close()`, `yuktai.openTools("forms")`, `yuktai.apply({ highContrast: true })`, `yuktai.reset()` and `yuktai.getSettings()` control the widget from code. Settings are saved in `localStorage` (`yuktai-a11y-prefs`), the same key the npm package uses.
|
|
54
|
+
|
|
55
|
+
## `renderGrid(container, options)`
|
|
56
|
+
|
|
57
|
+
The v5.1 vanilla signature `renderGrid(container, rows, columns, options)` still works.
|
|
58
|
+
|
|
59
|
+
| Option | Purpose |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| `data`, `columns`, `rowKey` (`"id"`) | Rows, columns, row ID field |
|
|
62
|
+
| column: `key`, `label`, `type` (`text`/`number`/`date`/`boolean`/`badge`), `align`, `sortable`, `render(value, row, index)` returns text or a DOM node, `hiddenOnMobile`, `width` | |
|
|
63
|
+
| `label` | Accessible name of the grid |
|
|
64
|
+
| `locale` | `"en-IN"` (default), `"te-IN"` for Telugu UI and messages, or any Indian locale code |
|
|
65
|
+
| `theme` | `default`, `high-contrast`, `dark`, `color-blind`, `dyslexia` |
|
|
66
|
+
| `view`, `mobileBreakpoint` | `table`, `card` or `auto` (cards below 640px) |
|
|
67
|
+
| `pagination` | `{ pageSize, showSizeChanger, sizeOptions }`, or `false` |
|
|
68
|
+
| `search`, `selectable`, `exportable` | `false` turns each one off |
|
|
69
|
+
| `selectedKeys`, `highlightIds`, `autoScrollToHighlight` | Initial state |
|
|
70
|
+
| `loading`, `empty` | Loading state; empty message (text or a node) |
|
|
71
|
+
| `agentic` | `true` or `{ title, placeholder, examples, hint }`: the question bar |
|
|
72
|
+
| `ai`, `inputLanguage`, `assistantExamples` | Built-in assistant with voice input |
|
|
73
|
+
| `customRules` | `[{ name, phrases, description, execute({ input, data, columns, executeTool }) }]`, in any language |
|
|
74
|
+
| `parseIntent(text, ctx)` | Replace the built-in phrase parser |
|
|
75
|
+
| `webmcp`, `toolName`, `toolDescriptions`, `onWebMCPStatusChange` | Expose the 11 grid tools to browser AI agents |
|
|
76
|
+
| `referenceDate` | "Now" for "this month" questions |
|
|
77
|
+
| `onRowClick(row)`, `onOpenRow(id)` | Enables the `open` tool and "open Ravi" |
|
|
78
|
+
| `onSelectionChange(keys)`, `onSortChange(sort)`, `onFiltersChange(filters)`, `onAgentResult(r)` | Events |
|
|
79
|
+
| `wrap`, `maxHeight`, `showTitle`, `className` | Layout |
|
|
80
|
+
|
|
81
|
+
**Keyboard:** Tab into the table, then use the arrow keys to move between cells.
|
|
82
|
+
|
|
83
|
+
- Home / End go to the first or last cell in a row; Ctrl+Home / Ctrl+End go to the first or last cell in the table.
|
|
84
|
+
- Page Up / Page Down change the page.
|
|
85
|
+
- Space selects a row; Enter sorts (on a column header) or opens the row.
|
|
86
|
+
- Only one cell is in the Tab order.
|
|
87
|
+
|
|
88
|
+
### Grid API
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
await grid.ask("salary over 1 lakh in Hyderabad") // answer text (useAgenticGrid)
|
|
92
|
+
await grid.askDetailed("average salary by department") // { answer, kind, table, steps, gridData, … }
|
|
93
|
+
await grid.assistantAsk("sort by salary desc") // assistant pipeline result
|
|
94
|
+
await grid.executeTool("filter", { key: "salary", operator: "greaterThan", value: 100000 })
|
|
95
|
+
grid.search("Pune"); grid.setFilters([...]); grid.clearFilters(); grid.sortBy("name", "desc"); grid.clearSort()
|
|
96
|
+
grid.highlight(["1001"]); grid.clearHighlight(); grid.select(["1001"]); grid.getSelectedRows()
|
|
97
|
+
grid.goToPage(3); grid.nextPage(); grid.prevPage(); grid.setPageSize(50); grid.getPage()
|
|
98
|
+
grid.setTheme("dark"); grid.setView("card"); grid.setLoading(true)
|
|
99
|
+
grid.getRows(); grid.getPageRows(); grid.getData(); grid.refresh(newRows); grid.setData(rows, columns)
|
|
100
|
+
grid.biSummary(); grid.anomalies(); grid.exportCSV(); grid.reset(); grid.destroy()
|
|
101
|
+
grid.tools; grid.agent; grid.agentic; grid.webmcpStatus
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Tool results are always `{ success, message, data?, error?: { code } }` and never throw. The error codes are `NOT_FOUND`, `NOT_SUPPORTED`, `INVALID_INPUT`, `INTERNAL` and `NOT_UNDERSTOOD`.
|
|
105
|
+
|
|
106
|
+
## Without a grid
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
const agentic = yuktai.createAgenticGrid({ data: rows, columns, rowKey: "id" }) // useAgenticGrid
|
|
110
|
+
yuktai.mountAgenticGridBar("#bar", agentic, { examples: ["salary under 50k"] }) // AgenticGridBar
|
|
111
|
+
agentic.subscribe((s) => drawMyTable(s.gridData, s.highlightIds))
|
|
112
|
+
|
|
113
|
+
const tools = yuktai.createGridTools({ data: rows, columns, rowKey: "id", onFiltersChange, onSortChange }, { name: "my_grid" })
|
|
114
|
+
const agent = yuktai.createGridAgent({ tools, columns, customRules, locale: "te" }) // useYuktaiGridAgent
|
|
115
|
+
await agent.ask("ఎన్ని")
|
|
116
|
+
yuktai.registerWebMCP(tools, { onStatusChange: console.log }) // YuktaiGridWebMCP
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Page tools
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
yuktai.mountAgenticPanel("#tools", { defaultTab: "qa", voiceLang: "te-IN" }) // AgenticPanel, six tabs
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The panel is marked `data-yuktai-panel`, so the agents never audit their own UI.
|
|
126
|
+
|
|
127
|
+
## Core functions (same as npm)
|
|
128
|
+
|
|
129
|
+
- **Grid queries:** `parseAmount`, `parseGridQuery`, `executeGridQuery`, `runGridQuery`, `answerGridQuestion`, `detectAnomalies`, `summarizeRows`
|
|
130
|
+
- **BI:** `askInsight`, `groupBy`, `comparePeriods`, `trend`, `aggregate`
|
|
131
|
+
- **Tasks:** `planTasks`, `runTasks`
|
|
132
|
+
- **QA:** `runQaAudit`, `auditToMarkdown`, `auditToJSON`, `AUDIT_RULES`
|
|
133
|
+
- **Copilot:** `createA11yCopilot`
|
|
134
|
+
- **Page understanding:** `askAboutPage`, `analyzePage`, `detectPageIntent`
|
|
135
|
+
- **Page and data RAG:** `createContextIndex`, `tokenize`
|
|
136
|
+
- **Forms and design:** `reviewForms`, `reviewForm`, `readFormFields`, `reviewDesign`
|
|
137
|
+
- **Voice:** `parseVoiceA11yCommand`, `createVoiceA11yController`, `moveGridRowFocus`
|
|
138
|
+
- **Grid tools:** `createGridTools`, `getRowId`, `applyGridFilters`, `toGridToolColumns`, and each tool function
|
|
139
|
+
- **Other:** `contrastRatio`, `parseColor`, `relativeLuminance`, `accessibleName`, `wcagPlugin`
|
|
140
|
+
- **Icons:** `icon(name, size, label?)` and `iconNames`
|
|
141
|
+
|
|
142
|
+
## Build and test
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
npm i -D esbuild # once
|
|
146
|
+
node vanilla/build.mjs # → vanilla/index.js and vanilla/index.min.js
|
|
147
|
+
|
|
148
|
+
# End-to-end checks in real Chromium (37 checks plus axe-core)
|
|
149
|
+
npm i -D playwright-core axe-core
|
|
150
|
+
CHROME=/path/to/chrome node vanilla/test/e2e.mjs
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Edit `vanilla/src/*` or `src/*`, then rebuild. Do not edit `vanilla/index.js` by hand.
|
|
154
|
+
|
|
155
|
+
## Honest limits
|
|
156
|
+
|
|
157
|
+
- Questions are understood with rules, not a language model, so unusual phrasing may need rewording. Telugu and Hindi data questions need custom rules.
|
|
158
|
+
- QA, form and design checks are heuristics. Test with a keyboard and a screen reader before release.
|
|
159
|
+
- Voice depends on the browser's speech recognition. Typed commands always work.
|
|
160
|
+
- WebMCP needs `document.modelContext`. The real status is always reported.
|
|
161
|
+
- Filtering and paging run in the browser and suit a few thousand rows. For 100K+ rows, page on the server and call `grid.refresh(pageRows)`.
|
|
162
|
+
- The floating buttons are added under `<html>` (not `<body>`), so the colour-blind filter on `<body>` cannot move them.
|