Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2024-07-27 - Dynamic ARIA labels for icon-only toggles
**Learning:** Icon-only toggle buttons (like show/hide password, show/hide API key) need dynamic `:aria-label` attributes that update based on their current state, so screen readers can announce the correct action rather than a static label.
**Action:** When adding `aria-label` to toggle buttons, use a ternary operator bound to the same state used for the icon (e.g., `:aria-label="showPassword ? 'Hide password' : 'Show password'"`).
9 changes: 2 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,11 @@ jobs:
- name: Install Playwright (chromium)
run: npx playwright install --with-deps chromium

- name: Setup Supabase CLI
uses: supabase/setup-cli@v1
with:
version: latest

- name: Boot Supabase + run two-client Realtime e2e (R1–R7)
run: |
supabase start
npx supabase start
./scripts/run-e2e.sh canvas-sync-regressions.spec.ts --project=chromium --workers=2

- name: Stop Supabase
if: always()
run: supabase stop || true
run: npx supabase stop || true
2 changes: 1 addition & 1 deletion scripts/run-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
set -euo pipefail

# Auto-fetch keys from local Supabase if not already set
SUPABASE_STATUS_ENV="${SUPABASE_STATUS_ENV:-$(supabase status -o env 2>&1 || true)}"
SUPABASE_STATUS_ENV="${SUPABASE_STATUS_ENV:-$(npx supabase status -o env 2>&1 || true)}"

if [ -z "${SUPABASE_SERVICE_ROLE_KEY:-}" ]; then
# Try new-format secret key first (Supabase v2.x uses sb_secret_* instead of HS256 JWT)
Expand Down
2 changes: 1 addition & 1 deletion src/components/settings/tabs/AISettingsTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ async function onClearMemories() {
spellcheck="false"
autocomplete="off"
/>
<button class="key-toggle-btn" @click="showGroqKey = !showGroqKey" :title="showGroqKey ? 'Hide' : 'Show'">
<button class="key-toggle-btn" @click="showGroqKey = !showGroqKey" :title="showGroqKey ? 'Hide API key' : 'Show API key'" :aria-label="showGroqKey ? 'Hide API key' : 'Show API key'">
<EyeOff v-if="showGroqKey" :size="14" />
<Eye v-else :size="14" />
</button>
Expand Down
4 changes: 2 additions & 2 deletions src/components/settings/tabs/AccountSettingsTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ const handleChangePassword = async () => {
class="form-input"
placeholder="Enter new password"
>
<button class="toggle-visibility" @click="showPassword = !showPassword">
<button class="toggle-visibility" @click="showPassword = !showPassword" :aria-label="showPassword ? 'Hide password' : 'Show password'" :title="showPassword ? 'Hide password' : 'Show password'">
<Eye v-if="!showPassword" :size="16" />
<EyeOff v-else :size="16" />
</button>
Expand Down Expand Up @@ -504,7 +504,7 @@ const handleChangePassword = async () => {
class="form-input"
@focus="(e) => (e.target as HTMLInputElement).select()"
>
<button class="toggle-visibility" :title="localApiCopied ? 'Copied!' : 'Copy'" @click="copyLocalApiToken">
<button class="toggle-visibility" :title="localApiCopied ? 'Copied!' : 'Copy API token'" :aria-label="localApiCopied ? 'Copied!' : 'Copy API token'" @click="copyLocalApiToken">
<Check v-if="localApiCopied" :size="16" />
<Copy v-else :size="16" />
</button>
Expand Down
Loading