169 lines
4.7 KiB
Python
169 lines
4.7 KiB
Python
from dataclasses import dataclass, field
|
|
from typing import Any
|
|
|
|
|
|
# === Condition ===
|
|
|
|
@dataclass
|
|
class Condition:
|
|
"""
|
|
Represents a condition for conditional formatting.
|
|
|
|
Attributes:
|
|
operator: Comparison operator ("==", "!=", "<", "<=", ">", ">=",
|
|
"contains", "startswith", "endswith", "in", "between",
|
|
"isempty", "isnotempty")
|
|
value: Value to compare against (literal, list, or {"col": "..."} for reference)
|
|
negate: If True, inverts the condition result
|
|
case_sensitive: If True, string comparisons are case-sensitive (default False)
|
|
col: Column ID for row-level conditions (evaluate this column instead of current cell)
|
|
row: Row index for column-level conditions (evaluate this row instead of current cell)
|
|
"""
|
|
operator: str
|
|
value: Any = None
|
|
negate: bool = False
|
|
case_sensitive: bool = False
|
|
col: str = None
|
|
row: int = None
|
|
|
|
|
|
# === Style ===
|
|
|
|
@dataclass
|
|
class Style:
|
|
"""
|
|
Represents style properties for cell formatting.
|
|
|
|
Attributes:
|
|
preset: Name of a style preset ("primary", "success", "error", etc.)
|
|
background_color: Background color (hex, CSS name, or CSS variable)
|
|
color: Text color
|
|
font_weight: "normal" or "bold"
|
|
font_style: "normal" or "italic"
|
|
font_size: Font size ("12px", "0.9em")
|
|
text_decoration: "none", "underline", or "line-through"
|
|
"""
|
|
preset: str = None
|
|
background_color: str = None
|
|
color: str = None
|
|
font_weight: str = None
|
|
font_style: str = None
|
|
font_size: str = None
|
|
text_decoration: str = None
|
|
|
|
|
|
# === Formatters ===
|
|
|
|
@dataclass
|
|
class Formatter:
|
|
"""Base class for all formatters."""
|
|
preset: str = None
|
|
|
|
|
|
@dataclass
|
|
class NumberFormatter(Formatter):
|
|
"""
|
|
Formatter for numbers, currencies, and percentages.
|
|
|
|
Attributes:
|
|
prefix: Text before value (e.g., "$")
|
|
suffix: Text after value (e.g., " EUR")
|
|
thousands_sep: Thousands separator (e.g., ",", " ")
|
|
decimal_sep: Decimal separator (e.g., ".", ",")
|
|
precision: Number of decimal places
|
|
multiplier: Multiply value before display (e.g., 100 for percentage)
|
|
"""
|
|
prefix: str = ""
|
|
suffix: str = ""
|
|
thousands_sep: str = ""
|
|
decimal_sep: str = "."
|
|
precision: int = 0
|
|
multiplier: float = 1.0
|
|
|
|
|
|
@dataclass
|
|
class DateFormatter(Formatter):
|
|
"""
|
|
Formatter for dates and datetimes.
|
|
|
|
Attributes:
|
|
format: strftime format pattern (default: "%Y-%m-%d")
|
|
"""
|
|
format: str = "%Y-%m-%d"
|
|
|
|
|
|
@dataclass
|
|
class BooleanFormatter(Formatter):
|
|
"""
|
|
Formatter for boolean values.
|
|
|
|
Attributes:
|
|
true_value: Display string for True
|
|
false_value: Display string for False
|
|
null_value: Display string for None/null
|
|
"""
|
|
true_value: str = "true"
|
|
false_value: str = "false"
|
|
null_value: str = ""
|
|
|
|
|
|
@dataclass
|
|
class TextFormatter(Formatter):
|
|
"""
|
|
Formatter for text transformations.
|
|
|
|
Attributes:
|
|
transform: Text transformation ("uppercase", "lowercase", "capitalize")
|
|
max_length: Maximum length before truncation
|
|
ellipsis: Suffix when truncated (default: "...")
|
|
"""
|
|
transform: str = None
|
|
max_length: int = None
|
|
ellipsis: str = "..."
|
|
|
|
@dataclass
|
|
class ConstantFormatter(Formatter):
|
|
value: str = None
|
|
|
|
@dataclass
|
|
class EnumFormatter(Formatter):
|
|
"""
|
|
Formatter for mapping values to display labels.
|
|
|
|
Attributes:
|
|
source: Data source dict with "type" and "value" keys
|
|
- {"type": "mapping", "value": {"key": "label", ...}}
|
|
- {"type": "datagrid", "value": "grid_id", "value_column": "id", "display_column": "name"}
|
|
default: Label for unknown values
|
|
allow_empty: Show empty option in Select dropdowns
|
|
empty_label: Label for empty option
|
|
order_by: Sort order ("source", "display", "value")
|
|
"""
|
|
source: dict = field(default_factory=dict)
|
|
default: str = ""
|
|
allow_empty: bool = True
|
|
empty_label: str = "-- Select --"
|
|
order_by: str = "source"
|
|
|
|
|
|
# === Format Rule ===
|
|
|
|
@dataclass
|
|
class FormatRule:
|
|
"""
|
|
A formatting rule combining condition, style, and formatter.
|
|
|
|
Rules:
|
|
- style and formatter can appear alone (unconditional formatting)
|
|
- condition cannot appear alone - must be paired with style and/or formatter
|
|
- If condition is present, style/formatter is applied only if condition is met
|
|
|
|
Attributes:
|
|
condition: Optional condition for conditional formatting
|
|
style: Optional style to apply
|
|
formatter: Optional formatter to apply
|
|
"""
|
|
condition: Condition = None
|
|
style: Style = None
|
|
formatter: Formatter = None
|