@ktjs/core 0.26.8 → 0.27.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.
- package/dist/index.d.ts +10 -9
- package/dist/index.iife.js +203 -103
- package/dist/index.legacy.js +203 -105
- package/dist/index.mjs +203 -104
- package/dist/jsx/index.d.ts +4 -4
- package/dist/jsx/index.mjs +183 -52
- package/dist/jsx/jsx-runtime.d.ts +4 -4
- package/dist/jsx/jsx-runtime.mjs +183 -52
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -117,6 +117,9 @@ declare const surfaceRef: <T extends Object>(obj: T) => KTSurfaceRef<T>;
|
|
|
117
117
|
* Assert k-model to be a ref object
|
|
118
118
|
*/
|
|
119
119
|
declare const $modelOrRef: <T = any>(props: any, defaultValue?: T) => KTRef<T>;
|
|
120
|
+
declare const $setRef: (props: {
|
|
121
|
+
ref?: KTRef<any>;
|
|
122
|
+
}, node: Node) => void;
|
|
120
123
|
|
|
121
124
|
type HTML<T extends (HTMLTag | SVGTag | MathMLTag) & otherstring> = T extends SVGTag
|
|
122
125
|
? SVGElementTagNameMap[T]
|
|
@@ -240,7 +243,7 @@ type KTComponent = (
|
|
|
240
243
|
* ## About
|
|
241
244
|
* @package @ktjs/core
|
|
242
245
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
243
|
-
* @version 0.
|
|
246
|
+
* @version 0.27.1 (Last Update: 2026.02.10 01:30:30.991)
|
|
244
247
|
* @license MIT
|
|
245
248
|
* @link https://github.com/baendlorel/kt.js
|
|
246
249
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -257,11 +260,11 @@ type JSXTag = HTMLTag | ((props?: any) => HTMLElement) | ((props?: any) => Promi
|
|
|
257
260
|
declare function jsx(tag: JSXTag, props: KTAttribute): JSX.Element;
|
|
258
261
|
/**
|
|
259
262
|
* Fragment support - returns an array of children
|
|
260
|
-
*
|
|
263
|
+
* Enhanced Fragment component that manages arrays of elements
|
|
261
264
|
*/
|
|
262
|
-
declare function Fragment(
|
|
265
|
+
declare function Fragment(props: {
|
|
263
266
|
children?: KTRawContent;
|
|
264
|
-
}):
|
|
267
|
+
}): JSX.Element;
|
|
265
268
|
/**
|
|
266
269
|
* JSX Development runtime - same as jsx but with additional dev checks
|
|
267
270
|
*/
|
|
@@ -1388,12 +1391,10 @@ declare function KTAsync<T extends KTComponent>(props: {
|
|
|
1388
1391
|
children?: KTRawContent;
|
|
1389
1392
|
} & ExtractComponentProps<T>): JSX.Element;
|
|
1390
1393
|
|
|
1391
|
-
type KTForElement = JSX.Element
|
|
1392
|
-
redraw: (newProps?: KTAttribute) => void;
|
|
1393
|
-
};
|
|
1394
|
+
type KTForElement = JSX.Element;
|
|
1394
1395
|
interface KTForProps<T> {
|
|
1395
1396
|
ref?: KTRef<KTForElement>;
|
|
1396
|
-
list: T[]
|
|
1397
|
+
list: T[] | KTReactive<T[]>;
|
|
1397
1398
|
key?: (item: T, index: number, array: T[]) => any;
|
|
1398
1399
|
map: (item: T, index: number, array: T[]) => HTMLElement;
|
|
1399
1400
|
}
|
|
@@ -1403,5 +1404,5 @@ interface KTForProps<T> {
|
|
|
1403
1404
|
*/
|
|
1404
1405
|
declare function KTFor<T>(props: KTForProps<T>): KTForElement;
|
|
1405
1406
|
|
|
1406
|
-
export { $modelOrRef, Fragment, KTAsync, KTComputed, KTFor, KTReactiveType, KTRef, computed, h as createElement, createRedrawable, deref, effect, h, isComputed, isKT, isRef, jsx, jsxDEV, jsxs, ref, surfaceRef, toReactive, toRef };
|
|
1407
|
+
export { $modelOrRef, $setRef, Fragment, KTAsync, KTComputed, KTFor, KTReactiveType, KTRef, computed, h as createElement, createRedrawable, deref, effect, h, isComputed, isKT, isRef, jsx, jsxDEV, jsxs, ref, surfaceRef, toReactive, toRef };
|
|
1407
1408
|
export type { EventHandler, KTAttribute, KTForElement, KTForProps, KTPrefixedEventAttribute, KTRawAttr, KTRawContent, KTRawContents, KTReactify, KTReactifyObject, KTReactifyProps, KTReactive, KTSurfaceRef, ReactiveChangeHandler };
|
package/dist/index.iife.js
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
var __ktjs_core__ = (function (exports) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
// Cached native methods for performance optimization
|
|
5
|
+
const $isArray = Array.isArray;
|
|
6
|
+
const $is = Object.is;
|
|
7
|
+
const $entries = Object.entries;
|
|
8
|
+
const $random = Math.random;
|
|
9
|
+
const $isThenable = (o) => typeof o?.then === 'function';
|
|
10
|
+
|
|
11
|
+
if (typeof Symbol === 'undefined') {
|
|
12
|
+
window.Symbol = function Symbol(description) {
|
|
13
|
+
return `@@SYMBOL_${description || ''}_${$random().toString(36).slice(2)}`;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// String manipulation utilities
|
|
18
|
+
/**
|
|
19
|
+
* Default empty function
|
|
20
|
+
*/
|
|
21
|
+
const $emptyFn = (() => true);
|
|
22
|
+
const $emptyArray = [];
|
|
23
|
+
/**
|
|
24
|
+
* Safe and quick forEach implementation that works with array-like objects and handles sparse arrays.
|
|
25
|
+
*/
|
|
26
|
+
const $forEach = (array, callback) => {
|
|
27
|
+
const len = array.length;
|
|
28
|
+
for (let i = 0; i < len; i++) {
|
|
29
|
+
callback(array[i], i, array);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const $emptyChildrenRef = { value: $emptyArray };
|
|
34
|
+
// each instance shares the same empty array, but it will be replaced when used
|
|
35
|
+
Comment.prototype.kisFragmentAnchor = false;
|
|
36
|
+
Comment.prototype.kFragmentList = $emptyArray;
|
|
37
|
+
Comment.prototype.kredraw = $emptyFn;
|
|
38
|
+
Comment.prototype.kchildrenRef = $emptyChildrenRef;
|
|
39
|
+
|
|
4
40
|
// Shared constants
|
|
5
41
|
// Empty for now - can be extended with framework-wide constants
|
|
6
42
|
/**
|
|
@@ -12,13 +48,6 @@ var __ktjs_core__ = (function (exports) {
|
|
|
12
48
|
*/
|
|
13
49
|
const MATHML_ATTR_FLAG = '__kt_mathml__';
|
|
14
50
|
|
|
15
|
-
// Cached native methods for performance optimization
|
|
16
|
-
const $isArray = Array.isArray;
|
|
17
|
-
const $is = Object.is;
|
|
18
|
-
const $entries = Object.entries;
|
|
19
|
-
const $random = Math.random;
|
|
20
|
-
const $isThenable = (o) => typeof o?.then === 'function';
|
|
21
|
-
|
|
22
51
|
// DOM manipulation utilities
|
|
23
52
|
// # dom natives
|
|
24
53
|
const $isNode = (x) => x?.nodeType > 0;
|
|
@@ -72,26 +101,14 @@ var __ktjs_core__ = (function (exports) {
|
|
|
72
101
|
/**
|
|
73
102
|
* Used for `k-model`
|
|
74
103
|
*/
|
|
75
|
-
const applyModel = (element, valueRef, propName, eventName) => {
|
|
104
|
+
const $applyModel = (element, valueRef, propName, eventName) => {
|
|
76
105
|
element[propName] = valueRef.value; // initialize
|
|
77
106
|
valueRef.addOnChange((newValue) => (element[propName] = newValue));
|
|
78
107
|
element.addEventListener(eventName, () => (valueRef.value = element[propName]));
|
|
79
108
|
};
|
|
80
109
|
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
* Default empty function
|
|
84
|
-
*/
|
|
85
|
-
const $emptyFn = (() => true);
|
|
86
|
-
|
|
87
|
-
if (typeof Symbol === 'undefined') {
|
|
88
|
-
window.Symbol = function Symbol(description) {
|
|
89
|
-
return `@@SYMBOL_${description || ''}_${$random().toString(36).slice(2)}`;
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Shared utilities and cached native methods for kt.js framework
|
|
94
|
-
Object.defineProperty(window, '__ktjs__', { value: '0.23.3' });
|
|
110
|
+
// incase that symbol is not supported
|
|
111
|
+
Object.defineProperty(window, '__ktjs__', { value: '0.23.10' });
|
|
95
112
|
|
|
96
113
|
const isKT = (obj) => obj?.isKT;
|
|
97
114
|
const isRef = (obj) => obj?.ktType === 1 /* KTReactiveType.REF */;
|
|
@@ -247,6 +264,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
247
264
|
else {
|
|
248
265
|
$append.call(element, c);
|
|
249
266
|
// Handle KTFor anchor
|
|
267
|
+
// todo Maybe not needed anymore
|
|
250
268
|
const list = c.__kt_for_list__;
|
|
251
269
|
if ($isArray(list)) {
|
|
252
270
|
apd(element, list);
|
|
@@ -405,13 +423,26 @@ var __ktjs_core__ = (function (exports) {
|
|
|
405
423
|
// & props is an object. Won't use it in any other place
|
|
406
424
|
if ('k-model' in props) {
|
|
407
425
|
const kmodel = props['k-model'];
|
|
408
|
-
if (
|
|
426
|
+
if (isRef(kmodel)) {
|
|
427
|
+
return kmodel;
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
409
430
|
throw new Error(`[kt.js error] k-model data must be a KTRef object, please use 'ref(...)' to wrap it.`);
|
|
410
431
|
}
|
|
411
|
-
return kmodel;
|
|
412
432
|
}
|
|
413
433
|
return ref(defaultValue);
|
|
414
434
|
};
|
|
435
|
+
const $setRef = (props, node) => {
|
|
436
|
+
if ('ref' in props) {
|
|
437
|
+
const r = props.ref;
|
|
438
|
+
if (isRef(r)) {
|
|
439
|
+
r.value = node;
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
throw new Error('[kt.js error] Fragment: ref must be a KTRef');
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
};
|
|
415
446
|
|
|
416
447
|
class KTComputed {
|
|
417
448
|
/**
|
|
@@ -564,17 +595,17 @@ var __ktjs_core__ = (function (exports) {
|
|
|
564
595
|
}
|
|
565
596
|
if (element instanceof HTMLInputElement) {
|
|
566
597
|
if (element.type === 'radio' || element.type === 'checkbox') {
|
|
567
|
-
applyModel(element, valueRef, 'checked', 'change');
|
|
598
|
+
$applyModel(element, valueRef, 'checked', 'change');
|
|
568
599
|
}
|
|
569
600
|
else {
|
|
570
|
-
applyModel(element, valueRef, 'value', 'input');
|
|
601
|
+
$applyModel(element, valueRef, 'value', 'input');
|
|
571
602
|
}
|
|
572
603
|
}
|
|
573
604
|
else if (element instanceof HTMLSelectElement) {
|
|
574
|
-
applyModel(element, valueRef, 'value', 'change');
|
|
605
|
+
$applyModel(element, valueRef, 'value', 'change');
|
|
575
606
|
}
|
|
576
607
|
else if (element instanceof HTMLTextAreaElement) {
|
|
577
|
-
applyModel(element, valueRef, 'value', 'input');
|
|
608
|
+
$applyModel(element, valueRef, 'value', 'input');
|
|
578
609
|
}
|
|
579
610
|
else {
|
|
580
611
|
console.warn('[kt.js warn]','not supported element for k-model:');
|
|
@@ -595,7 +626,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
595
626
|
* ## About
|
|
596
627
|
* @package @ktjs/core
|
|
597
628
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
598
|
-
* @version 0.
|
|
629
|
+
* @version 0.27.1 (Last Update: 2026.02.10 01:30:30.991)
|
|
599
630
|
* @license MIT
|
|
600
631
|
* @link https://github.com/baendlorel/kt.js
|
|
601
632
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -630,7 +661,110 @@ var __ktjs_core__ = (function (exports) {
|
|
|
630
661
|
return element;
|
|
631
662
|
};
|
|
632
663
|
|
|
633
|
-
const
|
|
664
|
+
const kredraw = function () {
|
|
665
|
+
const newElements = this.kchildrenRef.value;
|
|
666
|
+
const parent = this.parentNode;
|
|
667
|
+
if (!parent) {
|
|
668
|
+
// If anchor is not in DOM, only update internal state
|
|
669
|
+
this.kFragmentList.length = 0;
|
|
670
|
+
for (let i = 0; i < newElements.length; i++) {
|
|
671
|
+
this.kFragmentList.push(newElements[i]);
|
|
672
|
+
}
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
// Simple replacement algorithm: remove all old elements, insert all new elements
|
|
676
|
+
// todo Future enhancement: key-based optimization
|
|
677
|
+
// 1. Remove all old elements
|
|
678
|
+
for (let i = 0; i < this.kFragmentList.length; i++) {
|
|
679
|
+
this.kFragmentList[i].remove();
|
|
680
|
+
}
|
|
681
|
+
// 2. Insert all new elements
|
|
682
|
+
const fragment = document.createDocumentFragment();
|
|
683
|
+
this.kFragmentList.length = 0;
|
|
684
|
+
for (let i = 0; i < newElements.length; i++) {
|
|
685
|
+
const element = newElements[i];
|
|
686
|
+
this.kFragmentList.push(element);
|
|
687
|
+
fragment.appendChild(element);
|
|
688
|
+
}
|
|
689
|
+
// Insert after anchor
|
|
690
|
+
parent.insertBefore(fragment, this.nextSibling);
|
|
691
|
+
};
|
|
692
|
+
/**
|
|
693
|
+
* Fragment - Container component for managing arrays of child elements
|
|
694
|
+
*
|
|
695
|
+
* Features:
|
|
696
|
+
* 1. Returns a comment anchor node, child elements are inserted after the anchor
|
|
697
|
+
* 2. Supports reactive arrays, automatically updates DOM when array changes
|
|
698
|
+
* 3. Basic version uses simple replacement algorithm (remove all old elements, insert all new elements)
|
|
699
|
+
* 4. Future enhancement: key-based optimization
|
|
700
|
+
*
|
|
701
|
+
* Usage example:
|
|
702
|
+
* ```tsx
|
|
703
|
+
* const children = ref([<div>A</div>, <div>B</div>]);
|
|
704
|
+
* const fragment = <Fragment children={children} />;
|
|
705
|
+
* document.body.appendChild(fragment);
|
|
706
|
+
*
|
|
707
|
+
* // Automatic update
|
|
708
|
+
* children.value = [<div>C</div>, <div>D</div>];
|
|
709
|
+
* ```
|
|
710
|
+
*/
|
|
711
|
+
function Fragment$1(props) {
|
|
712
|
+
// key parameter reserved for future enhancement, currently unused
|
|
713
|
+
const { key: _key } = props;
|
|
714
|
+
const childrenRef = toReactive(props.children, () => anchor.kredraw());
|
|
715
|
+
const anchor = document.createComment('kt-fragment');
|
|
716
|
+
anchor.kredraw = kredraw;
|
|
717
|
+
anchor.kchildrenRef = childrenRef;
|
|
718
|
+
anchor.kFragmentList = [];
|
|
719
|
+
anchor.kisFragmentAnchor = true;
|
|
720
|
+
// Observe DOM insertion
|
|
721
|
+
const observer = new MutationObserver(() => {
|
|
722
|
+
if (anchor.isConnected) {
|
|
723
|
+
anchor.kredraw();
|
|
724
|
+
observer.disconnect();
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
728
|
+
// Set ref reference
|
|
729
|
+
$setRef(props, anchor);
|
|
730
|
+
return anchor;
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Convert KTRawContent to HTMLElement array
|
|
734
|
+
*/
|
|
735
|
+
function convertChildrenToElements(children) {
|
|
736
|
+
const elements = [];
|
|
737
|
+
const processChild = (child) => {
|
|
738
|
+
if (child == null || child === false || child === true) {
|
|
739
|
+
// Ignore null, undefined, false, true
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
if ($isArray(child)) {
|
|
743
|
+
// Recursively process array
|
|
744
|
+
$forEach(child, processChild);
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
if (typeof child === 'string' || typeof child === 'number') {
|
|
748
|
+
// & Wrap text in span element? No! use text node instead
|
|
749
|
+
const textNode = document.createTextNode(String(child));
|
|
750
|
+
elements.push(textNode);
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
if (child instanceof HTMLElement) {
|
|
754
|
+
elements.push(child);
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
if (isKT(child)) {
|
|
758
|
+
processChild(child.value);
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
// Other types ignored or converted to string
|
|
762
|
+
console.warn('[kt.js warn]','Fragment: unsupported child type', child);
|
|
763
|
+
};
|
|
764
|
+
processChild(children);
|
|
765
|
+
return elements;
|
|
766
|
+
}
|
|
767
|
+
|
|
634
768
|
const create = (tag, props) => {
|
|
635
769
|
if (typeof tag === 'function') {
|
|
636
770
|
return tag(props);
|
|
@@ -648,7 +782,6 @@ var __ktjs_core__ = (function (exports) {
|
|
|
648
782
|
if (isComputed(props.ref)) {
|
|
649
783
|
throw new Error('[kt.js error] Cannot assign a computed value to an element.');
|
|
650
784
|
}
|
|
651
|
-
const maybeDummyRef = isRef(props.ref) ? props.ref : dummyRef;
|
|
652
785
|
let el;
|
|
653
786
|
if ('k-if' in props) {
|
|
654
787
|
const kif = props['k-if'];
|
|
@@ -660,49 +793,31 @@ var __ktjs_core__ = (function (exports) {
|
|
|
660
793
|
return;
|
|
661
794
|
}
|
|
662
795
|
const oldEl = el;
|
|
663
|
-
el = newValue ? create(tag, props) : placeholder();
|
|
796
|
+
$setRef(props, (el = newValue ? create(tag, props) : placeholder()));
|
|
664
797
|
$replaceNode(oldEl, el);
|
|
665
|
-
maybeDummyRef.value = el;
|
|
666
798
|
});
|
|
667
799
|
condition = kif.value;
|
|
668
800
|
}
|
|
669
801
|
if (!condition) {
|
|
670
802
|
// & make comment placeholder in case that ref might be redrawn later
|
|
671
|
-
el = placeholder();
|
|
672
|
-
maybeDummyRef.value = el;
|
|
803
|
+
$setRef(props, (el = placeholder()));
|
|
673
804
|
return el;
|
|
674
805
|
}
|
|
675
806
|
}
|
|
676
|
-
el = create(tag, props);
|
|
677
|
-
maybeDummyRef.value = el;
|
|
807
|
+
$setRef(props, (el = create(tag, props)));
|
|
678
808
|
return el;
|
|
679
809
|
}
|
|
680
810
|
/**
|
|
681
811
|
* Fragment support - returns an array of children
|
|
682
|
-
*
|
|
812
|
+
* Enhanced Fragment component that manages arrays of elements
|
|
683
813
|
*/
|
|
684
|
-
function Fragment(
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
// if (!Array.isArray(children)) {
|
|
692
|
-
// return children as HTMLElement;
|
|
693
|
-
// }
|
|
694
|
-
// // For multiple children, create a document fragment wrapper
|
|
695
|
-
// // This is a limitation - JSX fragments must be wrapped in kt.js
|
|
696
|
-
// const wrapper = document.createElement('div');
|
|
697
|
-
// wrapper.setAttribute('data-kt-fragment', 'true');
|
|
698
|
-
// children.forEach((child) => {
|
|
699
|
-
// if (typeof child === 'string') {
|
|
700
|
-
// wrapper.appendChild(document.createTextNode(child));
|
|
701
|
-
// } else if (child instanceof HTMLElement) {
|
|
702
|
-
// wrapper.appendChild(child);
|
|
703
|
-
// }
|
|
704
|
-
// });
|
|
705
|
-
// return wrapper;
|
|
814
|
+
function Fragment(props) {
|
|
815
|
+
const { children } = props ?? {};
|
|
816
|
+
if (!children) {
|
|
817
|
+
return document.createComment('kt-fragment-empty');
|
|
818
|
+
}
|
|
819
|
+
const elements = convertChildrenToElements(children);
|
|
820
|
+
return Fragment$1({ children: elements });
|
|
706
821
|
}
|
|
707
822
|
/**
|
|
708
823
|
* JSX Development runtime - same as jsx but with additional dev checks
|
|
@@ -759,45 +874,17 @@ var __ktjs_core__ = (function (exports) {
|
|
|
759
874
|
* Returns a Comment anchor node with rendered elements in __kt_for_list__
|
|
760
875
|
*/
|
|
761
876
|
function KTFor(props) {
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
// Create anchor comment node
|
|
765
|
-
const anchor = document.createComment('kt-for');
|
|
766
|
-
// Store current state
|
|
767
|
-
let currentList = list;
|
|
768
|
-
let currentKey = key;
|
|
769
|
-
let currentMap = map;
|
|
770
|
-
// Map to track rendered nodes by key
|
|
771
|
-
const nodeMap = new Map();
|
|
772
|
-
// Render initial list
|
|
773
|
-
const elements = [];
|
|
774
|
-
for (let index = 0; index < currentList.length; index++) {
|
|
775
|
-
const item = currentList[index];
|
|
776
|
-
const itemKey = currentKey(item, index, currentList);
|
|
777
|
-
const node = currentMap(item, index, currentList);
|
|
778
|
-
nodeMap.set(itemKey, node);
|
|
779
|
-
elements.push(node);
|
|
780
|
-
}
|
|
781
|
-
// Attach elements array to anchor
|
|
782
|
-
anchor.__kt_for_list__ = elements;
|
|
783
|
-
// Redraw function for updates
|
|
784
|
-
anchor.redraw = (newProps) => {
|
|
785
|
-
const newList = (newProps?.list ?? currentList);
|
|
786
|
-
const newKey = (newProps?.key ?? currentKey);
|
|
787
|
-
const newMap = (newProps?.map ?? currentMap);
|
|
788
|
-
// Update stored values
|
|
789
|
-
currentList = newList;
|
|
790
|
-
currentKey = newKey;
|
|
791
|
-
currentMap = newMap;
|
|
877
|
+
const redraw = () => {
|
|
878
|
+
const newList = listRef.value;
|
|
792
879
|
const parent = anchor.parentNode;
|
|
793
880
|
if (!parent) {
|
|
794
881
|
// If not in DOM yet, just rebuild the list
|
|
795
882
|
const newElements = [];
|
|
796
883
|
nodeMap.clear();
|
|
797
|
-
for (let index = 0; index <
|
|
798
|
-
const item =
|
|
799
|
-
const itemKey = currentKey(item, index,
|
|
800
|
-
const node = currentMap(item, index,
|
|
884
|
+
for (let index = 0; index < newList.length; index++) {
|
|
885
|
+
const item = newList[index];
|
|
886
|
+
const itemKey = currentKey(item, index, newList);
|
|
887
|
+
const node = currentMap(item, index, newList);
|
|
801
888
|
nodeMap.set(itemKey, node);
|
|
802
889
|
newElements.push(node);
|
|
803
890
|
}
|
|
@@ -819,8 +906,8 @@ var __ktjs_core__ = (function (exports) {
|
|
|
819
906
|
const fragment = document.createDocumentFragment();
|
|
820
907
|
for (let i = 0; i < newLength; i++) {
|
|
821
908
|
const item = newList[i];
|
|
822
|
-
const itemKey =
|
|
823
|
-
const node =
|
|
909
|
+
const itemKey = currentKey(item, i, newList);
|
|
910
|
+
const node = currentMap(item, i, newList);
|
|
824
911
|
nodeMap.set(itemKey, node);
|
|
825
912
|
newElements.push(node);
|
|
826
913
|
fragment.appendChild(node);
|
|
@@ -836,7 +923,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
836
923
|
let moved = false;
|
|
837
924
|
for (let i = 0; i < newLength; i++) {
|
|
838
925
|
const item = newList[i];
|
|
839
|
-
const itemKey =
|
|
926
|
+
const itemKey = currentKey(item, i, newList);
|
|
840
927
|
newKeyToNewIndex.set(itemKey, i);
|
|
841
928
|
if (nodeMap.has(itemKey)) {
|
|
842
929
|
// Reuse existing node
|
|
@@ -852,7 +939,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
852
939
|
}
|
|
853
940
|
else {
|
|
854
941
|
// Create new node
|
|
855
|
-
newElements[i] =
|
|
942
|
+
newElements[i] = currentMap(item, i, newList);
|
|
856
943
|
}
|
|
857
944
|
}
|
|
858
945
|
// Remove nodes not in new list
|
|
@@ -868,7 +955,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
868
955
|
// Update DOM with minimal operations
|
|
869
956
|
if (moved) {
|
|
870
957
|
// Use longest increasing subsequence to minimize moves
|
|
871
|
-
const seq = getSequence(newElements.map((el, i) => (nodeMap.has(
|
|
958
|
+
const seq = getSequence(newElements.map((el, i) => (nodeMap.has(currentKey(newList[i], i, newList)) ? i : -1)));
|
|
872
959
|
let j = seq.length - 1;
|
|
873
960
|
let anchor = null;
|
|
874
961
|
// Traverse from end to start for stable insertions
|
|
@@ -911,16 +998,28 @@ var __ktjs_core__ = (function (exports) {
|
|
|
911
998
|
// Update maps
|
|
912
999
|
nodeMap.clear();
|
|
913
1000
|
for (let i = 0; i < newLength; i++) {
|
|
914
|
-
const itemKey =
|
|
1001
|
+
const itemKey = currentKey(newList[i], i, newList);
|
|
915
1002
|
nodeMap.set(itemKey, newElements[i]);
|
|
916
1003
|
}
|
|
917
1004
|
anchor.__kt_for_list__ = newElements;
|
|
918
1005
|
return anchor;
|
|
919
1006
|
};
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1007
|
+
const { key: currentKey = (item) => item, map: currentMap } = props;
|
|
1008
|
+
const listRef = toReactive(props.list, redraw);
|
|
1009
|
+
const anchor = document.createComment('kt-for');
|
|
1010
|
+
// Map to track rendered nodes by key
|
|
1011
|
+
const nodeMap = new Map();
|
|
1012
|
+
// Render initial list
|
|
1013
|
+
const elements = [];
|
|
1014
|
+
for (let index = 0; index < listRef.value.length; index++) {
|
|
1015
|
+
const item = listRef.value[index];
|
|
1016
|
+
const itemKey = currentKey(item, index, listRef.value);
|
|
1017
|
+
const node = currentMap(item, index, listRef.value);
|
|
1018
|
+
nodeMap.set(itemKey, node);
|
|
1019
|
+
elements.push(node);
|
|
923
1020
|
}
|
|
1021
|
+
anchor.__kt_for_list__ = elements;
|
|
1022
|
+
$setRef(props, anchor);
|
|
924
1023
|
return anchor;
|
|
925
1024
|
}
|
|
926
1025
|
// Longest Increasing Subsequence algorithm (optimized for diff)
|
|
@@ -967,6 +1066,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
967
1066
|
}
|
|
968
1067
|
|
|
969
1068
|
exports.$modelOrRef = $modelOrRef;
|
|
1069
|
+
exports.$setRef = $setRef;
|
|
970
1070
|
exports.Fragment = Fragment;
|
|
971
1071
|
exports.KTAsync = KTAsync;
|
|
972
1072
|
exports.KTComputed = KTComputed;
|