Repository navigation
Commit 9fbbb17
fix(components): RefreshIndicator requires its accessible name; four views pass a translated one (objectui#10580) (#10635)
Fixes #10580
Clause-②: yes
`RefreshIndicator`'s published `ariaLabel` prop loses its English
default ("Refreshing") and becomes required, so a caller that passes no
name is a type error instead of an English accessible name. This is the
"declaration enforces" option the triage allowed on this PR (triage
comment `5831898614`), taken by the seat's claim (`5832044126`). The
four views that passed no name now pass their translated one. It is the
objectui#3546 class: text a user meets that bypasses the translation
layer.
## What changes
- `packages/components/src/custom/refresh-indicator.tsx`: `ariaLabel:
string` is required, the `= "Refreshing"` default is gone, and the
docblock says why.
- `ObjectGrid` passes `t('grid.refreshing')` and `ListView` passes
`t('list.refreshing')`: the same keys, through the same hooks, that
their pull-to-refresh text already reads. No new grid or list key.
- `ObjectChart` passes `t('chart.refreshing')`. The `t` comes from the
`useObjectTranslation()` call the file already makes for `language`. It
is deliberately not the file's `tt` (`useSafeTranslate`), because `tt`
takes an English fallback string at every call, and the ruling is no
English fallback anywhere.
- `ObjectDataTable` passes `t('dashboard.refreshing')` from the
`useObjectTranslation()` call it already makes.
- `packages/i18n/src/locales/*.ts`: `chart.refreshing` in the `chart`
block and `dashboard.refreshing` at the `dashboard` block's top level,
each placed after that block's `loading` key, in all ten packs. Each
pack's value is the translation its own `grid.refreshing` already
carries.
- `.changeset/10580-refresh-indicator-translated-name.md`: `minor` for
`@object-ui/components`, with the break stated as BREAKING (this repo
marks its own breaking changes `minor`), and `patch` for `plugin-grid`,
`plugin-list`, `plugin-charts`, `plugin-dashboard` and `i18n`. The
changeset prose states the contract change, so a contract review is
owed.
## Caller census (H4)
`git grep -n 'RefreshIndicator'` over the whole tree, re-run on the
merged head `641ed9f`, finds five render sites. After this PR every one
passes a translated name: `ObjectGrid`, `ListView`, `ObjectChart`,
`ObjectDataTable`, and `ObjectGantt`, which already passed
`t('gantt.aria.refreshing')` and is unchanged. Before this PR no other
package, app, example, docs snippet or test rendered it.
`RefreshIndicatorProps` has no other code reader; its one other mention
is a docblock in `MetricWidget.tsx`. No docs page renders the component,
so `check:doc-snippets` and `check:doc-types` have nothing of it to read
and were not run. The sibling objectstack checkout has zero
`RefreshIndicator` hits. The merge of `origin/main` brought in no new
render site.
## H5
`ariaLabel=""` still type-checks, because the prop is a plain `string`.
As ruled, no runtime check was added: the type is the gate.
## Pins
| File | What it holds |
|---|---|
|
`packages/components/src/__tests__/refresh-indicator-required-name-10580.test.tsx`
| TYPE: `RefreshIndicator` with no `ariaLabel` sits under
`@ts-expect-error`, checked by the package's `tsc -p
tsconfig.test.json`. DOM: the bar is named with exactly the passed
string, and a caller that casts past the type gets no `aria-label` at
all, so there is no English fallback left. |
|
`packages/plugin-grid/src/__tests__/ObjectGrid.refreshIndicatorLocale-10580.test.tsx`
| `de`: the bar is named `Wird aktualisiert…` during a bus-driven
re-read. `en` control: `Refreshing…`. |
|
`packages/plugin-list/src/__tests__/ListView.refreshIndicatorLocale-10580.test.tsx`
| `zh`: `刷新中…` during a toolbar-refresh re-read. `en` control:
`Refreshing…`. |
|
`packages/plugin-charts/src/ObjectChart.refreshIndicatorLocale-10580.test.tsx`
| `zh`: `刷新中…` during a bus-driven re-read. `en` control: `Refreshing…`.
|
|
`packages/plugin-dashboard/src/__tests__/ObjectDataTable.refreshIndicatorLocale-10580.test.tsx`
| `ja`: `更新中…` during a filter-change re-read. `en` control:
`Refreshing…`. |
In every view pin the second query is held open by hand, so the bar is
read while the query really is in flight.
`ObjectGantt.refreshInPlace-7237.test.tsx` was run unchanged and stays
green.
## Reverse verification (each leg ran from a committed state, with trap
restore and restore proven by hash)
1. **Base leg.** The implementation files (the component, the four
callers, the ten packs) were checked out at BASE `adeecd6`, with the
pins taken from HEAD `7a1b619`. The 5 pin files then gave exit **1**,
`Tests 9 failed | 3 passed (12)`. The failure dump reads
`aria-label="Refreshing"` on the progress bar. On-disk proof of the
mutation: the default literal counted 1 and the grid caller's name
counted 0. After the restore (`git checkout HEAD --`), `git diff HEAD`
was 0 bytes and all 15 paths were hash-equal to their HEAD blobs. The
same 5 files at HEAD gave exit **0**, `Tests 12 passed (12)`.
2. **Type leg.** `ariaLabel?: string` was written back on disk (optional
count 1, required count 0). `tsc -p tsconfig.test.json` in
`packages/components` then gave exit **2**, `error TS2578: Unused
'@ts-expect-error' directive.` at the pin. After the restore it gave
exit **0**. `--listFiles` shows the pin file in that program (1 hit).
3. **Consumer leg** (proves the plugins read the rebuilt `dist/*.d.ts`,
whose `refresh-indicator.d.ts` declares `ariaLabel: string;`). With
`ObjectGrid`'s `ariaLabel` dropped on disk, `tsc --noEmit` in
`packages/plugin-grid` gave exit **2**, `TS2741: Property 'ariaLabel' is
missing in type '{ active: boolean; }' but required in type
'RefreshIndicatorProps'.` It was restored hash-equal.
## Gates
Pre-merge head `b240863`:
- `pnpm exec vitest run --maxWorkers=2 packages/plugin-grid/`: exit 0,
`157 passed (157)` files, `1489 passed` tests.
- `… packages/plugin-list/ packages/plugin-charts/`: exit 0, `172 passed
(172)`, `1982 passed`.
- `… packages/plugin-dashboard/ packages/i18n/`: exit 0, `201 passed
(201)`, `2424 passed`.
- `… packages/components/src/custom/` plus the components pin plus
`ObjectGantt.refreshInPlace-7237.test.tsx`: exit 0, `2 passed (2)`, `11
passed`. `src/custom/` holds no test file.
Merged head `641ed9f`, after the merge of `origin/main` `6516320`, which
moved all ten packs and `packages/components`:
- `pnpm exec vitest run --maxWorkers=2 packages/i18n/` plus the 5 pins
plus the gantt pin: exit 0, `77 passed (77)`, `1197 passed`.
- `pnpm turbo run type-check --filter @object-ui/components --filter
@object-ui/i18n --filter @object-ui/plugin-grid --filter
@object-ui/plugin-list --filter @object-ui/plugin-charts --filter
@object-ui/plugin-dashboard --filter @object-ui/plugin-gantt
--concurrency=2`: exit 0, `22 successful, 22 total`, with all 7
type-check tasks executed (cache miss).
- `pnpm check:i18n-keys`, `check:i18n-drift`, `check:i18n-dead-keys` (no
`refreshing` candidate), `check:control-bytes`, `check:test-path-roots`,
`check:vi-mock-specifiers`, `check:vi-mock-inherit`,
`check:vi-mock-override-shape`, `check:new-line-citations`,
`check:changeset-claims`, `check:pending-changeset-literals`,
`changeset:check`, `node scripts/check-changeset-presence.mjs`: all exit
0.
- `pnpm exec eslint` over the 20 changed `.ts`/`.tsx` files: exit 0, 0
errors.
**Lint, narrowed and declared.** The repo-wide `pnpm lint` was not run
locally; CI owns it. Evidence that the narrowing excludes nothing: (1)
`eslint.config.js` applies to `**/*.{ts,tsx}`, and every one of this
diff's 20 `.ts`/`.tsx` files is in that population; (2) `--format json`
reports 20 files linted, 0 errors; (3) the config has no
`parserOptions`, `projectService` or `project:` (0 hits) and no import
plugin (0 hits), so linting is not type-aware and this diff cannot move
the verdict of any file it does not touch.
- Round 2: the branch merged `origin/main` `4a3d500` as `1a89050` (merge
only; this PR's own diff is unchanged at 21 files, +543 / −8). There,
the `plugin-list` suite plus the five pins and the `ObjectGantt` 7237
pin (104 files, 1166 tests), and the seven type-checks, re-ran green.
The merge-queue eviction at 13:55Z was the objectui#10645 test, which is
not this PR's (os-dev-report round 2, comment `5834284916`).
- Round 3: merged `origin/main` `7baede3` (it carries PR objectui#10677,
the change for objectui#10645) at `a6512a7`, with no conflicts; the five
pins, the `ObjectGantt` 7237 pin and the seven type-checks re-ran green
there (os-dev-report round 3, comment `5836351479`).
## Acceptance notes
- **Hosts with no i18next instance.** A throwaway probe, not committed,
rendered `ObjectChart` with no `I18nProvider`: the bar is named
`chart.refreshing`, the key itself. `ObjectDataTable` reads its name the
same way (`useObjectTranslation().t`) and was not measured separately.
Grid, list and gantt still resolve English there through their own
`createSafeTranslation` defaults maps. This is what "no English
fallback" means at the two new call sites. The console mounts
`I18nProvider` in `apps/console/src/main.tsx`, so it does not reach the
console. The changeset says so.
- `RefreshIndicator` spreads `...props` after `aria-label`, so a
caller's own `aria-label` attribute still overrides `ariaLabel`. That
was true before this PR and is unchanged.
- The comment on the `chart` block in `en.ts` still describes the pack
as budgeted inside the `framework` chunk.
`scripts/check-eager-closure-budget.mjs` now gives the pack its own
`i18n-locale-en` ceiling. The comment has drifted and is not touched
here.
- In `de`, `grid.refreshing` reads `Wird aktualisiert…` while
`list.refreshing` reads `Aktualisiere…`. The two new keys use the
former. This is polish and is not touched here.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent d435e96 commit 9fbbb17
21 files changed
Lines changed: 543 additions & 8 deletions
File tree
- .changeset
- packages
- components/src
- __tests__
- custom
- i18n/src/locales
- plugin-charts/src
- plugin-dashboard/src
- __tests__
- plugin-grid/src
- __tests__
- plugin-list/src
- __tests__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
Lines changed: 59 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
39 | | - | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
40 | 46 | | |
41 | 47 | | |
42 | 48 | | |
| |||
50 | 56 | | |
51 | 57 | | |
52 | 58 | | |
53 | | - | |
| 59 | + | |
54 | 60 | | |
55 | 61 | | |
56 | 62 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1149 | 1149 | | |
1150 | 1150 | | |
1151 | 1151 | | |
| 1152 | + | |
1152 | 1153 | | |
1153 | 1154 | | |
1154 | 1155 | | |
| |||
1170 | 1171 | | |
1171 | 1172 | | |
1172 | 1173 | | |
| 1174 | + | |
1173 | 1175 | | |
1174 | 1176 | | |
1175 | 1177 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1129 | 1129 | | |
1130 | 1130 | | |
1131 | 1131 | | |
| 1132 | + | |
1132 | 1133 | | |
1133 | 1134 | | |
1134 | 1135 | | |
| |||
1150 | 1151 | | |
1151 | 1152 | | |
1152 | 1153 | | |
| 1154 | + | |
1153 | 1155 | | |
1154 | 1156 | | |
1155 | 1157 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1337 | 1337 | | |
1338 | 1338 | | |
1339 | 1339 | | |
| 1340 | + | |
1340 | 1341 | | |
1341 | 1342 | | |
1342 | 1343 | | |
| |||
1421 | 1422 | | |
1422 | 1423 | | |
1423 | 1424 | | |
| 1425 | + | |
1424 | 1426 | | |
1425 | 1427 | | |
1426 | 1428 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1133 | 1133 | | |
1134 | 1134 | | |
1135 | 1135 | | |
| 1136 | + | |
1136 | 1137 | | |
1137 | 1138 | | |
1138 | 1139 | | |
| |||
1154 | 1155 | | |
1155 | 1156 | | |
1156 | 1157 | | |
| 1158 | + | |
1157 | 1159 | | |
1158 | 1160 | | |
1159 | 1161 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1131 | 1131 | | |
1132 | 1132 | | |
1133 | 1133 | | |
| 1134 | + | |
1134 | 1135 | | |
1135 | 1136 | | |
1136 | 1137 | | |
| |||
1152 | 1153 | | |
1153 | 1154 | | |
1154 | 1155 | | |
| 1156 | + | |
1155 | 1157 | | |
1156 | 1158 | | |
1157 | 1159 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1129 | 1129 | | |
1130 | 1130 | | |
1131 | 1131 | | |
| 1132 | + | |
1132 | 1133 | | |
1133 | 1134 | | |
1134 | 1135 | | |
| |||
1150 | 1151 | | |
1151 | 1152 | | |
1152 | 1153 | | |
| 1154 | + | |
1153 | 1155 | | |
1154 | 1156 | | |
1155 | 1157 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1129 | 1129 | | |
1130 | 1130 | | |
1131 | 1131 | | |
| 1132 | + | |
1132 | 1133 | | |
1133 | 1134 | | |
1134 | 1135 | | |
| |||
1150 | 1151 | | |
1151 | 1152 | | |
1152 | 1153 | | |
| 1154 | + | |
1153 | 1155 | | |
1154 | 1156 | | |
1155 | 1157 | | |
| |||
0 commit comments