@ktjs/core 0.21.1 → 0.22.2

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.mjs CHANGED
@@ -3,14 +3,8 @@ const $isArray = Array.isArray;
3
3
  const $entries = Object.entries;
4
4
  const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
5
5
 
6
- // Error handling utilities
7
- const $throw = (message) => {
8
- throw new Error('@ktjs/shared: ' + message);
9
- };
10
-
11
6
  // DOM manipulation utilities
12
7
  // # dom natives
13
- const $replaceWith = Element.prototype.replaceWith;
14
8
  /**
15
9
  * & Remove `bind` because it is shockingly slower than wrapper
16
10
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -47,10 +41,108 @@ const $append = // for ie 9/10/11
47
41
  }
48
42
  };
49
43
  const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
44
+ /**
45
+ * Used for `k-model`
46
+ */
47
+ const applyModel = (element, valueRef, propName, eventName) => {
48
+ element[propName] = valueRef.value; // initialize
49
+ valueRef.addOnChange((newValue) => (element[propName] = newValue));
50
+ element.addEventListener(eventName, () => (valueRef.value = element[propName]));
51
+ };
50
52
 
51
53
  // Shared utilities and cached native methods for kt.js framework
52
54
  // Re-export all utilities
53
- Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
55
+ Object.defineProperty(window, '__ktjs__', { value: '0.22.2' });
56
+
57
+ class KTRef {
58
+ /**
59
+ * Indicates that this is a KTRef instance
60
+ */
61
+ isKT = true;
62
+ /**
63
+ * @internal
64
+ */
65
+ _value;
66
+ /**
67
+ * @internal
68
+ */
69
+ _onChanges;
70
+ constructor(_value, _onChanges) {
71
+ this._value = _value;
72
+ this._onChanges = _onChanges;
73
+ }
74
+ /**
75
+ * If new value and old value are both nodes, the old one will be replaced in the DOM
76
+ */
77
+ get value() {
78
+ return this._value;
79
+ }
80
+ set value(newValue) {
81
+ if (newValue === this._value) {
82
+ return;
83
+ }
84
+ // replace the old node with the new one in the DOM if both are nodes
85
+ if (this._value instanceof Node && newValue instanceof Node) {
86
+ if (newValue.contains(this._value)) {
87
+ this._value.remove();
88
+ }
89
+ this._value.replaceWith(newValue);
90
+ }
91
+ const oldValue = this._value;
92
+ this._value = newValue;
93
+ for (let i = 0; i < this._onChanges.length; i++) {
94
+ this._onChanges[i](newValue, oldValue);
95
+ }
96
+ }
97
+ addOnChange(callback) {
98
+ this._onChanges.push(callback);
99
+ }
100
+ removeOnChange(callback) {
101
+ for (let i = this._onChanges.length - 1; i >= 0; i--) {
102
+ if (this._onChanges[i] === callback) {
103
+ this._onChanges.splice(i, 1);
104
+ return true;
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ }
110
+ const isKTRef = (obj) => {
111
+ return typeof obj === 'object' && obj !== null && obj.isKT === true;
112
+ };
113
+ /**
114
+ * Reference to the created HTML element.
115
+ * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
116
+ * - can alse be used to store normal values, but it is not reactive.
117
+ * @param value mostly an HTMLElement
118
+ */
119
+ function ref(value, onChange) {
120
+ return new KTRef(value, onChange ? [onChange] : []);
121
+ }
122
+ function kcollect() {
123
+ const newObj = {};
124
+ const entries = $entries(this);
125
+ for (let i = 0; i < entries.length; i++) {
126
+ const key = entries[i][0];
127
+ if (key === 'kcollect') {
128
+ continue;
129
+ }
130
+ newObj[key] = entries[i][1].value;
131
+ }
132
+ return newObj;
133
+ }
134
+ /**
135
+ * Make all first-level properties of the object a `KTRef`.
136
+ * - `obj.a.b` is not reactive
137
+ */
138
+ const surfaceRef = (obj) => {
139
+ const entries = $entries(obj);
140
+ const newObj = { kcollect };
141
+ for (let i = 0; i < entries.length; i++) {
142
+ newObj[entries[i][0]] = ref(entries[i][1]);
143
+ }
144
+ return newObj;
145
+ };
54
146
 
55
147
  const booleanHandler = (element, key, value) => {
56
148
  if (key in element) {
@@ -116,6 +208,7 @@ function attrIsObject(element, attr) {
116
208
  key === 'style' ||
117
209
  key === 'children' ||
118
210
  key === 'k-if' ||
211
+ key.startsWith('k-model') ||
119
212
  key === 'ref') {
120
213
  continue;
121
214
  }
@@ -138,7 +231,7 @@ function applyAttr(element, attr) {
138
231
  attrIsObject(element, attr);
139
232
  }
140
233
  else {
141
- throw new Error('kt.js: attr must be an object.');
234
+ throw new Error('[kt.js error] attr must be an object.');
142
235
  }
143
236
  }
144
237
 
@@ -193,6 +286,30 @@ function applyContent(element, content) {
193
286
  }
194
287
  }
195
288
 
289
+ function applyKModel(element, valueRef) {
290
+ if (!isKTRef(valueRef)) {
291
+ console.warn('[kt.js warn] k-model value must be a KTRef.');
292
+ return;
293
+ }
294
+ if (element instanceof HTMLInputElement) {
295
+ if (element.type === 'radio' || element.type === 'checkbox') {
296
+ applyModel(element, valueRef, 'checked', 'change');
297
+ }
298
+ else {
299
+ applyModel(element, valueRef, 'value', 'input');
300
+ }
301
+ }
302
+ else if (element instanceof HTMLSelectElement) {
303
+ applyModel(element, valueRef, 'value', 'change');
304
+ }
305
+ else if (element instanceof HTMLTextAreaElement) {
306
+ applyModel(element, valueRef, 'value', 'input');
307
+ }
308
+ else {
309
+ console.warn('[kt.js warn] not supported element for k-model:');
310
+ }
311
+ }
312
+
196
313
  const htmlCreator = (tag) => document.createElement(tag);
197
314
  const svgCreator = (tag) => document.createElementNS('http://www.w3.org/2000/svg', tag);
198
315
  const mathMLCreator = (tag) => document.createElementNS('http://www.w3.org/1998/Math/MathML', tag);
@@ -210,7 +327,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
210
327
  * ## About
211
328
  * @package @ktjs/core
212
329
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
213
- * @version 0.21.1 (Last Update: 2026.02.02 09:20:07.959)
330
+ * @version 0.22.2 (Last Update: 2026.02.02 20:28:37.901)
214
331
  * @license MIT
215
332
  * @link https://github.com/baendlorel/kt.js
216
333
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -219,7 +336,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
219
336
  */
220
337
  const h = (tag, attr, content) => {
221
338
  if (typeof tag !== 'string') {
222
- $throw('tagName must be a string.');
339
+ throw new Error('[kt.js error] tagName must be a string.');
223
340
  }
224
341
  if (attr) {
225
342
  if (SVG_ATTR_FLAG in attr) {
@@ -239,97 +356,16 @@ const h = (tag, attr, content) => {
239
356
  // * Handle content
240
357
  applyAttr(element, attr);
241
358
  applyContent(element, content);
242
- return element;
243
- };
244
-
245
- class KTRef {
246
- /**
247
- * Indicates that this is a KTRef instance
248
- */
249
- isKT = true;
250
- /**
251
- * @internal
252
- */
253
- _value;
254
- /**
255
- * @internal
256
- */
257
- _onChanges;
258
- constructor(_value, _onChanges) {
259
- this._value = _value;
260
- this._onChanges = _onChanges;
261
- }
262
- /**
263
- * If new value and old value are both nodes, the old one will be replaced in the DOM
264
- */
265
- get value() {
266
- return this._value;
267
- }
268
- set value(newValue) {
269
- if (newValue === this._value) {
270
- return;
271
- }
272
- // replace the old node with the new one in the DOM if both are nodes
273
- if (this._value instanceof Node && newValue instanceof Node) {
274
- if (newValue.contains(this._value)) {
275
- this._value.remove();
276
- }
277
- this._value.replaceWith(newValue);
278
- }
279
- const oldValue = this._value;
280
- this._value = newValue;
281
- for (let i = 0; i < this._onChanges.length; i++) {
282
- this._onChanges[i](newValue, oldValue);
359
+ if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
360
+ const kmodel = attr['k-model'];
361
+ if (isKTRef(kmodel)) {
362
+ applyKModel(element, kmodel);
283
363
  }
284
- }
285
- addOnChange(callback) {
286
- this._onChanges.push(callback);
287
- }
288
- removeOnChange(callback) {
289
- for (let i = this._onChanges.length - 1; i >= 0; i--) {
290
- if (this._onChanges[i] === callback) {
291
- this._onChanges.splice(i, 1);
292
- return true;
293
- }
294
- }
295
- return false;
296
- }
297
- }
298
- const isKTRef = (obj) => {
299
- return typeof obj === 'object' && obj !== null && obj.isKT === true;
300
- };
301
- /**
302
- * Reference to the created HTML element.
303
- * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
304
- * - can alse be used to store normal values, but it is not reactive.
305
- * @param value mostly an HTMLElement
306
- */
307
- function ref(value, onChange) {
308
- return new KTRef(value, onChange ? [onChange] : []);
309
- }
310
- function kcollect() {
311
- const newObj = {};
312
- const entries = $entries(this);
313
- for (let i = 0; i < entries.length; i++) {
314
- const key = entries[i][0];
315
- if (key === 'kcollect') {
316
- continue;
364
+ else {
365
+ throw new Error('[kt.js error] k-model value must be a KTRef.');
317
366
  }
318
- newObj[key] = entries[i][1].value;
319
- }
320
- return newObj;
321
- }
322
- /**
323
- * Make all first-level properties of the object a `KTRef`.
324
- * - `obj.a.b` is not reactive
325
- */
326
- const surfaceRef = (obj) => {
327
- const entries = $entries(obj);
328
- const newObj = { kcollect };
329
- for (let i = 0; i < entries.length; i++) {
330
- newObj[entries[i][0]] = ref(entries[i][1]);
331
367
  }
332
- return newObj;
368
+ return element;
333
369
  };
334
370
 
335
371
  const dummyRef = { value: null };
@@ -360,7 +396,7 @@ function jsx(tag, props) {
360
396
  }
361
397
  const oldEl = el;
362
398
  el = newValue ? create(tag, props) : placeholder();
363
- $replaceWith.call(oldEl, el);
399
+ oldEl.replaceWith(el);
364
400
  maybeDummyRef.value = el;
365
401
  });
366
402
  condition = kif.value;
@@ -381,7 +417,7 @@ function jsx(tag, props) {
381
417
  * Note: kt.js doesn't have a real Fragment concept,
382
418
  */
383
419
  function Fragment(_props) {
384
- throw new Error("kt.js doesn't have a Fragment concept");
420
+ throw new Error("[kt.js error] doesn't have a Fragment concept");
385
421
  // const { children } = props ?? {};
386
422
  // if (!children) {
387
423
  // return ;
@@ -66,12 +66,15 @@ interface KTBaseAttribute {
66
66
  // # kt-specific attributes
67
67
  ref?: KTRef<JSX.Element>;
68
68
 
69
- // todo 是否要让k-if是KTRef的时候具备响应能力?
70
69
  /**
71
70
  * If a `KTRef` is bound, it will be reactive; otherwise, it will be static.
72
71
  */
73
72
  'k-if'?: any;
74
- // todo k-model如何指定value还是checked还是别的什么?
73
+
74
+ /**
75
+ * Register two-way data binding between an input element and a KTRef.
76
+ * - Default to regist `input` event and `value` property(`checked` for checkboxes and radios).
77
+ */
75
78
  'k-model'?: KTRef<any>;
76
79
 
77
80
  // # normal HTML attributes
@@ -143,7 +146,7 @@ type KTAttribute = KTBaseAttribute & KTPrefixedEventHandlers;
143
146
  * ## About
144
147
  * @package @ktjs/core
145
148
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
146
- * @version 0.21.1 (Last Update: 2026.02.02 09:20:07.959)
149
+ * @version 0.22.2 (Last Update: 2026.02.02 20:28:37.901)
147
150
  * @license MIT
148
151
  * @link https://github.com/baendlorel/kt.js
149
152
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -3,14 +3,8 @@ const $isArray = Array.isArray;
3
3
  const $entries = Object.entries;
4
4
  const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
5
5
 
6
- // Error handling utilities
7
- const $throw = (message) => {
8
- throw new Error('@ktjs/shared: ' + message);
9
- };
10
-
11
6
  // DOM manipulation utilities
12
7
  // # dom natives
13
- const $replaceWith = Element.prototype.replaceWith;
14
8
  /**
15
9
  * & Remove `bind` because it is shockingly slower than wrapper
16
10
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -47,10 +41,108 @@ const $append = // for ie 9/10/11
47
41
  }
48
42
  };
49
43
  const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
44
+ /**
45
+ * Used for `k-model`
46
+ */
47
+ const applyModel = (element, valueRef, propName, eventName) => {
48
+ element[propName] = valueRef.value; // initialize
49
+ valueRef.addOnChange((newValue) => (element[propName] = newValue));
50
+ element.addEventListener(eventName, () => (valueRef.value = element[propName]));
51
+ };
50
52
 
51
53
  // Shared utilities and cached native methods for kt.js framework
52
54
  // Re-export all utilities
53
- Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
55
+ Object.defineProperty(window, '__ktjs__', { value: '0.22.2' });
56
+
57
+ class KTRef {
58
+ /**
59
+ * Indicates that this is a KTRef instance
60
+ */
61
+ isKT = true;
62
+ /**
63
+ * @internal
64
+ */
65
+ _value;
66
+ /**
67
+ * @internal
68
+ */
69
+ _onChanges;
70
+ constructor(_value, _onChanges) {
71
+ this._value = _value;
72
+ this._onChanges = _onChanges;
73
+ }
74
+ /**
75
+ * If new value and old value are both nodes, the old one will be replaced in the DOM
76
+ */
77
+ get value() {
78
+ return this._value;
79
+ }
80
+ set value(newValue) {
81
+ if (newValue === this._value) {
82
+ return;
83
+ }
84
+ // replace the old node with the new one in the DOM if both are nodes
85
+ if (this._value instanceof Node && newValue instanceof Node) {
86
+ if (newValue.contains(this._value)) {
87
+ this._value.remove();
88
+ }
89
+ this._value.replaceWith(newValue);
90
+ }
91
+ const oldValue = this._value;
92
+ this._value = newValue;
93
+ for (let i = 0; i < this._onChanges.length; i++) {
94
+ this._onChanges[i](newValue, oldValue);
95
+ }
96
+ }
97
+ addOnChange(callback) {
98
+ this._onChanges.push(callback);
99
+ }
100
+ removeOnChange(callback) {
101
+ for (let i = this._onChanges.length - 1; i >= 0; i--) {
102
+ if (this._onChanges[i] === callback) {
103
+ this._onChanges.splice(i, 1);
104
+ return true;
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ }
110
+ const isKTRef = (obj) => {
111
+ return typeof obj === 'object' && obj !== null && obj.isKT === true;
112
+ };
113
+ /**
114
+ * Reference to the created HTML element.
115
+ * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
116
+ * - can alse be used to store normal values, but it is not reactive.
117
+ * @param value mostly an HTMLElement
118
+ */
119
+ function ref(value, onChange) {
120
+ return new KTRef(value, onChange ? [onChange] : []);
121
+ }
122
+ function kcollect() {
123
+ const newObj = {};
124
+ const entries = $entries(this);
125
+ for (let i = 0; i < entries.length; i++) {
126
+ const key = entries[i][0];
127
+ if (key === 'kcollect') {
128
+ continue;
129
+ }
130
+ newObj[key] = entries[i][1].value;
131
+ }
132
+ return newObj;
133
+ }
134
+ /**
135
+ * Make all first-level properties of the object a `KTRef`.
136
+ * - `obj.a.b` is not reactive
137
+ */
138
+ const surfaceRef = (obj) => {
139
+ const entries = $entries(obj);
140
+ const newObj = { kcollect };
141
+ for (let i = 0; i < entries.length; i++) {
142
+ newObj[entries[i][0]] = ref(entries[i][1]);
143
+ }
144
+ return newObj;
145
+ };
54
146
 
55
147
  const booleanHandler = (element, key, value) => {
56
148
  if (key in element) {
@@ -116,6 +208,7 @@ function attrIsObject(element, attr) {
116
208
  key === 'style' ||
117
209
  key === 'children' ||
118
210
  key === 'k-if' ||
211
+ key.startsWith('k-model') ||
119
212
  key === 'ref') {
120
213
  continue;
121
214
  }
@@ -138,7 +231,7 @@ function applyAttr(element, attr) {
138
231
  attrIsObject(element, attr);
139
232
  }
140
233
  else {
141
- throw new Error('kt.js: attr must be an object.');
234
+ throw new Error('[kt.js error] attr must be an object.');
142
235
  }
143
236
  }
144
237
 
@@ -193,6 +286,30 @@ function applyContent(element, content) {
193
286
  }
194
287
  }
195
288
 
289
+ function applyKModel(element, valueRef) {
290
+ if (!isKTRef(valueRef)) {
291
+ console.warn('[kt.js warn] k-model value must be a KTRef.');
292
+ return;
293
+ }
294
+ if (element instanceof HTMLInputElement) {
295
+ if (element.type === 'radio' || element.type === 'checkbox') {
296
+ applyModel(element, valueRef, 'checked', 'change');
297
+ }
298
+ else {
299
+ applyModel(element, valueRef, 'value', 'input');
300
+ }
301
+ }
302
+ else if (element instanceof HTMLSelectElement) {
303
+ applyModel(element, valueRef, 'value', 'change');
304
+ }
305
+ else if (element instanceof HTMLTextAreaElement) {
306
+ applyModel(element, valueRef, 'value', 'input');
307
+ }
308
+ else {
309
+ console.warn('[kt.js warn] not supported element for k-model:');
310
+ }
311
+ }
312
+
196
313
  const htmlCreator = (tag) => document.createElement(tag);
197
314
  const svgCreator = (tag) => document.createElementNS('http://www.w3.org/2000/svg', tag);
198
315
  const mathMLCreator = (tag) => document.createElementNS('http://www.w3.org/1998/Math/MathML', tag);
@@ -210,7 +327,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
210
327
  * ## About
211
328
  * @package @ktjs/core
212
329
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
213
- * @version 0.21.1 (Last Update: 2026.02.02 09:20:07.959)
330
+ * @version 0.22.2 (Last Update: 2026.02.02 20:28:37.901)
214
331
  * @license MIT
215
332
  * @link https://github.com/baendlorel/kt.js
216
333
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -219,7 +336,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
219
336
  */
220
337
  const h = (tag, attr, content) => {
221
338
  if (typeof tag !== 'string') {
222
- $throw('tagName must be a string.');
339
+ throw new Error('[kt.js error] tagName must be a string.');
223
340
  }
224
341
  if (attr) {
225
342
  if (SVG_ATTR_FLAG in attr) {
@@ -239,97 +356,16 @@ const h = (tag, attr, content) => {
239
356
  // * Handle content
240
357
  applyAttr(element, attr);
241
358
  applyContent(element, content);
242
- return element;
243
- };
244
-
245
- class KTRef {
246
- /**
247
- * Indicates that this is a KTRef instance
248
- */
249
- isKT = true;
250
- /**
251
- * @internal
252
- */
253
- _value;
254
- /**
255
- * @internal
256
- */
257
- _onChanges;
258
- constructor(_value, _onChanges) {
259
- this._value = _value;
260
- this._onChanges = _onChanges;
261
- }
262
- /**
263
- * If new value and old value are both nodes, the old one will be replaced in the DOM
264
- */
265
- get value() {
266
- return this._value;
267
- }
268
- set value(newValue) {
269
- if (newValue === this._value) {
270
- return;
271
- }
272
- // replace the old node with the new one in the DOM if both are nodes
273
- if (this._value instanceof Node && newValue instanceof Node) {
274
- if (newValue.contains(this._value)) {
275
- this._value.remove();
276
- }
277
- this._value.replaceWith(newValue);
278
- }
279
- const oldValue = this._value;
280
- this._value = newValue;
281
- for (let i = 0; i < this._onChanges.length; i++) {
282
- this._onChanges[i](newValue, oldValue);
359
+ if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
360
+ const kmodel = attr['k-model'];
361
+ if (isKTRef(kmodel)) {
362
+ applyKModel(element, kmodel);
283
363
  }
284
- }
285
- addOnChange(callback) {
286
- this._onChanges.push(callback);
287
- }
288
- removeOnChange(callback) {
289
- for (let i = this._onChanges.length - 1; i >= 0; i--) {
290
- if (this._onChanges[i] === callback) {
291
- this._onChanges.splice(i, 1);
292
- return true;
293
- }
294
- }
295
- return false;
296
- }
297
- }
298
- const isKTRef = (obj) => {
299
- return typeof obj === 'object' && obj !== null && obj.isKT === true;
300
- };
301
- /**
302
- * Reference to the created HTML element.
303
- * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
304
- * - can alse be used to store normal values, but it is not reactive.
305
- * @param value mostly an HTMLElement
306
- */
307
- function ref(value, onChange) {
308
- return new KTRef(value, onChange ? [onChange] : []);
309
- }
310
- function kcollect() {
311
- const newObj = {};
312
- const entries = $entries(this);
313
- for (let i = 0; i < entries.length; i++) {
314
- const key = entries[i][0];
315
- if (key === 'kcollect') {
316
- continue;
364
+ else {
365
+ throw new Error('[kt.js error] k-model value must be a KTRef.');
317
366
  }
318
- newObj[key] = entries[i][1].value;
319
- }
320
- return newObj;
321
- }
322
- /**
323
- * Make all first-level properties of the object a `KTRef`.
324
- * - `obj.a.b` is not reactive
325
- */
326
- const surfaceRef = (obj) => {
327
- const entries = $entries(obj);
328
- const newObj = { kcollect };
329
- for (let i = 0; i < entries.length; i++) {
330
- newObj[entries[i][0]] = ref(entries[i][1]);
331
367
  }
332
- return newObj;
368
+ return element;
333
369
  };
334
370
 
335
371
  const dummyRef = { value: null };
@@ -360,7 +396,7 @@ function jsx(tag, props) {
360
396
  }
361
397
  const oldEl = el;
362
398
  el = newValue ? create(tag, props) : placeholder();
363
- $replaceWith.call(oldEl, el);
399
+ oldEl.replaceWith(el);
364
400
  maybeDummyRef.value = el;
365
401
  });
366
402
  condition = kif.value;
@@ -381,7 +417,7 @@ function jsx(tag, props) {
381
417
  * Note: kt.js doesn't have a real Fragment concept,
382
418
  */
383
419
  function Fragment(_props) {
384
- throw new Error("kt.js doesn't have a Fragment concept");
420
+ throw new Error("[kt.js error] doesn't have a Fragment concept");
385
421
  // const { children } = props ?? {};
386
422
  // if (!children) {
387
423
  // return ;
@@ -45,12 +45,15 @@ interface KTBaseAttribute {
45
45
  // # kt-specific attributes
46
46
  ref?: KTRef<JSX.Element>;
47
47
 
48
- // todo 是否要让k-if是KTRef的时候具备响应能力?
49
48
  /**
50
49
  * If a `KTRef` is bound, it will be reactive; otherwise, it will be static.
51
50
  */
52
51
  'k-if'?: any;
53
- // todo k-model如何指定value还是checked还是别的什么?
52
+
53
+ /**
54
+ * Register two-way data binding between an input element and a KTRef.
55
+ * - Default to regist `input` event and `value` property(`checked` for checkboxes and radios).
56
+ */
54
57
  'k-model'?: KTRef<any>;
55
58
 
56
59
  // # normal HTML attributes
@@ -122,7 +125,7 @@ type KTAttribute = KTBaseAttribute & KTPrefixedEventHandlers;
122
125
  * ## About
123
126
  * @package @ktjs/core
124
127
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
125
- * @version 0.21.1 (Last Update: 2026.02.02 09:20:07.959)
128
+ * @version 0.22.2 (Last Update: 2026.02.02 20:28:37.901)
126
129
  * @license MIT
127
130
  * @link https://github.com/baendlorel/kt.js
128
131
  * @link https://baendlorel.github.io/ Welcome to my site!