Repository navigation
spec(native): a container label does not merge its children; targets measure in their environment - #8135
spec(native): a container label does not merge its children; targets measure in their environment#8135imdreamrunner wants to merge 2 commits into
Conversation
…measure in their environment X5 states the outcome, one element per thing a person reads, without the mechanism that produces it. A text child inside a labelled ancestor keeps its own element and publishes the ancestor's label instead of its own words, so the same name is reachable twice and the child's words are never read. X5 now says a component that reads as one thing merges its children explicitly, and the acceptance checks assert it rather than leaving it to the audit. A control's rendered size follows the environment its ancestor establishes, so X7 measures a hit target in the environment the component ships in, at the largest text size.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
PR Analysis Report
No new or modified components detected. Bundle Size SummaryNo component packages changed. Accessibility AuditStatus: No accessibility violations detected. Visual Regression46 of 496 shot(s) changed. A change here is a question, not a failure: check whether the after is the
and 26 more. Generated by PR Enrichment workflow | View full report |
There was a problem hiding this comment.
Approval waits on an engineering owner deciding the two draft requirements this pull request rewrites in the Swift accessibility contract: X5's explicit-merge rule with its new acceptance row, and X7's measuring condition with its amended row. An engineering owner records that decision by commenting /approve-spec <full head SHA> on the pull request, and the author may do so if they are an engineering owner. Separately from that decision, two wording fixes are needed, and because a new commit resets approval, making them first lets the decision land on the final head:
- X7 and its acceptance row measure the 44-point target only at the largest text size, where text-scaled controls are biggest, so a target under 44 points at the default size can pass; measure at the default and the largest text sizes.
- X5 names
accessibilityElement(children: .combine)and.ignorewith a label as the only ways to merge, which excludes equivalents such as X1's ownaccessibilityRepresentation; present them as examples, or add "or any equivalent that exposes one element named with its own words".
[Automated review]
| smaller. A control's rendered size follows the environment its ancestor | ||
| establishes, so a target is measured in the environment the component ships | ||
| in, at the largest text size, and not in isolation. |
There was a problem hiding this comment.
This measures the 44-point target only at the largest text size, which is where text-scaled controls are biggest, so a control under 44 points at the default size in its shipping environment can pass (the fixture in the description measured a 34-point-tall control). Consider "measured in the environment the component ships in, at the default and the largest text sizes, and not in isolation", with the same wording in the X7 acceptance row.
| read. A component that reads as one thing merges its children explicitly, | ||
| with `accessibilityElement(children: .combine)` or with `.ignore` and a label | ||
| of its own, rather than resting on a container label. Every action reachable |
There was a problem hiding this comment.
As worded, these two modifiers read as the only permitted ways to merge, though the description says any equivalent satisfies the requirement, and X1 itself requires accessibilityRepresentation, which yields one element through neither. Consider "for example with accessibilityElement(children: .combine) or with .ignore and a label of its own, or with any equivalent that exposes one element named with its own words".
… examples X7 and its acceptance row measure the 44-point target at the default and the largest text sizes, not only the largest, where text-scaled controls are biggest. X5 gives the merge modifiers as examples and admits any equivalent that exposes one element named with the component's own words.
|
Both wording fixes from the review are in
One file changed, |
There was a problem hiding this comment.
Incremental review of 04bc7e5..1e7066d; prior findings carried: spec_authority, context, user_impact, mechanism, evidence_by_spec_claim, disposition
Both wording fixes are in: X7 and its acceptance row now measure the 44-point target at the default and the largest text sizes, and X5 gives its merge modifiers as examples beside any equivalent. Approval now waits only on an engineering owner deciding the two draft requirements this pull request rewrites, X5's explicit-merge rule with its new acceptance row and X7's measuring condition with its amended row, because no current spec states either. An engineering owner records that decision by commenting /approve-spec <full head SHA> on the pull request, and the author may do so if they are an engineering owner. Open pull requests #8288 and #8500 convert this same file into packages/native/specs/swift/accessibility.spec.md with the earlier X5 and X7 wording, so whichever lands second needs to carry the approved text.
[Automated review]
Exact decision needed
Two claims in the Swift accessibility draft,
packages/native/specs/swift/library/accessibility.md:Existing authority searched
packages/native/specs/swift/library/accessibility.md, X5 and X7: the draft that owns both claims and the only place either is stated.docs/specs/AST-093-native-component-guidelines/spec.mdFR3 (hit targets, Dynamic Type and VoiceOver follow the Apple Human Interface Guidelines) and FR5 (accessibility assertions for label, traits and value, plus a check at the largest Dynamic Type size). Both name the outcome and leave the mechanism and the measuring environment to this library spec.docs/specs/AST-082-native-first-surfaces/spec.md: owns the core contract's accessibility semantics and their per-platform mapping; it carries no element-merging or hit-target claim.docs/specs/AST-009/spec.md(core accessibility): no element-merging or minimum-target claim.packages/native/specs/swift/library/(styles, component API, slots) and the AST-093 spec-location change: none of them touchesaccessibility.md.No current claim settles either point, so X5 and X7 keep them.
Decision
X5 states its mechanism. A label on a container does not merge what the container holds: a text child inside a labelled ancestor keeps its own accessibility element and its static-text role, and that element publishes the ancestor's label in place of the child's own words — so the same name is reachable twice and the words the child draws are never read. A component that reads as one thing merges its children explicitly rather than resting on a container label:
accessibilityElement(children: .combine),.ignorewith a label of its own, andaccessibilityRepresentationeach do this, as does any equivalent that exposes one element named with the component's own words.X7 states its environment. A control's rendered size follows the environment its ancestor establishes, so a target is measured in the environment the component ships in, at the default and the largest text sizes, and not in isolation. The largest size alone is where text-scaled controls are biggest, so a control under 44 points at the default size would pass it.
The acceptance checks gain a row for X5 — a text child inside a labelled container, exactly one element, reachable once, named with the words the component reads as — and the X7 row names the environment and both text sizes.
performAccessibilityAudit()remains the screen-level check shared by X4 and X5; whether it reports a duplicate name is not tested here, so the new row says only that the audit does not establish the claim on its own and that the test asserts it.Rejected alternatives
Resting on a container label to make a component read as one thing. It stays as one clause inside X5 rather than a separate note, because it is the implementation the requirement's old wording invited.
Claim scope and non-goals
performAccessibilityAudit()flags a duplicate name is untested and unclaimed.Evidence and implementation relationship
This is a specification clarification, not a code change. No Swift view exists for it to govern yet, which the record's
Current statesection already says.Measured on a SwiftUI fixture on a simulator:
Writing rubric results
proposes,we decided,previously,a port ofandused toreturned nothing.#followed by digits,/pull/and/issues/.Scope
Validation
pnpm check:knowledge— pass: "Knowledge templates and records are aligned."pnpm check:repo— pass.git diff --check— clean.pnpm vitest run --project node packages/native— 6 files, 34 tests, all pass.swift build/swift test, and no captures. This change touches no Swift source and adds no view to capture.