Comments, phase 3 — search, the thread find, announcements, and a11y
Board search reaches comment bodies through a search-owned transient
index: the first live-query keystroke sweeps comments/*/index.md
off-actor (.draft and comments/.trash excluded), keystrokes re-filter
in memory, the index discards on clear — the snapshot stays O(cards).
⌘F routes by focus: the comments pane gets an app-owned find bar
spanning the whole rendered thread (next/prev cross rows with
wraparound); body and composer keep NSTextFinder; Find Next/Previous
graduate from FutureCommands. Foreign comment changes speak
path-shaped beside the announcer's ladder ("New comment on 'X'",
plural folds), narrowed by EchoLedger receipts consumed through
CommentPath.classify — and that read fixed a latent footprint bug
where a comment receipt resolved against the card's attachment
listing, read .absent, and classified the user's own write as
foreign. The pane completes its a11y story: flattened comment
elements with Edit/Delete/Reveal custom actions (un-flattening
during inline edit), phrase-table vocabulary, labeled composer and
sort control, and an audit over the open pane on a comment-seeded
fixture (runnable only where automation permission exists).
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -88,7 +88,11 @@ struct CommentAuthoringSurface<Actions: View>: View {
|
||||
onCommandReturn: onCommandReturn,
|
||||
onEscape: onEscape,
|
||||
onBlur: onBlur,
|
||||
focusRequest: focusRequest
|
||||
focusRequest: focusRequest,
|
||||
// Both authoring surfaces report themselves to the pane's focus register, which is
|
||||
// what routes ⌘F here to the editor's own find bar rather than to the thread's
|
||||
// (05 ▸ Preview; `CardWindowFind.route`).
|
||||
focus: comments
|
||||
)
|
||||
.frame(height: height)
|
||||
|
||||
@@ -124,7 +128,7 @@ struct CommentAuthoringSurface<Actions: View>: View {
|
||||
.buttonStyle(.plain)
|
||||
.disabled(!comments.isEditable)
|
||||
.help("Attach Files…")
|
||||
.accessibilityLabel("Attach Files")
|
||||
.accessibilityLabel(AccessibilityPhrases.commentAttachFilesLabel)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +187,10 @@ struct CommentComposerView: View {
|
||||
.controlSize(.small)
|
||||
.disabled(!comments.isEditable || !session.canPost)
|
||||
}
|
||||
.accessibilityLabel("Add a comment")
|
||||
// "The composer is a labeled text field (⌘↩ posts)" — 10-accessibility.md ▸ Comments. The
|
||||
// label is the placeholder's own sentence, so what a sighted user reads in the empty editor
|
||||
// and what VoiceOver announces are the same invitation.
|
||||
.accessibilityLabel(AccessibilityPhrases.commentComposerLabel)
|
||||
}
|
||||
|
||||
/// Post, then re-read: the rename moved a folder into the thread, and the pane shows the thread.
|
||||
|
||||
Reference in New Issue
Block a user