feat: add extra-compact density option and fix font size scaling
- Add 'extra-compact' density level that hides avatars and preview text, showing only sender and subject for maximum information density - Add visual density preview in appearance settings showing a 3-row email list mockup that reflects each density option - Fix global font size setting only changing line height by moving font-size from body to :root so rem-based Tailwind classes scale - Apply extra-compact behavior to email list items, thread list items, thread email items, and thread conversation view (EmailCard) - Update email list virtualizer size estimates for extra-compact - Add extra-compact translations for all 8 locales
This commit is contained in:
@@ -2,9 +2,62 @@
|
||||
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useThemeStore } from '@/stores/theme-store';
|
||||
import { useSettingsStore, type ToolbarPosition } from '@/stores/settings-store';
|
||||
import { useSettingsStore, type ToolbarPosition, type Density } from '@/stores/settings-store';
|
||||
import { LanguageSwitcher } from '@/components/ui/language-switcher';
|
||||
import { SettingsSection, SettingItem, RadioGroup, ToggleSwitch } from './settings-section';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const DENSITY_PREVIEW: Record<Density, { py: string; gap: string; showAvatar: boolean; showPreview: boolean }> = {
|
||||
'extra-compact': { py: 'py-0.5', gap: 'gap-1.5', showAvatar: false, showPreview: false },
|
||||
compact: { py: 'py-1', gap: 'gap-2', showAvatar: true, showPreview: false },
|
||||
regular: { py: 'py-2.5', gap: 'gap-3', showAvatar: true, showPreview: true },
|
||||
comfortable: { py: 'py-4', gap: 'gap-4', showAvatar: true, showPreview: true },
|
||||
};
|
||||
|
||||
function DensityPreview({ density }: { density: Density }) {
|
||||
const cfg = DENSITY_PREVIEW[density];
|
||||
const rows = [
|
||||
{ unread: true, sender: 'Alice Johnson', subject: 'Project update — Q1 roadmap', preview: 'Here are the latest numbers from…' },
|
||||
{ unread: false, sender: 'Bob Smith', subject: 'Re: Meeting notes', preview: 'Thanks, will review and get back...' },
|
||||
{ unread: true, sender: 'Carol Lee', subject: 'Invoice #4092', preview: 'Please find attached the invoice…' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="mt-3 rounded-lg border border-border overflow-hidden bg-background text-xs select-none">
|
||||
{rows.map((row, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={cn(
|
||||
"flex items-center px-3 border-b border-border last:border-b-0",
|
||||
cfg.py,
|
||||
cfg.gap
|
||||
)}
|
||||
>
|
||||
{cfg.showAvatar && (
|
||||
<div className={cn(
|
||||
"flex-shrink-0 rounded-full bg-muted",
|
||||
density === 'comfortable' ? "w-8 h-8" : "w-6 h-6"
|
||||
)} />
|
||||
)}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className={cn("truncate", row.unread ? "font-semibold text-foreground" : "text-muted-foreground")}>
|
||||
{row.sender}
|
||||
</span>
|
||||
<span className="text-[10px] text-muted-foreground flex-shrink-0 tabular-nums">12:00</span>
|
||||
</div>
|
||||
<div className={cn("truncate", row.unread ? "font-medium text-foreground" : "text-foreground/80")}>
|
||||
{row.subject}
|
||||
</div>
|
||||
{cfg.showPreview && (
|
||||
<div className="truncate text-muted-foreground/70">{row.preview}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function AppearanceSettings() {
|
||||
const t = useTranslations('settings.appearance');
|
||||
@@ -49,14 +102,16 @@ export function AppearanceSettings() {
|
||||
<RadioGroup
|
||||
value={density}
|
||||
onChange={(value) =>
|
||||
updateSetting('density', value as 'compact' | 'regular' | 'comfortable')
|
||||
updateSetting('density', value as Density)
|
||||
}
|
||||
options={[
|
||||
{ value: 'extra-compact', label: t('list_density.extra_compact') },
|
||||
{ value: 'compact', label: t('list_density.compact') },
|
||||
{ value: 'regular', label: t('list_density.regular') },
|
||||
{ value: 'comfortable', label: t('list_density.comfortable') },
|
||||
]}
|
||||
/>
|
||||
<DensityPreview density={density} />
|
||||
</SettingItem>
|
||||
|
||||
{/* Toolbar Position */}
|
||||
|
||||
Reference in New Issue
Block a user