pyx/pss.py
2025-07-23 14:19:36 -04:00

90 lines
2.4 KiB
Python

from typing import TypedDict, Union, Literal, Tuple, Optional, cast
# --- Units and Sizes ---
MediaQueryCheck = Literal["max-width", "min-width", "max-height", "min-height"]
Unit = Literal["px", "em", "rem", "%", "vh", "vw"]
Size = Tuple[float, Unit] # e.g., (16.0, "px")
MediaQuery = Tuple[MediaQueryCheck, float, Unit]
# --- Colors ---
RGB = Tuple[float, float, float] # 0-255 or 0.0-1.0
RGBA = Tuple[float, float, float, float] # includes alpha
Color = Union[RGB, RGBA]
# --- Positions ---
PositionKeyword = Literal["static", "relative", "absolute", "fixed", "sticky"]
# --- Display ---
Display = Literal["none", "block", "inline", "inline-block", "flex", "grid"]
# --- Alignment ---
TextAlign = Literal["left", "right", "center", "justify", "start", "end"]
# --- Overflow ---
Overflow = Literal["visible", "hidden", "scroll", "auto", "clip"]
# --- Border Style ---
BorderStyle = Literal["none", "solid", "dashed", "dotted", "double", "groove", "ridge", "inset", "outset"]
# --- Length / Size or keyword ---
AutoSize = Union[Size, Literal["auto"]]
class CSS(TypedDict, total=False):
color: Color
backgroundColor: Color
fontSize: Size
margin: Union[AutoSize, Tuple[AutoSize, AutoSize], Tuple[AutoSize, AutoSize, AutoSize, AutoSize]]
padding: Union[AutoSize, Tuple[AutoSize, AutoSize], Tuple[AutoSize, AutoSize, AutoSize, AutoSize]]
width: AutoSize
height: AutoSize
display: Display
position: PositionKeyword
top: AutoSize
left: AutoSize
right: AutoSize
bottom: AutoSize
textAlign: TextAlign
overflow: Overflow
borderColor: Color
borderWidth: Size
borderStyle: BorderStyle
opacity: float # 0.0 to 1.0
zIndex: int
lineHeight: Union[float, Size]
# --- Media Queries ---
ChildMQ = Tuple[Size, MediaQueryCheck]
ScopedCSS = Tuple[MediaQuery, CSS]
def Styles(
color: Optional[Color] = None,
backgroundColor: Optional[Color] = None,
fontSize: Optional[Size] = None,
display: Optional[Display] = None,
) -> CSS:
return cast(CSS, {k: v for k, v in locals().items() if v is not None})
def ScopedStyles(
mediaQuery: MediaQuery,
styles: CSS
) -> ScopedCSS:
return (mediaQuery, styles)
test = ScopedStyles(
("max-width", 1024, "px"),
{
"fontSize":(16, "px"),
"color":(255, 0, 0),
"backgroundColor":(0, 255, 0),
"display":"flex",
}
)
print(test)