transitions-refine 0.3.29 → 0.3.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/demo.html CHANGED
@@ -2644,8 +2644,12 @@
2644
2644
  const vn=vm?rootVar(vm[1]):null;
2645
2645
  // distance is a magnitude — direction lives in the CSS (± calc).
2646
2646
  const num=Math.abs(vn?parseFloat(cs.getPropertyValue(vn)):parseFloat(inner));
2647
- if(Number.isFinite(num)&&num>1e-4&&(!bestTranslate||num>bestTranslate.translate))
2648
- bestTranslate={translate:num,...(vn?{translateVarName:vn}:{})};}}
2647
+ // a var-backed translate at rest (0) still reports its var — the
2648
+ // hook for ADDING a slide distance the source neutralized (e.g. a
2649
+ // generic text swap with --text-swap-translate-y: 0).
2650
+ if(Number.isFinite(num)&&(num>1e-4||vn)){
2651
+ const better=!bestTranslate||num>bestTranslate.translate||(bestTranslate.translateVarName==null&&vn);
2652
+ if(better)bestTranslate={translate:num,...(vn?{translateVarName:vn}:{})};}}}
2649
2653
  }else{
2650
2654
  const fm=txt.match(/filter\s*:\s*([^;}]+)/i);
2651
2655
  if(fm){const bl=fm[1].match(/blur\(\s*([^)]+)\)/i);
@@ -5168,10 +5172,32 @@
5168
5172
  if(sp.toSuf) active=stEls.length?stEls.some(e=>safeMatches(e,sp.toSuf)):true; // open
5169
5173
  else if(sp.fromSuf) active=stEls.length?stEls.some(e=>!safeMatches(e,sp.fromSuf)):true; // close = not in fromState
5170
5174
  else active=true; // no state info → always reflect (degrades to old behavior)
5175
+ const spVars={}; // union of this phase's value vars (scale/blur/translate)
5176
+ const memberEls=[]; // {el,css} of resolved members this phase
5171
5177
  for(const mm of sp.members) for(const el of txMemberEls(mm.selector,sp.stateTarget)){
5172
5178
  if(inUI(el))continue;
5173
- if(mm.vars&&Object.keys(mm.vars).length){ const ex=desiredVars.get(el)||{}; desiredVars.set(el,{...ex,...mm.vars}); }
5179
+ if(mm.vars&&Object.keys(mm.vars).length){ const ex=desiredVars.get(el)||{}; desiredVars.set(el,{...ex,...mm.vars}); Object.assign(spVars,mm.vars); }
5174
5180
  if(active) desiredCss.set(el,mm.css);
5181
+ memberEls.push({el,css:mm.css});
5182
+ }
5183
+ // SHARED-VAR recipes (icon/text swap, page slide, …) drive the non-
5184
+ // resting look through a custom property read by SEVERAL stacked
5185
+ // members from a COMMON ANCESTOR — and the "from" member is often not
5186
+ // even a captured lane (e.g. only opacity animates at rest, so the
5187
+ // entering icon has no filter/transform lane). Writing the var inline
5188
+ // on one member can't reach its siblings, and only the captured
5189
+ // member gets the recipe timing. So when a phase carries value vars:
5190
+ // (1) set the vars on the stateTarget container — every descendant
5191
+ // member inherits them, and each state's own CSS rule
5192
+ // (active → blur(0)/scale(1); inactive → blur(var)/scale(var))
5193
+ // gates where they actually show; and
5194
+ // (2) give the same recipe timing to the member's same-slot stacked
5195
+ // siblings (element children of the same parent sharing a class)
5196
+ // so the ENTERING member animates the new filter/transform lanes
5197
+ // instead of snapping.
5198
+ if(Object.keys(spVars).length){
5199
+ for(const el of stEls){ if(inUI(el))continue; const ex=desiredVars.get(el)||{}; desiredVars.set(el,{...ex,...spVars}); }
5200
+ if(active) for(const{el,css}of memberEls){ const parent=el.parentElement; if(!parent)continue; const cls=[...(el.classList||[])]; for(const sib of Array.from(parent.children)){ if(sib===el||inUI(sib)||!sib.classList)continue; if(cls.some(c=>sib.classList.contains(c))&&!desiredCss.has(sib))desiredCss.set(sib,css); } }
5175
5201
  }
5176
5202
  }
5177
5203
  const allEls=new Set([...desiredCss.keys(),...desiredVars.keys()]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "transitions-refine",
3
- "version": "0.3.29",
3
+ "version": "0.3.31",
4
4
  "description": "Live, agent-driven Refine panel for CSS/Motion transitions — injects a timeline + Refine UI and runs transitions.dev suggestions via your coding agent.",
5
5
  "type": "module",
6
6
  "bin": {
package/server/relay.mjs CHANGED
@@ -269,6 +269,7 @@ const RECIPES_BLOCK = [
269
269
  " - Panel reveal → filter blur 2px (Small)",
270
270
  " - Page side-by-side → filter blur 3px (Medium) AND transform translate distance 8px, both on the sliding page",
271
271
  " - Icon swap → filter blur 2px (Small) AND transform scale 0.25 (start-scale) on the swapping icon",
272
+ " - Text states swap → filter blur 2px (Small) AND transform translateY distance 4px, on the swapping text (exit and enter both settle to blur 0 / translate 0)",
272
273
  " - Skeleton loader and reveal → filter blur 2px (Small)",
273
274
  " - Texts reveal → filter blur 3px (Medium)",
274
275
  " - Success check → filter blur 8px (Large)",