transitions-refine 0.3.1 → 0.3.3
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 +36 -17
- package/package.json +1 -1
package/demo.html
CHANGED
|
@@ -346,7 +346,7 @@
|
|
|
346
346
|
.tl-main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
|
|
347
347
|
.tl-inspector { flex: 0 0 280px; padding: 14px 16px 18px; display: flex; flex-direction: column;
|
|
348
348
|
border-left: 1px solid var(--c-line); min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
|
|
349
|
-
.tl-insp-title { font-size: 13px; font-weight: 500; line-height: 18px; color: #171717; margin-bottom:
|
|
349
|
+
.tl-insp-title { font-size: 13px; font-weight: 500; line-height: 18px; color: #171717; margin-bottom: 10px; text-transform: capitalize; }
|
|
350
350
|
.tl-insp-label { font-size: 12px; line-height: 18px; color: #737373; margin: 10px 0 6px; }
|
|
351
351
|
|
|
352
352
|
/* ── tracks / ruler ── */
|
|
@@ -1076,23 +1076,32 @@
|
|
|
1076
1076
|
function easingToCubic(v) { const p=kwMap.get(v); if(p)return p.cubic; const m=v.match(/cubic-bezier\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/); if(m)return[parseFloat(m[1]),parseFloat(m[2]),parseFloat(m[3]),parseFloat(m[4])]; return null; }
|
|
1077
1077
|
|
|
1078
1078
|
// Easing dropdown library. `group` rows are non-selectable section headers.
|
|
1079
|
-
// Motion tokens
|
|
1080
|
-
// skill (
|
|
1079
|
+
// The "Motion tokens (transitions.dev)" set is verbatim from the transitions.dev
|
|
1080
|
+
// skill's Easings table (name, value and usage all match the skill); the
|
|
1081
|
+
// "Standard" set is the five native CSS timing-function keywords.
|
|
1081
1082
|
const EASING_LIBRARY = [
|
|
1082
1083
|
{ group:"Motion tokens (transitions.dev)" },
|
|
1083
|
-
{ label:"Smooth out", value:"cubic-bezier(0.22, 1, 0.36, 1)", usage:"
|
|
1084
|
-
{ label:"
|
|
1085
|
-
{ label:"
|
|
1086
|
-
{ label:"
|
|
1087
|
-
{ label:"
|
|
1088
|
-
{ label:"
|
|
1089
|
-
{
|
|
1084
|
+
{ label:"Smooth ease out", value:"cubic-bezier(0.22, 1, 0.36, 1)", usage:"Modal / dropdown / panel open + close, page slide, resize, position change." },
|
|
1085
|
+
{ label:"Ease in out", value:"ease-in-out", usage:"Icon swap, text swap, text reveal, skeleton reveal." },
|
|
1086
|
+
{ label:"Ease out", value:"ease-out", usage:"Tooltip open / close." },
|
|
1087
|
+
{ label:"Linear", value:"linear", usage:"Shimmer, skeleton pulse, spinner." },
|
|
1088
|
+
{ label:"Bouncy overshoot", value:"cubic-bezier(0.34, 1.36, 0.64, 1)", usage:"Badge pop open — a small overshoot past the target." },
|
|
1089
|
+
{ label:"Strong bouncy overshoot", value:"cubic-bezier(0.34, 3.85, 0.64, 1)", usage:"Bouncy hover-out (avatar return) — aggressive, spring-like overshoot." },
|
|
1090
|
+
{ group:"Standard" },
|
|
1091
|
+
{ label:"ease", value:"ease", usage:"CSS default — gentle ease in, ease out." },
|
|
1092
|
+
{ label:"ease-in", value:"ease-in", usage:"Accelerate from rest — slow start, fast finish." },
|
|
1093
|
+
{ label:"ease-out", value:"ease-out", usage:"Decelerate to rest — fast start, slow finish." },
|
|
1094
|
+
{ label:"ease-in-out", value:"ease-in-out", usage:"Accelerate then decelerate — symmetric." },
|
|
1095
|
+
{ label:"linear", value:"linear", usage:"Constant speed — no acceleration." },
|
|
1090
1096
|
{ group:"Custom" },
|
|
1091
1097
|
{ label:"cubic-bezier(\u2026)", value:"__cubic" },
|
|
1092
1098
|
{ label:"custom", value:"__custom" },
|
|
1093
1099
|
];
|
|
1094
1100
|
const normEase = s => (s||"").replace(/\s+/g,"");
|
|
1095
|
-
|
|
1101
|
+
// First occurrence wins, so a shared keyword (e.g. ease-out) shows its
|
|
1102
|
+
// semantic transitions.dev name rather than the bare Standard keyword.
|
|
1103
|
+
const EASING_LABEL = EASING_LIBRARY.filter(o=>o.value&&o.value[0]!=="_")
|
|
1104
|
+
.reduce((m,o)=>{const k=normEase(o.value);if(!m.has(k))m.set(k,o.label);return m;},new Map());
|
|
1096
1105
|
function easingLabel(v){ return EASING_LABEL.get(normEase(v)) || null; }
|
|
1097
1106
|
|
|
1098
1107
|
// Most-common predefined springs. tension/friction follow react-spring's
|
|
@@ -1943,6 +1952,9 @@
|
|
|
1943
1952
|
const easeRef = useRef(null);
|
|
1944
1953
|
const [easeOpen, setEaseOpen] = useState(false);
|
|
1945
1954
|
const selLabel = easingLabel(easing) || (isCubic ? "cubic-bezier(\u2026)" : easing ? easing : "custom");
|
|
1955
|
+
// first selectable row whose value matches — so a keyword shared between the
|
|
1956
|
+
// transitions.dev and Standard groups only checks once (the first one).
|
|
1957
|
+
const selEaseIdx = EASING_LIBRARY.findIndex(o=>o.value&&o.value[0]!=="_"&&normEase(o.value)===normEase(easing));
|
|
1946
1958
|
const pickEase = useCallback(v=>{
|
|
1947
1959
|
if(v==="__cubic") setEasing(`cubic-bezier(${cb.join(", ")})`);
|
|
1948
1960
|
else if(v==="__custom") setEasing("");
|
|
@@ -1996,9 +2008,9 @@
|
|
|
1996
2008
|
width:Math.max(248,(easeRef.current&&easeRef.current.offsetWidth)||248),align:"left"},
|
|
1997
2009
|
EASING_LIBRARY.map((o,i)=> o.group
|
|
1998
2010
|
? h("div",{key:"g"+i,className:"tl-menu-group"},o.group)
|
|
1999
|
-
: h(MenuItem,{key:
|
|
2011
|
+
: h(MenuItem,{key:"e"+i,active:selEaseIdx>=0?i===selEaseIdx:(o.value===mode),
|
|
2000
2012
|
onClick:()=>pickEase(o.value),
|
|
2001
|
-
right:(
|
|
2013
|
+
right:(i===selEaseIdx)&&h("span",{className:"tl-menu-check"},h(Ic,{name:"check"}))},
|
|
2002
2014
|
h("span",{className:"tl-menu-text"},o.label),
|
|
2003
2015
|
o.usage&&h("span",{className:"t-tt-wrap tl-menu-help",
|
|
2004
2016
|
onClick:e=>e.stopPropagation(),onMouseDown:e=>e.stopPropagation()},
|
|
@@ -2466,8 +2478,10 @@
|
|
|
2466
2478
|
setGroupScanState("scanning");
|
|
2467
2479
|
// wait for the flat DOM scan to settle (count stable twice) so the agent
|
|
2468
2480
|
// sees every transition, not a partial set discovered progressively.
|
|
2469
|
-
|
|
2470
|
-
|
|
2481
|
+
// Capped (~12s) so a page with no resolvable flat entries can never hang
|
|
2482
|
+
// the panel on "Grouping…" — it falls through to the empty-flat check below.
|
|
2483
|
+
let prev=-1,stable=0,iters=0;
|
|
2484
|
+
while(scanTokenRef.current===token&&iters++<40){
|
|
2471
2485
|
const n=registry.getAll().filter(e=>e.kind!=="phase").length;
|
|
2472
2486
|
if(n>0&&n===prev){if(++stable>=2)break;}else stable=0;
|
|
2473
2487
|
prev=n;
|
|
@@ -2503,11 +2517,16 @@
|
|
|
2503
2517
|
setGroupScanState("error");
|
|
2504
2518
|
}catch(e){ setGroupScanState("error"); /* relay down → stay flat, retry next open */ }
|
|
2505
2519
|
},[registry,GROUP_STORE_KEY,flatSig,readGroupCache]);
|
|
2506
|
-
// manual "Rescan transitions" — drop the cache
|
|
2520
|
+
// manual "Rescan transitions" — drop the cache AND clear the in-memory
|
|
2521
|
+
// groups first. Once groups claim every DOM transition the snapshot has no
|
|
2522
|
+
// "flat" entries left, so the settle loop above would otherwise spin forever
|
|
2523
|
+
// waiting for a flat count that never arrives. Clearing groups re-surfaces
|
|
2524
|
+
// the flat entries the agent needs to re-group.
|
|
2507
2525
|
const rescanTransitions=useCallback(()=>{
|
|
2508
2526
|
try{localStorage.removeItem(GROUP_STORE_KEY);}catch{}
|
|
2527
|
+
registry.clearGroups();
|
|
2509
2528
|
runGroupScan();
|
|
2510
|
-
},[runGroupScan,GROUP_STORE_KEY]);
|
|
2529
|
+
},[runGroupScan,GROUP_STORE_KEY,registry]);
|
|
2511
2530
|
// On mount, run the group resolver once. It waits for the flat scan to
|
|
2512
2531
|
// settle, then either re-applies cached groups (when the content signature
|
|
2513
2532
|
// matches — a pure cache read, no agent) or kicks off a fresh agent scan
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "transitions-refine",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
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": {
|