@constela/runtime 6.0.1 → 7.0.0

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/dist/index.js +85 -2
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -13489,6 +13489,69 @@ async function highlightCode(code, language) {
13489
13489
  });
13490
13490
  }
13491
13491
 
13492
+ // src/transition/index.ts
13493
+ function applyEnterTransition(el, config) {
13494
+ const duration = config.duration ?? 300;
13495
+ let cancelled = false;
13496
+ el.classList.add(config.enter);
13497
+ requestAnimationFrame(() => {
13498
+ if (cancelled) return;
13499
+ el.classList.add(config.enterActive);
13500
+ let done = false;
13501
+ const cleanup = () => {
13502
+ if (done) return;
13503
+ done = true;
13504
+ el.classList.remove(config.enter);
13505
+ el.classList.remove(config.enterActive);
13506
+ el.removeEventListener("transitionend", onEnd);
13507
+ };
13508
+ const onEnd = (e) => {
13509
+ if (e.target !== el) return;
13510
+ cleanup();
13511
+ };
13512
+ el.addEventListener("transitionend", onEnd);
13513
+ setTimeout(cleanup, duration);
13514
+ });
13515
+ return () => {
13516
+ cancelled = true;
13517
+ };
13518
+ }
13519
+ function applyExitTransition(el, config) {
13520
+ const duration = config.duration ?? 300;
13521
+ let cancelled = false;
13522
+ const promise = new Promise((resolve) => {
13523
+ el.classList.add(config.exit);
13524
+ requestAnimationFrame(() => {
13525
+ if (cancelled) {
13526
+ resolve();
13527
+ return;
13528
+ }
13529
+ el.classList.add(config.exitActive);
13530
+ let done = false;
13531
+ const cleanup = () => {
13532
+ if (done) return;
13533
+ done = true;
13534
+ el.classList.remove(config.exit);
13535
+ el.classList.remove(config.exitActive);
13536
+ el.removeEventListener("transitionend", onEnd);
13537
+ resolve();
13538
+ };
13539
+ const onEnd = (e) => {
13540
+ if (e.target !== el) return;
13541
+ cleanup();
13542
+ };
13543
+ el.addEventListener("transitionend", onEnd);
13544
+ setTimeout(cleanup, duration);
13545
+ });
13546
+ });
13547
+ const cancel = () => {
13548
+ cancelled = true;
13549
+ el.classList.remove(config.exit);
13550
+ el.classList.remove(config.exitActive);
13551
+ };
13552
+ return { promise, cancel };
13553
+ }
13554
+
13492
13555
  // src/renderer/index.ts
13493
13556
  var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
13494
13557
  var SVG_TAGS = /* @__PURE__ */ new Set([
@@ -13860,17 +13923,34 @@ function renderIf(node, ctx) {
13860
13923
  let currentNode = null;
13861
13924
  let currentBranch = "none";
13862
13925
  let branchCleanups = [];
13926
+ let pendingExitCancel = null;
13863
13927
  const effectCleanup = createEffect(() => {
13864
13928
  const condition = evaluate(node.condition, { state: ctx.state, locals: ctx.locals, ...ctx.refs && { refs: ctx.refs }, ...ctx.imports && { imports: ctx.imports }, ...ctx.route && { route: ctx.route }, ...ctx.styles && { styles: ctx.styles } });
13865
13929
  const shouldShowThen = Boolean(condition);
13866
13930
  const newBranch = shouldShowThen ? "then" : node.else ? "else" : "none";
13867
13931
  if (newBranch !== currentBranch) {
13932
+ if (pendingExitCancel) {
13933
+ pendingExitCancel();
13934
+ pendingExitCancel = null;
13935
+ }
13868
13936
  for (const cleanup of branchCleanups) {
13869
13937
  cleanup();
13870
13938
  }
13871
13939
  branchCleanups = [];
13872
- if (currentNode && currentNode.parentNode) {
13873
- currentNode.parentNode.removeChild(currentNode);
13940
+ const oldNode = currentNode;
13941
+ if (oldNode && oldNode.parentNode) {
13942
+ if (node.transition && oldNode instanceof HTMLElement) {
13943
+ const { promise, cancel } = applyExitTransition(oldNode, node.transition);
13944
+ pendingExitCancel = cancel;
13945
+ promise.then(() => {
13946
+ pendingExitCancel = null;
13947
+ if (oldNode.parentNode) {
13948
+ oldNode.parentNode.removeChild(oldNode);
13949
+ }
13950
+ });
13951
+ } else {
13952
+ oldNode.parentNode.removeChild(oldNode);
13953
+ }
13874
13954
  }
13875
13955
  const localCleanups = [];
13876
13956
  const branchCtx = { ...ctx, cleanups: localCleanups };
@@ -13886,6 +13966,9 @@ function renderIf(node, ctx) {
13886
13966
  if (currentNode && anchor.parentNode) {
13887
13967
  anchor.parentNode.insertBefore(currentNode, anchor.nextSibling);
13888
13968
  }
13969
+ if (currentNode && node.transition && currentNode instanceof HTMLElement) {
13970
+ applyEnterTransition(currentNode, node.transition);
13971
+ }
13889
13972
  currentBranch = newBranch;
13890
13973
  }
13891
13974
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/runtime",
3
- "version": "6.0.1",
3
+ "version": "7.0.0",
4
4
  "description": "Runtime DOM renderer for Constela UI framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -18,8 +18,8 @@
18
18
  "dompurify": "^3.3.1",
19
19
  "marked": "^17.0.1",
20
20
  "shiki": "^3.20.0",
21
- "@constela/compiler": "0.15.22",
22
- "@constela/core": "0.22.1"
21
+ "@constela/compiler": "0.16.0",
22
+ "@constela/core": "0.23.0"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/dompurify": "^3.2.0",
@@ -29,10 +29,10 @@
29
29
  "tsup": "^8.0.0",
30
30
  "typescript": "^5.3.0",
31
31
  "vitest": "^2.0.0",
32
- "@constela/server": "18.0.1"
32
+ "@constela/server": "19.0.0"
33
33
  },
34
34
  "peerDependencies": {
35
- "@constela/ai": "7.0.1"
35
+ "@constela/ai": "8.0.0"
36
36
  },
37
37
  "peerDependenciesMeta": {
38
38
  "@constela/ai": {