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 @@
## 2025-03-09 - Accessible Icon Buttons in React Native
**Learning:** In this React Native application, several icon-only components (like `<TouchableOpacity>` containing only a `<MaterialIcons>`) lacked inherent meaning for screen readers. Using standard ARIA attributes directly isn't perfectly 1-to-1 with React Native.
**Action:** Next time, when adding accessibility to interactive elements in React Native, ensure `<TouchableOpacity>` (or similar) is given the props `accessible={true}`, `accessibilityRole="button"`, and a descriptive `accessibilityLabel` (ideally translated) to provide context for screen readers.
51 changes: 24 additions & 27 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 37 additions & 5 deletions src/screens/PasswordScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,15 @@ function PinOverlay({ onUnlock, onCancel, title }: { onUnlock: (pin: string) =>
{keys.map((k, i) => (
k === '' ? <View key={i} style={s.keyEmpty} /> :
k === '⌫' ? (
<TouchableOpacity key={i} style={s.key} onPress={del} activeOpacity={0.7}>
<TouchableOpacity
key={i}
style={s.key}
onPress={del}
activeOpacity={0.7}
accessible={true}
accessibilityRole="button"
accessibilityLabel="Cancella ultima cifra"
>
Comment on lines +83 to +91
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accessibilityLabel is hardcoded in Italian, but the app supports multiple languages via useLanguage()/translations.ts. Screen-reader labels should be localized (e.g., add a translation key for the PIN backspace/delete action and use t(...) here) so English users don't get Italian announcements.

Copilot uses AI. Check for mistakes.
<MaterialIcons name="backspace" size={20} color={colors.text} />
</TouchableOpacity>
) : (
Expand Down Expand Up @@ -113,17 +121,35 @@ function PasswordRow({ item, onEdit, onDelete }: { item: PasswordEntry; onEdit:
{item.username ? <Text style={s.username}>{item.username}</Text> : null}
<View style={s.pwRow}>
<Text style={s.pw}>{revealed ? item.password : '••••••••'}</Text>
<TouchableOpacity onPress={() => setRevealed(r => !r)} style={s.eyeBtn}>
<TouchableOpacity
onPress={() => setRevealed(r => !r)}
style={s.eyeBtn}
accessible={true}
accessibilityRole="button"
accessibilityLabel={revealed ? "Nascondi password" : "Mostra password"}
>
Comment on lines +124 to +130
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These new accessibilityLabel values are hardcoded in Italian. Since this screen already uses useLanguage()/t(...) elsewhere, please move these labels into src/i18n/translations.ts and use localized keys (for both "show"/"hide" states) so screen readers announce the correct language.

Copilot uses AI. Check for mistakes.
<MaterialIcons name={revealed ? 'visibility-off' : 'visibility'} size={16} color={colors.textSub} />
</TouchableOpacity>
</View>
{item.notes ? <Text style={s.notes}>{item.notes}</Text> : null}
</View>
<View style={s.actions}>
<TouchableOpacity style={s.editBtn} onPress={onEdit}>
<TouchableOpacity
style={s.editBtn}
onPress={onEdit}
accessible={true}
accessibilityRole="button"
accessibilityLabel="Modifica password"
>
<MaterialIcons name="edit" size={17} color={colors.primary} />
</TouchableOpacity>
<TouchableOpacity style={s.delBtn} onPress={onDelete}>
<TouchableOpacity
style={s.delBtn}
onPress={onDelete}
accessible={true}
accessibilityRole="button"
accessibilityLabel="Elimina password"
>
Comment on lines +137 to +152
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accessibilityLabel for edit/delete is hardcoded in Italian. To avoid mixed-language announcements when lang === 'en', add translation keys and source the labels via t(...) (either by calling useLanguage() in PasswordRow or by passing localized strings in as props).

Copilot uses AI. Check for mistakes.
<MaterialIcons name="delete-outline" size={17} color="#EF4444" />
</TouchableOpacity>
</View>
Expand Down Expand Up @@ -327,7 +353,13 @@ export default function PasswordScreen() {
secureTextEntry={!showPw}
autoCapitalize="none"
/>
<TouchableOpacity onPress={() => setShowPw(p => !p)} style={s.eyeModal}>
<TouchableOpacity
onPress={() => setShowPw(p => !p)}
style={s.eyeModal}
accessible={true}
accessibilityRole="button"
accessibilityLabel={showPw ? "Nascondi password" : "Mostra password"}
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This accessibilityLabel is hardcoded in Italian and duplicates the show/hide label logic used in PasswordRow. Consider introducing shared i18n keys (e.g., showPassword/hidePassword) and using t(...) here to keep screen-reader announcements localized and consistent.

Suggested change
accessibilityLabel={showPw ? "Nascondi password" : "Mostra password"}
accessibilityLabel={t(showPw ? 'hidePassword' : 'showPassword')}

Copilot uses AI. Check for mistakes.
>
<MaterialIcons name={showPw ? 'visibility-off' : 'visibility'} size={20} color={colors.textSub} />
</TouchableOpacity>
</View>
Expand Down
Loading