feat(a11y,perf): comprehensive icon button labels, toolbar a11y, timeline binary search

A11y C-1: aria-label on 30+ remaining icon-only buttons across:
  - settings panels (close, reset, info, expand, remove, undo)
  - editor toolbar (bold, italic, underline, strike, code, spoiler,
    blockquote, code block, ordered/unordered list, headings 1-3)
  - auth stages (cancel buttons in SSO, Password stages)
  - device verification (cancel buttons)
  - password input (show/hide toggle with dynamic label)
  - event readers, account data editor close buttons
  - global emoji packs (add/remove buttons)
Perf-5: Replace O(N×T) getTimelineAndBaseIndex scan with precomputed binary
  search (timelineSegments useMemo) — O(log T) per visible message render

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lotus Bot
2026-05-20 21:54:33 -04:00
parent d4705f9235
commit 4e80c0a0f5
23 changed files with 89 additions and 30 deletions
+39 -13
View File
@@ -54,8 +54,8 @@ function BtnTooltip({ text, shortCode }: { text: string; shortCode?: string }) {
);
}
type MarkButtonProps = { format: MarkType; icon: IconSrc; tooltip: ReactNode };
export function MarkButton({ format, icon, tooltip }: MarkButtonProps) {
type MarkButtonProps = { format: MarkType; icon: IconSrc; tooltip: ReactNode; label?: string };
export function MarkButton({ format, icon, tooltip, label }: MarkButtonProps) {
const editor = useSlate();
const disableInline = isBlockActive(editor, BlockType.CodeBlock);
@@ -76,6 +76,7 @@ export function MarkButton({ format, icon, tooltip }: MarkButtonProps) {
variant="SurfaceVariant"
onClick={handleClick}
aria-pressed={isMarkActive(editor, format)}
aria-label={label}
size="400"
radii="300"
disabled={disableInline}
@@ -91,8 +92,9 @@ type BlockButtonProps = {
format: BlockType;
icon: IconSrc;
tooltip: ReactNode;
label?: string;
};
export function BlockButton({ format, icon, tooltip }: BlockButtonProps) {
export function BlockButton({ format, icon, tooltip, label }: BlockButtonProps) {
const editor = useSlate();
const handleClick = () => {
@@ -108,6 +110,7 @@ export function BlockButton({ format, icon, tooltip }: BlockButtonProps) {
variant="SurfaceVariant"
onClick={handleClick}
aria-pressed={isBlockActive(editor, format)}
aria-label={label}
size="400"
radii="300"
>
@@ -165,6 +168,7 @@ export function HeadingBlockButton() {
<IconButton
ref={triggerRef}
onClick={() => handleMenuSelect(1)}
aria-label="Heading 1"
size="400"
radii="300"
>
@@ -180,6 +184,7 @@ export function HeadingBlockButton() {
<IconButton
ref={triggerRef}
onClick={() => handleMenuSelect(2)}
aria-label="Heading 2"
size="400"
radii="300"
>
@@ -195,6 +200,7 @@ export function HeadingBlockButton() {
<IconButton
ref={triggerRef}
onClick={() => handleMenuSelect(3)}
aria-label="Heading 3"
size="400"
radii="300"
>
@@ -271,32 +277,44 @@ export function Toolbar() {
<MarkButton
format={MarkType.Bold}
icon={Icons.Bold}
tooltip={<BtnTooltip text="Bold" shortCode={`${modKey} + B`} />}
tooltip={<BtnTooltip text="Bold" shortCode={`${modKey} + B`}
label="Bold"
/>}
/>
<MarkButton
format={MarkType.Italic}
icon={Icons.Italic}
tooltip={<BtnTooltip text="Italic" shortCode={`${modKey} + I`} />}
tooltip={<BtnTooltip text="Italic" shortCode={`${modKey} + I`}
label="Italic"
/>}
/>
<MarkButton
format={MarkType.Underline}
icon={Icons.Underline}
tooltip={<BtnTooltip text="Underline" shortCode={`${modKey} + U`} />}
tooltip={<BtnTooltip text="Underline" shortCode={`${modKey} + U`}
label="Underline"
/>}
/>
<MarkButton
format={MarkType.StrikeThrough}
icon={Icons.Strike}
tooltip={<BtnTooltip text="Strike Through" shortCode={`${modKey} + S`} />}
tooltip={<BtnTooltip text="Strike Through" shortCode={`${modKey} + S`}
label="Strikethrough"
/>}
/>
<MarkButton
format={MarkType.Code}
icon={Icons.Code}
tooltip={<BtnTooltip text="Inline Code" shortCode={`${modKey} + [`} />}
tooltip={<BtnTooltip text="Inline Code" shortCode={`${modKey} + [`}
label="Inline code"
/>}
/>
<MarkButton
format={MarkType.Spoiler}
icon={Icons.EyeBlind}
tooltip={<BtnTooltip text="Spoiler" shortCode={`${modKey} + H`} />}
tooltip={<BtnTooltip text="Spoiler" shortCode={`${modKey} + H`}
label="Spoiler"
/>}
/>
</Box>
<Line variant="SurfaceVariant" direction="Vertical" style={{ height: toRem(12) }} />
@@ -305,22 +323,30 @@ export function Toolbar() {
<BlockButton
format={BlockType.BlockQuote}
icon={Icons.BlockQuote}
tooltip={<BtnTooltip text="Block Quote" shortCode={`${modKey} + '`} />}
tooltip={<BtnTooltip text="Block Quote" shortCode={`${modKey} + '`}
label="Block quote"
/>}
/>
<BlockButton
format={BlockType.CodeBlock}
icon={Icons.BlockCode}
tooltip={<BtnTooltip text="Block Code" shortCode={`${modKey} + ;`} />}
tooltip={<BtnTooltip text="Block Code" shortCode={`${modKey} + ;`}
label="Code block"
/>}
/>
<BlockButton
format={BlockType.OrderedList}
icon={Icons.OrderList}
tooltip={<BtnTooltip text="Ordered List" shortCode={`${modKey} + 7`} />}
tooltip={<BtnTooltip text="Ordered List" shortCode={`${modKey} + 7`}
label="Ordered list"
/>}
/>
<BlockButton
format={BlockType.UnorderedList}
icon={Icons.UnorderList}
tooltip={<BtnTooltip text="Unordered List" shortCode={`${modKey} + 8`} />}
tooltip={<BtnTooltip text="Unordered List" shortCode={`${modKey} + 8`}
label="Unordered list"
/>}
/>
<HeadingBlockButton />
</Box>