diff --git a/.Jules/palette.md b/.Jules/palette.md index 6e3411a..193c5eb 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -31,3 +31,6 @@ ## 2026-06-09 - Empty State Feedback **Learning:** When a list or process finishes with zero results, an empty summary container gives no feedback, leaving the user wondering if it actually ran or failed silently. **Action:** Always provide a helpful empty state message explaining why no results might have occurred, using styles consistent with other hints to offer guidance without showing as an error. +## 2026-06-15 - Use Semantic Fieldsets for Form Grouping +**Learning:** Generic `div` containers and pseudo-labels using `role="group"`, `role="radiogroup"`, and `aria-labelledby` can be entirely avoided by using native `
` and `` elements. This inherently structures grouped form controls (like radio buttons or segmented buttons) for assistive technologies. We can then easily reset browser default `fieldset` styles (`border`, `padding`, `margin`) in CSS. +**Action:** Next time I encounter `div`s with `role="radiogroup"` or `role="group"`, replace them with native `
` and style `` directly instead of managing `aria-labelledby` attributes. diff --git a/popup.css b/popup.css index 85153c2..67270cc 100644 --- a/popup.css +++ b/popup.css @@ -50,7 +50,8 @@ section { border-radius: 6px; } -label { +label, +legend { display: block; font-size: 12px; color: #94a3b8; @@ -260,3 +261,9 @@ button.secondary:hover { .summary .skipped { color: #fbbf24; } + +fieldset { + border: none; + padding: 0; + margin: 0; +} diff --git a/popup.html b/popup.html index e4c322c..6a91a70 100644 --- a/popup.html +++ b/popup.html @@ -13,20 +13,20 @@

Jules Task Archiver

Options

-
- -
+
+ Operation +
-
-
- -
+
+
+ Execution Mode +
- +
Archive every task, ignoring state and matching open Pull Requests
-
- -
+
+ Scope +
-
+
diff --git a/tests/popup.test.js b/tests/popup.test.js index 3f3db03..d2759ad 100644 --- a/tests/popup.test.js +++ b/tests/popup.test.js @@ -435,11 +435,10 @@ describe('popup.html accessibility', () => { ) }) - it('should use explicit visible labels for radio groups via aria-labelledby', () => { - assert.ok(popupHtml.includes('id="execModeLabel"'), 'execModeLabel should exist') - assert.ok(popupHtml.includes('aria-labelledby="execModeLabel"'), 'mode radiogroup should use aria-labelledby') - assert.ok(popupHtml.includes('id="scopeLabel"'), 'scopeLabel should exist') - assert.ok(popupHtml.includes('aria-labelledby="scopeLabel"'), 'scope radiogroup should use aria-labelledby') + it('should use explicit visible labels for radio groups via fieldset and legend', () => { + assert.ok(popupHtml.includes(''), 'execModeLabel legend should exist') + assert.ok(popupHtml.includes(''), 'scopeLabel legend should exist') + assert.ok(popupHtml.includes('