!isVirtualNode && onMailboxSelect?.(node.id)}
disabled={isVirtualNode}
className={cn(
- "flex items-center py-1 lg:py-1 max-lg:py-2 px-1 rounded",
+ "flex items-center px-1 rounded",
"transition-colors duration-150",
isCollapsed ? "justify-center" : "flex-1 text-left",
isVirtualNode && "cursor-default select-none"
)}
- style={isCollapsed ? undefined : {
- paddingLeft: hasChildren ? '4px' : `${indentPixels + 24}px`
+ style={{
+ paddingBlock: 'var(--density-sidebar-py)',
+ ...(isCollapsed ? {} : { paddingLeft: hasChildren ? '4px' : `${indentPixels + 24}px` })
}}
title={isCollapsed ? node.name : undefined}
>
@@ -258,8 +260,9 @@ function TagItem({
return (
onTagSelect?.(isSelected ? null : kw.id)}
className={cn(
- "flex items-center py-1 lg:py-1 max-lg:py-2 px-1 rounded transition-colors duration-150",
+ "flex items-center px-1 rounded transition-colors duration-150",
isCollapsed ? "justify-center" : "flex-1 text-left"
)}
- style={isCollapsed ? undefined : { paddingLeft: '40px' }}
+ style={{ paddingBlock: 'var(--density-sidebar-py)', ...(isCollapsed ? {} : { paddingLeft: '40px' }) }}
title={isCollapsed ? kw.label : undefined}
>
@@ -489,8 +492,9 @@ export function Sidebar({
{emailKeywords.length > 0 && (
<>
@@ -44,12 +44,12 @@ export function AppearanceSettings() {
/>
- {/* List Density */}
+ {/* Density */}
- updateSetting('listDensity', value as 'compact' | 'regular' | 'comfortable')
+ updateSetting('density', value as 'compact' | 'regular' | 'comfortable')
}
options={[
{ value: 'compact', label: t('list_density.compact') },
diff --git a/locales/de/common.json b/locales/de/common.json
index b00d3070..44c03db4 100644
--- a/locales/de/common.json
+++ b/locales/de/common.json
@@ -510,8 +510,8 @@
"large": "Groß"
},
"list_density": {
- "label": "Listendichte",
- "description": "Abstand in E-Mail-Listen steuern",
+ "label": "Dichte",
+ "description": "Abstände in der Benutzeroberfläche steuern",
"compact": "Kompakt",
"regular": "Normal",
"comfortable": "Komfortabel"
diff --git a/locales/en/common.json b/locales/en/common.json
index 94f1537d..0dd03897 100644
--- a/locales/en/common.json
+++ b/locales/en/common.json
@@ -510,8 +510,8 @@
"large": "Large"
},
"list_density": {
- "label": "List Density",
- "description": "Control spacing in email lists",
+ "label": "Density",
+ "description": "Control spacing and padding across the UI",
"compact": "Compact",
"regular": "Regular",
"comfortable": "Comfortable"
diff --git a/locales/es/common.json b/locales/es/common.json
index 80f62888..192ff548 100644
--- a/locales/es/common.json
+++ b/locales/es/common.json
@@ -510,8 +510,8 @@
"large": "Grande"
},
"list_density": {
- "label": "Densidad de Lista",
- "description": "Controle el espaciado en las listas de correo",
+ "label": "Densidad",
+ "description": "Controle el espaciado en toda la interfaz",
"compact": "Compacto",
"regular": "Regular",
"comfortable": "Cómodo"
diff --git a/locales/fr/common.json b/locales/fr/common.json
index 6003549c..c0806d7b 100644
--- a/locales/fr/common.json
+++ b/locales/fr/common.json
@@ -510,8 +510,8 @@
"large": "Grande"
},
"list_density": {
- "label": "Densité de la liste",
- "description": "Contrôlez l'espacement dans les listes d'emails",
+ "label": "Densité",
+ "description": "Contrôlez l'espacement dans toute l'interface",
"compact": "Compacte",
"regular": "Normale",
"comfortable": "Confortable"
diff --git a/locales/it/common.json b/locales/it/common.json
index 6d495da1..6b0a85de 100644
--- a/locales/it/common.json
+++ b/locales/it/common.json
@@ -510,8 +510,8 @@
"large": "Grande"
},
"list_density": {
- "label": "Densità elenco",
- "description": "Controlla la spaziatura negli elenchi email",
+ "label": "Densità",
+ "description": "Controlla la spaziatura in tutta l'interfaccia",
"compact": "Compatto",
"regular": "Normale",
"comfortable": "Comodo"
diff --git a/locales/ja/common.json b/locales/ja/common.json
index b23ca401..a989e717 100644
--- a/locales/ja/common.json
+++ b/locales/ja/common.json
@@ -510,8 +510,8 @@
"large": "大"
},
"list_density": {
- "label": "リストの密度",
- "description": "メールリストの間隔を調整",
+ "label": "密度",
+ "description": "UI全体の間隔を調整",
"compact": "コンパクト",
"regular": "標準",
"comfortable": "ゆったり"
diff --git a/locales/nl/common.json b/locales/nl/common.json
index 5299d6b0..9aac4f48 100644
--- a/locales/nl/common.json
+++ b/locales/nl/common.json
@@ -510,8 +510,8 @@
"large": "Groot"
},
"list_density": {
- "label": "Lijstdichtheid",
- "description": "Regeleer de ruimte in e-maillijsten",
+ "label": "Dichtheid",
+ "description": "Regeleer de ruimte in de gehele interface",
"compact": "Compact",
"regular": "Normaal",
"comfortable": "Comfortabel"
diff --git a/locales/pt/common.json b/locales/pt/common.json
index 0dfb2835..ee55b304 100644
--- a/locales/pt/common.json
+++ b/locales/pt/common.json
@@ -510,8 +510,8 @@
"large": "Grande"
},
"list_density": {
- "label": "Densidade da Lista",
- "description": "Controle o espaçamento nas listas de e-mail",
+ "label": "Densidade",
+ "description": "Controle o espaçamento em toda a interface",
"compact": "Compacto",
"regular": "Regular",
"comfortable": "Confortável"
diff --git a/stores/settings-store.ts b/stores/settings-store.ts
index 5cd35029..f858163a 100644
--- a/stores/settings-store.ts
+++ b/stores/settings-store.ts
@@ -19,7 +19,9 @@ let isLoadingFromServer = false;
const SYNC_DEBOUNCE_MS = 2000;
export type FontSize = 'small' | 'medium' | 'large';
-export type ListDensity = 'compact' | 'regular' | 'comfortable';
+export type Density = 'compact' | 'regular' | 'comfortable';
+/** @deprecated Use Density instead */
+export type ListDensity = Density;
export type DeleteAction = 'trash' | 'permanent';
export type ReplyMode = 'reply' | 'replyAll';
export type DateFormat = 'regional' | 'iso' | 'custom';
@@ -64,7 +66,7 @@ export const DEFAULT_KEYWORDS: KeywordDefinition[] = [
interface SettingsState {
// Appearance
fontSize: FontSize;
- listDensity: ListDensity;
+ density: Density;
animationsEnabled: boolean;
// Language & Region
@@ -141,7 +143,7 @@ interface SettingsState {
const DEFAULT_SETTINGS = {
// Appearance
fontSize: 'medium' as FontSize,
- listDensity: 'regular' as ListDensity,
+ density: 'regular' as Density,
animationsEnabled: true,
// Language & Region
@@ -199,9 +201,9 @@ export const useSettingsStore = create()(
applyFontSize(value as FontSize);
}
- // Apply list density to document root
- if (key === 'listDensity') {
- applyListDensity(value as ListDensity);
+ // Apply density to document root
+ if (key === 'density') {
+ applyDensity(value as Density);
}
// Apply animations to document root
@@ -213,7 +215,7 @@ export const useSettingsStore = create()(
resetToDefaults: () => {
set(DEFAULT_SETTINGS);
applyFontSize(DEFAULT_SETTINGS.fontSize);
- applyListDensity(DEFAULT_SETTINGS.listDensity);
+ applyDensity(DEFAULT_SETTINGS.density);
applyAnimations(DEFAULT_SETTINGS.animationsEnabled);
},
@@ -221,7 +223,7 @@ export const useSettingsStore = create()(
const state = get();
const settings = {
fontSize: state.fontSize,
- listDensity: state.listDensity,
+ density: state.density,
animationsEnabled: state.animationsEnabled,
dateFormat: state.dateFormat,
timeFormat: state.timeFormat,
@@ -269,7 +271,7 @@ export const useSettingsStore = create()(
// Apply visual settings
applyFontSize(get().fontSize);
- applyListDensity(get().listDensity);
+ applyDensity(get().density);
applyAnimations(get().animationsEnabled);
// Apply cross-store settings
@@ -395,7 +397,24 @@ export const useSettingsStore = create()(
}),
{
name: 'settings-storage',
- version: 1,
+ version: 2,
+ migrate: (persisted, version) => {
+ const state = persisted as Record;
+ if (version < 2 && state.listDensity) {
+ state.density = state.listDensity;
+ delete state.listDensity;
+ }
+ return state as unknown as SettingsState;
+ },
+ onRehydrateStorage: () => {
+ return (state) => {
+ if (state) {
+ applyFontSize(state.fontSize);
+ applyDensity(state.density);
+ applyAnimations(state.animationsEnabled);
+ }
+ };
+ },
}
)
);
@@ -413,16 +432,42 @@ function applyFontSize(size: FontSize) {
root.style.setProperty('--font-size-base', sizeMap[size]);
}
-function applyListDensity(density: ListDensity) {
+function applyDensity(density: Density) {
if (typeof document === 'undefined') return;
const root = document.documentElement;
- const densityMap = {
- compact: '32px',
- regular: '48px',
- comfortable: '64px',
+
+ const densityValues = {
+ compact: {
+ '--list-item-height': 'auto',
+ '--density-item-py': '4px',
+ '--density-item-gap': '8px',
+ '--density-header-py': '6px',
+ '--density-card-p': '10px',
+ '--density-sidebar-py': '1px',
+ },
+ regular: {
+ '--list-item-height': '48px',
+ '--density-item-py': '12px',
+ '--density-item-gap': '12px',
+ '--density-header-py': '12px',
+ '--density-card-p': '16px',
+ '--density-sidebar-py': '4px',
+ },
+ comfortable: {
+ '--list-item-height': '64px',
+ '--density-item-py': '16px',
+ '--density-item-gap': '16px',
+ '--density-header-py': '16px',
+ '--density-card-p': '20px',
+ '--density-sidebar-py': '6px',
+ },
};
- root.style.setProperty('--list-item-height', densityMap[density]);
+
+ const values = densityValues[density];
+ for (const [prop, val] of Object.entries(values)) {
+ root.style.setProperty(prop, val);
+ }
}
function applyAnimations(enabled: boolean) {
@@ -440,7 +485,7 @@ function applyAnimations(enabled: boolean) {
if (typeof window !== 'undefined') {
const store = useSettingsStore.getState();
applyFontSize(store.fontSize);
- applyListDensity(store.listDensity);
+ applyDensity(store.density);
applyAnimations(store.animationsEnabled);
// Shared sync function used by all store subscribers