Merge branch 'worktree-cssx-components' into macros
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 14m0s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 14m0s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -493,9 +493,9 @@ def _sf_define(expr: list, env: dict) -> Any:
|
||||
|
||||
|
||||
def _sf_defstyle(expr: list, env: dict) -> Any:
|
||||
"""``(defstyle card-base (css :rounded-xl :bg-white :shadow))``
|
||||
"""``(defstyle card-base ...)``
|
||||
|
||||
Evaluates body → StyleValue, binds to name in env.
|
||||
Evaluates body and binds to name in env.
|
||||
"""
|
||||
if len(expr) < 3:
|
||||
raise EvalError("defstyle requires name and body")
|
||||
@@ -507,63 +507,6 @@ def _sf_defstyle(expr: list, env: dict) -> Any:
|
||||
return value
|
||||
|
||||
|
||||
def _sf_defkeyframes(expr: list, env: dict) -> Any:
|
||||
"""``(defkeyframes fade-in (from (css :opacity-0)) (to (css :opacity-100)))``
|
||||
|
||||
Builds @keyframes rule from steps, registers it, and binds the animation.
|
||||
"""
|
||||
from .types import StyleValue
|
||||
from .css_registry import register_generated_rule
|
||||
from .style_dict import KEYFRAMES
|
||||
|
||||
if len(expr) < 3:
|
||||
raise EvalError("defkeyframes requires name and at least one step")
|
||||
name_sym = expr[1]
|
||||
if not isinstance(name_sym, Symbol):
|
||||
raise EvalError(f"defkeyframes name must be symbol, got {type(name_sym).__name__}")
|
||||
|
||||
kf_name = name_sym.name
|
||||
|
||||
# Build @keyframes rule from steps
|
||||
steps: list[str] = []
|
||||
for step_expr in expr[2:]:
|
||||
if not isinstance(step_expr, list) or len(step_expr) < 2:
|
||||
raise EvalError("defkeyframes step must be (selector (css ...))")
|
||||
selector = step_expr[0]
|
||||
if isinstance(selector, Symbol):
|
||||
selector = selector.name
|
||||
else:
|
||||
selector = str(selector)
|
||||
body = _trampoline(_eval(step_expr[1], env))
|
||||
if isinstance(body, StyleValue):
|
||||
decls = body.declarations
|
||||
elif isinstance(body, str):
|
||||
decls = body
|
||||
else:
|
||||
raise EvalError(f"defkeyframes step body must be css/string, got {type(body).__name__}")
|
||||
steps.append(f"{selector}{{{decls}}}")
|
||||
|
||||
kf_rule = f"@keyframes {kf_name}{{{' '.join(steps)}}}"
|
||||
|
||||
# Register in KEYFRAMES so animate-{name} works
|
||||
KEYFRAMES[kf_name] = kf_rule
|
||||
# Clear resolver cache so new keyframes are picked up
|
||||
from .style_resolver import _resolve_cached
|
||||
_resolve_cached.cache_clear()
|
||||
|
||||
# Create a StyleValue for the animation property
|
||||
import hashlib
|
||||
h = hashlib.sha256(kf_rule.encode()).hexdigest()[:6]
|
||||
sv = StyleValue(
|
||||
class_name=f"sx-{h}",
|
||||
declarations=f"animation-name:{kf_name}",
|
||||
keyframes=((kf_name, kf_rule),),
|
||||
)
|
||||
register_generated_rule(sv)
|
||||
env[kf_name] = sv
|
||||
return sv
|
||||
|
||||
|
||||
def _sf_defcomp(expr: list, env: dict) -> Component:
|
||||
"""``(defcomp ~name (&key ...) [:affinity :client|:server] body)``"""
|
||||
if len(expr) < 4:
|
||||
@@ -1077,7 +1020,6 @@ _SPECIAL_FORMS: dict[str, Any] = {
|
||||
"fn": _sf_lambda,
|
||||
"define": _sf_define,
|
||||
"defstyle": _sf_defstyle,
|
||||
"defkeyframes": _sf_defkeyframes,
|
||||
"defcomp": _sf_defcomp,
|
||||
"defrelation": _sf_defrelation,
|
||||
"begin": _sf_begin,
|
||||
|
||||
Reference in New Issue
Block a user