@smwb/ui-solid 0.12.0 → 0.12.1

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.
@@ -1,40 +1,43 @@
1
- import { createSignal as v, createEffect as x, onCleanup as D } from "solid-js";
2
- const F = (...t) => t.filter(Boolean).join(" ");
3
- function C(t) {
4
- const [l, m] = v(t.in()), [A, i] = v("");
5
- let o = !0, r, n, s;
6
- const f = () => {
7
- r !== void 0 && clearTimeout(r), n !== void 0 && cancelAnimationFrame(n), s !== void 0 && cancelAnimationFrame(s), r = void 0, n = void 0, s = void 0;
8
- }, u = (c, e, a, d, p) => {
9
- i(c ?? ""), n = requestAnimationFrame(() => {
10
- s = requestAnimationFrame(() => i(F(c, e)));
11
- }), r = setTimeout(() => {
12
- p ? p() : i(a ?? "");
13
- }, d);
1
+ import { createSignal as A, createEffect as F, onCleanup as T } from "solid-js";
2
+ const C = (...t) => t.filter(Boolean).join(" ");
3
+ function j(t) {
4
+ const [f, u] = A(t.in()), [x, r] = A("");
5
+ let l = !0, o, n, a, s = 0;
6
+ const m = () => {
7
+ s++, o !== void 0 && clearTimeout(o), n !== void 0 && cancelAnimationFrame(n), a !== void 0 && cancelAnimationFrame(a), o = void 0, n = void 0, a = void 0;
8
+ }, v = (c, e, i, D, d) => {
9
+ const p = s;
10
+ r(c ?? ""), n = requestAnimationFrame(() => {
11
+ n = void 0, p === s && (a = requestAnimationFrame(() => {
12
+ a = void 0, p === s && r(C(c, e));
13
+ }));
14
+ }), o = setTimeout(() => {
15
+ m(), d ? d() : r(i ?? "");
16
+ }, D);
14
17
  };
15
- return x(() => {
18
+ return F(() => {
16
19
  const c = t.in();
17
- f();
20
+ m();
18
21
  const e = t.classNames;
19
22
  if (c)
20
- if (m(!0), o && !t.appear)
21
- i(e.enterDone ?? "");
23
+ if (u(!0), l && !t.appear)
24
+ r(e.enterDone ?? "");
22
25
  else {
23
- const a = o && !!t.appear;
24
- u(
25
- a ? e.appear : e.enter,
26
- a ? e.appearActive : e.enterActive,
27
- a ? e.appearDone ?? e.enterDone : e.enterDone,
28
- a ? t.timeout.appear ?? t.timeout.enter : t.timeout.enter
26
+ const i = l && !!t.appear;
27
+ v(
28
+ i ? e.appear : e.enter,
29
+ i ? e.appearActive : e.enterActive,
30
+ i ? e.appearDone ?? e.enterDone : e.enterDone,
31
+ i ? t.timeout.appear ?? t.timeout.enter : t.timeout.enter
29
32
  );
30
33
  }
31
- else l() && u(e.exit, e.exitActive, e.exitDone, t.timeout.exit, () => {
32
- m(!1), i("");
34
+ else f() && v(e.exit, e.exitActive, e.exitDone, t.timeout.exit, () => {
35
+ u(!1), r("");
33
36
  });
34
- o = !1;
35
- }), D(f), { mounted: l, classes: A };
37
+ l = !1;
38
+ }), T(m), { mounted: f, classes: x };
36
39
  }
37
40
  export {
38
- C as createCssTransition
41
+ j as createCssTransition
39
42
  };
40
43
  //# sourceMappingURL=createCssTransition.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"createCssTransition.js","sources":["../../../src/primitives/createCssTransition.ts"],"sourcesContent":["import { type Accessor, createEffect, createSignal, onCleanup } from \"solid-js\";\n\nexport interface CssTransitionClassNames {\n appear?: string;\n appearActive?: string;\n appearDone?: string;\n enter?: string;\n enterActive?: string;\n enterDone?: string;\n exit?: string;\n exitActive?: string;\n exitDone?: string;\n}\n\nexport interface CreateCssTransitionOptions {\n in: Accessor<boolean>;\n timeout: { appear?: number; enter: number; exit: number };\n classNames: CssTransitionClassNames;\n /** Animate the very first mount when `in` is already true. */\n appear?: boolean;\n}\n\nexport interface CssTransitionState {\n /** Whether the node should be in the DOM (mountOnEnter + unmountOnExit). */\n mounted: Accessor<boolean>;\n /** Transition classes to apply to the node for the current phase. */\n classes: Accessor<string>;\n}\n\nconst join = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\n/**\n * Single-node CSS transition with mountOnEnter + unmountOnExit semantics — a\n * dependency-free replacement for react-transition-group's CSSTransition. Uses\n * a double rAF to flush the start class before the active class so the CSS\n * transition runs, and a timeout to advance to the done/unmounted phase.\n */\nexport function createCssTransition(options: CreateCssTransitionOptions): CssTransitionState {\n const [mounted, setMounted] = createSignal(options.in());\n const [classes, setClasses] = createSignal(\"\");\n\n let first = true;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let raf1: number | undefined;\n let raf2: number | undefined;\n\n const clearTimers = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n if (raf1 !== undefined) cancelAnimationFrame(raf1);\n if (raf2 !== undefined) cancelAnimationFrame(raf2);\n timer = undefined;\n raf1 = undefined;\n raf2 = undefined;\n };\n\n const run = (start: string | undefined, active: string | undefined, done: string | undefined, duration: number, onEnd?: () => void): void => {\n setClasses(start ?? \"\");\n raf1 = requestAnimationFrame(() => {\n raf2 = requestAnimationFrame(() => setClasses(join(start, active)));\n });\n timer = setTimeout(() => {\n if (onEnd) onEnd();\n else setClasses(done ?? \"\");\n }, duration);\n };\n\n createEffect(() => {\n const show = options.in();\n clearTimers();\n const cls = options.classNames;\n\n if (show) {\n setMounted(true);\n if (first && !options.appear) {\n setClasses(cls.enterDone ?? \"\");\n } else {\n const useAppear = first && !!options.appear;\n run(\n useAppear ? cls.appear : cls.enter,\n useAppear ? cls.appearActive : cls.enterActive,\n useAppear ? (cls.appearDone ?? cls.enterDone) : cls.enterDone,\n useAppear ? (options.timeout.appear ?? options.timeout.enter) : options.timeout.enter\n );\n }\n } else if (mounted()) {\n run(cls.exit, cls.exitActive, cls.exitDone, options.timeout.exit, () => {\n setMounted(false);\n setClasses(\"\");\n });\n }\n first = false;\n });\n\n onCleanup(clearTimers);\n\n return { mounted, classes };\n}\n"],"names":["join","parts","createCssTransition","options","mounted","setMounted","createSignal","classes","setClasses","first","timer","raf1","raf2","clearTimers","run","start","active","done","duration","onEnd","createEffect","show","cls","useAppear","onCleanup"],"mappings":";AA6BA,MAAMA,IAAO,IAAIC,MAA6CA,EAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AAQrF,SAASC,EAAoBC,GAAyD;AAC3F,QAAM,CAACC,GAASC,CAAU,IAAIC,EAAaH,EAAQ,IAAI,GACjD,CAACI,GAASC,CAAU,IAAIF,EAAa,EAAE;AAE7C,MAAIG,IAAQ,IACRC,GACAC,GACAC;AAEJ,QAAMC,IAAc,MAAY;AAC9B,IAAIH,MAAU,UAAW,aAAaA,CAAK,GACvCC,MAAS,UAAW,qBAAqBA,CAAI,GAC7CC,MAAS,UAAW,qBAAqBA,CAAI,GACjDF,IAAQ,QACRC,IAAO,QACPC,IAAO;AAAA,EACT,GAEME,IAAM,CAACC,GAA2BC,GAA4BC,GAA0BC,GAAkBC,MAA6B;AAC3I,IAAAX,EAAWO,KAAS,EAAE,GACtBJ,IAAO,sBAAsB,MAAM;AACjC,MAAAC,IAAO,sBAAsB,MAAMJ,EAAWR,EAAKe,GAAOC,CAAM,CAAC,CAAC;AAAA,IACpE,CAAC,GACDN,IAAQ,WAAW,MAAM;AACvB,MAAIS,IAAOA,EAAA,IACNX,EAAWS,KAAQ,EAAE;AAAA,IAC5B,GAAGC,CAAQ;AAAA,EACb;AAEA,SAAAE,EAAa,MAAM;AACjB,UAAMC,IAAOlB,EAAQ,GAAA;AACrB,IAAAU,EAAA;AACA,UAAMS,IAAMnB,EAAQ;AAEpB,QAAIkB;AAEF,UADAhB,EAAW,EAAI,GACXI,KAAS,CAACN,EAAQ;AACpB,QAAAK,EAAWc,EAAI,aAAa,EAAE;AAAA,WACzB;AACL,cAAMC,IAAYd,KAAS,CAAC,CAACN,EAAQ;AACrC,QAAAW;AAAA,UACES,IAAYD,EAAI,SAASA,EAAI;AAAA,UAC7BC,IAAYD,EAAI,eAAeA,EAAI;AAAA,UACnCC,IAAaD,EAAI,cAAcA,EAAI,YAAaA,EAAI;AAAA,UACpDC,IAAapB,EAAQ,QAAQ,UAAUA,EAAQ,QAAQ,QAASA,EAAQ,QAAQ;AAAA,QAAA;AAAA,MAEpF;AAAA,QACF,CAAWC,OACTU,EAAIQ,EAAI,MAAMA,EAAI,YAAYA,EAAI,UAAUnB,EAAQ,QAAQ,MAAM,MAAM;AACtE,MAAAE,EAAW,EAAK,GAChBG,EAAW,EAAE;AAAA,IACf,CAAC;AAEH,IAAAC,IAAQ;AAAA,EACV,CAAC,GAEDe,EAAUX,CAAW,GAEd,EAAE,SAAAT,GAAS,SAAAG,EAAA;AACpB;"}
1
+ {"version":3,"file":"createCssTransition.js","sources":["../../../src/primitives/createCssTransition.ts"],"sourcesContent":["import { type Accessor, createEffect, createSignal, onCleanup } from \"solid-js\";\n\nexport interface CssTransitionClassNames {\n appear?: string;\n appearActive?: string;\n appearDone?: string;\n enter?: string;\n enterActive?: string;\n enterDone?: string;\n exit?: string;\n exitActive?: string;\n exitDone?: string;\n}\n\nexport interface CreateCssTransitionOptions {\n in: Accessor<boolean>;\n timeout: { appear?: number; enter: number; exit: number };\n classNames: CssTransitionClassNames;\n /** Animate the very first mount when `in` is already true. */\n appear?: boolean;\n}\n\nexport interface CssTransitionState {\n /** Whether the node should be in the DOM (mountOnEnter + unmountOnExit). */\n mounted: Accessor<boolean>;\n /** Transition classes to apply to the node for the current phase. */\n classes: Accessor<string>;\n}\n\nconst join = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\n/**\n * Single-node CSS transition with mountOnEnter + unmountOnExit semantics — a\n * dependency-free replacement for react-transition-group's CSSTransition. Uses\n * a double rAF to flush the start class before the active class so the CSS\n * transition runs, and a timeout to advance to the done/unmounted phase.\n *\n * Each phase settles once: when the timeout fires, the pending rAFs are\n * cancelled and can no longer rewrite the classes. At a low frame rate the\n * second rAF can land after the timeout, and it used to overwrite the done\n * class with the start/active classes, parking the node in its off-screen\n * state.\n */\nexport function createCssTransition(options: CreateCssTransitionOptions): CssTransitionState {\n const [mounted, setMounted] = createSignal(options.in());\n const [classes, setClasses] = createSignal(\"\");\n\n let first = true;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let raf1: number | undefined;\n let raf2: number | undefined;\n // Bumped whenever a phase settles or is replaced; a frame callback from an\n // older phase sees a different value and does nothing.\n let generation = 0;\n\n const clearTimers = (): void => {\n generation++;\n if (timer !== undefined) clearTimeout(timer);\n if (raf1 !== undefined) cancelAnimationFrame(raf1);\n if (raf2 !== undefined) cancelAnimationFrame(raf2);\n timer = undefined;\n raf1 = undefined;\n raf2 = undefined;\n };\n\n const run = (start: string | undefined, active: string | undefined, done: string | undefined, duration: number, onEnd?: () => void): void => {\n const own = generation;\n setClasses(start ?? \"\");\n raf1 = requestAnimationFrame(() => {\n raf1 = undefined;\n if (own !== generation) return;\n raf2 = requestAnimationFrame(() => {\n raf2 = undefined;\n if (own === generation) setClasses(join(start, active));\n });\n });\n timer = setTimeout(() => {\n clearTimers();\n if (onEnd) onEnd();\n else setClasses(done ?? \"\");\n }, duration);\n };\n\n createEffect(() => {\n const show = options.in();\n clearTimers();\n const cls = options.classNames;\n\n if (show) {\n setMounted(true);\n if (first && !options.appear) {\n setClasses(cls.enterDone ?? \"\");\n } else {\n const useAppear = first && !!options.appear;\n run(\n useAppear ? cls.appear : cls.enter,\n useAppear ? cls.appearActive : cls.enterActive,\n useAppear ? (cls.appearDone ?? cls.enterDone) : cls.enterDone,\n useAppear ? (options.timeout.appear ?? options.timeout.enter) : options.timeout.enter\n );\n }\n } else if (mounted()) {\n run(cls.exit, cls.exitActive, cls.exitDone, options.timeout.exit, () => {\n setMounted(false);\n setClasses(\"\");\n });\n }\n first = false;\n });\n\n onCleanup(clearTimers);\n\n return { mounted, classes };\n}\n"],"names":["join","parts","createCssTransition","options","mounted","setMounted","createSignal","classes","setClasses","first","timer","raf1","raf2","generation","clearTimers","run","start","active","done","duration","onEnd","own","createEffect","show","cls","useAppear","onCleanup"],"mappings":";AA6BA,MAAMA,IAAO,IAAIC,MAA6CA,EAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AAcrF,SAASC,EAAoBC,GAAyD;AAC3F,QAAM,CAACC,GAASC,CAAU,IAAIC,EAAaH,EAAQ,IAAI,GACjD,CAACI,GAASC,CAAU,IAAIF,EAAa,EAAE;AAE7C,MAAIG,IAAQ,IACRC,GACAC,GACAC,GAGAC,IAAa;AAEjB,QAAMC,IAAc,MAAY;AAC9B,IAAAD,KACIH,MAAU,UAAW,aAAaA,CAAK,GACvCC,MAAS,UAAW,qBAAqBA,CAAI,GAC7CC,MAAS,UAAW,qBAAqBA,CAAI,GACjDF,IAAQ,QACRC,IAAO,QACPC,IAAO;AAAA,EACT,GAEMG,IAAM,CAACC,GAA2BC,GAA4BC,GAA0BC,GAAkBC,MAA6B;AAC3I,UAAMC,IAAMR;AACZ,IAAAL,EAAWQ,KAAS,EAAE,GACtBL,IAAO,sBAAsB,MAAM;AAEjC,MADAA,IAAO,QACHU,MAAQR,MACZD,IAAO,sBAAsB,MAAM;AACjC,QAAAA,IAAO,QACHS,MAAQR,KAAYL,EAAWR,EAAKgB,GAAOC,CAAM,CAAC;AAAA,MACxD,CAAC;AAAA,IACH,CAAC,GACDP,IAAQ,WAAW,MAAM;AACvB,MAAAI,EAAA,GACIM,IAAOA,EAAA,IACNZ,EAAWU,KAAQ,EAAE;AAAA,IAC5B,GAAGC,CAAQ;AAAA,EACb;AAEA,SAAAG,EAAa,MAAM;AACjB,UAAMC,IAAOpB,EAAQ,GAAA;AACrB,IAAAW,EAAA;AACA,UAAMU,IAAMrB,EAAQ;AAEpB,QAAIoB;AAEF,UADAlB,EAAW,EAAI,GACXI,KAAS,CAACN,EAAQ;AACpB,QAAAK,EAAWgB,EAAI,aAAa,EAAE;AAAA,WACzB;AACL,cAAMC,IAAYhB,KAAS,CAAC,CAACN,EAAQ;AACrC,QAAAY;AAAA,UACEU,IAAYD,EAAI,SAASA,EAAI;AAAA,UAC7BC,IAAYD,EAAI,eAAeA,EAAI;AAAA,UACnCC,IAAaD,EAAI,cAAcA,EAAI,YAAaA,EAAI;AAAA,UACpDC,IAAatB,EAAQ,QAAQ,UAAUA,EAAQ,QAAQ,QAASA,EAAQ,QAAQ;AAAA,QAAA;AAAA,MAEpF;AAAA,QACF,CAAWC,OACTW,EAAIS,EAAI,MAAMA,EAAI,YAAYA,EAAI,UAAUrB,EAAQ,QAAQ,MAAM,MAAM;AACtE,MAAAE,EAAW,EAAK,GAChBG,EAAW,EAAE;AAAA,IACf,CAAC;AAEH,IAAAC,IAAQ;AAAA,EACV,CAAC,GAEDiB,EAAUZ,CAAW,GAEd,EAAE,SAAAV,GAAS,SAAAG,EAAA;AACpB;"}
@@ -7,7 +7,9 @@ function createCssTransition(options) {
7
7
  let timer;
8
8
  let raf1;
9
9
  let raf2;
10
+ let generation = 0;
10
11
  const clearTimers = () => {
12
+ generation++;
11
13
  if (timer !== void 0) clearTimeout(timer);
12
14
  if (raf1 !== void 0) cancelAnimationFrame(raf1);
13
15
  if (raf2 !== void 0) cancelAnimationFrame(raf2);
@@ -16,11 +18,18 @@ function createCssTransition(options) {
16
18
  raf2 = void 0;
17
19
  };
18
20
  const run = (start, active, done, duration, onEnd) => {
21
+ const own = generation;
19
22
  setClasses(start ?? "");
20
23
  raf1 = requestAnimationFrame(() => {
21
- raf2 = requestAnimationFrame(() => setClasses(join(start, active)));
24
+ raf1 = void 0;
25
+ if (own !== generation) return;
26
+ raf2 = requestAnimationFrame(() => {
27
+ raf2 = void 0;
28
+ if (own === generation) setClasses(join(start, active));
29
+ });
22
30
  });
23
31
  timer = setTimeout(() => {
32
+ clearTimers();
24
33
  if (onEnd) onEnd();
25
34
  else setClasses(done ?? "");
26
35
  }, duration);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/primitives/createCssTransition.ts"],
4
- "sourcesContent": ["import { type Accessor, createEffect, createSignal, onCleanup } from \"solid-js\";\n\nexport interface CssTransitionClassNames {\n appear?: string;\n appearActive?: string;\n appearDone?: string;\n enter?: string;\n enterActive?: string;\n enterDone?: string;\n exit?: string;\n exitActive?: string;\n exitDone?: string;\n}\n\nexport interface CreateCssTransitionOptions {\n in: Accessor<boolean>;\n timeout: { appear?: number; enter: number; exit: number };\n classNames: CssTransitionClassNames;\n /** Animate the very first mount when `in` is already true. */\n appear?: boolean;\n}\n\nexport interface CssTransitionState {\n /** Whether the node should be in the DOM (mountOnEnter + unmountOnExit). */\n mounted: Accessor<boolean>;\n /** Transition classes to apply to the node for the current phase. */\n classes: Accessor<string>;\n}\n\nconst join = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\n/**\n * Single-node CSS transition with mountOnEnter + unmountOnExit semantics \u2014 a\n * dependency-free replacement for react-transition-group's CSSTransition. Uses\n * a double rAF to flush the start class before the active class so the CSS\n * transition runs, and a timeout to advance to the done/unmounted phase.\n */\nexport function createCssTransition(options: CreateCssTransitionOptions): CssTransitionState {\n const [mounted, setMounted] = createSignal(options.in());\n const [classes, setClasses] = createSignal(\"\");\n\n let first = true;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let raf1: number | undefined;\n let raf2: number | undefined;\n\n const clearTimers = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n if (raf1 !== undefined) cancelAnimationFrame(raf1);\n if (raf2 !== undefined) cancelAnimationFrame(raf2);\n timer = undefined;\n raf1 = undefined;\n raf2 = undefined;\n };\n\n const run = (start: string | undefined, active: string | undefined, done: string | undefined, duration: number, onEnd?: () => void): void => {\n setClasses(start ?? \"\");\n raf1 = requestAnimationFrame(() => {\n raf2 = requestAnimationFrame(() => setClasses(join(start, active)));\n });\n timer = setTimeout(() => {\n if (onEnd) onEnd();\n else setClasses(done ?? \"\");\n }, duration);\n };\n\n createEffect(() => {\n const show = options.in();\n clearTimers();\n const cls = options.classNames;\n\n if (show) {\n setMounted(true);\n if (first && !options.appear) {\n setClasses(cls.enterDone ?? \"\");\n } else {\n const useAppear = first && !!options.appear;\n run(\n useAppear ? cls.appear : cls.enter,\n useAppear ? cls.appearActive : cls.enterActive,\n useAppear ? (cls.appearDone ?? cls.enterDone) : cls.enterDone,\n useAppear ? (options.timeout.appear ?? options.timeout.enter) : options.timeout.enter\n );\n }\n } else if (mounted()) {\n run(cls.exit, cls.exitActive, cls.exitDone, options.timeout.exit, () => {\n setMounted(false);\n setClasses(\"\");\n });\n }\n first = false;\n });\n\n onCleanup(clearTimers);\n\n return { mounted, classes };\n}\n"],
5
- "mappings": "AAAA,SAAwB,cAAc,cAAc,iBAAiB;AA6BrE,MAAM,OAAO,IAAI,UAA6C,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AAQrF,SAAS,oBAAoB,SAAyD;AAC3F,QAAM,CAAC,SAAS,UAAU,IAAI,aAAa,QAAQ,GAAG,CAAC;AACvD,QAAM,CAAC,SAAS,UAAU,IAAI,aAAa,EAAE;AAE7C,MAAI,QAAQ;AACZ,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,QAAM,cAAc,MAAY;AAC9B,QAAI,UAAU,OAAW,cAAa,KAAK;AAC3C,QAAI,SAAS,OAAW,sBAAqB,IAAI;AACjD,QAAI,SAAS,OAAW,sBAAqB,IAAI;AACjD,YAAQ;AACR,WAAO;AACP,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,CAAC,OAA2B,QAA4B,MAA0B,UAAkB,UAA6B;AAC3I,eAAW,SAAS,EAAE;AACtB,WAAO,sBAAsB,MAAM;AACjC,aAAO,sBAAsB,MAAM,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACpE,CAAC;AACD,YAAQ,WAAW,MAAM;AACvB,UAAI,MAAO,OAAM;AAAA,UACZ,YAAW,QAAQ,EAAE;AAAA,IAC5B,GAAG,QAAQ;AAAA,EACb;AAEA,eAAa,MAAM;AACjB,UAAM,OAAO,QAAQ,GAAG;AACxB,gBAAY;AACZ,UAAM,MAAM,QAAQ;AAEpB,QAAI,MAAM;AACR,iBAAW,IAAI;AACf,UAAI,SAAS,CAAC,QAAQ,QAAQ;AAC5B,mBAAW,IAAI,aAAa,EAAE;AAAA,MAChC,OAAO;AACL,cAAM,YAAY,SAAS,CAAC,CAAC,QAAQ;AACrC;AAAA,UACE,YAAY,IAAI,SAAS,IAAI;AAAA,UAC7B,YAAY,IAAI,eAAe,IAAI;AAAA,UACnC,YAAa,IAAI,cAAc,IAAI,YAAa,IAAI;AAAA,UACpD,YAAa,QAAQ,QAAQ,UAAU,QAAQ,QAAQ,QAAS,QAAQ,QAAQ;AAAA,QAClF;AAAA,MACF;AAAA,IACF,WAAW,QAAQ,GAAG;AACpB,UAAI,IAAI,MAAM,IAAI,YAAY,IAAI,UAAU,QAAQ,QAAQ,MAAM,MAAM;AACtE,mBAAW,KAAK;AAChB,mBAAW,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AACA,YAAQ;AAAA,EACV,CAAC;AAED,YAAU,WAAW;AAErB,SAAO,EAAE,SAAS,QAAQ;AAC5B;",
4
+ "sourcesContent": ["import { type Accessor, createEffect, createSignal, onCleanup } from \"solid-js\";\n\nexport interface CssTransitionClassNames {\n appear?: string;\n appearActive?: string;\n appearDone?: string;\n enter?: string;\n enterActive?: string;\n enterDone?: string;\n exit?: string;\n exitActive?: string;\n exitDone?: string;\n}\n\nexport interface CreateCssTransitionOptions {\n in: Accessor<boolean>;\n timeout: { appear?: number; enter: number; exit: number };\n classNames: CssTransitionClassNames;\n /** Animate the very first mount when `in` is already true. */\n appear?: boolean;\n}\n\nexport interface CssTransitionState {\n /** Whether the node should be in the DOM (mountOnEnter + unmountOnExit). */\n mounted: Accessor<boolean>;\n /** Transition classes to apply to the node for the current phase. */\n classes: Accessor<string>;\n}\n\nconst join = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\n/**\n * Single-node CSS transition with mountOnEnter + unmountOnExit semantics \u2014 a\n * dependency-free replacement for react-transition-group's CSSTransition. Uses\n * a double rAF to flush the start class before the active class so the CSS\n * transition runs, and a timeout to advance to the done/unmounted phase.\n *\n * Each phase settles once: when the timeout fires, the pending rAFs are\n * cancelled and can no longer rewrite the classes. At a low frame rate the\n * second rAF can land after the timeout, and it used to overwrite the done\n * class with the start/active classes, parking the node in its off-screen\n * state.\n */\nexport function createCssTransition(options: CreateCssTransitionOptions): CssTransitionState {\n const [mounted, setMounted] = createSignal(options.in());\n const [classes, setClasses] = createSignal(\"\");\n\n let first = true;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let raf1: number | undefined;\n let raf2: number | undefined;\n // Bumped whenever a phase settles or is replaced; a frame callback from an\n // older phase sees a different value and does nothing.\n let generation = 0;\n\n const clearTimers = (): void => {\n generation++;\n if (timer !== undefined) clearTimeout(timer);\n if (raf1 !== undefined) cancelAnimationFrame(raf1);\n if (raf2 !== undefined) cancelAnimationFrame(raf2);\n timer = undefined;\n raf1 = undefined;\n raf2 = undefined;\n };\n\n const run = (start: string | undefined, active: string | undefined, done: string | undefined, duration: number, onEnd?: () => void): void => {\n const own = generation;\n setClasses(start ?? \"\");\n raf1 = requestAnimationFrame(() => {\n raf1 = undefined;\n if (own !== generation) return;\n raf2 = requestAnimationFrame(() => {\n raf2 = undefined;\n if (own === generation) setClasses(join(start, active));\n });\n });\n timer = setTimeout(() => {\n clearTimers();\n if (onEnd) onEnd();\n else setClasses(done ?? \"\");\n }, duration);\n };\n\n createEffect(() => {\n const show = options.in();\n clearTimers();\n const cls = options.classNames;\n\n if (show) {\n setMounted(true);\n if (first && !options.appear) {\n setClasses(cls.enterDone ?? \"\");\n } else {\n const useAppear = first && !!options.appear;\n run(\n useAppear ? cls.appear : cls.enter,\n useAppear ? cls.appearActive : cls.enterActive,\n useAppear ? (cls.appearDone ?? cls.enterDone) : cls.enterDone,\n useAppear ? (options.timeout.appear ?? options.timeout.enter) : options.timeout.enter\n );\n }\n } else if (mounted()) {\n run(cls.exit, cls.exitActive, cls.exitDone, options.timeout.exit, () => {\n setMounted(false);\n setClasses(\"\");\n });\n }\n first = false;\n });\n\n onCleanup(clearTimers);\n\n return { mounted, classes };\n}\n"],
5
+ "mappings": "AAAA,SAAwB,cAAc,cAAc,iBAAiB;AA6BrE,MAAM,OAAO,IAAI,UAA6C,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AAcrF,SAAS,oBAAoB,SAAyD;AAC3F,QAAM,CAAC,SAAS,UAAU,IAAI,aAAa,QAAQ,GAAG,CAAC;AACvD,QAAM,CAAC,SAAS,UAAU,IAAI,aAAa,EAAE;AAE7C,MAAI,QAAQ;AACZ,MAAI;AACJ,MAAI;AACJ,MAAI;AAGJ,MAAI,aAAa;AAEjB,QAAM,cAAc,MAAY;AAC9B;AACA,QAAI,UAAU,OAAW,cAAa,KAAK;AAC3C,QAAI,SAAS,OAAW,sBAAqB,IAAI;AACjD,QAAI,SAAS,OAAW,sBAAqB,IAAI;AACjD,YAAQ;AACR,WAAO;AACP,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,CAAC,OAA2B,QAA4B,MAA0B,UAAkB,UAA6B;AAC3I,UAAM,MAAM;AACZ,eAAW,SAAS,EAAE;AACtB,WAAO,sBAAsB,MAAM;AACjC,aAAO;AACP,UAAI,QAAQ,WAAY;AACxB,aAAO,sBAAsB,MAAM;AACjC,eAAO;AACP,YAAI,QAAQ,WAAY,YAAW,KAAK,OAAO,MAAM,CAAC;AAAA,MACxD,CAAC;AAAA,IACH,CAAC;AACD,YAAQ,WAAW,MAAM;AACvB,kBAAY;AACZ,UAAI,MAAO,OAAM;AAAA,UACZ,YAAW,QAAQ,EAAE;AAAA,IAC5B,GAAG,QAAQ;AAAA,EACb;AAEA,eAAa,MAAM;AACjB,UAAM,OAAO,QAAQ,GAAG;AACxB,gBAAY;AACZ,UAAM,MAAM,QAAQ;AAEpB,QAAI,MAAM;AACR,iBAAW,IAAI;AACf,UAAI,SAAS,CAAC,QAAQ,QAAQ;AAC5B,mBAAW,IAAI,aAAa,EAAE;AAAA,MAChC,OAAO;AACL,cAAM,YAAY,SAAS,CAAC,CAAC,QAAQ;AACrC;AAAA,UACE,YAAY,IAAI,SAAS,IAAI;AAAA,UAC7B,YAAY,IAAI,eAAe,IAAI;AAAA,UACnC,YAAa,IAAI,cAAc,IAAI,YAAa,IAAI;AAAA,UACpD,YAAa,QAAQ,QAAQ,UAAU,QAAQ,QAAQ,QAAS,QAAQ,QAAQ;AAAA,QAClF;AAAA,MACF;AAAA,IACF,WAAW,QAAQ,GAAG;AACpB,UAAI,IAAI,MAAM,IAAI,YAAY,IAAI,UAAU,QAAQ,QAAQ,MAAM,MAAM;AACtE,mBAAW,KAAK;AAChB,mBAAW,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AACA,YAAQ;AAAA,EACV,CAAC;AAED,YAAU,WAAW;AAErB,SAAO,EAAE,SAAS,QAAQ;AAC5B;",
6
6
  "names": []
7
7
  }
@@ -32,5 +32,11 @@ export interface CssTransitionState {
32
32
  * dependency-free replacement for react-transition-group's CSSTransition. Uses
33
33
  * a double rAF to flush the start class before the active class so the CSS
34
34
  * transition runs, and a timeout to advance to the done/unmounted phase.
35
+ *
36
+ * Each phase settles once: when the timeout fires, the pending rAFs are
37
+ * cancelled and can no longer rewrite the classes. At a low frame rate the
38
+ * second rAF can land after the timeout, and it used to overwrite the done
39
+ * class with the start/active classes, parking the node in its off-screen
40
+ * state.
35
41
  */
36
42
  export declare function createCssTransition(options: CreateCssTransitionOptions): CssTransitionState;
@@ -1,40 +1,43 @@
1
- import { createSignal as v, createEffect as x, onCleanup as D } from "solid-js";
2
- const F = (...t) => t.filter(Boolean).join(" ");
3
- function C(t) {
4
- const [l, m] = v(t.in()), [A, i] = v("");
5
- let o = !0, r, n, s;
6
- const f = () => {
7
- r !== void 0 && clearTimeout(r), n !== void 0 && cancelAnimationFrame(n), s !== void 0 && cancelAnimationFrame(s), r = void 0, n = void 0, s = void 0;
8
- }, u = (c, e, a, d, p) => {
9
- i(c ?? ""), n = requestAnimationFrame(() => {
10
- s = requestAnimationFrame(() => i(F(c, e)));
11
- }), r = setTimeout(() => {
12
- p ? p() : i(a ?? "");
13
- }, d);
1
+ import { createSignal as A, createEffect as F, onCleanup as T } from "solid-js";
2
+ const C = (...t) => t.filter(Boolean).join(" ");
3
+ function j(t) {
4
+ const [f, u] = A(t.in()), [x, r] = A("");
5
+ let l = !0, o, n, a, s = 0;
6
+ const m = () => {
7
+ s++, o !== void 0 && clearTimeout(o), n !== void 0 && cancelAnimationFrame(n), a !== void 0 && cancelAnimationFrame(a), o = void 0, n = void 0, a = void 0;
8
+ }, v = (c, e, i, D, d) => {
9
+ const p = s;
10
+ r(c ?? ""), n = requestAnimationFrame(() => {
11
+ n = void 0, p === s && (a = requestAnimationFrame(() => {
12
+ a = void 0, p === s && r(C(c, e));
13
+ }));
14
+ }), o = setTimeout(() => {
15
+ m(), d ? d() : r(i ?? "");
16
+ }, D);
14
17
  };
15
- return x(() => {
18
+ return F(() => {
16
19
  const c = t.in();
17
- f();
20
+ m();
18
21
  const e = t.classNames;
19
22
  if (c)
20
- if (m(!0), o && !t.appear)
21
- i(e.enterDone ?? "");
23
+ if (u(!0), l && !t.appear)
24
+ r(e.enterDone ?? "");
22
25
  else {
23
- const a = o && !!t.appear;
24
- u(
25
- a ? e.appear : e.enter,
26
- a ? e.appearActive : e.enterActive,
27
- a ? e.appearDone ?? e.enterDone : e.enterDone,
28
- a ? t.timeout.appear ?? t.timeout.enter : t.timeout.enter
26
+ const i = l && !!t.appear;
27
+ v(
28
+ i ? e.appear : e.enter,
29
+ i ? e.appearActive : e.enterActive,
30
+ i ? e.appearDone ?? e.enterDone : e.enterDone,
31
+ i ? t.timeout.appear ?? t.timeout.enter : t.timeout.enter
29
32
  );
30
33
  }
31
- else l() && u(e.exit, e.exitActive, e.exitDone, t.timeout.exit, () => {
32
- m(!1), i("");
34
+ else f() && v(e.exit, e.exitActive, e.exitDone, t.timeout.exit, () => {
35
+ u(!1), r("");
33
36
  });
34
- o = !1;
35
- }), D(f), { mounted: l, classes: A };
37
+ l = !1;
38
+ }), T(m), { mounted: f, classes: x };
36
39
  }
37
40
  export {
38
- C as createCssTransition
41
+ j as createCssTransition
39
42
  };
40
43
  //# sourceMappingURL=createCssTransition.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"createCssTransition.js","sources":["../../src/primitives/createCssTransition.ts"],"sourcesContent":["import { type Accessor, createEffect, createSignal, onCleanup } from \"solid-js\";\n\nexport interface CssTransitionClassNames {\n appear?: string;\n appearActive?: string;\n appearDone?: string;\n enter?: string;\n enterActive?: string;\n enterDone?: string;\n exit?: string;\n exitActive?: string;\n exitDone?: string;\n}\n\nexport interface CreateCssTransitionOptions {\n in: Accessor<boolean>;\n timeout: { appear?: number; enter: number; exit: number };\n classNames: CssTransitionClassNames;\n /** Animate the very first mount when `in` is already true. */\n appear?: boolean;\n}\n\nexport interface CssTransitionState {\n /** Whether the node should be in the DOM (mountOnEnter + unmountOnExit). */\n mounted: Accessor<boolean>;\n /** Transition classes to apply to the node for the current phase. */\n classes: Accessor<string>;\n}\n\nconst join = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\n/**\n * Single-node CSS transition with mountOnEnter + unmountOnExit semantics — a\n * dependency-free replacement for react-transition-group's CSSTransition. Uses\n * a double rAF to flush the start class before the active class so the CSS\n * transition runs, and a timeout to advance to the done/unmounted phase.\n */\nexport function createCssTransition(options: CreateCssTransitionOptions): CssTransitionState {\n const [mounted, setMounted] = createSignal(options.in());\n const [classes, setClasses] = createSignal(\"\");\n\n let first = true;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let raf1: number | undefined;\n let raf2: number | undefined;\n\n const clearTimers = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n if (raf1 !== undefined) cancelAnimationFrame(raf1);\n if (raf2 !== undefined) cancelAnimationFrame(raf2);\n timer = undefined;\n raf1 = undefined;\n raf2 = undefined;\n };\n\n const run = (start: string | undefined, active: string | undefined, done: string | undefined, duration: number, onEnd?: () => void): void => {\n setClasses(start ?? \"\");\n raf1 = requestAnimationFrame(() => {\n raf2 = requestAnimationFrame(() => setClasses(join(start, active)));\n });\n timer = setTimeout(() => {\n if (onEnd) onEnd();\n else setClasses(done ?? \"\");\n }, duration);\n };\n\n createEffect(() => {\n const show = options.in();\n clearTimers();\n const cls = options.classNames;\n\n if (show) {\n setMounted(true);\n if (first && !options.appear) {\n setClasses(cls.enterDone ?? \"\");\n } else {\n const useAppear = first && !!options.appear;\n run(\n useAppear ? cls.appear : cls.enter,\n useAppear ? cls.appearActive : cls.enterActive,\n useAppear ? (cls.appearDone ?? cls.enterDone) : cls.enterDone,\n useAppear ? (options.timeout.appear ?? options.timeout.enter) : options.timeout.enter\n );\n }\n } else if (mounted()) {\n run(cls.exit, cls.exitActive, cls.exitDone, options.timeout.exit, () => {\n setMounted(false);\n setClasses(\"\");\n });\n }\n first = false;\n });\n\n onCleanup(clearTimers);\n\n return { mounted, classes };\n}\n"],"names":["join","parts","createCssTransition","options","mounted","setMounted","createSignal","classes","setClasses","first","timer","raf1","raf2","clearTimers","run","start","active","done","duration","onEnd","createEffect","show","cls","useAppear","onCleanup"],"mappings":";AA6BA,MAAMA,IAAO,IAAIC,MAA6CA,EAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AAQrF,SAASC,EAAoBC,GAAyD;AAC3F,QAAM,CAACC,GAASC,CAAU,IAAIC,EAAaH,EAAQ,IAAI,GACjD,CAACI,GAASC,CAAU,IAAIF,EAAa,EAAE;AAE7C,MAAIG,IAAQ,IACRC,GACAC,GACAC;AAEJ,QAAMC,IAAc,MAAY;AAC9B,IAAIH,MAAU,UAAW,aAAaA,CAAK,GACvCC,MAAS,UAAW,qBAAqBA,CAAI,GAC7CC,MAAS,UAAW,qBAAqBA,CAAI,GACjDF,IAAQ,QACRC,IAAO,QACPC,IAAO;AAAA,EACT,GAEME,IAAM,CAACC,GAA2BC,GAA4BC,GAA0BC,GAAkBC,MAA6B;AAC3I,IAAAX,EAAWO,KAAS,EAAE,GACtBJ,IAAO,sBAAsB,MAAM;AACjC,MAAAC,IAAO,sBAAsB,MAAMJ,EAAWR,EAAKe,GAAOC,CAAM,CAAC,CAAC;AAAA,IACpE,CAAC,GACDN,IAAQ,WAAW,MAAM;AACvB,MAAIS,IAAOA,EAAA,IACNX,EAAWS,KAAQ,EAAE;AAAA,IAC5B,GAAGC,CAAQ;AAAA,EACb;AAEA,SAAAE,EAAa,MAAM;AACjB,UAAMC,IAAOlB,EAAQ,GAAA;AACrB,IAAAU,EAAA;AACA,UAAMS,IAAMnB,EAAQ;AAEpB,QAAIkB;AAEF,UADAhB,EAAW,EAAI,GACXI,KAAS,CAACN,EAAQ;AACpB,QAAAK,EAAWc,EAAI,aAAa,EAAE;AAAA,WACzB;AACL,cAAMC,IAAYd,KAAS,CAAC,CAACN,EAAQ;AACrC,QAAAW;AAAA,UACES,IAAYD,EAAI,SAASA,EAAI;AAAA,UAC7BC,IAAYD,EAAI,eAAeA,EAAI;AAAA,UACnCC,IAAaD,EAAI,cAAcA,EAAI,YAAaA,EAAI;AAAA,UACpDC,IAAapB,EAAQ,QAAQ,UAAUA,EAAQ,QAAQ,QAASA,EAAQ,QAAQ;AAAA,QAAA;AAAA,MAEpF;AAAA,QACF,CAAWC,OACTU,EAAIQ,EAAI,MAAMA,EAAI,YAAYA,EAAI,UAAUnB,EAAQ,QAAQ,MAAM,MAAM;AACtE,MAAAE,EAAW,EAAK,GAChBG,EAAW,EAAE;AAAA,IACf,CAAC;AAEH,IAAAC,IAAQ;AAAA,EACV,CAAC,GAEDe,EAAUX,CAAW,GAEd,EAAE,SAAAT,GAAS,SAAAG,EAAA;AACpB;"}
1
+ {"version":3,"file":"createCssTransition.js","sources":["../../src/primitives/createCssTransition.ts"],"sourcesContent":["import { type Accessor, createEffect, createSignal, onCleanup } from \"solid-js\";\n\nexport interface CssTransitionClassNames {\n appear?: string;\n appearActive?: string;\n appearDone?: string;\n enter?: string;\n enterActive?: string;\n enterDone?: string;\n exit?: string;\n exitActive?: string;\n exitDone?: string;\n}\n\nexport interface CreateCssTransitionOptions {\n in: Accessor<boolean>;\n timeout: { appear?: number; enter: number; exit: number };\n classNames: CssTransitionClassNames;\n /** Animate the very first mount when `in` is already true. */\n appear?: boolean;\n}\n\nexport interface CssTransitionState {\n /** Whether the node should be in the DOM (mountOnEnter + unmountOnExit). */\n mounted: Accessor<boolean>;\n /** Transition classes to apply to the node for the current phase. */\n classes: Accessor<string>;\n}\n\nconst join = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\n/**\n * Single-node CSS transition with mountOnEnter + unmountOnExit semantics — a\n * dependency-free replacement for react-transition-group's CSSTransition. Uses\n * a double rAF to flush the start class before the active class so the CSS\n * transition runs, and a timeout to advance to the done/unmounted phase.\n *\n * Each phase settles once: when the timeout fires, the pending rAFs are\n * cancelled and can no longer rewrite the classes. At a low frame rate the\n * second rAF can land after the timeout, and it used to overwrite the done\n * class with the start/active classes, parking the node in its off-screen\n * state.\n */\nexport function createCssTransition(options: CreateCssTransitionOptions): CssTransitionState {\n const [mounted, setMounted] = createSignal(options.in());\n const [classes, setClasses] = createSignal(\"\");\n\n let first = true;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let raf1: number | undefined;\n let raf2: number | undefined;\n // Bumped whenever a phase settles or is replaced; a frame callback from an\n // older phase sees a different value and does nothing.\n let generation = 0;\n\n const clearTimers = (): void => {\n generation++;\n if (timer !== undefined) clearTimeout(timer);\n if (raf1 !== undefined) cancelAnimationFrame(raf1);\n if (raf2 !== undefined) cancelAnimationFrame(raf2);\n timer = undefined;\n raf1 = undefined;\n raf2 = undefined;\n };\n\n const run = (start: string | undefined, active: string | undefined, done: string | undefined, duration: number, onEnd?: () => void): void => {\n const own = generation;\n setClasses(start ?? \"\");\n raf1 = requestAnimationFrame(() => {\n raf1 = undefined;\n if (own !== generation) return;\n raf2 = requestAnimationFrame(() => {\n raf2 = undefined;\n if (own === generation) setClasses(join(start, active));\n });\n });\n timer = setTimeout(() => {\n clearTimers();\n if (onEnd) onEnd();\n else setClasses(done ?? \"\");\n }, duration);\n };\n\n createEffect(() => {\n const show = options.in();\n clearTimers();\n const cls = options.classNames;\n\n if (show) {\n setMounted(true);\n if (first && !options.appear) {\n setClasses(cls.enterDone ?? \"\");\n } else {\n const useAppear = first && !!options.appear;\n run(\n useAppear ? cls.appear : cls.enter,\n useAppear ? cls.appearActive : cls.enterActive,\n useAppear ? (cls.appearDone ?? cls.enterDone) : cls.enterDone,\n useAppear ? (options.timeout.appear ?? options.timeout.enter) : options.timeout.enter\n );\n }\n } else if (mounted()) {\n run(cls.exit, cls.exitActive, cls.exitDone, options.timeout.exit, () => {\n setMounted(false);\n setClasses(\"\");\n });\n }\n first = false;\n });\n\n onCleanup(clearTimers);\n\n return { mounted, classes };\n}\n"],"names":["join","parts","createCssTransition","options","mounted","setMounted","createSignal","classes","setClasses","first","timer","raf1","raf2","generation","clearTimers","run","start","active","done","duration","onEnd","own","createEffect","show","cls","useAppear","onCleanup"],"mappings":";AA6BA,MAAMA,IAAO,IAAIC,MAA6CA,EAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AAcrF,SAASC,EAAoBC,GAAyD;AAC3F,QAAM,CAACC,GAASC,CAAU,IAAIC,EAAaH,EAAQ,IAAI,GACjD,CAACI,GAASC,CAAU,IAAIF,EAAa,EAAE;AAE7C,MAAIG,IAAQ,IACRC,GACAC,GACAC,GAGAC,IAAa;AAEjB,QAAMC,IAAc,MAAY;AAC9B,IAAAD,KACIH,MAAU,UAAW,aAAaA,CAAK,GACvCC,MAAS,UAAW,qBAAqBA,CAAI,GAC7CC,MAAS,UAAW,qBAAqBA,CAAI,GACjDF,IAAQ,QACRC,IAAO,QACPC,IAAO;AAAA,EACT,GAEMG,IAAM,CAACC,GAA2BC,GAA4BC,GAA0BC,GAAkBC,MAA6B;AAC3I,UAAMC,IAAMR;AACZ,IAAAL,EAAWQ,KAAS,EAAE,GACtBL,IAAO,sBAAsB,MAAM;AAEjC,MADAA,IAAO,QACHU,MAAQR,MACZD,IAAO,sBAAsB,MAAM;AACjC,QAAAA,IAAO,QACHS,MAAQR,KAAYL,EAAWR,EAAKgB,GAAOC,CAAM,CAAC;AAAA,MACxD,CAAC;AAAA,IACH,CAAC,GACDP,IAAQ,WAAW,MAAM;AACvB,MAAAI,EAAA,GACIM,IAAOA,EAAA,IACNZ,EAAWU,KAAQ,EAAE;AAAA,IAC5B,GAAGC,CAAQ;AAAA,EACb;AAEA,SAAAG,EAAa,MAAM;AACjB,UAAMC,IAAOpB,EAAQ,GAAA;AACrB,IAAAW,EAAA;AACA,UAAMU,IAAMrB,EAAQ;AAEpB,QAAIoB;AAEF,UADAlB,EAAW,EAAI,GACXI,KAAS,CAACN,EAAQ;AACpB,QAAAK,EAAWgB,EAAI,aAAa,EAAE;AAAA,WACzB;AACL,cAAMC,IAAYhB,KAAS,CAAC,CAACN,EAAQ;AACrC,QAAAY;AAAA,UACEU,IAAYD,EAAI,SAASA,EAAI;AAAA,UAC7BC,IAAYD,EAAI,eAAeA,EAAI;AAAA,UACnCC,IAAaD,EAAI,cAAcA,EAAI,YAAaA,EAAI;AAAA,UACpDC,IAAatB,EAAQ,QAAQ,UAAUA,EAAQ,QAAQ,QAASA,EAAQ,QAAQ;AAAA,QAAA;AAAA,MAEpF;AAAA,QACF,CAAWC,OACTW,EAAIS,EAAI,MAAMA,EAAI,YAAYA,EAAI,UAAUrB,EAAQ,QAAQ,MAAM,MAAM;AACtE,MAAAE,EAAW,EAAK,GAChBG,EAAW,EAAE;AAAA,IACf,CAAC;AAEH,IAAAC,IAAQ;AAAA,EACV,CAAC,GAEDiB,EAAUZ,CAAW,GAEd,EAAE,SAAAV,GAAS,SAAAG,EAAA;AACpB;"}
@@ -7,7 +7,9 @@ function createCssTransition(options) {
7
7
  let timer;
8
8
  let raf1;
9
9
  let raf2;
10
+ let generation = 0;
10
11
  const clearTimers = () => {
12
+ generation++;
11
13
  if (timer !== void 0) clearTimeout(timer);
12
14
  if (raf1 !== void 0) cancelAnimationFrame(raf1);
13
15
  if (raf2 !== void 0) cancelAnimationFrame(raf2);
@@ -16,11 +18,18 @@ function createCssTransition(options) {
16
18
  raf2 = void 0;
17
19
  };
18
20
  const run = (start, active, done, duration, onEnd) => {
21
+ const own = generation;
19
22
  setClasses(start ?? "");
20
23
  raf1 = requestAnimationFrame(() => {
21
- raf2 = requestAnimationFrame(() => setClasses(join(start, active)));
24
+ raf1 = void 0;
25
+ if (own !== generation) return;
26
+ raf2 = requestAnimationFrame(() => {
27
+ raf2 = void 0;
28
+ if (own === generation) setClasses(join(start, active));
29
+ });
22
30
  });
23
31
  timer = setTimeout(() => {
32
+ clearTimers();
24
33
  if (onEnd) onEnd();
25
34
  else setClasses(done ?? "");
26
35
  }, duration);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/primitives/createCssTransition.ts"],
4
- "sourcesContent": ["import { type Accessor, createEffect, createSignal, onCleanup } from \"solid-js\";\n\nexport interface CssTransitionClassNames {\n appear?: string;\n appearActive?: string;\n appearDone?: string;\n enter?: string;\n enterActive?: string;\n enterDone?: string;\n exit?: string;\n exitActive?: string;\n exitDone?: string;\n}\n\nexport interface CreateCssTransitionOptions {\n in: Accessor<boolean>;\n timeout: { appear?: number; enter: number; exit: number };\n classNames: CssTransitionClassNames;\n /** Animate the very first mount when `in` is already true. */\n appear?: boolean;\n}\n\nexport interface CssTransitionState {\n /** Whether the node should be in the DOM (mountOnEnter + unmountOnExit). */\n mounted: Accessor<boolean>;\n /** Transition classes to apply to the node for the current phase. */\n classes: Accessor<string>;\n}\n\nconst join = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\n/**\n * Single-node CSS transition with mountOnEnter + unmountOnExit semantics \u2014 a\n * dependency-free replacement for react-transition-group's CSSTransition. Uses\n * a double rAF to flush the start class before the active class so the CSS\n * transition runs, and a timeout to advance to the done/unmounted phase.\n */\nexport function createCssTransition(options: CreateCssTransitionOptions): CssTransitionState {\n const [mounted, setMounted] = createSignal(options.in());\n const [classes, setClasses] = createSignal(\"\");\n\n let first = true;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let raf1: number | undefined;\n let raf2: number | undefined;\n\n const clearTimers = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n if (raf1 !== undefined) cancelAnimationFrame(raf1);\n if (raf2 !== undefined) cancelAnimationFrame(raf2);\n timer = undefined;\n raf1 = undefined;\n raf2 = undefined;\n };\n\n const run = (start: string | undefined, active: string | undefined, done: string | undefined, duration: number, onEnd?: () => void): void => {\n setClasses(start ?? \"\");\n raf1 = requestAnimationFrame(() => {\n raf2 = requestAnimationFrame(() => setClasses(join(start, active)));\n });\n timer = setTimeout(() => {\n if (onEnd) onEnd();\n else setClasses(done ?? \"\");\n }, duration);\n };\n\n createEffect(() => {\n const show = options.in();\n clearTimers();\n const cls = options.classNames;\n\n if (show) {\n setMounted(true);\n if (first && !options.appear) {\n setClasses(cls.enterDone ?? \"\");\n } else {\n const useAppear = first && !!options.appear;\n run(\n useAppear ? cls.appear : cls.enter,\n useAppear ? cls.appearActive : cls.enterActive,\n useAppear ? (cls.appearDone ?? cls.enterDone) : cls.enterDone,\n useAppear ? (options.timeout.appear ?? options.timeout.enter) : options.timeout.enter\n );\n }\n } else if (mounted()) {\n run(cls.exit, cls.exitActive, cls.exitDone, options.timeout.exit, () => {\n setMounted(false);\n setClasses(\"\");\n });\n }\n first = false;\n });\n\n onCleanup(clearTimers);\n\n return { mounted, classes };\n}\n"],
5
- "mappings": "AAAA,SAAwB,cAAc,cAAc,iBAAiB;AA6BrE,MAAM,OAAO,IAAI,UAA6C,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AAQrF,SAAS,oBAAoB,SAAyD;AAC3F,QAAM,CAAC,SAAS,UAAU,IAAI,aAAa,QAAQ,GAAG,CAAC;AACvD,QAAM,CAAC,SAAS,UAAU,IAAI,aAAa,EAAE;AAE7C,MAAI,QAAQ;AACZ,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,QAAM,cAAc,MAAY;AAC9B,QAAI,UAAU,OAAW,cAAa,KAAK;AAC3C,QAAI,SAAS,OAAW,sBAAqB,IAAI;AACjD,QAAI,SAAS,OAAW,sBAAqB,IAAI;AACjD,YAAQ;AACR,WAAO;AACP,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,CAAC,OAA2B,QAA4B,MAA0B,UAAkB,UAA6B;AAC3I,eAAW,SAAS,EAAE;AACtB,WAAO,sBAAsB,MAAM;AACjC,aAAO,sBAAsB,MAAM,WAAW,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACpE,CAAC;AACD,YAAQ,WAAW,MAAM;AACvB,UAAI,MAAO,OAAM;AAAA,UACZ,YAAW,QAAQ,EAAE;AAAA,IAC5B,GAAG,QAAQ;AAAA,EACb;AAEA,eAAa,MAAM;AACjB,UAAM,OAAO,QAAQ,GAAG;AACxB,gBAAY;AACZ,UAAM,MAAM,QAAQ;AAEpB,QAAI,MAAM;AACR,iBAAW,IAAI;AACf,UAAI,SAAS,CAAC,QAAQ,QAAQ;AAC5B,mBAAW,IAAI,aAAa,EAAE;AAAA,MAChC,OAAO;AACL,cAAM,YAAY,SAAS,CAAC,CAAC,QAAQ;AACrC;AAAA,UACE,YAAY,IAAI,SAAS,IAAI;AAAA,UAC7B,YAAY,IAAI,eAAe,IAAI;AAAA,UACnC,YAAa,IAAI,cAAc,IAAI,YAAa,IAAI;AAAA,UACpD,YAAa,QAAQ,QAAQ,UAAU,QAAQ,QAAQ,QAAS,QAAQ,QAAQ;AAAA,QAClF;AAAA,MACF;AAAA,IACF,WAAW,QAAQ,GAAG;AACpB,UAAI,IAAI,MAAM,IAAI,YAAY,IAAI,UAAU,QAAQ,QAAQ,MAAM,MAAM;AACtE,mBAAW,KAAK;AAChB,mBAAW,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AACA,YAAQ;AAAA,EACV,CAAC;AAED,YAAU,WAAW;AAErB,SAAO,EAAE,SAAS,QAAQ;AAC5B;",
4
+ "sourcesContent": ["import { type Accessor, createEffect, createSignal, onCleanup } from \"solid-js\";\n\nexport interface CssTransitionClassNames {\n appear?: string;\n appearActive?: string;\n appearDone?: string;\n enter?: string;\n enterActive?: string;\n enterDone?: string;\n exit?: string;\n exitActive?: string;\n exitDone?: string;\n}\n\nexport interface CreateCssTransitionOptions {\n in: Accessor<boolean>;\n timeout: { appear?: number; enter: number; exit: number };\n classNames: CssTransitionClassNames;\n /** Animate the very first mount when `in` is already true. */\n appear?: boolean;\n}\n\nexport interface CssTransitionState {\n /** Whether the node should be in the DOM (mountOnEnter + unmountOnExit). */\n mounted: Accessor<boolean>;\n /** Transition classes to apply to the node for the current phase. */\n classes: Accessor<string>;\n}\n\nconst join = (...parts: Array<string | undefined>): string => parts.filter(Boolean).join(\" \");\n\n/**\n * Single-node CSS transition with mountOnEnter + unmountOnExit semantics \u2014 a\n * dependency-free replacement for react-transition-group's CSSTransition. Uses\n * a double rAF to flush the start class before the active class so the CSS\n * transition runs, and a timeout to advance to the done/unmounted phase.\n *\n * Each phase settles once: when the timeout fires, the pending rAFs are\n * cancelled and can no longer rewrite the classes. At a low frame rate the\n * second rAF can land after the timeout, and it used to overwrite the done\n * class with the start/active classes, parking the node in its off-screen\n * state.\n */\nexport function createCssTransition(options: CreateCssTransitionOptions): CssTransitionState {\n const [mounted, setMounted] = createSignal(options.in());\n const [classes, setClasses] = createSignal(\"\");\n\n let first = true;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let raf1: number | undefined;\n let raf2: number | undefined;\n // Bumped whenever a phase settles or is replaced; a frame callback from an\n // older phase sees a different value and does nothing.\n let generation = 0;\n\n const clearTimers = (): void => {\n generation++;\n if (timer !== undefined) clearTimeout(timer);\n if (raf1 !== undefined) cancelAnimationFrame(raf1);\n if (raf2 !== undefined) cancelAnimationFrame(raf2);\n timer = undefined;\n raf1 = undefined;\n raf2 = undefined;\n };\n\n const run = (start: string | undefined, active: string | undefined, done: string | undefined, duration: number, onEnd?: () => void): void => {\n const own = generation;\n setClasses(start ?? \"\");\n raf1 = requestAnimationFrame(() => {\n raf1 = undefined;\n if (own !== generation) return;\n raf2 = requestAnimationFrame(() => {\n raf2 = undefined;\n if (own === generation) setClasses(join(start, active));\n });\n });\n timer = setTimeout(() => {\n clearTimers();\n if (onEnd) onEnd();\n else setClasses(done ?? \"\");\n }, duration);\n };\n\n createEffect(() => {\n const show = options.in();\n clearTimers();\n const cls = options.classNames;\n\n if (show) {\n setMounted(true);\n if (first && !options.appear) {\n setClasses(cls.enterDone ?? \"\");\n } else {\n const useAppear = first && !!options.appear;\n run(\n useAppear ? cls.appear : cls.enter,\n useAppear ? cls.appearActive : cls.enterActive,\n useAppear ? (cls.appearDone ?? cls.enterDone) : cls.enterDone,\n useAppear ? (options.timeout.appear ?? options.timeout.enter) : options.timeout.enter\n );\n }\n } else if (mounted()) {\n run(cls.exit, cls.exitActive, cls.exitDone, options.timeout.exit, () => {\n setMounted(false);\n setClasses(\"\");\n });\n }\n first = false;\n });\n\n onCleanup(clearTimers);\n\n return { mounted, classes };\n}\n"],
5
+ "mappings": "AAAA,SAAwB,cAAc,cAAc,iBAAiB;AA6BrE,MAAM,OAAO,IAAI,UAA6C,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AAcrF,SAAS,oBAAoB,SAAyD;AAC3F,QAAM,CAAC,SAAS,UAAU,IAAI,aAAa,QAAQ,GAAG,CAAC;AACvD,QAAM,CAAC,SAAS,UAAU,IAAI,aAAa,EAAE;AAE7C,MAAI,QAAQ;AACZ,MAAI;AACJ,MAAI;AACJ,MAAI;AAGJ,MAAI,aAAa;AAEjB,QAAM,cAAc,MAAY;AAC9B;AACA,QAAI,UAAU,OAAW,cAAa,KAAK;AAC3C,QAAI,SAAS,OAAW,sBAAqB,IAAI;AACjD,QAAI,SAAS,OAAW,sBAAqB,IAAI;AACjD,YAAQ;AACR,WAAO;AACP,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,CAAC,OAA2B,QAA4B,MAA0B,UAAkB,UAA6B;AAC3I,UAAM,MAAM;AACZ,eAAW,SAAS,EAAE;AACtB,WAAO,sBAAsB,MAAM;AACjC,aAAO;AACP,UAAI,QAAQ,WAAY;AACxB,aAAO,sBAAsB,MAAM;AACjC,eAAO;AACP,YAAI,QAAQ,WAAY,YAAW,KAAK,OAAO,MAAM,CAAC;AAAA,MACxD,CAAC;AAAA,IACH,CAAC;AACD,YAAQ,WAAW,MAAM;AACvB,kBAAY;AACZ,UAAI,MAAO,OAAM;AAAA,UACZ,YAAW,QAAQ,EAAE;AAAA,IAC5B,GAAG,QAAQ;AAAA,EACb;AAEA,eAAa,MAAM;AACjB,UAAM,OAAO,QAAQ,GAAG;AACxB,gBAAY;AACZ,UAAM,MAAM,QAAQ;AAEpB,QAAI,MAAM;AACR,iBAAW,IAAI;AACf,UAAI,SAAS,CAAC,QAAQ,QAAQ;AAC5B,mBAAW,IAAI,aAAa,EAAE;AAAA,MAChC,OAAO;AACL,cAAM,YAAY,SAAS,CAAC,CAAC,QAAQ;AACrC;AAAA,UACE,YAAY,IAAI,SAAS,IAAI;AAAA,UAC7B,YAAY,IAAI,eAAe,IAAI;AAAA,UACnC,YAAa,IAAI,cAAc,IAAI,YAAa,IAAI;AAAA,UACpD,YAAa,QAAQ,QAAQ,UAAU,QAAQ,QAAQ,QAAS,QAAQ,QAAQ;AAAA,QAClF;AAAA,MACF;AAAA,IACF,WAAW,QAAQ,GAAG;AACpB,UAAI,IAAI,MAAM,IAAI,YAAY,IAAI,UAAU,QAAQ,QAAQ,MAAM,MAAM;AACtE,mBAAW,KAAK;AAChB,mBAAW,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AACA,YAAQ;AAAA,EACV,CAAC;AAED,YAAU,WAAW;AAErB,SAAO,EAAE,SAAS,QAAQ;AAC5B;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smwb/ui-solid",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "SolidJS port of summer-ui: strict, tree-shakeable Material-style component library sharing the @smwb/ui-styles design system.",
5
5
  "license": "MIT",
6
6
  "type": "module",