diff --git a/.jules/palette.md b/.jules/palette.md index bd0f73248..869be9e7b 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -57,3 +57,7 @@ ## 2026-07-30 - Add window.confirm for destructive actions **Learning:** Destructive actions like deleting groups and edge relationships previously occurred immediately without user confirmation. **Action:** Always wrap delete operations with window.confirm() dialogs and ensure corresponding tests successfully mock window.confirm. + +## 2024-09-04 - Accessible disabled button hints +**Learning:** Using the native HTML `disabled` attribute on a button removes it from the document's tab order. This makes it impossible for screen reader and keyboard-only users to focus the button and hear any associated `aria-describedby` hints explaining why the button is disabled (such as access control warnings). +**Action:** To create a fully accessible disabled button with an explanatory hint, use `aria-disabled={true}`, visually style it as disabled (e.g., `opacity: 0.5, cursor: "not-allowed"`), and manually block its action via `onClick={(e) => e.preventDefault()}`. diff --git a/frontend/src/components/modals/ExportModal.test.tsx b/frontend/src/components/modals/ExportModal.test.tsx index bd89c5384..1458e6848 100644 --- a/frontend/src/components/modals/ExportModal.test.tsx +++ b/frontend/src/components/modals/ExportModal.test.tsx @@ -176,8 +176,12 @@ describe('ExportModal', () => { expect(screen.getByText('접근 권한 관리는 프로젝트 권한 설정에서 처리합니다.')).toBeInTheDocument(); const accessManagementButton = screen.getByRole('button', { name: '접근 관리' }); - expect(accessManagementButton).toBeDisabled(); + expect(accessManagementButton).toHaveAttribute('aria-disabled', 'true'); expect(accessManagementButton).toHaveAttribute('aria-describedby', 'share-export-access-hint'); expect(accessManagementButton).not.toHaveAttribute('title'); + + // Verify it is still keyboard-focusable + accessManagementButton.focus(); + expect(accessManagementButton).toHaveFocus(); }); }); diff --git a/frontend/src/components/modals/ExportModal.tsx b/frontend/src/components/modals/ExportModal.tsx index 995393ceb..9ccda8ad9 100644 --- a/frontend/src/components/modals/ExportModal.tsx +++ b/frontend/src/components/modals/ExportModal.tsx @@ -202,7 +202,8 @@ export function ExportModal({ )}