Files
MyFastHtml/src/myfasthtml/core/formatting/dataclasses.py

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