ImageViewer toolbar optimizations (DES-130)
Version: 0.3.1 · Type: 🐛 Bug Fix
Problem
The ImageViewer bottom toolbar had three areas for improvement:
- Navigation still shown for a single image: With a single image (or an empty list), the previous / next buttons were still rendered and merely grayed out — a meaningless placeholder for the user.
- Wrong cursor on disabled icons: When disabled at a boundary, hovering the icon area still showed a
pointercursor instead ofnot-allowed. - Missing zoom accessibility: Zoom in / zoom out only had
aria-label; zoom-level changes were not perceivable to screen readers.
Root Cause (Problem 2)
The button text color disabled:text-(--Labels-Disabled) itself worked (correctly inherited by the icon via currentColor, so the color was fine); the cursor failure was because the injected icon SVG carries its own cursor-pointer (e.g. design-site IconSvg's ICON_BASE_CLASS), whose selector overrode the button's disabled:cursor-not-allowed. Verified in a real browser: .btn:disabled svg { cursor: not-allowed } (specificity 0,2,1) can override the icon's .cursor-pointer (0,1,0).
Changed Files
packages/design/src/components/ImageViewer/ImageViewer.tsxpackages/design/src/components/ImageViewer/styles.tspackages/design/src/components/ImageViewer/__tests__/ImageViewer.test.tsxpackages/design/src/components/ImageViewer/ImageViewerDesignSpec.mdpackages/design-site/docs/components/patterns/image-viewer.mdx(Chinese i18n synced)
Changes
- Hide navigation for a single image: Added a derived
showNav = total > 1state; the previous / next buttons and the divider after them are only rendered when there are multiple images. The single-image toolbar collapses to[zoom out] [zoom in] | [delete]* | [export] | [collapse]. - Disabled icon cursor:
IMAGE_VIEWER_TOOLBAR_BUTTON_CLASSnow appendsdisabled:[&_svg]:cursor-not-allowed, explicitly setting the icon SVG cursor back tonot-allowedin the disabled state without depending on the injected icon's implementation details. - Zoom accessibility: Added a visually-hidden region with
role="status"andaria-live="polite"that announces the current percentage when zoom changes (Zoomed to 150%). - Keyboard zoom:
handleKeyDownnow handles+/=to zoom in and-to zoom out (previously it only handled←/→, so the keyboard could not zoom).zoomIn/zoomOutclamp at the boundaries themselves so they do not exceed limits;+/-withCmd/Ctrlare let through and not intercepted, to avoid hijacking the browser's native page zoom (preserving page-zoom accessibility for low-vision users). - Added unit tests: navigation hidden for a single image / shown for multiple images, disabled buttons include
disabled:[&_svg]:cursor-not-allowed, the zoom live region announces the percentage, and+/-withCmd/Ctrldo not take over zoom. - Synced the "single image" section in DesignSpec and on the documentation site to "hide navigation", and added notes about zoom announcements and the disabled icon cursor.
Notes
pnpm test:run1151 passingpnpm lint(including tsc) passing
Linear: