transitions-refine 0.3.22 → 0.3.23

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.
Files changed (2) hide show
  1. package/demo.html +39 -12
  2. package/package.json +1 -1
package/demo.html CHANGED
@@ -1202,8 +1202,11 @@
1202
1202
  gap: 8px; box-sizing: border-box; padding: 7.5px 7.5px 7.5px 14px;
1203
1203
  border-bottom: 1px solid #f0f0f0; }
1204
1204
  .tl-refine-titles { min-width: 0; }
1205
- .tl-refine-titles h3 { font-size: 13px; font-weight: 500; line-height: 14px; color: #17181c; }
1206
- .tl-refine-titles p { margin-top: 2px; font-size: 12px; font-weight: 400; line-height: 14px; color: #676767;
1205
+ /* Explicit margin:0 the injected build strips the demo-only global *{margin:0}
1206
+ reset, so without this h3/p inherit the UA default block margins (~1em) and
1207
+ the header balloons to ~82px instead of matching the 52px timeline top bar. */
1208
+ .tl-refine-titles h3 { margin: 0; font-size: 13px; font-weight: 500; line-height: 14px; color: #17181c; }
1209
+ .tl-refine-titles p { margin: 2px 0 0; font-size: 12px; font-weight: 400; line-height: 14px; color: #676767;
1207
1210
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 190px; }
1208
1211
  .tl-refine-actions { flex: none; display: flex; align-items: center; gap: 2px; }
1209
1212
  .tl-refine-mode { display: flex; align-items: center; gap: 6px; height: 36px;
@@ -4184,7 +4187,19 @@
4184
4187
  if(!specs.length) return ()=>txTeardownPhase(store);
4185
4188
  const varsKey=v=>Object.keys(v).sort().map(k=>k+":"+v[k]).join(";");
4186
4189
  const recompute=()=>{
4187
- const desired=new Map(); // el → {css,vars}
4190
+ // Two concerns, applied DIFFERENTLY:
4191
+ // • TIMING (the inline `transition` string) is direction-specific —
4192
+ // open and close share one element + one inline slot, so it must be
4193
+ // GATED to the active state (open's timing only while open, etc).
4194
+ // • VALUE VARS (scale/blur custom props, e.g. --dropdown-pre-scale)
4195
+ // define a STATE's resting value, not the transition itself. A
4196
+ // "from" var only shows in the OPPOSITE state, so gating it to the
4197
+ // destination state means it's never visible (this was the bug:
4198
+ // accepting a scale edit did nothing live). They're safe to apply
4199
+ // PERSISTENTLY — each var only affects whichever state references
4200
+ // it — which previews both directions. So: vars = always, css = gated.
4201
+ const desiredCss=new Map(); // el → css (state-gated)
4202
+ const desiredVars=new Map(); // el → {name:value} (persistent)
4188
4203
  for(const sp of specs){
4189
4204
  const stEls=fresh(sp.stateTarget);
4190
4205
  // is THIS phase's destination state active on the stateTarget RIGHT NOW?
@@ -4192,19 +4207,31 @@
4192
4207
  if(sp.toSuf) active=stEls.length?stEls.some(e=>safeMatches(e,sp.toSuf)):true; // open
4193
4208
  else if(sp.fromSuf) active=stEls.length?stEls.some(e=>!safeMatches(e,sp.fromSuf)):true; // close = not in fromState
4194
4209
  else active=true; // no state info → always reflect (degrades to old behavior)
4195
- if(!active)continue;
4196
- for(const mm of sp.members) for(const el of txMemberEls(mm.selector,sp.stateTarget)){ if(inUI(el))continue; desired.set(el,{css:mm.css,vars:mm.vars}); }
4210
+ for(const mm of sp.members) for(const el of txMemberEls(mm.selector,sp.stateTarget)){
4211
+ if(inUI(el))continue;
4212
+ if(mm.vars&&Object.keys(mm.vars).length){ const ex=desiredVars.get(el)||{}; desiredVars.set(el,{...ex,...mm.vars}); }
4213
+ if(active) desiredCss.set(el,mm.css);
4214
+ }
4197
4215
  }
4198
- for(const [el,d] of desired){
4199
- const vars=d.vars||{},vk=varsKey(vars),cur=store.applied.get(el);
4200
- if(cur&&cur.css===d.css&&cur.vk===vk)continue;
4201
- if(!cur) store.applied.set(el,{prevInline:el.style.transition||"",prevVars:Object.fromEntries(Object.keys(vars).map(n=>[n,el.style.getPropertyValue(n)])),css:d.css,vk});
4202
- else store.applied.set(el,{prevInline:cur.prevInline,prevVars:cur.prevVars,css:d.css,vk});
4203
- try{el.style.transition=d.css;}catch{}
4216
+ const allEls=new Set([...desiredCss.keys(),...desiredVars.keys()]);
4217
+ for(const el of allEls){
4218
+ const css=desiredCss.has(el)?desiredCss.get(el):null;
4219
+ const vars=desiredVars.get(el)||{};
4220
+ const vk=varsKey(vars);
4221
+ const cur=store.applied.get(el);
4222
+ if(cur&&cur.css===css&&cur.vk===vk)continue;
4223
+ if(!cur){
4224
+ store.applied.set(el,{prevInline:el.style.transition||"",prevVars:Object.fromEntries(Object.keys(vars).map(n=>[n,el.style.getPropertyValue(n)])),css,vk});
4225
+ }else{
4226
+ const prevVars={...(cur.prevVars||{})};for(const n of Object.keys(vars)){if(!(n in prevVars))prevVars[n]=el.style.getPropertyValue(n);}
4227
+ store.applied.set(el,{prevInline:cur.prevInline,prevVars,css,vk});
4228
+ }
4229
+ const rec=store.applied.get(el);
4230
+ try{el.style.transition=css!=null?css:rec.prevInline;}catch{}
4204
4231
  for(const n of Object.keys(vars)){try{el.style.setProperty(n,vars[n]);}catch{}}
4205
4232
  }
4206
4233
  for(const [el,rec] of Array.from(store.applied)){
4207
- if(desired.has(el))continue;
4234
+ if(allEls.has(el))continue;
4208
4235
  try{el.style.transition=rec.prevInline;}catch{}
4209
4236
  for(const n of Object.keys(rec.prevVars||{})){try{const pv=rec.prevVars[n];if(pv)el.style.setProperty(n,pv);else el.style.removeProperty(n);}catch{}}
4210
4237
  store.applied.delete(el);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "transitions-refine",
3
- "version": "0.3.22",
3
+ "version": "0.3.23",
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": {