Coverage for src / lexigram / admin / actions / header_manager / density.py: 0%

46 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-08-11 02:25 +0800

1""" 

2Table density management for header actions. 

3 

4Handles table row density settings and user preferences. 

5""" 

6 

7from __future__ import annotations 

8 

9from collections.abc import Callable 

10 

11from lexigram.admin.actions.header_manager.types import DensityConfig, TableDensity 

12 

13 

14class DensityManager: 

15 """Manages table density state and preferences.""" 

16 

17 def __init__( 

18 self, 

19 config: DensityConfig, 

20 storage: Callable[[str, str], None] | None = None, 

21 retriever: Callable[[str], str | None] | None = None, 

22 ) -> None: 

23 """Initialize the density manager. 

24 

25 Args: 

26 config: Density configuration 

27 storage: Function to store preferences (key, value) 

28 retriever: Function to retrieve preferences (key) -> value 

29 """ 

30 self.config = config 

31 self._storage = storage 

32 self._retriever = retriever 

33 self._current_density = config.default 

34 

35 # Load saved preferences 

36 if config.save_preference and retriever: 

37 saved = retriever(config.storage_key) 

38 if saved: 

39 try: 

40 self._current_density = TableDensity(saved) 

41 except ValueError: 

42 self._current_density = config.default 

43 

44 @property 

45 def current_density(self) -> TableDensity: 

46 """Get current density setting.""" 

47 return self._current_density 

48 

49 @property 

50 def available_options(self) -> list[TableDensity]: 

51 """Get available density options.""" 

52 return self.config.options.copy() 

53 

54 def set_density(self, density: TableDensity) -> None: 

55 """Set table density.""" 

56 if density in self.config.options: 

57 self._current_density = density 

58 self._save_preferences() 

59 

60 def cycle_density(self) -> TableDensity: 

61 """Cycle to next density option.""" 

62 current_index = self.config.options.index(self._current_density) 

63 next_index = (current_index + 1) % len(self.config.options) 

64 next_density = self.config.options[next_index] 

65 self.set_density(next_density) 

66 return next_density 

67 

68 def reset_to_default(self) -> None: 

69 """Reset to default density.""" 

70 self._current_density = self.config.default 

71 self._save_preferences() 

72 

73 def _save_preferences(self) -> None: 

74 """Save current preferences.""" 

75 if self.config.save_preference and self._storage: 

76 self._storage(self.config.storage_key, self._current_density.value) 

77 

78 def get_css_class(self) -> str: 

79 """Get CSS class for current density.""" 

80 return f"table-density-{self._current_density.value}" 

81 

82 def get_row_height(self) -> str: 

83 """Get row height for current density.""" 

84 heights = { 

85 TableDensity.COMPACT: "32px", 

86 TableDensity.NORMAL: "48px", 

87 TableDensity.COMFORTABLE: "64px", 

88 } 

89 return heights.get(self._current_density, "48px") 

90 

91 def get_font_size(self) -> str: 

92 """Get font size for current density.""" 

93 sizes = { 

94 TableDensity.COMPACT: "0.875rem", 

95 TableDensity.NORMAL: "1rem", 

96 TableDensity.COMFORTABLE: "1.125rem", 

97 } 

98 return sizes.get(self._current_density, "1rem")