mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-02 08:07:11 +00:00
feat: enhance SettingsScreen with dynamic localization and theming
- Integrated useColors hook for dynamic theming in SettingsScreen. - Updated tab labels and titles to use localized strings. - Refactored styles to utilize theme palette for consistent styling. - Improved locale subscription to re-render labels on language change. feat: implement useSheetDrag hook for bottom sheet gesture handling - Added useSheetDrag hook to manage drag-to-dismiss functionality for bottom sheets. - Configured pan responder for handling drag gestures and dismissing the sheet based on distance and velocity. refactor: restructure color and token management - Introduced useColors and useResolvedTheme hooks for better theme management. - Separated light and dark color palettes for improved maintainability. - Updated tokens to reflect new theming structure and ensure consistency across components.
This commit is contained in:
+30
-42
@@ -1,45 +1,33 @@
|
||||
export const colors = {
|
||||
// Primary brand colors (matching Bulwark web)
|
||||
primary: '#3b82f6',
|
||||
primaryDark: '#2563eb',
|
||||
primaryLight: '#60a5fa',
|
||||
import { useColorScheme } from 'react-native';
|
||||
import { useSettingsStore } from '../stores/settings-store';
|
||||
import { LIGHT_COLORS, DARK_COLORS, type ThemePalette } from './tokens';
|
||||
|
||||
// Backgrounds
|
||||
background: '#ffffff',
|
||||
surface: '#f8fafc',
|
||||
surfaceHover: '#f1f5f9',
|
||||
export type { ThemePalette };
|
||||
|
||||
// Text
|
||||
text: '#0f172a',
|
||||
textSecondary: '#64748b',
|
||||
textMuted: '#94a3b8',
|
||||
textInverse: '#ffffff',
|
||||
/**
|
||||
* Returns the active palette for the current render. Resolves the user's
|
||||
* theme preference ('light' | 'dark' | 'system') against the OS scheme.
|
||||
*
|
||||
* Prefer this hook in new and migrated components. Static `import { colors }`
|
||||
* still works for not-yet-migrated code (it always returns the dark palette).
|
||||
*/
|
||||
export function useColors(): ThemePalette {
|
||||
const themePref = useSettingsStore((s) => s.theme);
|
||||
const systemScheme = useColorScheme();
|
||||
const resolved =
|
||||
themePref === 'system'
|
||||
? systemScheme === 'light' ? 'light' : 'dark'
|
||||
: themePref;
|
||||
return resolved === 'light' ? LIGHT_COLORS : DARK_COLORS;
|
||||
}
|
||||
|
||||
// Borders
|
||||
border: '#e2e8f0',
|
||||
borderLight: '#f1f5f9',
|
||||
|
||||
// Status
|
||||
success: '#22c55e',
|
||||
warning: '#f59e0b',
|
||||
error: '#ef4444',
|
||||
info: '#3b82f6',
|
||||
|
||||
// Email-specific
|
||||
unread: '#0f172a',
|
||||
read: '#64748b',
|
||||
starred: '#f59e0b',
|
||||
flagged: '#ef4444',
|
||||
|
||||
// Dark mode
|
||||
dark: {
|
||||
background: '#0f172a',
|
||||
surface: '#1e293b',
|
||||
surfaceHover: '#334155',
|
||||
text: '#f8fafc',
|
||||
textSecondary: '#94a3b8',
|
||||
textMuted: '#64748b',
|
||||
border: '#334155',
|
||||
borderLight: '#1e293b',
|
||||
},
|
||||
} as const;
|
||||
/**
|
||||
* Resolves the user's theme preference to a concrete 'light' | 'dark'.
|
||||
* Useful for components that need to choose icons/imagery rather than colors.
|
||||
*/
|
||||
export function useResolvedTheme(): 'light' | 'dark' {
|
||||
const themePref = useSettingsStore((s) => s.theme);
|
||||
const systemScheme = useColorScheme();
|
||||
if (themePref === 'system') return systemScheme === 'light' ? 'light' : 'dark';
|
||||
return themePref;
|
||||
}
|
||||
|
||||
+253
-121
@@ -1,194 +1,326 @@
|
||||
// Qui Dark Theme - exact values from Bulwark Webmail's builtin-themes.ts
|
||||
export const colors = {
|
||||
// Primary brand (Qui theme)
|
||||
// Mirrors the webmail design tokens defined in app/globals.css.
|
||||
// Two palettes (light + dark) live here; consumers should call `useColors()`
|
||||
// from theme/colors.tsx to pick the active one based on the user's setting.
|
||||
// The `colors` export below is kept as a "dark-default" fallback for
|
||||
// not-yet-migrated StyleSheets so they keep rendering while migration is
|
||||
// underway.
|
||||
|
||||
interface CalendarColors {
|
||||
blue: string; purple: string; green: string; orange: string;
|
||||
red: string; pink: string; teal: string; indigo: string;
|
||||
purpleBg: string; tealBg: string; indigoBg: string; pinkBg: string; orangeBg: string;
|
||||
}
|
||||
|
||||
interface TagColor { dot: string; bg: string; text: string; }
|
||||
interface TagColors {
|
||||
red: TagColor; orange: TagColor; yellow: TagColor; green: TagColor;
|
||||
blue: TagColor; purple: TagColor; pink: TagColor; teal: TagColor;
|
||||
cyan: TagColor; indigo: TagColor; amber: TagColor; lime: TagColor; gray: TagColor;
|
||||
}
|
||||
|
||||
export interface ThemePalette {
|
||||
// Brand
|
||||
primary: string;
|
||||
primaryDark: string;
|
||||
primaryLight: string;
|
||||
primaryBg: string;
|
||||
primaryBgHover: string;
|
||||
primaryForeground: string;
|
||||
primaryBorder: string;
|
||||
|
||||
// Surfaces
|
||||
background: string;
|
||||
surface: string;
|
||||
surfaceHover: string;
|
||||
surfaceActive: string;
|
||||
card: string;
|
||||
cardForeground: string;
|
||||
|
||||
// Text
|
||||
text: string;
|
||||
textSecondary: string;
|
||||
textMuted: string;
|
||||
textInverse: string;
|
||||
textLink: string;
|
||||
|
||||
// Borders
|
||||
border: string;
|
||||
borderLight: string;
|
||||
borderFocus: string;
|
||||
|
||||
// Status
|
||||
success: string;
|
||||
successBg: string;
|
||||
successForeground: string;
|
||||
warning: string;
|
||||
warningBg: string;
|
||||
warningForeground: string;
|
||||
error: string;
|
||||
errorBg: string;
|
||||
errorForeground: string;
|
||||
errorBorder: string;
|
||||
info: string;
|
||||
infoForeground: string;
|
||||
|
||||
// Email-specific
|
||||
unread: string;
|
||||
read: string;
|
||||
starred: string;
|
||||
flagged: string;
|
||||
draft: string;
|
||||
|
||||
// Calendar
|
||||
calendar: CalendarColors;
|
||||
|
||||
// Tags
|
||||
tags: TagColors;
|
||||
|
||||
// Navigation
|
||||
navActive: string;
|
||||
navInactive: string;
|
||||
navBadge: string;
|
||||
|
||||
// Secondary / muted / accent
|
||||
secondary: string;
|
||||
secondaryForeground: string;
|
||||
muted: string;
|
||||
mutedForeground: string;
|
||||
accent: string;
|
||||
accentForeground: string;
|
||||
|
||||
// Selection
|
||||
selection: string;
|
||||
selectionForeground: string;
|
||||
|
||||
// Popover
|
||||
popover: string;
|
||||
popoverForeground: string;
|
||||
|
||||
// Charts
|
||||
chart1: string; chart2: string; chart3: string; chart4: string; chart5: string;
|
||||
}
|
||||
|
||||
const TAGS: TagColors = {
|
||||
red: { dot: '#ef4444', bg: 'rgba(69,10,10,0.30)', text: '#f87171' },
|
||||
orange: { dot: '#f97316', bg: 'rgba(67,20,7,0.30)', text: '#fb923c' },
|
||||
yellow: { dot: '#eab308', bg: 'rgba(66,32,6,0.30)', text: '#fbbf24' },
|
||||
green: { dot: '#22c55e', bg: 'rgba(5,46,22,0.30)', text: '#4ade80' },
|
||||
blue: { dot: '#3b82f6', bg: 'rgba(23,37,84,0.30)', text: '#60a5fa' },
|
||||
purple: { dot: '#a855f7', bg: 'rgba(59,7,100,0.30)', text: '#c084fc' },
|
||||
pink: { dot: '#ec4899', bg: 'rgba(80,7,36,0.30)', text: '#f472b6' },
|
||||
teal: { dot: '#14b8a6', bg: 'rgba(4,47,46,0.30)', text: '#2dd4bf' },
|
||||
cyan: { dot: '#06b6d4', bg: 'rgba(8,51,68,0.30)', text: '#22d3ee' },
|
||||
indigo: { dot: '#6366f1', bg: 'rgba(30,27,75,0.30)', text: '#818cf8' },
|
||||
amber: { dot: '#f59e0b', bg: 'rgba(69,26,3,0.30)', text: '#fbbf24' },
|
||||
lime: { dot: '#84cc16', bg: 'rgba(26,46,5,0.30)', text: '#a3e635' },
|
||||
gray: { dot: '#6b7280', bg: 'rgba(3,7,18,0.30)', text: '#9ca3af' },
|
||||
};
|
||||
|
||||
export const DARK_COLORS: ThemePalette = {
|
||||
primary: '#3b82f6',
|
||||
primaryDark: '#2563eb',
|
||||
primaryLight: '#60a5fa',
|
||||
primaryBg: '#172554',
|
||||
primaryBgHover: '#1e40af',
|
||||
primaryForeground: '#ffffff',
|
||||
primaryBorder: 'rgba(59, 130, 246, 0.19)',
|
||||
|
||||
// Backgrounds (Qui dark)
|
||||
background: '#09090b',
|
||||
surface: '#18181b', // --color-secondary / --color-muted
|
||||
surface: '#18181b',
|
||||
surfaceHover: '#1f1f23',
|
||||
surfaceActive: '#27272a',
|
||||
card: '#141414', // --color-card
|
||||
card: '#141414',
|
||||
cardForeground: '#fafafa',
|
||||
|
||||
// Text (Qui dark)
|
||||
text: '#fafafa', // --color-foreground
|
||||
textSecondary: '#a1a1aa', // --color-muted-foreground
|
||||
text: '#fafafa',
|
||||
textSecondary: '#a1a1aa',
|
||||
textMuted: '#71717a',
|
||||
textInverse: '#ffffff',
|
||||
textInverse: '#0f172a',
|
||||
textLink: '#60a5fa',
|
||||
|
||||
// Borders (Qui dark)
|
||||
border: '#27272a', // --color-border / --color-input
|
||||
border: '#27272a',
|
||||
borderLight: '#18181b',
|
||||
borderFocus: '#3b82f6', // --color-ring
|
||||
borderFocus: '#3b82f6',
|
||||
|
||||
// Status
|
||||
success: '#16a34a',
|
||||
successBg: '#052e16',
|
||||
successForeground: '#ffffff',
|
||||
warning: '#ca8a04',
|
||||
warningBg: '#422006',
|
||||
warningForeground: '#ffffff',
|
||||
error: '#ef4444', // --color-destructive
|
||||
error: '#ef4444',
|
||||
errorBg: '#450a0a',
|
||||
errorForeground: '#fafafa',
|
||||
errorBorder: 'rgba(239, 68, 68, 0.25)',
|
||||
info: '#60a5fa',
|
||||
infoForeground: '#ffffff',
|
||||
|
||||
// Email-specific
|
||||
unread: '#60a5fa', // --color-unread
|
||||
unread: '#60a5fa',
|
||||
read: '#a1a1aa',
|
||||
starred: '#fbbf24', // amber-400
|
||||
starred: '#fbbf24',
|
||||
flagged: '#ef4444',
|
||||
draft: '#a78bfa',
|
||||
// Border variants (for inline opacity hacks)
|
||||
primaryBorder: 'rgba(59, 130, 246, 0.19)', // primary + '30'
|
||||
errorBorder: 'rgba(239, 68, 68, 0.25)', // error + '40'
|
||||
|
||||
// Calendar event colors
|
||||
calendar: {
|
||||
blue: '#60a5fa',
|
||||
purple: '#a78bfa',
|
||||
green: '#4ade80',
|
||||
orange: '#fbbf24',
|
||||
red: '#f87171',
|
||||
pink: '#f472b6',
|
||||
teal: '#2dd4bf',
|
||||
indigo: '#818cf8',
|
||||
// Dark-mode backgrounds for colored icons (replaces hardcoded light colors)
|
||||
purpleBg: 'rgba(167, 139, 250, 0.08)', // purple-950/30 dark
|
||||
tealBg: 'rgba(45, 212, 191, 0.08)', // teal-950/30 dark
|
||||
indigoBg: 'rgba(129, 140, 248, 0.08)', // indigo-950/30 dark
|
||||
pinkBg: 'rgba(244, 114, 182, 0.08)', // pink-950/30 dark
|
||||
orangeBg: 'rgba(251, 191, 36, 0.08)', // orange-950/30 dark
|
||||
blue: '#60a5fa', purple: '#a78bfa', green: '#4ade80', orange: '#fbbf24',
|
||||
red: '#f87171', pink: '#f472b6', teal: '#2dd4bf', indigo: '#818cf8',
|
||||
purpleBg: 'rgba(167, 139, 250, 0.08)',
|
||||
tealBg: 'rgba(45, 212, 191, 0.08)',
|
||||
indigoBg: 'rgba(129, 140, 248, 0.08)',
|
||||
pinkBg: 'rgba(244, 114, 182, 0.08)',
|
||||
orangeBg: 'rgba(251, 191, 36, 0.08)',
|
||||
},
|
||||
|
||||
// Tag colors - from KEYWORD_PALETTE in stores/settings-store.ts
|
||||
// dark mode: bg-{color}-950/30, dot: bg-{color}-500, text: {color}-400
|
||||
tags: {
|
||||
red: { dot: '#ef4444', bg: 'rgba(69,10,10,0.30)', text: '#f87171' },
|
||||
orange: { dot: '#f97316', bg: 'rgba(67,20,7,0.30)', text: '#fb923c' },
|
||||
yellow: { dot: '#eab308', bg: 'rgba(66,32,6,0.30)', text: '#fbbf24' },
|
||||
green: { dot: '#22c55e', bg: 'rgba(5,46,22,0.30)', text: '#4ade80' },
|
||||
blue: { dot: '#3b82f6', bg: 'rgba(23,37,84,0.30)', text: '#60a5fa' },
|
||||
purple: { dot: '#a855f7', bg: 'rgba(59,7,100,0.30)', text: '#c084fc' },
|
||||
pink: { dot: '#ec4899', bg: 'rgba(80,7,36,0.30)', text: '#f472b6' },
|
||||
teal: { dot: '#14b8a6', bg: 'rgba(4,47,46,0.30)', text: '#2dd4bf' },
|
||||
cyan: { dot: '#06b6d4', bg: 'rgba(8,51,68,0.30)', text: '#22d3ee' },
|
||||
indigo: { dot: '#6366f1', bg: 'rgba(30,27,75,0.30)', text: '#818cf8' },
|
||||
amber: { dot: '#f59e0b', bg: 'rgba(69,26,3,0.30)', text: '#fbbf24' },
|
||||
lime: { dot: '#84cc16', bg: 'rgba(26,46,5,0.30)', text: '#a3e635' },
|
||||
gray: { dot: '#6b7280', bg: 'rgba(3,7,18,0.30)', text: '#9ca3af' },
|
||||
},
|
||||
tags: TAGS,
|
||||
|
||||
// Navigation - matches web nav-rail
|
||||
navActive: '#3b82f6',
|
||||
navInactive: '#71717a', // --color-muted-foreground
|
||||
navBadge: '#ef4444', // red-500
|
||||
navInactive: '#71717a',
|
||||
navBadge: '#ef4444',
|
||||
|
||||
// Secondary / Muted (Qui dark)
|
||||
secondary: '#18181b',
|
||||
secondaryForeground: '#fafafa',
|
||||
muted: '#18181b',
|
||||
mutedForeground: '#a1a1aa',
|
||||
|
||||
// Accent (Qui dark)
|
||||
accent: '#172554',
|
||||
accentForeground: '#93c5fd',
|
||||
|
||||
// Selection (Qui dark)
|
||||
selection: 'rgba(59, 130, 246, 0.25)',
|
||||
selectionForeground: '#93c5fd',
|
||||
|
||||
// Popover (Qui dark)
|
||||
popover: '#18181b',
|
||||
popoverForeground: '#fafafa',
|
||||
|
||||
// Chart colors (Qui dark)
|
||||
chart1: '#60a5fa',
|
||||
chart2: '#4ade80',
|
||||
chart3: '#fbbf24',
|
||||
chart4: '#f87171',
|
||||
chart5: '#a78bfa',
|
||||
} as const;
|
||||
chart1: '#60a5fa', chart2: '#4ade80', chart3: '#fbbf24', chart4: '#f87171', chart5: '#a78bfa',
|
||||
};
|
||||
|
||||
const LIGHT_TAGS: TagColors = {
|
||||
// For light mode, dot stays as the saturated swatch but bg gets lighter and text gets darker.
|
||||
red: { dot: '#ef4444', bg: 'rgba(254,226,226,0.6)', text: '#b91c1c' },
|
||||
orange: { dot: '#f97316', bg: 'rgba(254,237,213,0.6)', text: '#c2410c' },
|
||||
yellow: { dot: '#eab308', bg: 'rgba(254,249,195,0.6)', text: '#a16207' },
|
||||
green: { dot: '#22c55e', bg: 'rgba(220,252,231,0.6)', text: '#15803d' },
|
||||
blue: { dot: '#3b82f6', bg: 'rgba(219,234,254,0.6)', text: '#1d4ed8' },
|
||||
purple: { dot: '#a855f7', bg: 'rgba(243,232,255,0.6)', text: '#7e22ce' },
|
||||
pink: { dot: '#ec4899', bg: 'rgba(252,231,243,0.6)', text: '#be185d' },
|
||||
teal: { dot: '#14b8a6', bg: 'rgba(204,251,241,0.6)', text: '#0f766e' },
|
||||
cyan: { dot: '#06b6d4', bg: 'rgba(207,250,254,0.6)', text: '#0e7490' },
|
||||
indigo: { dot: '#6366f1', bg: 'rgba(224,231,255,0.6)', text: '#4338ca' },
|
||||
amber: { dot: '#f59e0b', bg: 'rgba(254,243,199,0.6)', text: '#b45309' },
|
||||
lime: { dot: '#84cc16', bg: 'rgba(236,252,203,0.6)', text: '#4d7c0f' },
|
||||
gray: { dot: '#6b7280', bg: 'rgba(243,244,246,0.6)', text: '#374151' },
|
||||
};
|
||||
|
||||
export const LIGHT_COLORS: ThemePalette = {
|
||||
primary: '#3b82f6',
|
||||
primaryDark: '#2563eb',
|
||||
primaryLight: '#60a5fa',
|
||||
primaryBg: '#dbeafe',
|
||||
primaryBgHover: '#bfdbfe',
|
||||
primaryForeground: '#ffffff',
|
||||
primaryBorder: 'rgba(59, 130, 246, 0.25)',
|
||||
|
||||
background: '#ffffff',
|
||||
surface: '#f8fafc',
|
||||
surfaceHover: '#f1f5f9',
|
||||
surfaceActive: '#e2e8f0',
|
||||
card: '#ffffff',
|
||||
cardForeground: '#0f172a',
|
||||
|
||||
text: '#0f172a',
|
||||
textSecondary: '#64748b',
|
||||
textMuted: '#94a3b8',
|
||||
textInverse: '#ffffff',
|
||||
textLink: '#1d4ed8',
|
||||
|
||||
border: '#e2e8f0',
|
||||
borderLight: '#f1f5f9',
|
||||
borderFocus: '#94a3b8',
|
||||
|
||||
success: '#22c55e',
|
||||
successBg: '#dcfce7',
|
||||
successForeground: '#ffffff',
|
||||
warning: '#eab308',
|
||||
warningBg: '#fef9c3',
|
||||
warningForeground: '#ffffff',
|
||||
error: '#ef4444',
|
||||
errorBg: '#fee2e2',
|
||||
errorForeground: '#ffffff',
|
||||
errorBorder: 'rgba(239, 68, 68, 0.30)',
|
||||
info: '#3b82f6',
|
||||
infoForeground: '#ffffff',
|
||||
|
||||
unread: '#3b82f6',
|
||||
read: '#64748b',
|
||||
starred: '#eab308',
|
||||
flagged: '#ef4444',
|
||||
draft: '#a855f7',
|
||||
|
||||
calendar: {
|
||||
blue: '#3b82f6', purple: '#a855f7', green: '#22c55e', orange: '#f59e0b',
|
||||
red: '#ef4444', pink: '#ec4899', teal: '#14b8a6', indigo: '#6366f1',
|
||||
purpleBg: 'rgba(168, 85, 247, 0.10)',
|
||||
tealBg: 'rgba(20, 184, 166, 0.10)',
|
||||
indigoBg: 'rgba(99, 102, 241, 0.10)',
|
||||
pinkBg: 'rgba(236, 72, 153, 0.10)',
|
||||
orangeBg: 'rgba(245, 158, 11, 0.10)',
|
||||
},
|
||||
|
||||
tags: LIGHT_TAGS,
|
||||
|
||||
navActive: '#3b82f6',
|
||||
navInactive: '#64748b',
|
||||
navBadge: '#ef4444',
|
||||
|
||||
secondary: '#f8fafc',
|
||||
secondaryForeground: '#0f172a',
|
||||
muted: '#f1f5f9',
|
||||
mutedForeground: '#64748b',
|
||||
accent: '#dbeafe',
|
||||
accentForeground: '#1e40af',
|
||||
|
||||
selection: 'rgba(59, 130, 246, 0.18)',
|
||||
selectionForeground: '#1e40af',
|
||||
|
||||
popover: '#ffffff',
|
||||
popoverForeground: '#0f172a',
|
||||
|
||||
chart1: '#3b82f6', chart2: '#22c55e', chart3: '#f59e0b', chart4: '#ef4444', chart5: '#8b5cf6',
|
||||
};
|
||||
|
||||
// Backwards-compat: not-yet-migrated StyleSheets keep importing `colors` and
|
||||
// see the dark palette. Migrate component-by-component to `useColors()`.
|
||||
export const colors = DARK_COLORS;
|
||||
|
||||
// Spacing matches Tailwind's rem scale converted to px
|
||||
export const spacing = {
|
||||
xs: 4, // 0.25rem
|
||||
sm: 8, // 0.5rem
|
||||
md: 12, // 0.75rem
|
||||
lg: 16, // 1rem
|
||||
xl: 20, // 1.25rem
|
||||
xxl: 24, // 1.5rem
|
||||
xxxl: 32, // 2rem
|
||||
xs: 4, sm: 8, md: 12, lg: 16, xl: 20, xxl: 24, xxxl: 32,
|
||||
} as const;
|
||||
|
||||
// Border radii matching Tailwind's rounded-* scale
|
||||
export const radius = {
|
||||
xs: 4, // rounded
|
||||
sm: 6, // rounded-md
|
||||
md: 8, // rounded-lg
|
||||
lg: 12, // rounded-xl
|
||||
xl: 16, // rounded-2xl
|
||||
full: 9999, // rounded-full
|
||||
xs: 4, sm: 6, md: 8, lg: 12, xl: 16, full: 9999,
|
||||
} as const;
|
||||
|
||||
// Typography matching web's Tailwind text-* classes
|
||||
export const typography = {
|
||||
// Headings
|
||||
h1: { fontSize: 24, fontWeight: '700' as const, lineHeight: 32 }, // text-2xl
|
||||
h2: { fontSize: 20, fontWeight: '700' as const, lineHeight: 28 }, // text-xl
|
||||
h3: { fontSize: 18, fontWeight: '600' as const, lineHeight: 28 }, // text-lg
|
||||
// Body = text-sm (14px) - the web uses text-sm for almost all content
|
||||
h1: { fontSize: 24, fontWeight: '700' as const, lineHeight: 32 },
|
||||
h2: { fontSize: 20, fontWeight: '700' as const, lineHeight: 28 },
|
||||
h3: { fontSize: 18, fontWeight: '600' as const, lineHeight: 28 },
|
||||
body: { fontSize: 14, fontWeight: '400' as const, lineHeight: 20 },
|
||||
bodyMedium: { fontSize: 14, fontWeight: '500' as const, lineHeight: 20 },
|
||||
bodySemibold: { fontSize: 14, fontWeight: '600' as const, lineHeight: 20 },
|
||||
bodyBold: { fontSize: 14, fontWeight: '700' as const, lineHeight: 20 },
|
||||
// Base = text-base (16px) - used for email content body
|
||||
base: { fontSize: 16, fontWeight: '400' as const, lineHeight: 24 },
|
||||
baseMedium: { fontSize: 16, fontWeight: '500' as const, lineHeight: 24 },
|
||||
// Caption = text-xs (12px)
|
||||
caption: { fontSize: 12, fontWeight: '400' as const, lineHeight: 16 },
|
||||
captionMedium: { fontSize: 12, fontWeight: '500' as const, lineHeight: 16 },
|
||||
// Small = 10px - for tags, badges, tab labels
|
||||
small: { fontSize: 10, fontWeight: '500' as const, lineHeight: 14 },
|
||||
tabLabel: { fontSize: 10, fontWeight: '500' as const, lineHeight: 14 },
|
||||
} as const;
|
||||
|
||||
// Component-specific sizes matching web
|
||||
export const componentSizes = {
|
||||
// Avatars (web: w-8/w-10/w-12)
|
||||
avatarSm: 32,
|
||||
avatarMd: 40,
|
||||
avatarLg: 48,
|
||||
// Nav icons (web: w-5 h-5 = 20px)
|
||||
navIcon: 20,
|
||||
// Status icons (web: w-3.5 h-3.5 = 14px)
|
||||
statusIcon: 14,
|
||||
// Mobile header height (web: h-14 = 56px)
|
||||
headerHeight: 56,
|
||||
// Input height (web: h-10 = 40px)
|
||||
inputHeight: 40,
|
||||
// Button heights
|
||||
buttonSm: 36, // h-9
|
||||
buttonMd: 40, // h-10
|
||||
buttonLg: 44, // h-11
|
||||
// Tag dot (web: w-1.5 h-1.5 = 6px)
|
||||
tagDot: 6,
|
||||
// Event dot (web: w-1.5 h-1.5 = 6px)
|
||||
eventDot: 6,
|
||||
// Toggle switch (web: h-6 w-11)
|
||||
toggleHeight: 24,
|
||||
toggleWidth: 44,
|
||||
toggleThumb: 16,
|
||||
// FAB (standard material)
|
||||
fab: 56,
|
||||
// Nav badge (web: min-w-4 h-4 = 16px)
|
||||
badgeSize: 16,
|
||||
avatarSm: 32, avatarMd: 40, avatarLg: 48,
|
||||
navIcon: 20, statusIcon: 14,
|
||||
headerHeight: 56, inputHeight: 40,
|
||||
buttonSm: 36, buttonMd: 40, buttonLg: 44,
|
||||
tagDot: 6, eventDot: 6,
|
||||
toggleHeight: 24, toggleWidth: 44, toggleThumb: 16,
|
||||
fab: 56, badgeSize: 16,
|
||||
} as const;
|
||||
|
||||
Reference in New Issue
Block a user