@ktjs/core 0.7.3 → 0.8.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 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,56 @@ 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.3 (Last Update: 2025.12.25 09:51:02.157)
113
+ * @version 0.8.1 (Last Update: 2025.12.25 11:07:30.486)
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;
145
+
146
+ declare global {
147
+ namespace JSX {
148
+ type Element = HTMLElementTagNameMap[keyof HTMLElementTagNameMap];
149
+
150
+ interface IntrinsicElements {
151
+ [tag: string]: KTAttribute & { children?: KTRawContent };
152
+ }
153
+
154
+ interface IntrinsicAttributes {
155
+ key?: string | number;
156
+ }
157
+
158
+ interface ElementChildrenAttribute {
159
+ children: {};
160
+ }
161
+ }
162
+ }
116
163
 
117
- export { h, ktnull, notSupportTextNode };
164
+ export { Fragment, Ref, h as createElement, h, jsx, jsxDEV, jsxs, ktnull, ref };
118
165
  export type { EventHandler, HTMLTag, KTAttribute, KTRawAttr, KTRawContent, KTRawContents, KTRuntime };
@@ -175,19 +175,25 @@ var __ktjs_core__ = (function (exports) {
175
175
  }
176
176
  }
177
177
 
178
- function applyContent(element, content) {
179
- console.log('applyContent', content);
180
- if (typeof content === 'function') {
181
- content = content();
178
+ const noop = () => ({});
179
+ class Ref {
180
+ value;
181
+ update;
182
+ constructor(value) {
183
+ this.value = value;
184
+ this.update = noop;
182
185
  }
186
+ }
187
+ function ref(value) {
188
+ return new Ref(value);
189
+ }
190
+
191
+ function applyContent(element, content) {
183
192
  if ($isArray(content)) {
184
193
  for (let i = 0; i < content.length; i++) {
185
194
  let c = content[i];
186
- if (typeof c === 'function') {
187
- c = c();
188
- }
189
- else if (typeof c === 'number') {
190
- $append.call(element, c.toString());
195
+ if (c instanceof Ref) {
196
+ $append.call(element, c.value);
191
197
  }
192
198
  else {
193
199
  $append.call(element, c);
@@ -195,8 +201,8 @@ var __ktjs_core__ = (function (exports) {
195
201
  }
196
202
  }
197
203
  else {
198
- if (typeof content === 'number') {
199
- $append.call(element, content.toString());
204
+ if (content instanceof Ref) {
205
+ $append.call(element, content.value);
200
206
  }
201
207
  else {
202
208
  $append.call(element, content);
@@ -214,11 +220,11 @@ var __ktjs_core__ = (function (exports) {
214
220
  * ## About
215
221
  * @package @ktjs/core
216
222
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
217
- * @version 0.7.3 (Last Update: 2025.12.25 09:51:02.157)
223
+ * @version 0.8.1 (Last Update: 2025.12.25 11:07:30.486)
218
224
  * @license MIT
219
225
  * @link https://github.com/baendlorel/kt.js
220
226
  * @link https://baendlorel.github.io/ Welcome to my site!
221
- * @description Core functionality for kt.js - DOM manipulation utilities
227
+ * @description Core functionality for kt.js - DOM manipulation utilities with JSX/TSX support
222
228
  * @copyright Copyright (c) 2025 Kasukabe Tsumugi. All rights reserved.
223
229
  */
224
230
  const h = (tag, attr = '', content = '') => {
@@ -235,87 +241,87 @@ var __ktjs_core__ = (function (exports) {
235
241
  $mark(h, 'h');
236
242
 
237
243
  /**
238
- * # Specialized Ehancement
239
- *
240
- * Different elements should be enhanced in different ways. For example, we should have `kvalue` to handle `<input>` values.
241
- * While we have no need to have `ktext` for `<br>` tags.
242
- *
243
- * ## Tags where appending a text node has no effect
244
- *
245
- * There are some HTML elements that appending a text node as their child takes no effect.
246
- * They are mostly void elements, but some non-void elements are also included.
247
- *
248
- * ## What means no effect
249
- * 1. appending a text node to these tags takes no effect.
250
- * 2. No effect means `innerText` does not include the text in the text node.
251
- *
252
- * After testing 15 browsers testing, I found that these elements are:
253
- *
254
- * - FireFox(as base):
255
- * - script -- this is skipped due to some bugs in The World 7
256
- * - 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
257
- * - 360: embed
258
- * - 2345: embed
259
- * - maxthon: embed
260
- * - quark: embed
261
- * - uc: embed
262
- * - chrome: embed,frame
263
- * - qq: embed
264
- * - sogou: embed
265
- * - cent: embed
266
- * - world: embed,frame,keygen,option
267
- * - opera: embed
268
- * - edge: embed
269
- * - liebao: embed
270
- * - 360turbo: embed,frame
271
- *
272
- * Since `Set.prototype.has` is about 80 times faster than `Array.prototype.includes`,
273
- * We put these tags into a `Set` object.
244
+ * @param tag html tag
245
+ * @param props properties/attributes
246
+ * @param _metadata metadata is ignored
274
247
  */
275
- const INVALID_TAGS = {
276
- area: true,
277
- audio: true,
278
- base: true,
279
- basefont: true,
280
- br: true,
281
- canvas: true,
282
- datalist: true,
283
- details: true,
284
- dialog: true,
285
- frameset: true,
286
- head: true,
287
- iframe: true,
288
- img: true,
289
- input: true,
290
- link: true,
291
- meta: true,
292
- meter: true,
293
- noembed: true,
294
- noframes: true,
295
- noscript: true,
296
- optgroup: true,
297
- param: true,
298
- progress: true,
299
- rp: true,
300
- select: true,
301
- style: true,
302
- template: true,
303
- textarea: true,
304
- title: true,
305
- video: true,
306
- wbr: true,
307
- embed: true,
308
- frame: true,
309
- keygen: true,
310
- option: true,
311
- };
312
- function notSupportTextNode(tag) {
313
- 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;
314
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;
315
315
 
316
+ exports.Fragment = Fragment;
317
+ exports.Ref = Ref;
318
+ exports.createElement = h;
316
319
  exports.h = h;
320
+ exports.jsx = jsx;
321
+ exports.jsxDEV = jsxDEV;
322
+ exports.jsxs = jsxs;
317
323
  exports.ktnull = ktnull;
318
- exports.notSupportTextNode = notSupportTextNode;
324
+ exports.ref = ref;
319
325
 
320
326
  return exports;
321
327
 
@@ -186,19 +186,24 @@ var __ktjs_core__ = (function (exports) {
186
186
  }
187
187
  }
188
188
 
189
- function applyContent(element, content) {
190
- console.log('applyContent', content);
191
- if (typeof content === 'function') {
192
- content = content();
189
+ var noop = function () { return ({}); };
190
+ var Ref = /** @class */ (function () {
191
+ function Ref(value) {
192
+ this.value = value;
193
+ this.update = noop;
193
194
  }
195
+ return Ref;
196
+ }());
197
+ function ref(value) {
198
+ return new Ref(value);
199
+ }
200
+
201
+ function applyContent(element, content) {
194
202
  if ($isArray(content)) {
195
203
  for (var i = 0; i < content.length; i++) {
196
204
  var c = content[i];
197
- if (typeof c === 'function') {
198
- c = c();
199
- }
200
- else if (typeof c === 'number') {
201
- $append.call(element, c.toString());
205
+ if (c instanceof Ref) {
206
+ $append.call(element, c.value);
202
207
  }
203
208
  else {
204
209
  $append.call(element, c);
@@ -206,8 +211,8 @@ var __ktjs_core__ = (function (exports) {
206
211
  }
207
212
  }
208
213
  else {
209
- if (typeof content === 'number') {
210
- $append.call(element, content.toString());
214
+ if (content instanceof Ref) {
215
+ $append.call(element, content.value);
211
216
  }
212
217
  else {
213
218
  $append.call(element, content);
@@ -225,11 +230,11 @@ var __ktjs_core__ = (function (exports) {
225
230
  * ## About
226
231
  * @package @ktjs/core
227
232
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
228
- * @version 0.7.3 (Last Update: 2025.12.25 09:51:02.157)
233
+ * @version 0.8.1 (Last Update: 2025.12.25 11:07:30.486)
229
234
  * @license MIT
230
235
  * @link https://github.com/baendlorel/kt.js
231
236
  * @link https://baendlorel.github.io/ Welcome to my site!
232
- * @description Core functionality for kt.js - DOM manipulation utilities
237
+ * @description Core functionality for kt.js - DOM manipulation utilities with JSX/TSX support
233
238
  * @copyright Copyright (c) 2025 Kasukabe Tsumugi. All rights reserved.
234
239
  */
235
240
  var h = function (tag, attr, content) {
@@ -247,88 +252,125 @@ var __ktjs_core__ = (function (exports) {
247
252
  };
248
253
  $mark(h, 'h');
249
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
+
250
287
  /**
251
- * # Specialized Ehancement
252
- *
253
- * Different elements should be enhanced in different ways. For example, we should have `kvalue` to handle `<input>` values.
254
- * While we have no need to have `ktext` for `<br>` tags.
255
- *
256
- * ## Tags where appending a text node has no effect
257
- *
258
- * There are some HTML elements that appending a text node as their child takes no effect.
259
- * They are mostly void elements, but some non-void elements are also included.
260
- *
261
- * ## What means no effect
262
- * 1. appending a text node to these tags takes no effect.
263
- * 2. No effect means `innerText` does not include the text in the text node.
264
- *
265
- * After testing 15 browsers testing, I found that these elements are:
266
- *
267
- * - FireFox(as base):
268
- * - script -- this is skipped due to some bugs in The World 7
269
- * - 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
270
- * - 360: embed
271
- * - 2345: embed
272
- * - maxthon: embed
273
- * - quark: embed
274
- * - uc: embed
275
- * - chrome: embed,frame
276
- * - qq: embed
277
- * - sogou: embed
278
- * - cent: embed
279
- * - world: embed,frame,keygen,option
280
- * - opera: embed
281
- * - edge: embed
282
- * - liebao: embed
283
- * - 360turbo: embed,frame
284
- *
285
- * Since `Set.prototype.has` is about 80 times faster than `Array.prototype.includes`,
286
- * We put these tags into a `Set` object.
288
+ * @param tag html tag
289
+ * @param props properties/attributes
290
+ * @param _metadata metadata is ignored
287
291
  */
288
- var INVALID_TAGS = {
289
- area: true,
290
- audio: true,
291
- base: true,
292
- basefont: true,
293
- br: true,
294
- canvas: true,
295
- datalist: true,
296
- details: true,
297
- dialog: true,
298
- frameset: true,
299
- head: true,
300
- iframe: true,
301
- img: true,
302
- input: true,
303
- link: true,
304
- meta: true,
305
- meter: true,
306
- noembed: true,
307
- noframes: true,
308
- noscript: true,
309
- optgroup: true,
310
- param: true,
311
- progress: true,
312
- rp: true,
313
- select: true,
314
- style: true,
315
- template: true,
316
- textarea: true,
317
- title: true,
318
- video: true,
319
- wbr: true,
320
- embed: true,
321
- frame: true,
322
- keygen: true,
323
- option: true,
324
- };
325
- function notSupportTextNode(tag) {
326
- 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;
327
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;
328
364
 
365
+ exports.Fragment = Fragment;
366
+ exports.Ref = Ref;
367
+ exports.createElement = h;
329
368
  exports.h = h;
369
+ exports.jsx = jsx;
370
+ exports.jsxDEV = jsxDEV;
371
+ exports.jsxs = jsxs;
330
372
  exports.ktnull = ktnull;
331
- exports.notSupportTextNode = notSupportTextNode;
373
+ exports.ref = ref;
332
374
 
333
375
  return exports;
334
376