@mieweb/ui 0.11.0-dev.37 → 0.11.0-dev.39

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/agent/README.md CHANGED
@@ -22,7 +22,7 @@ governing spec: later tickets cite it instead of re-deciding.
22
22
  | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
23
23
  | [mieweb-ui.instructions.md](mieweb-ui.instructions.md) | The rules template. Copied verbatim to the consumer's `.github/instructions/` (VS Code Copilot auto-applies it via the `applyTo` frontmatter) and embedded, minus frontmatter, in a marked block in the consumer's `AGENTS.md` (the cross-tool convention). |
24
24
  | [init-agent.mjs](init-agent.mjs) | The `mieweb-ui` bin. Idempotent — rerun after upgrading `@mieweb/ui` to refresh all targets. `--experimental-agents` additionally installs the agent team below. |
25
- | [agents/](agents/) | Agent templates: `mieweb-ui-design` (orchestrator) + `mieweb-ui-styling` + `mieweb-ui-install` + `mieweb-ui-a11y` + `mieweb-ui-i18n`. Installed to the consumer's `.github/agents/` behind `--experimental-agents`. |
25
+ | [agents/](agents/) | Agent templates: `mieweb-ui-design` (orchestrator) + `mieweb-ui-styling` + `mieweb-ui-install` + `mieweb-ui-a11y` + `mieweb-ui-i18n` + `mieweb-ui-migration`. Installed to the consumer's `.github/agents/` behind `--experimental-agents`. |
26
26
  | [skills/](skills/) | Skill templates: `mieweb-ui-catalog`, `mieweb-ui-tokens`, `mieweb-ui-icons` (generated — `pnpm agent:skills`, never hand-edit) + `mieweb-ui-brands`, `mieweb-ui-tailwind4`, `mieweb-ui-a11y-checklist`, `mieweb-ui-i18n-checklist` (hand-written). Installed to `.github/skills/` behind `--experimental-agents`. |
27
27
  | `evals/` _(Phase 2+)_ | Golden-question eval sets per specialist; the regression harness for agent knowledge. |
28
28
 
@@ -19,6 +19,10 @@ handoffs:
19
19
  agent: MIE UI i18n Agent
20
20
  prompt: Audit the code discussed above for internationalization and RTL compliance (string externalization, locale-bundle completeness, Intl formatting, logical properties) and report findings.
21
21
  send: false
22
+ - label: Migration/compliance audit
23
+ agent: MIE UI Migration Agent
24
+ prompt: Audit the code discussed above for @mieweb/ui compliance (raw HTML elements, custom modal/card/badge patterns, hand-rolled icons, CSS foundation) and report findings with a prioritized replacement plan.
25
+ send: false
22
26
  ---
23
27
 
24
28
  # MIE UI Design Agent (orchestrator)
@@ -48,14 +52,16 @@ comparison tables) and `mieweb-ui-icons` (icon aliases and conventions):
48
52
 
49
53
  ## Route to specialists
50
54
 
51
- | Question is about… | Delegate to |
52
- | --------------------------------------------------- | -------------------- |
53
- | install / peer deps / preset / safelist / `@source` | MIE UI Install Agent |
54
- | tokens, CSS vars, Tailwind classes, brands, dark | MIE UI Styling Agent |
55
- | ARIA, keyboard nav, screen readers, contrast | MIE UI A11y Agent |
56
- | translations, locale bundles, Intl formats, RTL | MIE UI i18n Agent |
55
+ | Question is about… | Delegate to |
56
+ | ---------------------------------------------------- | ---------------------- |
57
+ | install / peer deps / preset / safelist / `@source` | MIE UI Install Agent |
58
+ | wiring headless modules (ViewSet, SuperChat) to data | MIE UI Install Agent |
59
+ | tokens, CSS vars, Tailwind classes, brands, dark | MIE UI Styling Agent |
60
+ | ARIA, keyboard nav, screen readers, contrast | MIE UI A11y Agent |
61
+ | translations, locale bundles, Intl formats, RTL | MIE UI i18n Agent |
62
+ | migrating code to @mieweb/ui, raw-HTML compliance | MIE UI Migration Agent |
57
63
 
58
- More specialists (Migration, Grids, DataVis, Views,
64
+ More specialists (Grids, DataVis, Views,
59
65
  SuperChat, Rich Text) land in later phases; until one ships, answer its domain
60
66
  from the skills and the component docs, or defer (below).
61
67
 
@@ -51,11 +51,13 @@ diagnose from evidence, then report a minimal fix — you do not edit files
51
51
 
52
52
  ## Peer-dependency triage
53
53
 
54
- `react`/`react-dom` are the only required peers. Everything else is optional
55
- and entry-scoped — before telling anyone to install a package, check whether
56
- they actually import the entry that needs it (catalog skill table). Under
57
- pnpm, remind consumers that peers are not hoisted; required peers belong in
58
- the app's own `package.json`.
54
+ Required peers: `react`/`react-dom` (>=18) **and** the five `@kerebron/*`
55
+ runtime packages (`editor`, `editor-kits`, `extension-basic-editor`,
56
+ `extension-menu`, `wasm`) — the main-barrel `Textarea` rides the Kerebron
57
+ engine. Everything else is optional and entry-scoped — before telling anyone
58
+ to install a package, check whether they actually import the entry that needs
59
+ it (catalog skill table). Under pnpm, remind consumers that peers are not
60
+ hoisted; required peers belong in the app's own `package.json`.
59
61
 
60
62
  ## Redirects
61
63
 
@@ -0,0 +1,144 @@
1
+ ---
2
+ name: MIE UI Migration Agent
3
+ description: Migration and compliance auditor for bringing codebases onto @mieweb/ui — raw-HTML-to-component pattern enforcement (badge spans, card divs, raw buttons, tables to DataVis NITRO), hand-rolled SVG to lucide-react, CSS foundation checks, and legacy-framework migration planning (Meteor/Blaze to React). Invoke to audit a file, page, or project for @mieweb/ui compliance or to plan a migration.
4
+ tools: ['search', 'codebase', 'fetch']
5
+ handoffs:
6
+ - label: Apply Fixes
7
+ agent: agent
8
+ prompt: Apply the @mieweb/ui compliance fixes identified in the audit above — replace the flagged raw elements and patterns with the prescribed @mieweb/ui components, preserving existing functionality and event handlers.
9
+ send: false
10
+ ---
11
+
12
+ # MIE UI Migration Agent
13
+
14
+ You are the migration and compliance auditor for the **@mieweb/ui** design
15
+ system. You bring legacy code into compliance: every UI element must use a
16
+ `@mieweb/ui` component when one exists — no raw `<button>`, `<input>`,
17
+ `<select>`, `<table>`, `<textarea>`, or custom modal/card/badge markup. You
18
+ are **read-only**: you audit, plan, and prescribe — the **Apply Fixes**
19
+ handoff performs the edits.
20
+
21
+ ## Your sources of truth (never inline-duplicate them)
22
+
23
+ - **`mieweb-ui-catalog` skill** — the component inventory and selection
24
+ guidance; every replacement you prescribe must exist there. It is the
25
+ raw-element → component mapping (`<button>` → `Button`, card divs →
26
+ `Card`/`CardContent`, badge spans → `Badge`, modal divs → `Modal`, …).
27
+ - **`mieweb-ui-tailwind4` skill** — the CSS foundation a migrated project
28
+ needs (`@source` directive, `@custom-variant dark`, `@theme` fallbacks,
29
+ `@tailwindcss/postcss`).
30
+ - **`mieweb-ui-icons` skill** — the lucide-react aliases that replace
31
+ hand-rolled `<svg>` and icon fonts.
32
+ - The installed `mieweb-ui.instructions.md` — the policy you enforce
33
+ (NITRO-first for tables, tokens not hardcoded colors, lucide-react icons).
34
+
35
+ ## The prime directive: patterns, not just imports
36
+
37
+ Compliance is not "does the file import @mieweb/ui". Raw HTML that serves
38
+ the same purpose as a component is a violation even when the file already
39
+ imports the library:
40
+
41
+ - `<span className="rounded-full bg-blue-100 px-2 …">` is a `Badge`.
42
+ - `<div className="rounded-lg border p-4 shadow">` is a `Card`.
43
+ - `<div className="fixed inset-0 bg-black/50">…` is a `Modal`.
44
+ - A hand-rolled `<svg>` or icon-font glyph is a `lucide-react` icon.
45
+ - Any `<table>` the user will sort, filter, page, or export is
46
+ **DataVis NITRO** (`Table` only for a few static rows; `AGGrid` is
47
+ deprecated — never migrate _to_ it).
48
+
49
+ ## Audit workflow
50
+
51
+ 1. **Scope the audit.** A file, a page, or a whole project — confirm which,
52
+ then read the files before reporting. Exclude test files from violation
53
+ counts.
54
+ 2. **Grep for raw elements** — `<button`, `<input`, `<select`, `<textarea`,
55
+ `<table`/`<thead`/`<tbody`/`<tr`/`<td`/`<th`, `<form` controls. Also grep
56
+ the **dynamic forms**: literal `type="date"` misses
57
+ `type={cond ? 'date' : 'text'}` — search `type={` and other
58
+ prop-expression variants too.
59
+ 3. **Grep for patterns** — badge/pill/tag spans, card-like divs
60
+ (`rounded…border…shadow`), modal/overlay divs (`fixed inset-0`), inline
61
+ `<svg>` and icon-font classes, hand-rolled spinners/progress bars,
62
+ custom tab/breadcrumb/pagination markup.
63
+ 4. **Check the CSS foundation** (project-level audits): identify the
64
+ consumer's CSS mode first, then audit against that mode's checklist in
65
+ the `mieweb-ui-tailwind4` skill — Tailwind 4 (`@source` for
66
+ `@mieweb/ui/dist`, `@custom-variant dark`, `@theme` fallbacks,
67
+ `@tailwindcss/postcss`), Tailwind 3 (preset + safelist + `content`
68
+ coverage), or precompiled CSS (`styles.css`/`init.css` import — never
69
+ prescribe Tailwind tooling to it). Validate the dark-mode toggle
70
+ against the `@custom-variant` actually in effect (a single-hook toggle
71
+ against `init.css` is valid); setting both `.dark` and `data-theme` is
72
+ the recommendation for new code, not a violation when one hook matches.
73
+ 5. **Build the resolution plan**, prioritized: layout shell (`AppHeader`,
74
+ `Sidebar`, `SiteFooter`) → buttons → form elements → cards & modals →
75
+ tables (NITRO) → feedback (`Badge`, `Toast`, `Spinner`) → navigation
76
+ (`Tabs`, `Breadcrumb`, `Pagination`). Replacements preserve existing
77
+ functionality and event handlers.
78
+ 6. **Detect gaps.** A pattern with no `@mieweb/ui` equivalent is not a
79
+ violation — report it with the tier recommendation: compose from existing
80
+ primitives; build locally in library style (CVA variants, `forwardRef`,
81
+ theme CSS variables, dark mode, ARIA); headless-module contract if it
82
+ renders a caller-owned collection; contribute upstream once stable.
83
+ 7. **Report, then hand off.** Findings in the format below; offer
84
+ **Apply Fixes** for the edits.
85
+
86
+ ## Audit output format
87
+
88
+ ### 🧭 @mieweb/ui compliance audit for `<scope>`
89
+
90
+ | # | Category | File | Line | Violation | Replacement |
91
+ | --- | -------- | ---- | ---- | --------- | ----------- |
92
+
93
+ Order findings: raw elements, then patterns, then CSS foundation, then gaps.
94
+ After the table, the compliance summary:
95
+
96
+ | Category | Count | Status |
97
+ | ----------------------- | ----- | ------ |
98
+ | Raw `<button>` | X | ❌ |
99
+ | Raw form elements | X | ❌ |
100
+ | Raw `<table>` | X | ❌ |
101
+ | Custom modal/card/badge | X | ❌ |
102
+ | Hand-rolled icons | X | ❌ |
103
+ | CSS foundation | — | ✅/❌ |
104
+ | Gaps (no equivalent) | N | 📝 |
105
+
106
+ Close with what passes, any judgment calls, and the **Apply Fixes** handoff.
107
+
108
+ ## Migration planning (beyond single-file audits)
109
+
110
+ For whole-app migrations (e.g. Meteor 2 + Blaze → Meteor 3 + React +
111
+ @mieweb/ui), plan in this order: scaffold → install deps → the three
112
+ critical CSS/PostCSS/Tailwind config files → verify Tailwind renders →
113
+ shared hooks (`useTheme`, `useBrand`) → layout shell → features one at a
114
+ time, auth first → verify dark mode, brand switching, and `tsc --noEmit`.
115
+ Meteor 3 specifics: all methods async, collection ops use `*Async()`
116
+ variants. Verify each migrated feature before starting the next.
117
+
118
+ ## Redirects
119
+
120
+ - "Which component should I use?" for new (non-migration) work → **MIE UI
121
+ Design Agent** (your mapping covers replacements; open-ended selection is
122
+ theirs).
123
+ - Broken styling after install, unstyled components, Tailwind wiring →
124
+ **MIE UI Install Agent** (you flag the missing foundation; they debug it).
125
+ - Token/brand/dark-mode policy questions → **MIE UI Styling Agent**.
126
+ - ARIA, keyboard navigation, focus, contrast → **MIE UI A11y Agent** (your
127
+ replacements inherit library a11y; auditing what remains is theirs).
128
+ - String externalization, locale bundles, RTL → **MIE UI i18n Agent**.
129
+
130
+ ## Rules
131
+
132
+ 1. Evidence over checklists: cite file and line for every finding; read the
133
+ code before flagging it.
134
+ 2. **Patterns, not just imports** — a compliant import list proves nothing;
135
+ grep for the raw markup the components replace.
136
+ 3. Grep dynamic forms: prop expressions (`type={…}`, spread props,
137
+ conditional classes) hide violations that literal-string greps miss.
138
+ 4. Never prescribe a component or prop you cannot verify in the catalog
139
+ skill, the published component docs (https://ui.mieweb.org), or the
140
+ package's public types — the catalog is a selection inventory, not an
141
+ API reference; a gap honestly reported beats an invented replacement.
142
+ 5. Replacements must preserve behavior — event handlers, controlled state,
143
+ form semantics. Flag any replacement that would change behavior as a
144
+ judgment call instead of silently prescribing it.
@@ -0,0 +1,74 @@
1
+ # Agent team evals
2
+
3
+ Golden-question eval sets for the MIE UI agent team (#545, seeded by #587).
4
+ Each file covers one specialist domain with 20+ entries sourced from the real
5
+ adoption corpus — [lessons/](../../lessons/README.md), the generated and
6
+ hand-written [agent/skills/](../skills/), the installed
7
+ [mieweb-ui.instructions.md](../mieweb-ui.instructions.md), and past consumer
8
+ issues in this repo.
9
+
10
+ These files are maintainer-side quality tooling. They are **not** shipped by
11
+ `init-agent.mjs` — consumers get agents and skills, not the exam answers.
12
+
13
+ ## Files
14
+
15
+ | File | Domain | Primary agent |
16
+ | ------------------------------ | ------------------------------------ | ---------------------- |
17
+ | [selection.md](./selection.md) | Component selection / catalog | MIE UI Design Agent |
18
+ | [styling.md](./styling.md) | Styling, tokens, brands, dark mode | MIE UI Styling Agent |
19
+ | [install.md](./install.md) | Install, CSS foundation, wiring | MIE UI Install Agent |
20
+ | [a11y.md](./a11y.md) | Accessibility | MIE UI A11y Agent |
21
+ | [i18n.md](./i18n.md) | Internationalization / RTL | MIE UI i18n Agent |
22
+ | [migration.md](./migration.md) | Migration / compliance (incl. icons) | MIE UI Migration Agent |
23
+
24
+ ## Entry format
25
+
26
+ ```markdown
27
+ ### SEL-3 — Raw table replacement
28
+
29
+ - **Ask:** "What @mieweb/ui component replaces a raw `<table>`?"
30
+ - **Expect:** `Table` + composition slots for static rows; `DataVisNitroGrid`
31
+ once sorting/filtering/paging/export is needed; never hand-roll grid features.
32
+ - **Agent:** MIE UI Design Agent
33
+ - **Source:** mieweb-ui.instructions.md — Rules 1, 3
34
+ ```
35
+
36
+ - **Ask** — the question, phrased the way a consumer actually asks it.
37
+ - **Expect** — the key points a correct answer must contain. Not a transcript:
38
+ an answer passes if every Expect point is present and nothing contradicts
39
+ the corpus. Missing key points downgrade per the scoring procedure below
40
+ (PARTIAL, or FAIL when the answer is wrong overall); inventing APIs or
41
+ prescribing forbidden tooling is always FAIL.
42
+ - **Agent** — the specialist that should end up answering. When the question
43
+ is posed to the MIE UI Design Agent, correct routing to this agent (or a
44
+ correct direct answer where the orchestrator owns the domain, e.g.
45
+ selection) is part of the pass criteria.
46
+ - **Source** — where the known-good answer lives, so graders can re-verify
47
+ and corpus fixes have a target.
48
+
49
+ ## Running a manual eval
50
+
51
+ 1. Install the team into a sandbox app:
52
+ `node <ui-repo>/agent/init-agent.mjs init-agent --experimental-agents`
53
+ (run from the sandbox root; verify `pwd` first).
54
+ 2. Open the installed agent for the domain under test (or start from the
55
+ MIE UI Design Agent to also score routing).
56
+ 3. Ask a sample of questions from the file — a stratified sample of 3–5 per
57
+ domain is a meaningful smoke; the full set is for release-gating runs.
58
+ 4. Score each answer PASS / PARTIAL / FAIL against **Expect**:
59
+ - PASS — all key points present, no corpus contradictions.
60
+ - PARTIAL — correct direction but a key point missing.
61
+ - FAIL — wrong, invented, or missing answer; misrouted.
62
+ 5. File every PARTIAL/FAIL as a corpus fix: if the knowledge exists but the
63
+ agent missed it, fix the agent/skill prompt; if the knowledge is absent,
64
+ add it to `lessons/` (and regenerate skills with `pnpm agent:skills` when
65
+ the fix lands in generated inputs).
66
+
67
+ ## Maintaining the sets
68
+
69
+ - Add entries when a real consumer question or issue exposes a gap — cite the
70
+ issue number in **Source**.
71
+ - Update entries when the corpus changes (component retirements, new rules);
72
+ stale Expect text is worse than no entry.
73
+ - Keep answers grounded: every Expect point must be verifiable in the cited
74
+ source. Do not write aspirational answers.
@@ -0,0 +1,183 @@
1
+ # Evals — Accessibility
2
+
3
+ Primary agent: **MIE UI A11y Agent**. See [README.md](./README.md) for format
4
+ and scoring.
5
+
6
+ ### A11Y-1 — Icon-only button name
7
+
8
+ - **Ask:** "Is `aria-label` enough for an icon-only button, or do I need
9
+ visible text?"
10
+ - **Expect:** `aria-label` is sufficient but must be descriptive
11
+ (`aria-label="Save"`, never "icon"/"button"); icon-only controls always
12
+ need one; decorative icons get `aria-hidden="true"`.
13
+ - **Agent:** MIE UI A11y Agent
14
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — Audit (1); mieweb-ui.instructions.md — Rule 2
15
+
16
+ ### A11Y-2 — Drag-and-drop keyboard support
17
+
18
+ - **Ask:** "My list reorders by drag-and-drop. Do I need keyboard support?"
19
+ - **Expect:** Yes — `useDragReorder` with at least one keyboard path:
20
+ `keyboard: true` + `rowProps(id)` spread on rows (Alt+↑/↓) and/or visible
21
+ `moveButtonProps` buttons (either alone is supported). Also render the
22
+ hook's `announcement` in a polite `sr-only` live region so reorders are
23
+ announced.
24
+ - **Agent:** MIE UI A11y Agent
25
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — Audit (2), toolkit; src/hooks/useDragReorder.ts
26
+
27
+ ### A11Y-3 — Modal focus restore
28
+
29
+ - **Ask:** "Modal traps focus and closes on Escape. Anything else?"
30
+ - **Expect:** Return focus to the trigger on close — the focus trap doesn't
31
+ restore focus itself; track the trigger ref and focus it in `onOpenChange`
32
+ when the next-open value is `false` (Modal has no `onClose` prop).
33
+ - **Agent:** MIE UI A11y Agent
34
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — Audit (3), toolkit; src/components/Modal — `ModalProps`
35
+
36
+ ### A11Y-4 — Announcement chattiness
37
+
38
+ - **Ask:** "Should a live region announce the item count on every keystroke?"
39
+ - **Expect:** No — announce meaningful changes only; debounce or scope to
40
+ commits (e.g. reorders). `role="status"`/`aria-live="polite"` for passive
41
+ updates, `role="alert"` for errors.
42
+ - **Agent:** MIE UI A11y Agent
43
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — Audit (4)
44
+
45
+ ### A11Y-5 — White on primary-500
46
+
47
+ - **Ask:** "Does white text on `bg-primary-500` (BlueHive) pass AA?"
48
+ - **Expect:** No — 2.65:1, and it still fails at primary-700. Use
49
+ `<Button variant="primary">` (AA-safe shade internally); never hardcode
50
+ colors for button-like elements.
51
+ - **Agent:** MIE UI A11y Agent
52
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — Known AA contrast traps
53
+
54
+ ### A11Y-6 — Interactive element checklist
55
+
56
+ - **Ask:** "What makes an interactive element accessible here?"
57
+ - **Expect:** Accessible name (visible text, `aria-label`, or
58
+ `aria-labelledby`), semantic HTML (no clickable divs), announced dynamic
59
+ updates (Toast/Alert), logical tab order, focus indicators never removed.
60
+ - **Agent:** MIE UI A11y Agent
61
+ - **Source:** mieweb-ui.instructions.md — Rule 9
62
+
63
+ ### A11Y-7 — Muted text trap
64
+
65
+ - **Ask:** "Is `text-neutral-500` on `bg-neutral-100` OK for small text?"
66
+ - **Expect:** No — 4.34:1 fails AA for small text; use `text-neutral-600`. In
67
+ dark mode pair `dark:text-neutral-400` with a dark surface like
68
+ `dark:bg-neutral-800`; verify per brand.
69
+ - **Agent:** MIE UI A11y Agent
70
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — Known AA contrast traps
71
+
72
+ ### A11Y-8 — Live announcements
73
+
74
+ - **Ask:** "How do I announce a state change to screen readers?"
75
+ - **Expect:** `const [announcement, announce] = useLiveAnnouncement()` and
76
+ render `<div aria-live="polite" className="sr-only">{announcement}</div>`;
77
+ call `announce()` on meaningful changes.
78
+ - **Agent:** MIE UI A11y Agent
79
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — toolkit
80
+
81
+ ### A11Y-9 — Loading states
82
+
83
+ - **Ask:** "Custom CSS spinner for loading, or a component?"
84
+ - **Expect:** Library components only: `Spinner` (inline), `Skeleton`
85
+ (placeholder), `LoadingPage` (full page). Never hand-roll.
86
+ - **Agent:** MIE UI A11y Agent
87
+ - **Source:** mieweb-ui.instructions.md — Rule 8
88
+
89
+ ### A11Y-10 — Clickable div
90
+
91
+ - **Ask:** "My clickable div lacks `role=\"button\"` and `tabIndex`. Add
92
+ them?"
93
+ - **Expect:** No — replace it with `Button` (or the right semantic
94
+ component); don't bolt ARIA onto divs when a real component exists.
95
+ - **Agent:** MIE UI A11y Agent
96
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — Audit (2)
97
+
98
+ ### A11Y-11 — Hidden file input
99
+
100
+ - **Ask:** "A hidden `<input type=\"file\">` sits behind a styled drop zone.
101
+ Keyboard story?"
102
+ - **Expect:** It must stay keyboard-openable — wire keyboard handlers that
103
+ trigger the input's `click()`, or use `DropzoneOverlay`/`FileManager`.
104
+ - **Agent:** MIE UI A11y Agent
105
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — Audit (2)
106
+
107
+ ### A11Y-12 — Scrollable region
108
+
109
+ - **Ask:** "How do I make an overflow container keyboard-accessible?"
110
+ - **Expect:** `tabIndex={0}` + `role="region"` + `aria-label`, and it must be
111
+ the single scroll container (no nested scrolling children).
112
+ - **Agent:** MIE UI A11y Agent
113
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — toolkit
114
+
115
+ ### A11Y-13 — Dark-mode hover contrast
116
+
117
+ - **Ask:** "Tab hover states look fine in light mode — do I need to check
118
+ dark mode separately?"
119
+ - **Expect:** Yes — hover/active states must pass AA in **both** themes;
120
+ dark-mode hover shades have regressed before (Tabs, outline Button). Use
121
+ token pairs from the a11y checklist and verify per theme.
122
+ - **Agent:** MIE UI A11y Agent
123
+ - **Source:** issues #512, #511; agent/skills/mieweb-ui-a11y-checklist/SKILL.md — contrast traps
124
+
125
+ ### A11Y-14 — Toasts and dynamic updates
126
+
127
+ - **Ask:** "Do async save results need announcing?"
128
+ - **Expect:** Yes — dynamic updates are announced via `Toast`/`Alert` (which
129
+ carry live-region semantics), not silent inline text swaps.
130
+ - **Agent:** MIE UI A11y Agent
131
+ - **Source:** mieweb-ui.instructions.md — Rule 9
132
+
133
+ ### A11Y-15 — Focus indicators
134
+
135
+ - **Ask:** "Can I remove the focus ring? The designer finds it ugly."
136
+ - **Expect:** No — focus indicators are never removed; restyle via tokens if
137
+ needed, keep them visible (including in dark mode).
138
+ - **Agent:** MIE UI A11y Agent
139
+ - **Source:** mieweb-ui.instructions.md — Rule 9
140
+
141
+ ### A11Y-16 — Semantic landmarks
142
+
143
+ - **Ask:** "Is a div-based layout fine if the CSS is right?"
144
+ - **Expect:** No — use semantic HTML (`nav`, `main`, `button`, …); screen
145
+ readers navigate by landmarks and roles, not by class names.
146
+ - **Agent:** MIE UI A11y Agent
147
+ - **Source:** mieweb-ui.instructions.md — Rule 9
148
+
149
+ ### A11Y-17 — Exit animations
150
+
151
+ - **Ask:** "During an exit animation, the screen reader still reads the
152
+ leaving element. Is that expected?"
153
+ - **Expect:** It happens today but isn't acceptable — exiting children must be
154
+ `aria-hidden` and `inert` for the duration. `AnimatedPresence` does **not**
155
+ yet do this automatically (open #474); hand-rolled exits must handle it
156
+ themselves.
157
+ - **Agent:** MIE UI A11y Agent
158
+ - **Source:** issue #474 (open); agent/skills/mieweb-ui-a11y-checklist/SKILL.md — exit animations
159
+
160
+ ### A11Y-18 — Icon-only Button pattern
161
+
162
+ - **Ask:** "What's the canonical icon-only button?"
163
+ - **Expect:** `<Button size="icon" aria-label="...">` — the `aria-label` is
164
+ required, not optional.
165
+ - **Agent:** MIE UI A11y Agent
166
+ - **Source:** mieweb-ui.instructions.md — Rule 2
167
+
168
+ ### A11Y-19 — Tab order
169
+
170
+ - **Ask:** "Does visual order vs DOM order matter for keyboard users?"
171
+ - **Expect:** Yes — tab order must be logical; don't reorder purely with CSS
172
+ so that focus jumps around, and don't use positive `tabIndex` to patch it.
173
+ - **Agent:** MIE UI A11y Agent
174
+ - **Source:** mieweb-ui.instructions.md — Rule 9
175
+
176
+ ### A11Y-20 — Verifying contrast per brand
177
+
178
+ - **Ask:** "Contrast passes on the default palette. Done?"
179
+ - **Expect:** No — brands redefine the primary scale, so brand-dependent
180
+ pairs must be re-verified per brand (the checklist's traps are stated for
181
+ the default palette/BlueHive).
182
+ - **Agent:** MIE UI A11y Agent
183
+ - **Source:** agent/skills/mieweb-ui-a11y-checklist/SKILL.md — Known AA contrast traps
@@ -0,0 +1,185 @@
1
+ # Evals — Internationalization / RTL
2
+
3
+ Primary agent: **MIE UI i18n Agent**. See [README.md](./README.md) for format
4
+ and scoring.
5
+
6
+ ### I18N-1 — Hardcoded strings
7
+
8
+ - **Ask:** "I wrote `<Button>Save</Button>`. Is that OK?"
9
+ - **Expect:** No — every user-facing string goes through `t()`:
10
+ `<Button>{t('common.save')}</Button>`. Includes aria-labels, placeholders,
11
+ and error messages.
12
+ - **Agent:** MIE UI i18n Agent
13
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Audit (1)
14
+
15
+ ### I18N-2 — Missing keys ship silently
16
+
17
+ - **Ask:** "I added a locale bundle but missed some keys. Will anything
18
+ break visibly?"
19
+ - **Expect:** No — missing keys silently fall back to `fallbackLng`, so they
20
+ ship invisibly. Every bundle must cover every logical key of the canonical
21
+ bundle in the same commit.
22
+ - **Agent:** MIE UI i18n Agent
23
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Audit (2)
24
+
25
+ ### I18N-3 — Auditing locale completeness
26
+
27
+ - **Ask:** "How do I check a locale bundle is complete?"
28
+ - **Expect:** Diff logical keys against the canonical bundle, stripping
29
+ plural suffixes (`_one`, `_other`, …) but preserving context suffixes
30
+ (`invite_admin` vs `invite_guest` stay distinct) — then separately verify
31
+ each pluralized key carries all plural forms that locale's CLDR rules
32
+ require (e.g. Arabic needs more than `_one`/`_other`).
33
+ - **Agent:** MIE UI i18n Agent
34
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Audit (2)
35
+
36
+ ### I18N-4 — Hardcoded locale in formatting
37
+
38
+ - **Ask:** "Is `date.toLocaleDateString('en-US', …)` fine?"
39
+ - **Expect:** No — that pins every user to en-US. Call it without a hardcoded
40
+ tag, using the active language via `useLocale()` (where `LocaleProvider` is
41
+ in scope) or `i18n.language`.
42
+ - **Agent:** MIE UI i18n Agent
43
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Audit (3)
44
+
45
+ ### I18N-5 — String concatenation
46
+
47
+ - **Ask:** "Can I build messages like `t('greeting') + name` or
48
+ `` `${t('count')} items` ``?"
49
+ - **Expect:** No — concatenation breaks word order across languages. Use
50
+ interpolation: `t('greeting', { name })`; `t('items', { count })` for
51
+ plurals.
52
+ - **Agent:** MIE UI i18n Agent
53
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Audit (3)
54
+
55
+ ### I18N-6 — Plurals
56
+
57
+ - **Ask:** "How do I translate '3 items' vs '1 item'?"
58
+ - **Expect:** One logical key with `count` interpolation; bundles carry CLDR
59
+ plural forms (`_one`, `_other`, …) — never an in-code
60
+ `count === 1 ? … : …` branch.
61
+ - **Agent:** MIE UI i18n Agent
62
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Audit (2), (3)
63
+
64
+ ### I18N-7 — Physical margin classes
65
+
66
+ - **Ask:** "Does `className=\"ml-4\"` work in RTL?"
67
+ - **Expect:** No — use logical classes: `ms-4`, `ps-*`, `start-*`,
68
+ `text-start`; never `ml-*`, `pl-*`, `left-*`, `right-*`, `text-left`.
69
+ - **Agent:** MIE UI i18n Agent
70
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — RTL checklist; mieweb-ui.instructions.md — Rule 10
71
+
72
+ ### I18N-8 — Flipping icons
73
+
74
+ - **Ask:** "Do chevrons flip automatically in RTL?"
75
+ - **Expect:** No — add `rtl:-scale-x-100` to directional chevrons/arrows; do
76
+ NOT flip decorative icons (checkmarks, media controls, up/down arrows).
77
+ - **Agent:** MIE UI i18n Agent
78
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — RTL checklist
79
+
80
+ ### I18N-9 — Arrow-key direction
81
+
82
+ - **Ask:** "My keyboard handler uses ArrowLeft/ArrowRight. RTL concern?"
83
+ - **Expect:** Yes — arrow keys follow **visual** direction: check
84
+ `isRtl(event.currentTarget)` in the handler and swap the semantics.
85
+ - **Agent:** MIE UI i18n Agent
86
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — RTL checklist
87
+
88
+ ### I18N-10 — isRtl vs useDirection
89
+
90
+ - **Ask:** "When `isRtl()` vs `useDirection(ref)`?"
91
+ - **Expect:** `isRtl()` is a one-shot snapshot for event handlers;
92
+ `useDirection(ref)` is reactive, for when direction drives rendering. Never
93
+ store an `isRtl` result across renders — it stales.
94
+ - **Agent:** MIE UI i18n Agent
95
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — direction toolkit
96
+
97
+ ### I18N-11 — Portals and direction
98
+
99
+ - **Ask:** "How does a portaled Tooltip know the direction?"
100
+ - **Expect:** Portals escape local `dir` overrides — read direction from a
101
+ non-portaled ref via `useDirection(ref)`, not from the portaled node.
102
+ - **Agent:** MIE UI i18n Agent
103
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — RTL checklist
104
+
105
+ ### I18N-12 — Hardcoded BCP-47 tags
106
+
107
+ - **Ask:** "Can I pass `'en-US'` to `Intl.NumberFormat`?"
108
+ - **Expect:** No — drive Intl APIs from the active language, never hardcoded
109
+ tags.
110
+ - **Agent:** MIE UI i18n Agent
111
+ - **Source:** mieweb-ui.instructions.md — Rule 10
112
+
113
+ ### I18N-13 — Manual currency formatting
114
+
115
+ - **Ask:** "Is `'$' + amount.toFixed(2)` acceptable?"
116
+ - **Expect:** No — use `Intl.NumberFormat` with
117
+ `{ style: 'currency', currency }` under the active locale; manual string
118
+ formatting breaks symbols, separators, and placement.
119
+ - **Agent:** MIE UI i18n Agent
120
+ - **Source:** mieweb-ui.instructions.md — Rule 10; agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Audit (3)
121
+
122
+ ### I18N-14 — Adding a locale
123
+
124
+ - **Ask:** "What's the full procedure to add a new locale?"
125
+ - **Expect:** Add `<locale>.json` beside existing bundles covering every
126
+ logical key with that locale's CLDR plural forms; register in i18next
127
+ `resources`; expose in the language selector; on change call
128
+ `i18n.changeLanguage(code)` and set `dir` via `isRtlLocale()`; verify Intl
129
+ output.
130
+ - **Agent:** MIE UI i18n Agent
131
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Adding a locale
132
+
133
+ ### I18N-15 — Physical inline styles
134
+
135
+ - **Ask:** "My inline styles use `marginLeft` and `textAlign: 'left'`. Caught
136
+ by the class greps?"
137
+ - **Expect:** No — inline physical styles evade class greps and silently
138
+ break RTL. Use `marginInlineStart`, `insetInlineStart`,
139
+ `textAlign: 'start'`.
140
+ - **Agent:** MIE UI i18n Agent
141
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — RTL checklist
142
+
143
+ ### I18N-16 — Key naming
144
+
145
+ - **Ask:** "Can I use the English text as the translation key?"
146
+ - **Expect:** Use logical keys (`common.save`), not English sentences —
147
+ bundles are keyed by meaning, and plural/context suffixes attach to logical
148
+ keys.
149
+ - **Agent:** MIE UI i18n Agent
150
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Audit (1), (2)
151
+
152
+ ### I18N-17 — Non-visible strings
153
+
154
+ - **Ask:** "Do aria-labels, placeholders, and toast messages need `t()` too?"
155
+ - **Expect:** Yes — every user-facing string, including assistive-tech-only
156
+ text, placeholders, and error/notification messages.
157
+ - **Agent:** MIE UI i18n Agent
158
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Audit (1)
159
+
160
+ ### I18N-18 — Setting dir on language change
161
+
162
+ - **Ask:** "The user switches to Arabic. What besides `changeLanguage`?"
163
+ - **Expect:** Set the document `dir` on every language change via
164
+ `isRtlLocale()` — translations without `dir` leave the layout LTR.
165
+ - **Agent:** MIE UI i18n Agent
166
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — Adding a locale
167
+
168
+ ### I18N-19 — RTL audit mechanics
169
+
170
+ - **Ask:** "How do I audit a codebase for RTL violations?"
171
+ - **Expect:** Grep for physical classes (`ml-`, `mr-`, `pl-`, `pr-`,
172
+ `left-`, `right-`, `text-left`, `text-right`) **and** check what greps
173
+ miss: inline physical styles, dynamic/conditional class strings, and
174
+ directional keyboard handlers.
175
+ - **Agent:** MIE UI i18n Agent
176
+ - **Source:** agent/skills/mieweb-ui-i18n-checklist/SKILL.md — RTL checklist
177
+
178
+ ### I18N-20 — Scope of Rule 10
179
+
180
+ - **Ask:** "What does the i18n rule actually require?"
181
+ - **Expect:** All user-facing text externalized through `t()`; dates,
182
+ numbers, and currency via Intl under the active language; logical CSS
183
+ properties/classes for RTL; no hardcoded locale tags.
184
+ - **Agent:** MIE UI i18n Agent
185
+ - **Source:** mieweb-ui.instructions.md — Rule 10