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-05-24 - Accessible Icon Buttons
**Learning:** Screen readers cannot infer the purpose of icon-only buttons without text content, making actions like "Delete note" inaccessible to visually impaired users. In this app, many utility buttons (like the trash icon in Notepad) relied solely on visual metaphors.
**Action:** Always add `accessible={true}`, `accessibilityRole="button"`, and a descriptive `accessibilityLabel` to `<TouchableOpacity>` components that only contain an icon, using existing translation keys when possible.
2 changes: 2 additions & 0 deletions src/i18n/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const it = {
contactNoResults: 'Nessun risultato',
// Password
passwordTitle: 'Password', passwordAdd: 'Aggiungi',
passwordShow: 'Mostra password', passwordHide: 'Nascondi password',
passwordModalNew: 'Nuova voce', passwordModalEdit: 'Modifica voce',
passwordNameLabel: 'Nome *', passwordNamePh: 'es. Portale HR EasyJet',
passwordUsernameLabel: 'Username / Email', passwordUsernamePh: 'es. mario.rossi@easyjet.com',
Expand Down Expand Up @@ -279,6 +280,7 @@ const en: typeof it = {
contactNoResults: 'No results',
// Password
passwordTitle: 'Password', passwordAdd: 'Add',
passwordShow: 'Show password', passwordHide: 'Hide password',
passwordModalNew: 'New entry', passwordModalEdit: 'Edit entry',
passwordNameLabel: 'Name *', passwordNamePh: 'e.g. EasyJet HR Portal',
passwordUsernameLabel: 'Username / Email', passwordUsernamePh: 'e.g. mario.rossi@easyjet.com',
Expand Down
8 changes: 4 additions & 4 deletions src/screens/PasswordScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ const EMPTY_MODAL: ModalState = {
// ─── PIN Overlay ─────────────────────────────────────────────────────────────
function PinOverlay({ onUnlock, onCancel, title }: { onUnlock: (pin: string) => void; onCancel?: () => void; title: string }) {
const { colors } = useAppTheme();
const { t } = useLanguage();
const s = useMemo(() => makePinStyles(colors), [colors]);
const [digits, setDigits] = useState('');

Expand Down Expand Up @@ -103,6 +102,7 @@ function PinOverlay({ onUnlock, onCancel, title }: { onUnlock: (pin: string) =>
// ─── Password Row ─────────────────────────────────────────────────────────────
function PasswordRowComponent({ item, onEdit, onDelete }: { item: PasswordEntry; onEdit: () => void; onDelete: () => void }) {
const { colors } = useAppTheme();
const { t } = useLanguage();
const s = useMemo(() => makeRowStyles(colors), [colors]);
const [revealed, setRevealed] = useState(false);

Expand All @@ -113,7 +113,7 @@ function PasswordRowComponent({ item, onEdit, onDelete }: { item: PasswordEntry;
{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 accessibilityRole="button" accessibilityLabel={revealed ? t('passwordHide') : t('passwordShow')}>
<MaterialIcons name={revealed ? 'visibility-off' : 'visibility'} size={16} color={colors.textSub} />
</TouchableOpacity>
</View>
Expand All @@ -136,8 +136,8 @@ const PasswordRow = React.memo(PasswordRowComponent);

// ─── Main Screen ──────────────────────────────────────────────────────────────
export default function PasswordScreen() {
const { colors } = useAppTheme();
const { t } = useLanguage();
const { colors } = useAppTheme();
const s = useMemo(() => makeStyles(colors), [colors]);

const [entries, setEntries] = useState<PasswordEntry[]>([]);
Expand Down Expand Up @@ -330,7 +330,7 @@ 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 accessibilityRole="button" accessibilityLabel={showPw ? t('passwordHide') : t('passwordShow')}>
<MaterialIcons name={showPw ? 'visibility-off' : 'visibility'} size={20} color={colors.textSub} />
</TouchableOpacity>
</View>
Expand Down
Loading