@estjs/template 0.0.16-beta.7 → 0.0.16-beta.9

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,9 +1,7 @@
1
- import { getActiveScope, runWithScope, onCleanup, __objRest, createScope, disposeScope, __async } from './chunk-OEKE4VTS.dev.esm.js';
2
- import { normalizeClassName, isObject, warn, isSpecialBooleanAttr, isBooleanAttr, includeBooleanAttr, isSymbol, isString, isArray, kebabCase, camelCase, capitalize, isBrowser, error, isPromise, isFunction, isOn, coerceArray } from '@estjs/shared';
3
- import { effect, shallowReactive, isSignal, isComputed, signal } from '@estjs/signals';
1
+ import { getActiveScope, runWithScope, onCleanup, __objRest, createScope, disposeScope, __spreadValues, __async } from './chunk-W5LMSADN.dev.js';
2
+ import { normalizeClassName, SPREAD_NAME, isObject, warn, startsWith, isSpecialBooleanAttr, isBooleanAttr, includeBooleanAttr, isSymbol, isString, isArray, kebabCase, camelCase, capitalize, HYDRATION_ANCHOR_ATTR, isBrowser, error, isPromise, isFunction, isOn, coerceArray } from '@estjs/shared';
3
+ import { effect, shallowReactive, isSignal, isComputed, isReactive, signal } from '@estjs/signals';
4
4
 
5
- // src/constants.ts
6
- var SPREAD_NAME = "_$spread$";
7
5
  var REF_KEY = "ref";
8
6
  var KEY_PROP = "key";
9
7
  var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
@@ -13,6 +11,8 @@ var FRAGMENT_COMPONENT = /* @__PURE__ */ Symbol("Fragment Component" );
13
11
  var PORTAL_COMPONENT = /* @__PURE__ */ Symbol("Portal Component" );
14
12
  var SUSPENSE_COMPONENT = /* @__PURE__ */ Symbol("Suspense Component" );
15
13
  var FOR_COMPONENT = /* @__PURE__ */ Symbol("For Component" );
14
+ var TRANSITION_COMPONENT = /* @__PURE__ */ Symbol("Transition Component" );
15
+ var TRANSITION_GROUP_COMPONENT = /* @__PURE__ */ Symbol("TransitionGroup Component" );
16
16
  function patchAttr(el, key, prev, next2) {
17
17
  if (key === KEY_PROP) {
18
18
  if (next2 == null) {
@@ -57,8 +57,8 @@ function patchAttr(el, key, prev, next2) {
57
57
  return;
58
58
  }
59
59
  const elementIsSVG = (el == null ? void 0 : el.namespaceURI) === SVG_NAMESPACE;
60
- const isXlink = elementIsSVG && key.startsWith("xlink:");
61
- const isXmlns = elementIsSVG && key.startsWith("xmlns:");
60
+ const isXlink = elementIsSVG && startsWith(key, "xlink:");
61
+ const isXmlns = elementIsSVG && startsWith(key, "xmlns:");
62
62
  const isBoolean = isSpecialBooleanAttr(key) || isBooleanAttr(key);
63
63
  if (prev === next2) {
64
64
  return;
@@ -96,7 +96,7 @@ function patchAttr(el, key, prev, next2) {
96
96
  const isUrlAttr = lowerKey === "href" || lowerKey === "src" || lowerKey === "xlink:href" || lowerKey === "action" || lowerKey === "formaction" || lowerKey === "poster";
97
97
  if (isUrlAttr && isString(attrValue)) {
98
98
  const v = attrValue.trim().toLowerCase();
99
- if (v.startsWith("javascript:") || v.startsWith("data:")) {
99
+ if (startsWith(v, "javascript:") || startsWith(v, "data:")) {
100
100
  return;
101
101
  }
102
102
  }
@@ -200,7 +200,7 @@ function setStyle(style, name, val) {
200
200
  if (priority) {
201
201
  val = val.replace(importantRE, "");
202
202
  }
203
- if (name.startsWith("--")) {
203
+ if (startsWith(name, "--")) {
204
204
  if (priority) {
205
205
  style.setProperty(name, val, priority);
206
206
  } else {
@@ -217,7 +217,7 @@ function setStyle(style, name, val) {
217
217
  }
218
218
  function toCssPropertyName(name) {
219
219
  const hyphenated = kebabCase(name);
220
- return name.startsWith("Webkit") || name.startsWith("Moz") || name.startsWith("ms") ? `-${hyphenated}` : hyphenated;
220
+ return startsWith(name, "Webkit") || startsWith(name, "Moz") || startsWith(name, "ms") ? `-${hyphenated}` : hyphenated;
221
221
  }
222
222
  function autoPrefix(style, rawName) {
223
223
  const cached = prefixCache[rawName];
@@ -319,6 +319,77 @@ function endHydration() {
319
319
  _teleportCallsiteAnchors.length = 0;
320
320
  _teleportTargetStarts.clear();
321
321
  }
322
+ function claimHydratedNodes(parent, expected, before) {
323
+ var _a2, _b;
324
+ if (!_isHydrating || before && before.parentNode !== parent) return null;
325
+ if (expected.length === 0) return [];
326
+ const claimed = new Array(expected.length);
327
+ let cursor = before ? before.previousSibling : parent.lastChild;
328
+ for (let i = expected.length - 1; i >= 0; i--) {
329
+ if (!cursor) return null;
330
+ const expectedNode = expected[i];
331
+ const expectedType = expectedNode.nodeType;
332
+ if (expectedType === Node.TEXT_NODE) {
333
+ const expectedText = (_a2 = expectedNode.textContent) != null ? _a2 : "";
334
+ if (!expectedText || cursor.nodeType !== Node.TEXT_NODE) return null;
335
+ const existingText = (_b = cursor.textContent) != null ? _b : "";
336
+ if (existingText === expectedText) {
337
+ claimed[i] = cursor;
338
+ cursor = cursor.previousSibling;
339
+ continue;
340
+ }
341
+ if (!existingText.endsWith(expectedText)) return null;
342
+ const prefix = existingText.slice(0, existingText.length - expectedText.length);
343
+ if (!prefix) return null;
344
+ const prefixNode = document.createTextNode(prefix);
345
+ parent.insertBefore(prefixNode, cursor);
346
+ cursor.textContent = expectedText;
347
+ claimed[i] = cursor;
348
+ cursor = prefixNode;
349
+ continue;
350
+ }
351
+ if (cursor.nodeType !== expectedType) return null;
352
+ if (expectedType === Node.ELEMENT_NODE) {
353
+ if (cursor.tagName !== expectedNode.tagName) return null;
354
+ } else if (expectedType === Node.COMMENT_NODE && cursor.data !== expectedNode.data) {
355
+ return null;
356
+ }
357
+ claimed[i] = cursor;
358
+ cursor = cursor.previousSibling;
359
+ }
360
+ return claimed;
361
+ }
362
+ function resolveHydrationKey(parent) {
363
+ var _a2, _b, _c;
364
+ const el = parent;
365
+ return (_c = (_b = el.dataset.hk) != null ? _b : (_a2 = parent.closest("[data-hk]")) == null ? void 0 : _a2.dataset.hk) != null ? _c : null;
366
+ }
367
+ function hydrationMarker(parent, index) {
368
+ if (!_isHydrating || !parent || index < 0) return null;
369
+ const key = parent instanceof Element ? resolveHydrationKey(parent) : null;
370
+ const expected = key ? `${key}-${index}` : String(index);
371
+ let cursor = parent.firstChild;
372
+ while (cursor) {
373
+ if (cursor.nodeType === Node.COMMENT_NODE && cursor.data === expected) {
374
+ return cursor;
375
+ }
376
+ cursor = cursor.nextSibling;
377
+ }
378
+ return null;
379
+ }
380
+ function hydrationAnchor(parent, index) {
381
+ if (!_isHydrating || !(parent instanceof Element) || index < 0) return null;
382
+ const key = resolveHydrationKey(parent);
383
+ const expected = key ? `${key}-${index}` : String(index);
384
+ let cursor = parent.firstChild;
385
+ while (cursor) {
386
+ if (cursor instanceof Element && cursor.getAttribute(HYDRATION_ANCHOR_ATTR) === expected) {
387
+ return cursor;
388
+ }
389
+ cursor = cursor.nextSibling;
390
+ }
391
+ return null;
392
+ }
322
393
  function getRenderedElement(html) {
323
394
  if (!isBrowser()) {
324
395
  return () => {
@@ -416,12 +487,17 @@ function reconcileArrays(parent, oldNodes, newNodes, anchor) {
416
487
  }
417
488
  function reconcileUnknownSequence(parent, oldNodes, newNodes, start, oldEnd, newEnd, anchor) {
418
489
  const newLength = newEnd - start + 1;
419
- const newIndexMap = /* @__PURE__ */ new Map();
420
- for (let i = start; i <= newEnd; i++) {
421
- newIndexMap.set(newNodes[i], i);
422
- }
490
+ const findNewIndex = newLength <= 4 ? (node) => {
491
+ for (let i = start; i <= newEnd; i++) {
492
+ if (newNodes[i] === node) return i;
493
+ }
494
+ return void 0;
495
+ } : (() => {
496
+ const map = /* @__PURE__ */ new Map();
497
+ for (let i = start; i <= newEnd; i++) map.set(newNodes[i], i);
498
+ return (node) => map.get(node);
499
+ })();
423
500
  const newIndexToOldIndexMap = new Int32Array(newLength);
424
- newIndexToOldIndexMap.fill(0);
425
501
  let patched = 0;
426
502
  let moved = false;
427
503
  let maxNewIndexSoFar = 0;
@@ -431,7 +507,7 @@ function reconcileUnknownSequence(parent, oldNodes, newNodes, start, oldEnd, new
431
507
  removeNode(oldNode);
432
508
  continue;
433
509
  }
434
- const newIndex = newIndexMap.get(oldNode);
510
+ const newIndex = findNewIndex(oldNode);
435
511
  if (newIndex === void 0) {
436
512
  removeNode(oldNode);
437
513
  } else {
@@ -577,6 +653,14 @@ function insert(parent, nodeFactory, before) {
577
653
  isFirstRun = false;
578
654
  return;
579
655
  }
656
+ if (isFirstRun && isHydrating()) {
657
+ const hydratedNodes = claimHydratedNodes(parent, nodes, before);
658
+ if (hydratedNodes) {
659
+ renderedNodes = hydratedNodes;
660
+ isFirstRun = false;
661
+ return;
662
+ }
663
+ }
580
664
  renderedNodes = reconcileArrays(parent, renderedNodes, nodes, before);
581
665
  isFirstRun = false;
582
666
  };
@@ -723,14 +807,13 @@ function triggerUpdateHooks(scope) {
723
807
 
724
808
  // src/component.ts
725
809
  function syncDescriptors(target, source, pruneMissing = false) {
726
- const seen = pruneMissing ? /* @__PURE__ */ new Set() : null;
727
810
  for (const key of Object.getOwnPropertyNames(source)) {
728
- seen == null ? void 0 : seen.add(key);
729
811
  Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
730
812
  }
731
- if (seen) {
813
+ if (pruneMissing) {
814
+ const sourceKeys = Object.getOwnPropertyNames(source);
732
815
  for (const key of Object.getOwnPropertyNames(target)) {
733
- if (!seen.has(key)) delete target[key];
816
+ if (!sourceKeys.includes(key)) delete target[key];
734
817
  }
735
818
  }
736
819
  }
@@ -839,6 +922,9 @@ var Component = class {
839
922
  this.renderedNodes = [];
840
923
  this.firstChild = void 0;
841
924
  this.parentNode = void 0;
925
+ for (const key of Object.getOwnPropertyNames(this.reactiveProps)) {
926
+ delete this.reactiveProps[key];
927
+ }
842
928
  }
843
929
  /**
844
930
  * Apply props that bind to the root DOM element rather than flowing into
@@ -849,7 +935,7 @@ var Component = class {
849
935
  syncSpecialProps(props) {
850
936
  if (!props) return;
851
937
  const root = this.firstChild;
852
- if (!root) return;
938
+ if (!root || !(root instanceof Element)) return;
853
939
  this.releaseSpecialProps();
854
940
  for (const key of Object.getOwnPropertyNames(props)) {
855
941
  if (key === REF_KEY) {
@@ -861,7 +947,22 @@ var Component = class {
861
947
  const value = readProp(props, key);
862
948
  if (!isFunction(value)) continue;
863
949
  const eventName = key.slice(2).toLowerCase();
864
- this.rootEventCleanups.push(addEvent(root, eventName, value));
950
+ const target = root;
951
+ const slot = `_$${eventName}`;
952
+ const prev = target[slot];
953
+ if (isFunction(prev)) {
954
+ target[slot] = value;
955
+ this.rootEventCleanups.push(() => {
956
+ if (target[slot] === value) target[slot] = prev;
957
+ });
958
+ continue;
959
+ }
960
+ const fn = value;
961
+ const handler = (event) => {
962
+ if (target.disabled) return;
963
+ fn.call(target, event);
964
+ };
965
+ this.rootEventCleanups.push(addEvent(target, eventName, handler));
865
966
  }
866
967
  }
867
968
  }
@@ -908,91 +1009,6 @@ function createComponent(componentFn, props) {
908
1009
  }
909
1010
  return new Component(componentFn, props);
910
1011
  }
911
-
912
- // src/renderer.ts
913
- function template(html) {
914
- let node;
915
- const create = () => {
916
- const template2 = document.createElement("template");
917
- template2.innerHTML = html;
918
- const firstChild = template2.content.firstChild;
919
- if (!firstChild) {
920
- throw new Error("Invalid template: empty content");
921
- }
922
- return firstChild;
923
- };
924
- return () => (node || (node = create())).cloneNode(true);
925
- }
926
- function createApp(component, target) {
927
- const container = isString(target) ? document.querySelector(target) : target;
928
- if (!container) {
929
- {
930
- warn(`Target element not found: ${target}`);
931
- }
932
- return;
933
- }
934
- const existingContent = container.innerHTML;
935
- if (existingContent) {
936
- {
937
- warn(`Target element is not empty, it will be cleared: ${target}`);
938
- }
939
- container.innerHTML = "";
940
- }
941
- const scope = createScope();
942
- let rootNode;
943
- try {
944
- runWithScope(scope, () => {
945
- const mountedRoot = createComponent(component);
946
- if (isComponent(mountedRoot)) {
947
- rootNode = mountedRoot;
948
- insertNode(container, mountedRoot);
949
- }
950
- });
951
- } catch (error_) {
952
- disposeScope(scope);
953
- throw error_;
954
- }
955
- return {
956
- root: rootNode,
957
- unmount: () => {
958
- disposeScope(scope);
959
- rootNode == null ? void 0 : rootNode.destroy();
960
- }
961
- };
962
- }
963
- function hydrate(component, target) {
964
- const container = isString(target) ? document.querySelector(target) : target;
965
- if (!container) {
966
- {
967
- warn(`[essor] hydrate: target element not found: ${target}`);
968
- }
969
- return;
970
- }
971
- beginHydration(container);
972
- const scope = createScope();
973
- let rootNode;
974
- try {
975
- runWithScope(scope, () => {
976
- const mountedRoot = createComponent(component);
977
- if (isComponent(mountedRoot)) {
978
- rootNode = mountedRoot;
979
- insert(container, mountedRoot);
980
- }
981
- });
982
- } catch (error_) {
983
- disposeScope(scope);
984
- throw error_;
985
- } finally {
986
- endHydration();
987
- }
988
- return {
989
- root: rootNode,
990
- unmount: () => {
991
- disposeScope(scope);
992
- rootNode == null ? void 0 : rootNode.destroy();
993
- }
994
- };
995
- }
996
1012
  function provide(key, value) {
997
1013
  const scope = getActiveScope();
998
1014
  if (!scope) {
@@ -1025,6 +1041,186 @@ function inject(key, defaultValue) {
1025
1041
  }
1026
1042
  return defaultValue;
1027
1043
  }
1044
+
1045
+ // src/renderer.ts
1046
+ var VERSION = typeof __VERSION__ === "string" ? __VERSION__ : "";
1047
+ var ENFORCE_ORDER = { pre: 0, default: 1, post: 2 };
1048
+ function template(html) {
1049
+ let node;
1050
+ const create = () => {
1051
+ const template2 = document.createElement("template");
1052
+ template2.innerHTML = html;
1053
+ const firstChild = template2.content.firstChild;
1054
+ if (!firstChild) {
1055
+ throw new Error("Invalid template: empty content");
1056
+ }
1057
+ return firstChild;
1058
+ };
1059
+ return () => (node || (node = create())).cloneNode(true);
1060
+ }
1061
+ function createApp(component, arg) {
1062
+ if (isString(arg) || arg instanceof Element) {
1063
+ return buildApp(component).mount(arg);
1064
+ }
1065
+ return buildApp(component, arg);
1066
+ }
1067
+ function hydrate(component, target) {
1068
+ return buildApp(component).hydrate(target);
1069
+ }
1070
+ function definePlugin(plugin) {
1071
+ return plugin;
1072
+ }
1073
+ function buildApp(component, options) {
1074
+ var _a2, _b;
1075
+ const plugins = (_a2 = options == null ? void 0 : options.plugins) != null ? _a2 : [];
1076
+ const config = __spreadValues({}, (_b = options == null ? void 0 : options.config) != null ? _b : {});
1077
+ let mounted = false;
1078
+ function mount(target, isHydrate) {
1079
+ if (mounted) {
1080
+ warn("App is already mounted");
1081
+ return;
1082
+ }
1083
+ mounted = true;
1084
+ const container = isString(target) ? document.querySelector(target) : target;
1085
+ if (!container) {
1086
+ {
1087
+ warn(`[essor] ${isHydrate ? "hydrate" : "createApp"}: target element not found: ${target}`);
1088
+ }
1089
+ return;
1090
+ }
1091
+ if (!isHydrate && container.innerHTML) {
1092
+ warn(`Target element is not empty, it will be cleared: ${target}`);
1093
+ container.innerHTML = "";
1094
+ }
1095
+ const scope = createScope();
1096
+ const mountHooks = [];
1097
+ const seenNames = /* @__PURE__ */ new Set();
1098
+ const seenRefs = /* @__PURE__ */ new Set();
1099
+ let activePluginName;
1100
+ let root;
1101
+ function reportError(error4, info) {
1102
+ if (config.errorHandler) config.errorHandler(info, error4);
1103
+ else throw error4;
1104
+ }
1105
+ const ordered = plugins.map((entry, index) => ({ entry, index })).sort((a, b) => {
1106
+ var _a3, _b2;
1107
+ const pa = ENFORCE_ORDER[(_a3 = normalizePlugin(a.entry).enforce) != null ? _a3 : "default"];
1108
+ const pb = ENFORCE_ORDER[(_b2 = normalizePlugin(b.entry).enforce) != null ? _b2 : "default"];
1109
+ return pa - pb || a.index - b.index;
1110
+ }).map((x) => x.entry);
1111
+ function runSetup(plugin, opts) {
1112
+ if (seenRefs.has(plugin) || seenNames.has(plugin.name)) {
1113
+ warn(`Plugin "${plugin.name}" is already registered, skipping`);
1114
+ return;
1115
+ }
1116
+ seenRefs.add(plugin);
1117
+ seenNames.add(plugin.name);
1118
+ activePluginName = plugin.name;
1119
+ try {
1120
+ const result = plugin.setup(ctx, opts);
1121
+ if (result instanceof Promise) {
1122
+ const pinned = plugin.name;
1123
+ return result.catch((error4) => reportError(error4, { phase: "install", plugin: pinned })).finally(() => {
1124
+ if (activePluginName === pinned) activePluginName = void 0;
1125
+ });
1126
+ }
1127
+ activePluginName = void 0;
1128
+ return result;
1129
+ } catch (error4) {
1130
+ activePluginName = void 0;
1131
+ reportError(error4, { phase: "install", plugin: plugin.name });
1132
+ }
1133
+ }
1134
+ const ctx = {
1135
+ provide,
1136
+ inject,
1137
+ onMount: (fn) => void mountHooks.push(fn),
1138
+ onCleanup,
1139
+ warn(message) {
1140
+ const info = { plugin: activePluginName };
1141
+ if (config.warnHandler) config.warnHandler(info, message);
1142
+ else warn(message);
1143
+ },
1144
+ error(message) {
1145
+ throw new Error(message);
1146
+ },
1147
+ config,
1148
+ version: VERSION
1149
+ };
1150
+ function finishMount() {
1151
+ if (isHydrate) beginHydration(container);
1152
+ try {
1153
+ const node = createComponent(component);
1154
+ if (isComponent(node)) {
1155
+ root = node;
1156
+ (isHydrate ? insert : insertNode)(container, node);
1157
+ }
1158
+ } finally {
1159
+ if (isHydrate) endHydration();
1160
+ }
1161
+ for (const fn of mountHooks) {
1162
+ try {
1163
+ fn();
1164
+ } catch (error4) {
1165
+ reportError(error4, { phase: "mount" });
1166
+ }
1167
+ }
1168
+ return {
1169
+ root,
1170
+ unmount() {
1171
+ disposeScope(scope);
1172
+ root == null ? void 0 : root.destroy();
1173
+ }
1174
+ };
1175
+ }
1176
+ let asyncTail;
1177
+ try {
1178
+ runWithScope(scope, () => {
1179
+ for (const entry of ordered) {
1180
+ const [plugin, opts] = unpack(entry);
1181
+ if (asyncTail) {
1182
+ asyncTail = asyncTail.then(
1183
+ () => runWithScope(scope, () => {
1184
+ const r = runSetup(plugin, opts);
1185
+ return r instanceof Promise ? r : void 0;
1186
+ })
1187
+ );
1188
+ continue;
1189
+ }
1190
+ const result = runSetup(plugin, opts);
1191
+ if (result instanceof Promise) asyncTail = result;
1192
+ }
1193
+ });
1194
+ } catch (error4) {
1195
+ disposeScope(scope);
1196
+ throw error4;
1197
+ }
1198
+ if (asyncTail) {
1199
+ return asyncTail.then(() => runWithScope(scope, finishMount)).catch((error4) => {
1200
+ disposeScope(scope);
1201
+ throw error4;
1202
+ });
1203
+ }
1204
+ try {
1205
+ return runWithScope(scope, finishMount);
1206
+ } catch (error4) {
1207
+ disposeScope(scope);
1208
+ throw error4;
1209
+ }
1210
+ }
1211
+ const app = {
1212
+ config,
1213
+ mount: (target) => mount(target, false),
1214
+ hydrate: (target) => mount(target, true)
1215
+ };
1216
+ return app;
1217
+ }
1218
+ function normalizePlugin(entry) {
1219
+ return Array.isArray(entry) ? entry[0] : entry;
1220
+ }
1221
+ function unpack(entry) {
1222
+ return Array.isArray(entry) ? [entry[0], entry[1]] : [entry, void 0];
1223
+ }
1028
1224
  function reTargetEvent(e, value) {
1029
1225
  Object.defineProperty(e, "target", {
1030
1226
  configurable: true,
@@ -1079,7 +1275,7 @@ function eventHandler(e) {
1079
1275
  reTargetEvent(e, oriTarget);
1080
1276
  }
1081
1277
  var $EVENTS = /* @__PURE__ */ Symbol("_$EVENTS");
1082
- function delegateEvents(eventNames, document2 = window.document) {
1278
+ function delegateEvents(eventNames, document2 = globalThis.document) {
1083
1279
  const docWithEvents = document2;
1084
1280
  const eventSet = docWithEvents[$EVENTS] || (docWithEvents[$EVENTS] = /* @__PURE__ */ new Set());
1085
1281
  for (const name of eventNames) {
@@ -1089,7 +1285,7 @@ function delegateEvents(eventNames, document2 = window.document) {
1089
1285
  }
1090
1286
  }
1091
1287
  }
1092
- function clearDelegatedEvents(document2 = window.document) {
1288
+ function clearDelegatedEvents(document2 = globalThis.document) {
1093
1289
  const docWithEvents = document2;
1094
1290
  const eventSet = docWithEvents[$EVENTS];
1095
1291
  if (eventSet) {
@@ -1107,6 +1303,11 @@ function addEventListener(element, event, handler, options) {
1107
1303
  }
1108
1304
 
1109
1305
  // src/binding.ts
1306
+ var IDENTITY = (v) => v;
1307
+ var EMPTY_FILES = (() => {
1308
+ if (typeof DataTransfer !== "undefined") return new DataTransfer().files;
1309
+ return [];
1310
+ })();
1110
1311
  function writeValue(el, v) {
1111
1312
  const target = el;
1112
1313
  const next2 = v == null ? "" : String(v);
@@ -1115,10 +1316,11 @@ function writeValue(el, v) {
1115
1316
  var CHECKBOX = {
1116
1317
  event: "change",
1117
1318
  forceChange: true,
1319
+ checkboxArray: true,
1118
1320
  read: (el) => el.checked,
1119
1321
  write(el, v) {
1120
1322
  const e = el;
1121
- const next2 = Boolean(v);
1323
+ const next2 = isArray(v) ? v.map(String).includes(e.value) : Boolean(v);
1122
1324
  if (e.checked !== next2) e.checked = next2;
1123
1325
  }
1124
1326
  };
@@ -1139,17 +1341,15 @@ var FILE = {
1139
1341
  event: "change",
1140
1342
  forceChange: true,
1141
1343
  read: (el) => el.files,
1142
- write() {
1344
+ write(el, v) {
1345
+ if (v != null) return;
1346
+ try {
1347
+ el.files = EMPTY_FILES;
1348
+ } catch (e) {
1349
+ }
1143
1350
  }
1144
- // browsers forbid programmatic writes to file inputs
1145
- };
1146
- var TEXT = {
1147
- event: "input",
1148
- ime: true,
1149
- read: (el) => el.value,
1150
- write: writeValue
1151
1351
  };
1152
- var TEXTAREA = {
1352
+ var TEXT_LIKE = {
1153
1353
  event: "input",
1154
1354
  ime: true,
1155
1355
  read: (el) => el.value,
@@ -1164,41 +1364,44 @@ var SELECT = {
1164
1364
  },
1165
1365
  write(el, v) {
1166
1366
  const s = el;
1167
- if (s.multiple) {
1168
- const selected = new Set((Array.isArray(v) ? v : []).map(String));
1169
- for (const opt of Array.from(s.options)) opt.selected = selected.has(opt.value);
1170
- } else {
1171
- writeValue(el, v);
1172
- }
1367
+ if (!s.multiple) return writeValue(el, v);
1368
+ const selected = new Set((isArray(v) ? v : []).map(String));
1369
+ for (const opt of Array.from(s.options)) opt.selected = selected.has(opt.value);
1173
1370
  }
1174
1371
  };
1372
+ function customStrategy(prop) {
1373
+ return {
1374
+ event: "input",
1375
+ read: (el) => el[prop],
1376
+ write(el, v) {
1377
+ el[prop] = v;
1378
+ }
1379
+ };
1380
+ }
1175
1381
  function resolve(node, prop) {
1176
1382
  switch (node.nodeName) {
1177
1383
  case "INPUT":
1178
1384
  if (prop === "checked") return node.type === "radio" ? RADIO : CHECKBOX;
1179
1385
  if (prop === "files") return FILE;
1180
- return TEXT;
1386
+ if (prop === "value") return TEXT_LIKE;
1387
+ return customStrategy(prop);
1181
1388
  case "SELECT":
1182
1389
  return SELECT;
1183
1390
  case "TEXTAREA":
1184
- return TEXTAREA;
1391
+ return TEXT_LIKE;
1185
1392
  default:
1186
- return {
1187
- event: "input",
1188
- read: (el) => el[prop],
1189
- write(el, v) {
1190
- el[prop] = v;
1191
- }
1192
- };
1393
+ return customStrategy(prop);
1193
1394
  }
1194
1395
  }
1195
1396
  function applyModifiers(v, trim, toNum) {
1196
1397
  if (!isString(v)) return v;
1197
- let s = v;
1198
- if (trim) s = s.trim();
1199
- if (toNum && s !== "") {
1200
- const n = Number(s);
1201
- if (!Number.isNaN(n)) return n;
1398
+ const s = trim ? v.trim() : v;
1399
+ if (toNum) {
1400
+ const probe = trim ? s : s.trim();
1401
+ if (probe !== "") {
1402
+ const n = Number(probe);
1403
+ if (!Number.isNaN(n)) return n;
1404
+ }
1202
1405
  }
1203
1406
  return s;
1204
1407
  }
@@ -1206,44 +1409,54 @@ function isFocused(el) {
1206
1409
  const root = el.getRootNode();
1207
1410
  return (root instanceof Document || root instanceof ShadowRoot) && root.activeElement === el;
1208
1411
  }
1412
+ function shouldAutoCoerceNumber(node, prop) {
1413
+ if (prop !== "value" || node.nodeName !== "INPUT") return false;
1414
+ const t = node.type;
1415
+ return t === "number" || t === "range";
1416
+ }
1209
1417
  function bindElement(node, prop, getter, setter, modifiers = {}) {
1210
1418
  if (!node) return;
1211
- const { event, read, write, forceChange, ime } = resolve(node, prop);
1419
+ const { event, read, write, forceChange, ime, checkboxArray } = resolve(node, prop);
1212
1420
  const trim = modifiers.trim === true;
1213
- const toNum = modifiers.number === true;
1421
+ const toNum = modifiers.number === true || shouldAutoCoerceNumber(node, prop);
1214
1422
  const lazy = modifiers.lazy === true;
1215
1423
  const shouldCast = (trim || toNum) && prop !== "files";
1216
1424
  const getModel = isFunction(getter) ? getter : () => getter;
1217
- const cast = shouldCast ? (v) => applyModifiers(v, trim, toNum) : (v) => v;
1425
+ const cast = shouldCast ? (v) => applyModifiers(v, trim, toNum) : IDENTITY;
1426
+ const computeNext = checkboxArray ? (raw) => {
1427
+ const current = getModel();
1428
+ if (!isArray(current)) return cast(raw);
1429
+ const own = node.value;
1430
+ const next2 = current.filter((item) => String(item) !== own);
1431
+ if (raw) next2.push(own);
1432
+ return next2;
1433
+ } : cast;
1218
1434
  let composing = false;
1219
1435
  const eventName = lazy || forceChange ? "change" : event;
1220
1436
  const syncToModel = () => {
1221
1437
  if (composing) return;
1222
1438
  const raw = read(node);
1223
1439
  if (raw === void 0) return;
1224
- const next2 = cast(raw);
1440
+ const next2 = computeNext(raw);
1225
1441
  if (!Object.is(getModel(), next2)) setter(next2);
1226
1442
  };
1227
1443
  addEventListener(node, eventName, syncToModel);
1228
1444
  if (!lazy && shouldCast && eventName !== "change") {
1229
1445
  addEventListener(node, "change", () => write(node, cast(read(node))));
1230
1446
  }
1231
- if (ime && !lazy) {
1447
+ if (ime) {
1232
1448
  addEventListener(node, "compositionstart", () => {
1233
1449
  composing = true;
1234
1450
  });
1235
1451
  addEventListener(node, "compositionend", () => {
1236
- if (!composing) return;
1237
1452
  composing = false;
1238
- syncToModel();
1453
+ if (!lazy) syncToModel();
1239
1454
  });
1240
1455
  }
1241
1456
  const runner = effect(() => {
1242
1457
  const value = getModel();
1243
- if (ime && !lazy && isFocused(node)) {
1244
- if (composing) return;
1245
- if (Object.is(cast(read(node)), value)) return;
1246
- }
1458
+ if (ime && composing) return;
1459
+ if (ime && !lazy && isFocused(node) && Object.is(cast(read(node)), value)) return;
1247
1460
  write(node, value);
1248
1461
  });
1249
1462
  if (getActiveScope()) {
@@ -1252,6 +1465,18 @@ function bindElement(node, prop, getter, setter, modifiers = {}) {
1252
1465
  }
1253
1466
 
1254
1467
  // src/utils.ts
1468
+ function unwrapSlotValue(raw) {
1469
+ let v = raw;
1470
+ if (Array.isArray(v) && v.length === 1) v = v[0];
1471
+ return typeof v === "function" ? v() : v;
1472
+ }
1473
+ function useChildren(props) {
1474
+ const desc = Object.getOwnPropertyDescriptor(props, "children");
1475
+ if (desc == null ? void 0 : desc.get) {
1476
+ return () => unwrapSlotValue(desc.get.call(props));
1477
+ }
1478
+ return () => unwrapSlotValue(props.children);
1479
+ }
1255
1480
  function omitProps(target, keys) {
1256
1481
  const excludeSet = new Set(keys);
1257
1482
  return new Proxy(target, {
@@ -1290,9 +1515,11 @@ function omitProps(target, keys) {
1290
1515
  }
1291
1516
  });
1292
1517
  }
1293
-
1294
- // src/components/Fragment.ts
1295
1518
  function Fragment(props) {
1519
+ var _a2;
1520
+ if (props && (((_a2 = Object.getOwnPropertyDescriptor(props, "children")) == null ? void 0 : _a2.get) || isReactive(props))) {
1521
+ return [() => props.children];
1522
+ }
1296
1523
  const children = props == null ? void 0 : props.children;
1297
1524
  if (children == null) return null;
1298
1525
  return children;
@@ -1811,7 +2038,11 @@ function For(props) {
1811
2038
  let entries = [];
1812
2039
  let fallbackNodes = [];
1813
2040
  const keyFn = props.key;
1814
- const renderFn = props.children;
2041
+ const raw = props.children;
2042
+ const renderFn = Array.isArray(raw) && raw.length === 1 && isFunction(raw[0]) ? raw[0] : props.children;
2043
+ if (!isFunction(renderFn)) {
2044
+ throw new TypeError("<For> requires `children` to be a function (item, index) => Node");
2045
+ }
1815
2046
  const getList = () => {
1816
2047
  var _a2, _b;
1817
2048
  const input = props.each;
@@ -1819,27 +2050,21 @@ function For(props) {
1819
2050
  if (isFunction(input)) return (_b = input()) != null ? _b : [];
1820
2051
  return input != null ? input : [];
1821
2052
  };
1822
- const getKey = (item) => keyFn ? keyFn(item) : item;
1823
- const normalizeNodes = (value) => {
2053
+ const getKey = (item, index) => keyFn ? keyFn(item, index) : item;
2054
+ const mountValue = (value, parent, before) => {
2055
+ if (value == null || value === false) return [];
1824
2056
  if (Array.isArray(value)) {
1825
2057
  const nodes = [];
1826
- for (const item of value) {
1827
- nodes.push(...normalizeNodes(item));
1828
- }
2058
+ for (const child2 of value) nodes.push(...mountValue(child2, parent, before));
1829
2059
  return nodes;
1830
2060
  }
1831
- return [normalizeNode(value)];
1832
- };
1833
- const mountValue = (value, parent, before) => {
1834
- const nodes = normalizeNodes(value);
1835
- for (const node of nodes) {
1836
- if (before) {
1837
- parent.insertBefore(node, before);
1838
- } else {
1839
- parent.appendChild(node);
1840
- }
2061
+ if (isComponent(value)) {
2062
+ insertNode(parent, value, before != null ? before : void 0);
2063
+ return value.renderedNodes;
1841
2064
  }
1842
- return nodes;
2065
+ const node = normalizeNode(value);
2066
+ insertNode(parent, node, before != null ? before : void 0);
2067
+ return [node];
1843
2068
  };
1844
2069
  const mountFallback = (parent, before) => {
1845
2070
  if (!props.fallback) return;
@@ -1854,14 +2079,14 @@ function For(props) {
1854
2079
  }
1855
2080
  fallbackNodes = [];
1856
2081
  };
1857
- const renderItem = (item, index, parent, before) => {
2082
+ const renderItem = (item, index, parent, before, key = getKey(item, index)) => {
1858
2083
  const parentScope = getActiveScope();
1859
2084
  const scope = createScope(parentScope);
1860
2085
  let mountedNodes = [];
1861
2086
  runWithScope(scope, () => {
1862
2087
  mountedNodes = mountValue(renderFn(item, index), parent, before);
1863
2088
  });
1864
- return { key: getKey(item), item, nodes: mountedNodes, scope };
2089
+ return { key, item, nodes: mountedNodes, scope };
1865
2090
  };
1866
2091
  const disposeItem = (entry) => {
1867
2092
  disposeScope(entry.scope);
@@ -1930,7 +2155,7 @@ function For(props) {
1930
2155
  let maxOldSeen = 0;
1931
2156
  const newKeys = new Array(newLen);
1932
2157
  for (let i = 0; i < newLen; i++) {
1933
- newKeys[i] = getKey(newItems[i]);
2158
+ newKeys[i] = getKey(newItems[i], i);
1934
2159
  }
1935
2160
  for (let i = 0; i < newLen; i++) {
1936
2161
  const item = newItems[i];
@@ -1947,11 +2172,11 @@ function For(props) {
1947
2172
  } else {
1948
2173
  if (!batchFragment) batchFragment = document.createDocumentFragment();
1949
2174
  disposeItem(reused);
1950
- newEntries[i] = renderItem(item, i, batchFragment, null);
2175
+ newEntries[i] = renderItem(item, i, batchFragment, null, key);
1951
2176
  }
1952
2177
  } else {
1953
2178
  if (!batchFragment) batchFragment = document.createDocumentFragment();
1954
- newEntries[i] = renderItem(item, i, batchFragment, null);
2179
+ newEntries[i] = renderItem(item, i, batchFragment, null, key);
1955
2180
  }
1956
2181
  }
1957
2182
  for (const list of oldKeyMap.values()) {
@@ -1995,7 +2220,655 @@ function For(props) {
1995
2220
  return fragment;
1996
2221
  }
1997
2222
  For[FOR_COMPONENT] = true;
2223
+ function resolveTransitionClasses(props) {
2224
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2225
+ const n = (_a2 = props.name) != null ? _a2 : "v";
2226
+ const enterFrom = (_b = props.enterFromClass) != null ? _b : `${n}-enter-from`;
2227
+ const enterActive = (_c = props.enterActiveClass) != null ? _c : `${n}-enter-active`;
2228
+ const enterTo = (_d = props.enterToClass) != null ? _d : `${n}-enter-to`;
2229
+ return {
2230
+ enterFrom,
2231
+ enterActive,
2232
+ enterTo,
2233
+ leaveFrom: (_e = props.leaveFromClass) != null ? _e : `${n}-leave-from`,
2234
+ leaveActive: (_f = props.leaveActiveClass) != null ? _f : `${n}-leave-active`,
2235
+ leaveTo: (_g = props.leaveToClass) != null ? _g : `${n}-leave-to`,
2236
+ appearFrom: (_h = props.appearFromClass) != null ? _h : enterFrom,
2237
+ appearActive: (_i = props.appearActiveClass) != null ? _i : enterActive,
2238
+ appearTo: (_j = props.appearToClass) != null ? _j : enterTo
2239
+ };
2240
+ }
2241
+ var toMs = (s) => {
2242
+ if (!s) return 0;
2243
+ if (s.endsWith("ms")) return Number(s.slice(0, -2).replace(",", "."));
2244
+ return Number(s.slice(0, -1).replace(",", ".")) * 1e3;
2245
+ };
2246
+ function sumMs(delays, durations) {
2247
+ const d = delays.split(", ");
2248
+ const u = durations.split(", ");
2249
+ let max = 0;
2250
+ for (const [i, dur] of u.entries()) {
2251
+ const total = toMs(dur) + toMs(d[i % d.length] || "0s");
2252
+ if (total > max) max = total;
2253
+ }
2254
+ return max;
2255
+ }
2256
+ function getTransitionInfo(el, type) {
2257
+ const s = getComputedStyle(el);
2258
+ const tt = type !== "animation" ? sumMs(s.transitionDelay, s.transitionDuration) : 0;
2259
+ const at = type !== "transition" ? sumMs(s.animationDelay, s.animationDuration) : 0;
2260
+ if (tt === 0 && at === 0) return null;
2261
+ return tt >= at ? { event: "transitionend", timeout: tt } : { event: "animationend", timeout: at };
2262
+ }
2263
+ function addClass(el, cls) {
2264
+ for (const c of cls.split(/\s+/)) if (c) el.classList.add(c);
2265
+ }
2266
+ function removeClass(el, cls) {
2267
+ for (const c of cls.split(/\s+/)) if (c) el.classList.remove(c);
2268
+ }
2269
+ function nextFrame(cb) {
2270
+ requestAnimationFrame(() => requestAnimationFrame(cb));
2271
+ }
2272
+ function forceReflow(el) {
2273
+ void el.offsetHeight;
2274
+ }
2275
+ function whenTransitionEnds(el, type, explicit, resolve2) {
2276
+ if (explicit != null) {
2277
+ setTimeout(resolve2, explicit);
2278
+ return;
2279
+ }
2280
+ const info = getTransitionInfo(el, type);
2281
+ if (!info) {
2282
+ resolve2();
2283
+ return;
2284
+ }
2285
+ let done = false;
2286
+ const finish = () => {
2287
+ if (done) return;
2288
+ done = true;
2289
+ el.removeEventListener(info.event, onEnd);
2290
+ resolve2();
2291
+ };
2292
+ const onEnd = () => finish();
2293
+ el.addEventListener(info.event, onEnd);
2294
+ setTimeout(finish, info.timeout + 1);
2295
+ }
2296
+ function resolveDuration(d, dir) {
2297
+ if (d == null) return null;
2298
+ if (typeof d === "number") return d;
2299
+ return d[dir];
2300
+ }
2301
+ function validateSlot(value) {
2302
+ if (value == null || value === false) return null;
2303
+ if (Array.isArray(value)) {
2304
+ {
2305
+ throw new Error(
2306
+ "[essor] <Transition> expects a single root child. Use <TransitionGroup> for multiple children."
2307
+ );
2308
+ }
2309
+ }
2310
+ if (value instanceof Element) return value;
2311
+ if (isComponent(value)) {
2312
+ const comp = value;
2313
+ if (comp.scope == null) {
2314
+ const fragment = document.createDocumentFragment();
2315
+ comp.mount(fragment);
2316
+ }
2317
+ if (comp.renderedNodes.length > 1) {
2318
+ warn(
2319
+ "[Transition] child component rendered multiple root nodes; only the first is animated. Wrap the children in a single element or use <TransitionGroup>."
2320
+ );
2321
+ }
2322
+ const first = comp.firstChild;
2323
+ if (first instanceof Element) return first;
2324
+ {
2325
+ warn("[Transition] child component did not render an Element root.");
2326
+ }
2327
+ return null;
2328
+ }
2329
+ {
2330
+ warn("[Transition] received a non-element child; animation will be skipped.");
2331
+ }
2332
+ return null;
2333
+ }
2334
+ var ENTER_CB = /* @__PURE__ */ Symbol("enter_cb");
2335
+ var LEAVE_CB = /* @__PURE__ */ Symbol("leave_cb");
2336
+ function Transition(props) {
2337
+ const anchor = document.createComment("");
2338
+ const classes = resolveTransitionClasses(props);
2339
+ const useCss = props.css !== false;
2340
+ const readSlot = useChildren(props);
2341
+ let state = "idle";
2342
+ let currentEl = null;
2343
+ let leavingEl = null;
2344
+ let mounted = false;
2345
+ let pendingRaw = void 0;
2346
+ let hasPending = false;
2347
+ let scheduled = false;
2348
+ let disposed = false;
2349
+ const enter = (el, phase) => {
2350
+ var _a2;
2351
+ const prevLeave = el[LEAVE_CB];
2352
+ if (prevLeave) prevLeave(true);
2353
+ state = "entering";
2354
+ const fromCls = phase === "appear" ? classes.appearFrom : classes.enterFrom;
2355
+ const activeCls = phase === "appear" ? classes.appearActive : classes.enterActive;
2356
+ const toCls = phase === "appear" ? classes.appearTo : classes.enterTo;
2357
+ (_a2 = props.onBeforeEnter) == null ? void 0 : _a2.call(props, el);
2358
+ if (useCss) {
2359
+ addClass(el, fromCls);
2360
+ addClass(el, activeCls);
2361
+ }
2362
+ let called = false;
2363
+ const done = (cancelled) => {
2364
+ var _a3, _b;
2365
+ if (called) return;
2366
+ called = true;
2367
+ el[ENTER_CB] = void 0;
2368
+ if (useCss) {
2369
+ removeClass(el, fromCls);
2370
+ removeClass(el, activeCls);
2371
+ removeClass(el, toCls);
2372
+ }
2373
+ if (cancelled) {
2374
+ (_a3 = props.onEnterCancelled) == null ? void 0 : _a3.call(props, el);
2375
+ } else {
2376
+ state = "entered";
2377
+ (_b = props.onAfterEnter) == null ? void 0 : _b.call(props, el);
2378
+ }
2379
+ };
2380
+ el[ENTER_CB] = done;
2381
+ nextFrame(() => {
2382
+ if (called) return;
2383
+ if (useCss) {
2384
+ removeClass(el, fromCls);
2385
+ addClass(el, toCls);
2386
+ }
2387
+ if (props.onEnter) {
2388
+ props.onEnter(el, () => done(false));
2389
+ } else if (useCss) {
2390
+ const explicit = resolveDuration(props.duration, "enter");
2391
+ whenTransitionEnds(el, props.type, explicit, () => done(false));
2392
+ } else {
2393
+ done(false);
2394
+ }
2395
+ });
2396
+ };
2397
+ const leave = (el, after) => {
2398
+ var _a2;
2399
+ const prevEnter = el[ENTER_CB];
2400
+ if (prevEnter) {
2401
+ prevEnter(true);
2402
+ forceReflow(el);
2403
+ }
2404
+ state = "leaving";
2405
+ (_a2 = props.onBeforeLeave) == null ? void 0 : _a2.call(props, el);
2406
+ if (useCss) {
2407
+ addClass(el, classes.leaveFrom);
2408
+ addClass(el, classes.leaveActive);
2409
+ }
2410
+ let called = false;
2411
+ const done = (cancelled) => {
2412
+ var _a3, _b;
2413
+ if (called) return;
2414
+ called = true;
2415
+ el[LEAVE_CB] = void 0;
2416
+ if (useCss) {
2417
+ removeClass(el, classes.leaveFrom);
2418
+ removeClass(el, classes.leaveActive);
2419
+ removeClass(el, classes.leaveTo);
2420
+ }
2421
+ if (cancelled) {
2422
+ (_a3 = props.onLeaveCancelled) == null ? void 0 : _a3.call(props, el);
2423
+ } else {
2424
+ state = "idle";
2425
+ after();
2426
+ (_b = props.onAfterLeave) == null ? void 0 : _b.call(props, el);
2427
+ }
2428
+ };
2429
+ el[LEAVE_CB] = done;
2430
+ const explicit = resolveDuration(props.duration, "leave");
2431
+ const hasCssInfo = useCss && !props.onLeave && explicit == null ? !!getTransitionInfo(el, props.type) : false;
2432
+ if (!props.onLeave && explicit == null && !hasCssInfo) {
2433
+ done(false);
2434
+ return;
2435
+ }
2436
+ nextFrame(() => {
2437
+ if (called) return;
2438
+ if (useCss) {
2439
+ removeClass(el, classes.leaveFrom);
2440
+ addClass(el, classes.leaveTo);
2441
+ }
2442
+ if (props.onLeave) {
2443
+ props.onLeave(el, () => done(false));
2444
+ } else if (useCss) {
2445
+ whenTransitionEnds(el, props.type, explicit, () => done(false));
2446
+ } else {
2447
+ done(false);
2448
+ }
2449
+ });
2450
+ };
2451
+ const commit = (next2, isFirst) => {
2452
+ if (next2 && state === "leaving" && leavingEl) {
2453
+ const reviving = leavingEl;
2454
+ const leaveCb = reviving[LEAVE_CB];
2455
+ if (leaveCb) leaveCb(true);
2456
+ leavingEl = null;
2457
+ currentEl = reviving;
2458
+ enter(reviving, "enter");
2459
+ return;
2460
+ }
2461
+ if (next2 === currentEl) return;
2462
+ const outgoing = currentEl;
2463
+ currentEl = next2;
2464
+ if (outgoing) {
2465
+ leavingEl = outgoing;
2466
+ const captured = outgoing;
2467
+ leave(captured, () => {
2468
+ if (captured.parentNode) captured.parentNode.removeChild(captured);
2469
+ if (leavingEl === captured) leavingEl = null;
2470
+ });
2471
+ }
2472
+ if (next2 && anchor.parentNode) {
2473
+ anchor.parentNode.insertBefore(next2, anchor);
2474
+ if (isFirst && !props.appear) {
2475
+ state = "entered";
2476
+ } else {
2477
+ enter(next2, isFirst && props.appear ? "appear" : "enter");
2478
+ }
2479
+ } else if (!outgoing && !next2) {
2480
+ state = "idle";
2481
+ }
2482
+ };
2483
+ const flush = () => {
2484
+ scheduled = false;
2485
+ if (disposed || !hasPending) return;
2486
+ const raw = pendingRaw;
2487
+ hasPending = false;
2488
+ pendingRaw = void 0;
2489
+ try {
2490
+ commit(validateSlot(raw), false);
2491
+ } catch (error4) {
2492
+ console.error("[essor] <Transition>", error4);
2493
+ }
2494
+ };
2495
+ const scheduleCommit = (raw) => {
2496
+ pendingRaw = raw;
2497
+ hasPending = true;
2498
+ if (scheduled) return;
2499
+ scheduled = true;
2500
+ queueMicrotask(flush);
2501
+ };
2502
+ const effectRunner = effect(() => {
2503
+ const raw = readSlot();
2504
+ if (mounted) {
2505
+ scheduleCommit(raw);
2506
+ } else {
2507
+ pendingRaw = raw;
2508
+ hasPending = true;
2509
+ }
2510
+ });
2511
+ onMount(() => {
2512
+ mounted = true;
2513
+ const initial = hasPending ? validateSlot(pendingRaw) : null;
2514
+ hasPending = false;
2515
+ pendingRaw = void 0;
2516
+ commit(initial, true);
2517
+ });
2518
+ onCleanup(() => {
2519
+ disposed = true;
2520
+ effectRunner.stop();
2521
+ for (const el of [currentEl, leavingEl]) {
2522
+ if (!el) continue;
2523
+ const ec = el[ENTER_CB];
2524
+ const lc = el[LEAVE_CB];
2525
+ ec == null ? void 0 : ec(true);
2526
+ lc == null ? void 0 : lc(true);
2527
+ if (el.parentNode) el.parentNode.removeChild(el);
2528
+ }
2529
+ currentEl = null;
2530
+ leavingEl = null;
2531
+ state = "idle";
2532
+ });
2533
+ return anchor;
2534
+ }
2535
+ Transition[TRANSITION_COMPONENT] = true;
2536
+ function isTransition(node) {
2537
+ return !!node && !!node[TRANSITION_COMPONENT];
2538
+ }
2539
+ function resolveItemElement(raw, parent) {
2540
+ if (raw == null || raw === false) return { el: null, comp: null };
2541
+ if (Array.isArray(raw) && raw.length === 1) {
2542
+ return resolveItemElement(raw[0], parent);
2543
+ }
2544
+ if (isFunction(raw)) {
2545
+ return resolveItemElement(raw(), parent);
2546
+ }
2547
+ if (raw instanceof HTMLElement) {
2548
+ return { el: raw, comp: null };
2549
+ }
2550
+ if (isComponent(raw)) {
2551
+ const comp = raw;
2552
+ if (comp.scope == null) {
2553
+ comp.mount(parent);
2554
+ }
2555
+ if (comp.renderedNodes.length > 1) {
2556
+ warn(
2557
+ "[TransitionGroup] child component rendered multiple root nodes; only the first participates in enter/leave/move animations."
2558
+ );
2559
+ }
2560
+ const first = comp.firstChild;
2561
+ if (first instanceof HTMLElement) return { el: first, comp };
2562
+ return { el: null, comp };
2563
+ }
2564
+ {
2565
+ warn(
2566
+ "[TransitionGroup] child render returned a non-element value; animations require Element or Component roots."
2567
+ );
2568
+ }
2569
+ return { el: null, comp: null };
2570
+ }
2571
+ function saveStyles(el) {
2572
+ return {
2573
+ position: el.style.position,
2574
+ top: el.style.top,
2575
+ left: el.style.left,
2576
+ width: el.style.width,
2577
+ height: el.style.height
2578
+ };
2579
+ }
2580
+ function restoreStyles(el, s) {
2581
+ el.style.position = s.position;
2582
+ el.style.top = s.top;
2583
+ el.style.left = s.left;
2584
+ el.style.width = s.width;
2585
+ el.style.height = s.height;
2586
+ }
2587
+ function TransitionGroup(props) {
2588
+ var _a2, _b, _c;
2589
+ const tag = (_a2 = props.tag) != null ? _a2 : "div";
2590
+ const wrapper = document.createElement(tag);
2591
+ const classes = resolveTransitionClasses(props);
2592
+ const useCss = props.css !== false;
2593
+ const moveClass = (_c = props.moveClass) != null ? _c : `${(_b = props.name) != null ? _b : "v"}-move`;
2594
+ const keyFn = props.key;
2595
+ const rawChildren = props.children;
2596
+ const childrenFn = Array.isArray(rawChildren) && rawChildren.length === 1 && isFunction(rawChildren[0]) ? rawChildren[0] : props.children;
2597
+ if (!isFunction(childrenFn) || !isFunction(keyFn)) {
2598
+ throw new TypeError(
2599
+ "<TransitionGroup> requires `children: (item, index) => Node` and `key: (item, index) => unknown`"
2600
+ );
2601
+ }
2602
+ const getList = () => {
2603
+ var _a3, _b2;
2604
+ const input = props.each;
2605
+ if (isSignal(input)) return (_a3 = input.value) != null ? _a3 : [];
2606
+ if (isFunction(input)) return (_b2 = input()) != null ? _b2 : [];
2607
+ return input != null ? input : [];
2608
+ };
2609
+ let entries = [];
2610
+ let mounted = false;
2611
+ const renderEntry = (item, index) => {
2612
+ const parentScope = getActiveScope();
2613
+ const scope = createScope(parentScope);
2614
+ let raw;
2615
+ runWithScope(scope, () => {
2616
+ raw = childrenFn(item, index);
2617
+ });
2618
+ const { el, comp } = resolveItemElement(raw, wrapper);
2619
+ if (!el) {
2620
+ disposeScope(scope);
2621
+ return null;
2622
+ }
2623
+ return {
2624
+ key: keyFn(item, index),
2625
+ item,
2626
+ el,
2627
+ comp,
2628
+ scope,
2629
+ state: "entering"
2630
+ };
2631
+ };
2632
+ const detachEntryDom = (entry) => {
2633
+ if (entry.comp) {
2634
+ for (const node of entry.comp.renderedNodes) {
2635
+ if (node.parentNode === wrapper) wrapper.removeChild(node);
2636
+ }
2637
+ return;
2638
+ }
2639
+ if (entry.el.parentNode === wrapper) wrapper.removeChild(entry.el);
2640
+ };
2641
+ const disposeEntry = (entry) => {
2642
+ var _a3, _b2;
2643
+ (_a3 = entry.cancelEnter) == null ? void 0 : _a3.call(entry, true);
2644
+ (_b2 = entry.cancelLeave) == null ? void 0 : _b2.call(entry, true);
2645
+ if (entry.comp) entry.comp.destroy();
2646
+ detachEntryDom(entry);
2647
+ disposeScope(entry.scope);
2648
+ };
2649
+ const runEnter = (entry) => {
2650
+ var _a3, _b2, _c2;
2651
+ const el = entry.el;
2652
+ (_a3 = entry.cancelLeave) == null ? void 0 : _a3.call(entry, true);
2653
+ if (!useCss) {
2654
+ entry.state = "present";
2655
+ (_b2 = props.onAfterEnter) == null ? void 0 : _b2.call(props, el);
2656
+ return;
2657
+ }
2658
+ (_c2 = props.onBeforeEnter) == null ? void 0 : _c2.call(props, el);
2659
+ addClass(el, classes.enterFrom);
2660
+ addClass(el, classes.enterActive);
2661
+ let called = false;
2662
+ const done = (cancelled) => {
2663
+ var _a4, _b3;
2664
+ if (called) return;
2665
+ called = true;
2666
+ entry.cancelEnter = void 0;
2667
+ removeClass(el, classes.enterFrom);
2668
+ removeClass(el, classes.enterActive);
2669
+ removeClass(el, classes.enterTo);
2670
+ if (cancelled) {
2671
+ (_a4 = props.onEnterCancelled) == null ? void 0 : _a4.call(props, el);
2672
+ } else {
2673
+ entry.state = "present";
2674
+ (_b3 = props.onAfterEnter) == null ? void 0 : _b3.call(props, el);
2675
+ }
2676
+ };
2677
+ entry.cancelEnter = done;
2678
+ entry.state = "entering";
2679
+ nextFrame(() => {
2680
+ if (called) return;
2681
+ removeClass(el, classes.enterFrom);
2682
+ addClass(el, classes.enterTo);
2683
+ if (props.onEnter) {
2684
+ props.onEnter(el, () => done(false));
2685
+ } else {
2686
+ const explicit = resolveDuration(props.duration, "enter");
2687
+ whenTransitionEnds(el, props.type, explicit, () => done(false));
2688
+ }
2689
+ });
2690
+ };
2691
+ const runLeave = (entry, prevRect) => {
2692
+ var _a3, _b2;
2693
+ const el = entry.el;
2694
+ if (entry.cancelEnter) {
2695
+ entry.cancelEnter(true);
2696
+ forceReflow(el);
2697
+ }
2698
+ entry.state = "leaving";
2699
+ entry.savedStyles = saveStyles(el);
2700
+ const parentRect = wrapper.getBoundingClientRect();
2701
+ el.style.position = "absolute";
2702
+ el.style.top = `${prevRect.top - parentRect.top}px`;
2703
+ el.style.left = `${prevRect.left - parentRect.left}px`;
2704
+ el.style.width = `${prevRect.width}px`;
2705
+ el.style.height = `${prevRect.height}px`;
2706
+ if (!useCss) {
2707
+ if (entry.savedStyles) restoreStyles(el, entry.savedStyles);
2708
+ detachEntryDom(entry);
2709
+ disposeScope(entry.scope);
2710
+ if (entry.comp) entry.comp.destroy();
2711
+ (_a3 = props.onAfterLeave) == null ? void 0 : _a3.call(props, el);
2712
+ return;
2713
+ }
2714
+ (_b2 = props.onBeforeLeave) == null ? void 0 : _b2.call(props, el);
2715
+ addClass(el, classes.leaveFrom);
2716
+ addClass(el, classes.leaveActive);
2717
+ let called = false;
2718
+ const done = (cancelled) => {
2719
+ var _a4, _b3;
2720
+ if (called) return;
2721
+ called = true;
2722
+ entry.cancelLeave = void 0;
2723
+ removeClass(el, classes.leaveFrom);
2724
+ removeClass(el, classes.leaveActive);
2725
+ removeClass(el, classes.leaveTo);
2726
+ if (cancelled) {
2727
+ if (entry.savedStyles) restoreStyles(el, entry.savedStyles);
2728
+ entry.savedStyles = void 0;
2729
+ (_a4 = props.onLeaveCancelled) == null ? void 0 : _a4.call(props, el);
2730
+ return;
2731
+ }
2732
+ if (entry.savedStyles) restoreStyles(el, entry.savedStyles);
2733
+ entry.savedStyles = void 0;
2734
+ detachEntryDom(entry);
2735
+ disposeScope(entry.scope);
2736
+ if (entry.comp) entry.comp.destroy();
2737
+ (_b3 = props.onAfterLeave) == null ? void 0 : _b3.call(props, el);
2738
+ };
2739
+ entry.cancelLeave = done;
2740
+ nextFrame(() => {
2741
+ if (called) return;
2742
+ removeClass(el, classes.leaveFrom);
2743
+ addClass(el, classes.leaveTo);
2744
+ if (props.onLeave) {
2745
+ props.onLeave(el, () => done(false));
2746
+ } else {
2747
+ const explicit = resolveDuration(props.duration, "leave");
2748
+ whenTransitionEnds(el, props.type, explicit, () => done(false));
2749
+ }
2750
+ });
2751
+ };
2752
+ const runMove = (entry, prevRect) => {
2753
+ if (!useCss || entry.state !== "present") return;
2754
+ const el = entry.el;
2755
+ const newRect = el.getBoundingClientRect();
2756
+ const dx = prevRect.left - newRect.left;
2757
+ const dy = prevRect.top - newRect.top;
2758
+ if (!dx && !dy) return;
2759
+ const savedTransform = el.style.transform;
2760
+ const savedTransition = el.style.transitionDuration;
2761
+ el.style.transform = `translate(${dx}px, ${dy}px)`;
2762
+ el.style.transitionDuration = "0s";
2763
+ addClass(el, moveClass);
2764
+ forceReflow(el);
2765
+ el.style.transform = savedTransform;
2766
+ el.style.transitionDuration = savedTransition;
2767
+ const explicit = resolveDuration(props.duration, "enter");
2768
+ whenTransitionEnds(el, props.type, explicit, () => {
2769
+ removeClass(el, moveClass);
2770
+ });
2771
+ };
2772
+ const snapshotPositions = () => {
2773
+ for (const entry of entries) {
2774
+ if (entry.state === "leaving") continue;
2775
+ entry.prevRect = entry.el.getBoundingClientRect();
2776
+ }
2777
+ };
2778
+ const reconcile = (newItems) => {
2779
+ const byKey = /* @__PURE__ */ new Map();
2780
+ for (const entry of entries) byKey.set(entry.key, entry);
2781
+ const next2 = [];
2782
+ for (const [i, item] of newItems.entries()) {
2783
+ const key = keyFn(item, i);
2784
+ const reused = byKey.get(key);
2785
+ if (reused) {
2786
+ byKey.delete(key);
2787
+ reused.item = item;
2788
+ next2.push(reused);
2789
+ } else {
2790
+ const fresh = renderEntry(item, i);
2791
+ if (fresh) next2.push(fresh);
2792
+ }
2793
+ }
2794
+ const leaving = [];
2795
+ for (const entry of byKey.values()) {
2796
+ if (entry.state !== "leaving") leaving.push(entry);
2797
+ }
2798
+ let anchor = null;
2799
+ for (let i = next2.length - 1; i >= 0; i--) {
2800
+ const el = next2[i].el;
2801
+ if (el.parentNode !== wrapper || el.nextSibling !== anchor) {
2802
+ wrapper.insertBefore(el, anchor);
2803
+ }
2804
+ anchor = el;
2805
+ }
2806
+ return { next: next2, leaving };
2807
+ };
2808
+ const update = (newItems, isInitial) => {
2809
+ if (isInitial) {
2810
+ const initial = [];
2811
+ for (const [i, item] of newItems.entries()) {
2812
+ const entry = renderEntry(item, i);
2813
+ if (!entry) continue;
2814
+ if (entry.el.parentNode !== wrapper) wrapper.appendChild(entry.el);
2815
+ entry.state = "present";
2816
+ initial.push(entry);
2817
+ }
2818
+ entries = initial;
2819
+ return;
2820
+ }
2821
+ snapshotPositions();
2822
+ const { next: next2, leaving } = reconcile(newItems);
2823
+ for (const entry of next2) {
2824
+ if (entry.state !== "present") runEnter(entry);
2825
+ }
2826
+ for (const entry of leaving) {
2827
+ const rect = entry.prevRect;
2828
+ if (!rect) {
2829
+ {
2830
+ warn("[TransitionGroup] leaving entry without prevRect \u2014 skipping leave animation");
2831
+ }
2832
+ continue;
2833
+ }
2834
+ runLeave(entry, rect);
2835
+ }
2836
+ for (const entry of next2) {
2837
+ if (entry.state !== "present" || !entry.prevRect) continue;
2838
+ runMove(entry, entry.prevRect);
2839
+ entry.prevRect = void 0;
2840
+ }
2841
+ entries = next2.concat(leaving);
2842
+ };
2843
+ let pendingItems = null;
2844
+ const effectRunner = effect(() => {
2845
+ const list = getList();
2846
+ if (!mounted) {
2847
+ pendingItems = list;
2848
+ return;
2849
+ }
2850
+ update(list, false);
2851
+ });
2852
+ onMount(() => {
2853
+ mounted = true;
2854
+ if (pendingItems) {
2855
+ update(pendingItems, true);
2856
+ pendingItems = null;
2857
+ }
2858
+ });
2859
+ onCleanup(() => {
2860
+ effectRunner.stop();
2861
+ for (const entry of entries) disposeEntry(entry);
2862
+ entries = [];
2863
+ if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
2864
+ });
2865
+ return wrapper;
2866
+ }
2867
+ TransitionGroup[TRANSITION_GROUP_COMPONENT] = true;
2868
+ function isTransitionGroup(node) {
2869
+ return !!node && !!node[TRANSITION_GROUP_COMPONENT];
2870
+ }
1998
2871
 
1999
- export { Component, For, Fragment, Portal, Suspense, addEvent, addEventListener, beginHydration, bindElement, child, clearDelegatedEvents, consumeTeleportAnchor, consumeTeleportBlock, createApp, createComponent, createResource, defineAsyncComponent, delegateEvents, endHydration, getHydrationKey, getRenderedElement, hydrate, inject, insert, isComponent, isFragment, isHydrating, isPortal, isSuspense, next, normalizeClass, nthChild, omitProps, onDestroy, onMount, onUpdate, patchAttr, patchAttrHydrate, patchClass, patchClassHydrate, patchStyle, patchStyleHydrate, provide, resetHydrationKey, setStyle, template };
2000
- //# sourceMappingURL=template.dev.esm.js.map
2001
- //# sourceMappingURL=template.dev.esm.js.map
2872
+ export { Component, For, Fragment, Portal, Suspense, Transition, TransitionGroup, addEvent, addEventListener, beginHydration, bindElement, child, clearDelegatedEvents, consumeTeleportAnchor, consumeTeleportBlock, createApp, createComponent, createResource, defineAsyncComponent, definePlugin, delegateEvents, endHydration, getHydrationKey, getRenderedElement, hydrate, hydrationAnchor, hydrationMarker, inject, insert, isComponent, isFragment, isHydrating, isPortal, isSuspense, isTransition, isTransitionGroup, next, normalizeClass, nthChild, omitProps, onDestroy, onMount, onUpdate, patchAttr, patchAttrHydrate, patchClass, patchClassHydrate, patchStyle, patchStyleHydrate, provide, resetHydrationKey, setStyle, template };
2873
+ //# sourceMappingURL=template.dev.js.map
2874
+ //# sourceMappingURL=template.dev.js.map