@ktjs/core 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -22,8 +22,15 @@ type otherstring = string & {};
22
22
  */
23
23
  type HTMLTag = keyof HTMLElementTagNameMap & otherstring;
24
24
 
25
- type Ctt = HTMLElement | string | number | undefined;
26
- type KTRawContent = (Ctt | (() => Ctt))[] | Ctt;
25
+ declare class Ref<T> {
26
+ value: T;
27
+ update: () => T;
28
+ constructor(value: T);
29
+ }
30
+ declare function ref<T>(value: T): Ref<T>;
31
+
32
+ type Ctt = Ref<any> | HTMLElement | string | number | undefined;
33
+ type KTRawContent = Ctt[] | Ctt;
27
34
  type KTRawAttr = KTAttribute | string;
28
35
  type KTRawContents = (HTMLElement | string | undefined)[];
29
36
 
@@ -103,16 +110,38 @@ type HTML<T extends HTMLTag & otherstring> = T extends HTMLTag ? HTMLElementTagN
103
110
  * ## About
104
111
  * @package @ktjs/core
105
112
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
106
- * @version 0.7.1 (Last Update: 2025.12.25 09:44:03.948)
113
+ * @version 0.8.0 (Last Update: 2025.12.25 11:01:24.676)
107
114
  * @license MIT
108
115
  * @link https://github.com/baendlorel/kt.js
109
116
  * @link https://baendlorel.github.io/ Welcome to my site!
110
- * @description Core functionality for kt.js - DOM manipulation utilities
117
+ * @description Core functionality for kt.js - DOM manipulation utilities with JSX/TSX support
111
118
  * @copyright Copyright (c) 2025 Kasukabe Tsumugi. All rights reserved.
112
119
  */
113
120
  declare const h: <T extends HTMLTag>(tag: T, attr?: KTRawAttr, content?: KTRawContent) => HTML<T>;
114
121
 
115
- declare function notSupportTextNode(tag: HTMLTag): boolean;
122
+ /**
123
+ * @param tag html tag
124
+ * @param props properties/attributes
125
+ * @param _metadata metadata is ignored
126
+ */
127
+ declare function jsx<T extends HTMLTag>(tag: T, props: KTRawAttr, ..._metadata: any[]): HTMLElementTagNameMap[T];
128
+ /**
129
+ * Fragment support - returns an array of children
130
+ * Note: kt.js doesn't have a real Fragment concept,
131
+ * so we return ktnull for empty fragments or flatten children
132
+ */
133
+ declare function Fragment(props: {
134
+ children?: KTRawContent;
135
+ }): HTMLElement | typeof ktnull;
136
+ /**
137
+ * JSX Development runtime - same as jsx but with additional dev checks
138
+ */
139
+ declare const jsxDEV: typeof jsx;
140
+ /**
141
+ * JSX runtime for React 17+ automatic runtime
142
+ * This is called when using jsx: "react-jsx" or "react-jsxdev"
143
+ */
144
+ declare const jsxs: typeof jsx;
116
145
 
117
- export { h, ktnull, notSupportTextNode };
146
+ export { Fragment, Ref, h as createElement, h, jsx, jsxDEV, jsxs, ktnull, ref };
118
147
  export type { EventHandler, HTMLTag, KTAttribute, KTRawAttr, KTRawContent, KTRawContents, KTRuntime };
@@ -175,18 +175,25 @@ var __ktjs_core__ = (function (exports) {
175
175
  }
176
176
  }
177
177
 
178
- function applyContent(element, content) {
179
- if (typeof content === 'function') {
180
- content = content();
178
+ const noop = () => ({});
179
+ class Ref {
180
+ value;
181
+ update;
182
+ constructor(value) {
183
+ this.value = value;
184
+ this.update = noop;
181
185
  }
186
+ }
187
+ function ref(value) {
188
+ return new Ref(value);
189
+ }
190
+
191
+ function applyContent(element, content) {
182
192
  if ($isArray(content)) {
183
193
  for (let i = 0; i < content.length; i++) {
184
194
  let c = content[i];
185
- if (typeof c === 'function') {
186
- c = c();
187
- }
188
- else if (typeof c === 'number') {
189
- $append.call(element, c.toString());
195
+ if (c instanceof Ref) {
196
+ $append.call(element, c.value);
190
197
  }
191
198
  else {
192
199
  $append.call(element, c);
@@ -194,8 +201,8 @@ var __ktjs_core__ = (function (exports) {
194
201
  }
195
202
  }
196
203
  else {
197
- if (typeof content === 'number') {
198
- $append.call(element, content.toString());
204
+ if (content instanceof Ref) {
205
+ $append.call(element, content.value);
199
206
  }
200
207
  else {
201
208
  $append.call(element, content);
@@ -213,11 +220,11 @@ var __ktjs_core__ = (function (exports) {
213
220
  * ## About
214
221
  * @package @ktjs/core
215
222
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
216
- * @version 0.7.1 (Last Update: 2025.12.25 09:44:03.948)
223
+ * @version 0.8.0 (Last Update: 2025.12.25 11:01:24.676)
217
224
  * @license MIT
218
225
  * @link https://github.com/baendlorel/kt.js
219
226
  * @link https://baendlorel.github.io/ Welcome to my site!
220
- * @description Core functionality for kt.js - DOM manipulation utilities
227
+ * @description Core functionality for kt.js - DOM manipulation utilities with JSX/TSX support
221
228
  * @copyright Copyright (c) 2025 Kasukabe Tsumugi. All rights reserved.
222
229
  */
223
230
  const h = (tag, attr = '', content = '') => {
@@ -234,87 +241,87 @@ var __ktjs_core__ = (function (exports) {
234
241
  $mark(h, 'h');
235
242
 
236
243
  /**
237
- * # Specialized Ehancement
238
- *
239
- * Different elements should be enhanced in different ways. For example, we should have `kvalue` to handle `<input>` values.
240
- * While we have no need to have `ktext` for `<br>` tags.
241
- *
242
- * ## Tags where appending a text node has no effect
243
- *
244
- * There are some HTML elements that appending a text node as their child takes no effect.
245
- * They are mostly void elements, but some non-void elements are also included.
246
- *
247
- * ## What means no effect
248
- * 1. appending a text node to these tags takes no effect.
249
- * 2. No effect means `innerText` does not include the text in the text node.
250
- *
251
- * After testing 15 browsers testing, I found that these elements are:
252
- *
253
- * - FireFox(as base):
254
- * - script -- this is skipped due to some bugs in The World 7
255
- * - area, audio, base, basefont, br, canvas, datalist, details, dialog, frameset, head, iframe, img, input, link, meta, meter, noembed, noframes, noscript, optgroup, param, progress, rp, select, style, template, textarea, title, video, wbr
256
- * - 360: embed
257
- * - 2345: embed
258
- * - maxthon: embed
259
- * - quark: embed
260
- * - uc: embed
261
- * - chrome: embed,frame
262
- * - qq: embed
263
- * - sogou: embed
264
- * - cent: embed
265
- * - world: embed,frame,keygen,option
266
- * - opera: embed
267
- * - edge: embed
268
- * - liebao: embed
269
- * - 360turbo: embed,frame
270
- *
271
- * Since `Set.prototype.has` is about 80 times faster than `Array.prototype.includes`,
272
- * We put these tags into a `Set` object.
244
+ * @param tag html tag
245
+ * @param props properties/attributes
246
+ * @param _metadata metadata is ignored
273
247
  */
274
- const INVALID_TAGS = {
275
- area: true,
276
- audio: true,
277
- base: true,
278
- basefont: true,
279
- br: true,
280
- canvas: true,
281
- datalist: true,
282
- details: true,
283
- dialog: true,
284
- frameset: true,
285
- head: true,
286
- iframe: true,
287
- img: true,
288
- input: true,
289
- link: true,
290
- meta: true,
291
- meter: true,
292
- noembed: true,
293
- noframes: true,
294
- noscript: true,
295
- optgroup: true,
296
- param: true,
297
- progress: true,
298
- rp: true,
299
- select: true,
300
- style: true,
301
- template: true,
302
- textarea: true,
303
- title: true,
304
- video: true,
305
- wbr: true,
306
- embed: true,
307
- frame: true,
308
- keygen: true,
309
- option: true,
310
- };
311
- function notSupportTextNode(tag) {
312
- return INVALID_TAGS[tag];
248
+ function jsx(tag, props, ..._metadata) {
249
+ const propObj = typeof props === 'string' ? { class: props } : props;
250
+ if (propObj === undefined || propObj === null) {
251
+ return h(tag);
252
+ }
253
+ const children = propObj.children;
254
+ delete propObj.children;
255
+ // deal with ref attribute
256
+ const ref = 'ref' in propObj && propObj.ref instanceof Ref ? propObj.ref : null;
257
+ if (ref) {
258
+ delete propObj.ref;
259
+ }
260
+ const el = h(tag, propObj, children);
261
+ if (ref) {
262
+ ref.value = el;
263
+ ref.update = () => {
264
+ const old = ref.value;
265
+ ref.value = h(tag, propObj, children);
266
+ old.replaceWith(ref.value);
267
+ return ref.value;
268
+ };
269
+ }
270
+ return el;
271
+ }
272
+ /**
273
+ * Fragment support - returns an array of children
274
+ * Note: kt.js doesn't have a real Fragment concept,
275
+ * so we return ktnull for empty fragments or flatten children
276
+ */
277
+ function Fragment(props) {
278
+ window.__ktjs__.throws("kt.js doesn't have a Fragment concept");
279
+ // const { children } = props || {};
280
+ // if (!children) {
281
+ // return ktnull;
282
+ // }
283
+ // // If single child, return it directly
284
+ // if (!Array.isArray(children)) {
285
+ // return children as HTMLElement;
286
+ // }
287
+ // // For multiple children, create a document fragment wrapper
288
+ // // This is a limitation - JSX fragments must be wrapped in kt.js
289
+ // const wrapper = document.createElement('div');
290
+ // wrapper.setAttribute('data-kt-fragment', 'true');
291
+ // children.forEach((child) => {
292
+ // if (child && child !== ktnull) {
293
+ // if (typeof child === 'string') {
294
+ // wrapper.appendChild(document.createTextNode(child));
295
+ // } else if (child instanceof HTMLElement) {
296
+ // wrapper.appendChild(child);
297
+ // }
298
+ // }
299
+ // });
300
+ // return wrapper;
313
301
  }
302
+ /**
303
+ * JSX Development runtime - same as jsx but with additional dev checks
304
+ */
305
+ const jsxDEV = (...args) => {
306
+ console.log('JSX DEV called:', ...args);
307
+ console.log('chilren', args[1]?.children);
308
+ return jsx(...args);
309
+ };
310
+ /**
311
+ * JSX runtime for React 17+ automatic runtime
312
+ * This is called when using jsx: "react-jsx" or "react-jsxdev"
313
+ */
314
+ const jsxs = jsx;
314
315
 
316
+ exports.Fragment = Fragment;
317
+ exports.Ref = Ref;
318
+ exports.createElement = h;
315
319
  exports.h = h;
320
+ exports.jsx = jsx;
321
+ exports.jsxDEV = jsxDEV;
322
+ exports.jsxs = jsxs;
316
323
  exports.ktnull = ktnull;
317
- exports.notSupportTextNode = notSupportTextNode;
324
+ exports.ref = ref;
318
325
 
319
326
  return exports;
320
327
 
@@ -186,18 +186,24 @@ var __ktjs_core__ = (function (exports) {
186
186
  }
187
187
  }
188
188
 
189
- function applyContent(element, content) {
190
- if (typeof content === 'function') {
191
- content = content();
189
+ var noop = function () { return ({}); };
190
+ var Ref = /** @class */ (function () {
191
+ function Ref(value) {
192
+ this.value = value;
193
+ this.update = noop;
192
194
  }
195
+ return Ref;
196
+ }());
197
+ function ref(value) {
198
+ return new Ref(value);
199
+ }
200
+
201
+ function applyContent(element, content) {
193
202
  if ($isArray(content)) {
194
203
  for (var i = 0; i < content.length; i++) {
195
204
  var c = content[i];
196
- if (typeof c === 'function') {
197
- c = c();
198
- }
199
- else if (typeof c === 'number') {
200
- $append.call(element, c.toString());
205
+ if (c instanceof Ref) {
206
+ $append.call(element, c.value);
201
207
  }
202
208
  else {
203
209
  $append.call(element, c);
@@ -205,8 +211,8 @@ var __ktjs_core__ = (function (exports) {
205
211
  }
206
212
  }
207
213
  else {
208
- if (typeof content === 'number') {
209
- $append.call(element, content.toString());
214
+ if (content instanceof Ref) {
215
+ $append.call(element, content.value);
210
216
  }
211
217
  else {
212
218
  $append.call(element, content);
@@ -224,11 +230,11 @@ var __ktjs_core__ = (function (exports) {
224
230
  * ## About
225
231
  * @package @ktjs/core
226
232
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
227
- * @version 0.7.1 (Last Update: 2025.12.25 09:44:03.948)
233
+ * @version 0.8.0 (Last Update: 2025.12.25 11:01:24.676)
228
234
  * @license MIT
229
235
  * @link https://github.com/baendlorel/kt.js
230
236
  * @link https://baendlorel.github.io/ Welcome to my site!
231
- * @description Core functionality for kt.js - DOM manipulation utilities
237
+ * @description Core functionality for kt.js - DOM manipulation utilities with JSX/TSX support
232
238
  * @copyright Copyright (c) 2025 Kasukabe Tsumugi. All rights reserved.
233
239
  */
234
240
  var h = function (tag, attr, content) {
@@ -246,88 +252,125 @@ var __ktjs_core__ = (function (exports) {
246
252
  };
247
253
  $mark(h, 'h');
248
254
 
255
+ /******************************************************************************
256
+ Copyright (c) Microsoft Corporation.
257
+
258
+ Permission to use, copy, modify, and/or distribute this software for any
259
+ purpose with or without fee is hereby granted.
260
+
261
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
262
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
263
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
264
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
265
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
266
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
267
+ PERFORMANCE OF THIS SOFTWARE.
268
+ ***************************************************************************** */
269
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
270
+
271
+
272
+ function __spreadArray(to, from, pack) {
273
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
274
+ if (ar || !(i in from)) {
275
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
276
+ ar[i] = from[i];
277
+ }
278
+ }
279
+ return to.concat(ar || Array.prototype.slice.call(from));
280
+ }
281
+
282
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
283
+ var e = new Error(message);
284
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
285
+ };
286
+
249
287
  /**
250
- * # Specialized Ehancement
251
- *
252
- * Different elements should be enhanced in different ways. For example, we should have `kvalue` to handle `<input>` values.
253
- * While we have no need to have `ktext` for `<br>` tags.
254
- *
255
- * ## Tags where appending a text node has no effect
256
- *
257
- * There are some HTML elements that appending a text node as their child takes no effect.
258
- * They are mostly void elements, but some non-void elements are also included.
259
- *
260
- * ## What means no effect
261
- * 1. appending a text node to these tags takes no effect.
262
- * 2. No effect means `innerText` does not include the text in the text node.
263
- *
264
- * After testing 15 browsers testing, I found that these elements are:
265
- *
266
- * - FireFox(as base):
267
- * - script -- this is skipped due to some bugs in The World 7
268
- * - area, audio, base, basefont, br, canvas, datalist, details, dialog, frameset, head, iframe, img, input, link, meta, meter, noembed, noframes, noscript, optgroup, param, progress, rp, select, style, template, textarea, title, video, wbr
269
- * - 360: embed
270
- * - 2345: embed
271
- * - maxthon: embed
272
- * - quark: embed
273
- * - uc: embed
274
- * - chrome: embed,frame
275
- * - qq: embed
276
- * - sogou: embed
277
- * - cent: embed
278
- * - world: embed,frame,keygen,option
279
- * - opera: embed
280
- * - edge: embed
281
- * - liebao: embed
282
- * - 360turbo: embed,frame
283
- *
284
- * Since `Set.prototype.has` is about 80 times faster than `Array.prototype.includes`,
285
- * We put these tags into a `Set` object.
288
+ * @param tag html tag
289
+ * @param props properties/attributes
290
+ * @param _metadata metadata is ignored
286
291
  */
287
- var INVALID_TAGS = {
288
- area: true,
289
- audio: true,
290
- base: true,
291
- basefont: true,
292
- br: true,
293
- canvas: true,
294
- datalist: true,
295
- details: true,
296
- dialog: true,
297
- frameset: true,
298
- head: true,
299
- iframe: true,
300
- img: true,
301
- input: true,
302
- link: true,
303
- meta: true,
304
- meter: true,
305
- noembed: true,
306
- noframes: true,
307
- noscript: true,
308
- optgroup: true,
309
- param: true,
310
- progress: true,
311
- rp: true,
312
- select: true,
313
- style: true,
314
- template: true,
315
- textarea: true,
316
- title: true,
317
- video: true,
318
- wbr: true,
319
- embed: true,
320
- frame: true,
321
- keygen: true,
322
- option: true,
323
- };
324
- function notSupportTextNode(tag) {
325
- return INVALID_TAGS[tag];
292
+ function jsx(tag, props) {
293
+ var propObj = typeof props === 'string' ? { class: props } : props;
294
+ if (propObj === undefined || propObj === null) {
295
+ return h(tag);
296
+ }
297
+ var children = propObj.children;
298
+ delete propObj.children;
299
+ // deal with ref attribute
300
+ var ref = 'ref' in propObj && propObj.ref instanceof Ref ? propObj.ref : null;
301
+ if (ref) {
302
+ delete propObj.ref;
303
+ }
304
+ var el = h(tag, propObj, children);
305
+ if (ref) {
306
+ ref.value = el;
307
+ ref.update = function () {
308
+ var old = ref.value;
309
+ ref.value = h(tag, propObj, children);
310
+ old.replaceWith(ref.value);
311
+ return ref.value;
312
+ };
313
+ }
314
+ return el;
315
+ }
316
+ /**
317
+ * Fragment support - returns an array of children
318
+ * Note: kt.js doesn't have a real Fragment concept,
319
+ * so we return ktnull for empty fragments or flatten children
320
+ */
321
+ function Fragment(props) {
322
+ window.__ktjs__.throws("kt.js doesn't have a Fragment concept");
323
+ // const { children } = props || {};
324
+ // if (!children) {
325
+ // return ktnull;
326
+ // }
327
+ // // If single child, return it directly
328
+ // if (!Array.isArray(children)) {
329
+ // return children as HTMLElement;
330
+ // }
331
+ // // For multiple children, create a document fragment wrapper
332
+ // // This is a limitation - JSX fragments must be wrapped in kt.js
333
+ // const wrapper = document.createElement('div');
334
+ // wrapper.setAttribute('data-kt-fragment', 'true');
335
+ // children.forEach((child) => {
336
+ // if (child && child !== ktnull) {
337
+ // if (typeof child === 'string') {
338
+ // wrapper.appendChild(document.createTextNode(child));
339
+ // } else if (child instanceof HTMLElement) {
340
+ // wrapper.appendChild(child);
341
+ // }
342
+ // }
343
+ // });
344
+ // return wrapper;
326
345
  }
346
+ /**
347
+ * JSX Development runtime - same as jsx but with additional dev checks
348
+ */
349
+ var jsxDEV = function () {
350
+ var _a;
351
+ var args = [];
352
+ for (var _i = 0; _i < arguments.length; _i++) {
353
+ args[_i] = arguments[_i];
354
+ }
355
+ console.log.apply(console, __spreadArray(['JSX DEV called:'], args, false));
356
+ console.log('chilren', (_a = args[1]) === null || _a === void 0 ? void 0 : _a.children);
357
+ return jsx.apply(void 0, args);
358
+ };
359
+ /**
360
+ * JSX runtime for React 17+ automatic runtime
361
+ * This is called when using jsx: "react-jsx" or "react-jsxdev"
362
+ */
363
+ var jsxs = jsx;
327
364
 
365
+ exports.Fragment = Fragment;
366
+ exports.Ref = Ref;
367
+ exports.createElement = h;
328
368
  exports.h = h;
369
+ exports.jsx = jsx;
370
+ exports.jsxDEV = jsxDEV;
371
+ exports.jsxs = jsxs;
329
372
  exports.ktnull = ktnull;
330
- exports.notSupportTextNode = notSupportTextNode;
373
+ exports.ref = ref;
331
374
 
332
375
  return exports;
333
376