mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-04 16:06:41 +00:00
fix: make small buttons easier to hit
This commit is contained in:
@@ -186,7 +186,9 @@ function SidebarRow({
|
|||||||
{hasChildren ? (
|
{hasChildren ? (
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={onToggleExpand}
|
onPress={onToggleExpand}
|
||||||
hitSlop={6}
|
// The 20 dp slot keeps the tree indent; the touch area reaches
|
||||||
|
// 44 dp so a near miss doesn't open the folder instead.
|
||||||
|
hitSlop={12}
|
||||||
style={styles.chevron}
|
style={styles.chevron}
|
||||||
accessibilityRole="button"
|
accessibilityRole="button"
|
||||||
accessibilityLabel={isExpanded ? t('sidebar.collapse', 'Collapse') : t('sidebar.expand', 'Expand')}
|
accessibilityLabel={isExpanded ? t('sidebar.collapse', 'Collapse') : t('sidebar.expand', 'Expand')}
|
||||||
@@ -1399,7 +1401,7 @@ function makeStyles(c: ThemePalette) {
|
|||||||
...typography.bodySemibold,
|
...typography.bodySemibold,
|
||||||
color: c.text,
|
color: c.text,
|
||||||
},
|
},
|
||||||
sectionSettings: { padding: 4 },
|
sectionSettings: { padding: 10 },
|
||||||
|
|
||||||
quickRow: {
|
quickRow: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ export default function ToggleSwitch({ value, onValueChange, disabled = false, a
|
|||||||
disabled && styles.disabled,
|
disabled && styles.disabled,
|
||||||
]}
|
]}
|
||||||
onPress={() => !disabled && onValueChange(!value)}
|
onPress={() => !disabled && onValueChange(!value)}
|
||||||
|
// The track is 44 x 24; the touch area reaches 48 dp high.
|
||||||
|
hitSlop={{ top: 12, bottom: 12, left: 4, right: 4 }}
|
||||||
accessibilityRole="switch"
|
accessibilityRole="switch"
|
||||||
accessibilityLabel={accessibilityLabel}
|
accessibilityLabel={accessibilityLabel}
|
||||||
accessibilityState={{ checked: value, disabled }}
|
accessibilityState={{ checked: value, disabled }}
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ export function QuickReplyBox({ email, jmapAccountId, onMoreOptions, onSent, onF
|
|||||||
editable={!sending}
|
editable={!sending}
|
||||||
/>
|
/>
|
||||||
<View style={styles.actions}>
|
<View style={styles.actions}>
|
||||||
<Pressable style={styles.more} onPress={() => onMoreOptions(text)} hitSlop={6}>
|
<Pressable style={styles.more} onPress={() => onMoreOptions(text)} hitSlop={10} accessibilityRole="button">
|
||||||
<Maximize2 size={14} color={c.textSecondary} />
|
<Maximize2 size={14} color={c.textSecondary} />
|
||||||
<Text style={styles.moreText}>{t('email_viewer.more_options', 'More options')}</Text>
|
<Text style={styles.moreText}>{t('email_viewer.more_options', 'More options')}</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
@@ -169,6 +169,9 @@ export function QuickReplyBox({ email, jmapAccountId, onMoreOptions, onSent, onF
|
|||||||
style={[styles.send, (!text.trim() || sending) && styles.sendDisabled]}
|
style={[styles.send, (!text.trim() || sending) && styles.sendDisabled]}
|
||||||
onPress={send}
|
onPress={send}
|
||||||
disabled={!text.trim() || sending}
|
disabled={!text.trim() || sending}
|
||||||
|
hitSlop={10}
|
||||||
|
accessibilityRole="button"
|
||||||
|
accessibilityState={{ disabled: !text.trim() || sending, busy: sending }}
|
||||||
>
|
>
|
||||||
{sending ? <ActivityIndicator size="small" color={c.primaryForeground} /> : <Send size={14} color={c.primaryForeground} />}
|
{sending ? <ActivityIndicator size="small" color={c.primaryForeground} /> : <Send size={14} color={c.primaryForeground} />}
|
||||||
<Text style={styles.sendText}>{sending ? t('email_viewer.sending', 'Sending...') : t('email_viewer.send', 'Send')}</Text>
|
<Text style={styles.sendText}>{sending ? t('email_viewer.sending', 'Sending...') : t('email_viewer.send', 'Send')}</Text>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
|||||||
import { ArrowDown, ArrowUp, Check, ChevronRight, Plus, Star, Trash2, Users } from 'lucide-react-native';
|
import { ArrowDown, ArrowUp, Check, ChevronRight, Plus, Star, Trash2, Users } from 'lucide-react-native';
|
||||||
import { SettingsSection, SettingItem } from './settings-section';
|
import { SettingsSection, SettingItem } from './settings-section';
|
||||||
import Button from '../Button';
|
import Button from '../Button';
|
||||||
import { spacing, radius, typography, type ThemePalette } from '../../theme/tokens';
|
import { spacing, radius, typography, componentSizes, type ThemePalette } from '../../theme/tokens';
|
||||||
import { useColors } from '../../theme/colors';
|
import { useColors } from '../../theme/colors';
|
||||||
import { useAuthStore } from '../../stores/auth-store';
|
import { useAuthStore } from '../../stores/auth-store';
|
||||||
import { useAccountStore } from '../../stores/account-store';
|
import { useAccountStore } from '../../stores/account-store';
|
||||||
@@ -341,7 +341,7 @@ function makeStyles(c: ThemePalette) {
|
|||||||
rowError: { ...typography.caption, color: c.error },
|
rowError: { ...typography.caption, color: c.error },
|
||||||
defaultBadge: { ...typography.caption, color: c.primary, marginTop: 2 },
|
defaultBadge: { ...typography.caption, color: c.primary, marginTop: 2 },
|
||||||
rowActions: { flexDirection: 'row', gap: 2 },
|
rowActions: { flexDirection: 'row', gap: 2 },
|
||||||
iconBtn: { width: 28, height: 28, alignItems: 'center', justifyContent: 'center', borderRadius: radius.sm },
|
iconBtn: { width: componentSizes.buttonLg, height: componentSizes.buttonLg, alignItems: 'center', justifyContent: 'center', borderRadius: radius.sm },
|
||||||
addRow: { gap: spacing.sm, alignItems: 'flex-start' },
|
addRow: { gap: spacing.sm, alignItems: 'flex-start' },
|
||||||
hint: { ...typography.caption, color: c.mutedForeground },
|
hint: { ...typography.caption, color: c.mutedForeground },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -213,7 +213,8 @@ function RecipientChip({
|
|||||||
</Text>
|
</Text>
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={onRemove}
|
onPress={onRemove}
|
||||||
hitSlop={8}
|
// A 12 px icon: the touch area reaches about 40 dp around it.
|
||||||
|
hitSlop={14}
|
||||||
accessibilityRole="button"
|
accessibilityRole="button"
|
||||||
accessibilityLabel={t('email_composer.recipient_remove', 'Remove')}
|
accessibilityLabel={t('email_composer.recipient_remove', 'Remove')}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -2025,8 +2025,8 @@ function makeStyles(c: ThemePalette) {
|
|||||||
lineHeight: 14,
|
lineHeight: 14,
|
||||||
},
|
},
|
||||||
searchClearButton: {
|
searchClearButton: {
|
||||||
width: 20,
|
width: 32,
|
||||||
height: 20,
|
height: 32,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
borderRadius: radius.full,
|
borderRadius: radius.full,
|
||||||
|
|||||||
@@ -1627,8 +1627,8 @@ function makeStyles(c: ThemePalette) {
|
|||||||
borderBottomColor: c.border,
|
borderBottomColor: c.border,
|
||||||
},
|
},
|
||||||
toolbarBack: {
|
toolbarBack: {
|
||||||
width: componentSizes.avatarSm,
|
width: componentSizes.buttonLg,
|
||||||
height: componentSizes.avatarSm,
|
height: componentSizes.buttonLg,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
borderRadius: radius.full,
|
borderRadius: radius.full,
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ import { useLayout, useSheetInsets } from '../lib/use-layout';
|
|||||||
import { useBackWhileFocused } from '../lib/use-back-while-focused';
|
import { useBackWhileFocused } from '../lib/use-back-while-focused';
|
||||||
import { filesBackStep } from '../lib/files-back';
|
import { filesBackStep } from '../lib/files-back';
|
||||||
import type { FileNode } from '../api/types';
|
import type { FileNode } from '../api/types';
|
||||||
import { spacing, radius, typography, type ThemePalette } from '../theme/tokens';
|
import { spacing, radius, typography, componentSizes, type ThemePalette } from '../theme/tokens';
|
||||||
import { useColors } from '../theme/colors';
|
import { useColors } from '../theme/colors';
|
||||||
import {
|
import {
|
||||||
useSettingsStore, type FilesViewMode, type FilesSortKey, type FilesSortDir,
|
useSettingsStore, type FilesViewMode, type FilesSortKey, type FilesSortDir,
|
||||||
@@ -1492,7 +1492,10 @@ function makeStyles(c: ThemePalette) {
|
|||||||
gap: spacing.xs,
|
gap: spacing.xs,
|
||||||
},
|
},
|
||||||
headerBtn: {
|
headerBtn: {
|
||||||
padding: spacing.xs,
|
minWidth: componentSizes.buttonLg,
|
||||||
|
minHeight: componentSizes.buttonLg,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
borderRadius: radius.sm,
|
borderRadius: radius.sm,
|
||||||
},
|
},
|
||||||
headerBtnActive: {
|
headerBtnActive: {
|
||||||
@@ -1627,7 +1630,10 @@ function makeStyles(c: ThemePalette) {
|
|||||||
color: c.textMuted,
|
color: c.textMuted,
|
||||||
},
|
},
|
||||||
rowMore: {
|
rowMore: {
|
||||||
padding: spacing.xs,
|
width: componentSizes.buttonLg,
|
||||||
|
height: componentSizes.buttonLg,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
gridContent: {
|
gridContent: {
|
||||||
padding: spacing.sm,
|
padding: spacing.sm,
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ function makeStyles(c: ThemePalette) {
|
|||||||
paddingHorizontal: spacing.lg,
|
paddingHorizontal: spacing.lg,
|
||||||
height: componentSizes.headerHeight,
|
height: componentSizes.headerHeight,
|
||||||
},
|
},
|
||||||
headerButton: { width: 32, height: 32, alignItems: 'center', justifyContent: 'center' },
|
headerButton: { width: componentSizes.buttonLg, height: componentSizes.buttonLg, alignItems: 'center', justifyContent: 'center' },
|
||||||
// One readable column, centred on a tablet or a phone in landscape.
|
// One readable column, centred on a tablet or a phone in landscape.
|
||||||
content: {
|
content: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
|||||||
Reference in New Issue
Block a user