@mieweb/ui 0.11.0-dev.38 → 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/agents/mieweb-ui-design.agent.md +8 -7
- package/agent/agents/mieweb-ui-install.agent.md +7 -5
- package/agent/evals/README.md +74 -0
- package/agent/evals/a11y.md +183 -0
- package/agent/evals/i18n.md +185 -0
- package/agent/evals/install.md +200 -0
- package/agent/evals/migration.md +202 -0
- package/agent/evals/runs/2026-11-02.md +53 -0
- package/agent/evals/selection.md +212 -0
- package/agent/evals/styling.md +220 -0
- package/agent/skills/mieweb-ui-a11y-checklist/SKILL.md +2 -0
- package/agent/skills/mieweb-ui-tailwind4/SKILL.md +5 -2
- package/package.json +1 -1
|
@@ -52,13 +52,14 @@ comparison tables) and `mieweb-ui-icons` (icon aliases and conventions):
|
|
|
52
52
|
|
|
53
53
|
## Route to specialists
|
|
54
54
|
|
|
55
|
-
| Question is about…
|
|
56
|
-
|
|
|
57
|
-
| install / peer deps / preset / safelist / `@source`
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
|
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 |
|
|
62
63
|
|
|
63
64
|
More specialists (Grids, DataVis, Views,
|
|
64
65
|
SuperChat, Rich Text) land in later phases; until one ships, answer its domain
|
|
@@ -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`
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
the
|
|
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,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
|