@ktjs/core 0.13.0 → 0.14.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
@@ -16,6 +16,33 @@ interface KTRef<T> {
16
16
  */
17
17
  declare function ref<T = HTMLElement>(value?: T): KTRef<T>;
18
18
 
19
+ type KTHTMLElement = HTMLElement & {
20
+ /**
21
+ * Automically generate a redraw function if it is not provided
22
+ * @param props
23
+ */
24
+ redraw: (props?: KTAttribute, children?: KTRawContent) => void;
25
+ };
26
+
27
+ declare global {
28
+ namespace JSX {
29
+ type Element = KTHTMLElement;
30
+
31
+ interface IntrinsicElements {
32
+ [tag: string]: KTAttribute & { children?: KTRawContent };
33
+ }
34
+
35
+ // interface IntrinsicAttributes {
36
+ // key?: string | number;
37
+ // }
38
+ type IntrinsicAttributes = KTAttribute;
39
+
40
+ interface ElementChildrenAttribute {
41
+ children: {};
42
+ }
43
+ }
44
+ }
45
+
19
46
  type KTAvailableContent =
20
47
  | KTRef<any>
21
48
  | HTMLElement
@@ -42,6 +69,7 @@ interface KTBaseAttribute {
42
69
  [k: string]: any;
43
70
 
44
71
  ref?: KTRef<HTMLElement>;
72
+ 'k-if'?: any;
45
73
 
46
74
  id?: string;
47
75
  class?: string;
@@ -98,15 +126,25 @@ type KTPrefixedEventHandlers = {
98
126
  [EventName in keyof HTMLElementEventMap as `on:${EventName}`]?: (ev: HTMLElementEventMap[EventName]) => void;
99
127
  };
100
128
 
101
- type KTAttribute = KTBaseAttribute & KTPrefixedEventHandlers;
129
+ type KTSpecialEventHandlers = {
130
+ 'on:ktchange'?: (value: string) => void;
131
+ 'ontrim:ktchange'?: (value: string) => void;
132
+ 'on:ktchangenumber'?: (value: number) => void;
133
+
134
+ 'on:ktinput'?: (value: string) => void;
135
+ 'ontrim:ktinput'?: (value: string) => void;
136
+ 'on:ktinputnumber'?: (value: number) => void;
137
+ };
138
+
139
+ type KTAttribute = KTBaseAttribute & KTPrefixedEventHandlers & KTSpecialEventHandlers;
102
140
 
103
141
  type KTComponent = (
104
142
  props: {
105
- ref?: KTRef<HTMLElement>;
143
+ ref?: KTRef<KTHTMLElement>;
106
144
  children?: KTRawContent;
107
145
  } & KTAttribute &
108
146
  any
109
- ) => HTMLElement | Promise<HTMLElement>;
147
+ ) => KTHTMLElement | Promise<KTHTMLElement> | any;
110
148
 
111
149
  type HTML<T extends HTMLTag & otherstring> = T extends HTMLTag ? HTMLElementTagNameMap[T] : HTMLElement;
112
150
  type H = (<T extends HTMLTag>(tag: T, attr?: KTRawAttr, content?: KTRawContent) => HTML<T>) & {
@@ -123,7 +161,7 @@ type H = (<T extends HTMLTag>(tag: T, attr?: KTRawAttr, content?: KTRawContent)
123
161
  * ## About
124
162
  * @package @ktjs/core
125
163
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
126
- * @version 0.13.0 (Last Update: 2026.01.15 16:05:51.084)
164
+ * @version 0.14.0 (Last Update: 2026.01.16 20:08:50.505)
127
165
  * @license MIT
128
166
  * @link https://github.com/baendlorel/kt.js
129
167
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -132,33 +170,6 @@ type H = (<T extends HTMLTag>(tag: T, attr?: KTRawAttr, content?: KTRawContent)
132
170
  */
133
171
  declare const h: H;
134
172
 
135
- type KTHTMLElement = HTMLElement & {
136
- /**
137
- * Automically generate a redraw function if it is not provided
138
- * @param props
139
- */
140
- redraw: (props?: KTAttribute, children?: KTRawContent) => void;
141
- };
142
-
143
- declare global {
144
- namespace JSX {
145
- type Element = KTHTMLElement;
146
-
147
- interface IntrinsicElements {
148
- [tag: string]: KTAttribute & { children?: KTRawContent };
149
- }
150
-
151
- // interface IntrinsicAttributes {
152
- // key?: string | number;
153
- // }
154
- type IntrinsicAttributes = KTAttribute;
155
-
156
- interface ElementChildrenAttribute {
157
- children: {};
158
- }
159
- }
160
- }
161
-
162
173
  type JSXTag = HTMLTag | ((props?: any) => HTMLElement) | ((props?: any) => Promise<HTMLElement>) | ((props?: any) => KTHTMLElement) | ((props?: any) => Promise<KTHTMLElement>);
163
174
  /**
164
175
  * @param tag html tag or function component
@@ -187,11 +198,11 @@ declare const jsxs: typeof jsx;
187
198
  */
188
199
  type ExtractComponentProps<T> = T extends (props: infer P) => any ? Omit<P, 'ref' | 'children'> : {};
189
200
  declare function KTAsync<T extends KTComponent>(props: {
190
- ref?: KTRef<HTMLElement>;
191
- skeleton?: HTMLElement;
201
+ ref?: KTRef<KTHTMLElement>;
202
+ skeleton?: KTHTMLElement;
192
203
  component: T;
193
204
  children?: KTRawContent;
194
- } & ExtractComponentProps<T>): HTMLElement;
205
+ } & ExtractComponentProps<T>): KTHTMLElement;
195
206
 
196
207
  export { Fragment, KTAsync, h as createElement, h, jsx, jsxDEV, jsxs, ref };
197
208
  export type { EventHandler, HTMLTag, KTAttribute, KTHTMLElement, KTRawAttr, KTRawContent, KTRawContents, KTRef };
@@ -5,68 +5,22 @@ var __ktjs_core__ = (function (exports) {
5
5
  throw new Error('kt.js: ' + message);
6
6
  };
7
7
 
8
- /**
9
- * & Remove `bind` because it is shockingly slower than wrapper
10
- * & `window.document` is safe because it is not configurable and its setter is undefined
11
- */
12
- const $appendChild = HTMLElement.prototype.appendChild;
13
- const originAppend = HTMLElement.prototype.append;
14
- const $append = // for ie 9/10/11
15
- typeof originAppend === 'function'
16
- ? function (...args) {
17
- return originAppend.apply(this, args);
18
- }
19
- : function (...nodes) {
20
- if (nodes.length < 50) {
21
- for (let i = 0; i < nodes.length; i++) {
22
- const node = nodes[i];
23
- if (typeof node === 'string') {
24
- $appendChild.call(this, document.createTextNode(node));
25
- }
26
- else {
27
- $appendChild.call(this, node);
28
- }
29
- }
30
- }
31
- else {
32
- const fragment = document.createDocumentFragment();
33
- for (let i = 0; i < nodes.length; i++) {
34
- const node = nodes[i];
35
- if (typeof node === 'string') {
36
- $appendChild.call(fragment, document.createTextNode(node));
37
- }
38
- else {
39
- $appendChild.call(fragment, node);
40
- }
41
- }
42
- $appendChild.call(this, fragment);
43
- }
44
- };
45
-
46
- const $isArray = Array.isArray;
47
- const $keys = Object.keys;
48
- const emptyPromiseHandler = () => ({});
49
- if (typeof Promise === 'undefined') {
50
- window.Promise = { resolve: emptyPromiseHandler, reject: emptyPromiseHandler };
51
- }
52
- const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
53
-
54
- function booleanHandler(element, key, value) {
8
+ const booleanHandler = (element, key, value) => {
55
9
  if (key in element) {
56
10
  element[key] = !!value;
57
11
  }
58
12
  else {
59
13
  element.setAttribute(key, value);
60
14
  }
61
- }
62
- function valueHandler(element, key, value) {
15
+ };
16
+ const valueHandler = (element, key, value) => {
63
17
  if (key in element) {
64
18
  element[key] = value;
65
19
  }
66
20
  else {
67
21
  element.setAttribute(key, value);
68
22
  }
69
- }
23
+ };
70
24
  // Attribute handlers map for optimized lookup
71
25
  const handlers = {
72
26
  checked: booleanHandler,
@@ -89,14 +43,25 @@ var __ktjs_core__ = (function (exports) {
89
43
  muted: booleanHandler,
90
44
  defer: booleanHandler,
91
45
  async: booleanHandler,
92
- hidden: function (element, _key, value) {
93
- element.hidden = !!value;
94
- },
46
+ hidden: (element, _key, value) => (element.hidden = !!value),
95
47
  };
96
- const defaultHandler = function (element, key, value) {
97
- return element.setAttribute(key, value);
48
+ const ktEventHandlers = {
49
+ 'on:ktchange': (element, handler) => element.addEventListener('change', () => handler(element.value)),
50
+ 'ontrim:ktchange': (element, handler) => element.addEventListener('change', () => handler(element.value.trim())),
51
+ 'on:ktchangenumber': (element, handler) => element.addEventListener('change', () => handler(Number(element.value))),
52
+ 'on:ktinput': (element, handler) => element.addEventListener('input', () => handler(element.value)),
53
+ 'ontrim:ktinput': (element, handler) => element.addEventListener('input', () => handler(element.value.trim())),
54
+ 'on:ktinputnumber': (element, handler) => element.addEventListener('input', () => handler(Number(element.value))),
98
55
  };
56
+
57
+ const defaultHandler = (element, key, value) => element.setAttribute(key, value);
99
58
  function attrIsObject(element, attr) {
59
+ // & deal k-if first
60
+ if ('k-if' in attr) {
61
+ if (!attr['k-if']) {
62
+ return false;
63
+ }
64
+ }
100
65
  const classValue = attr.class;
101
66
  const style = attr.style;
102
67
  if (classValue !== undefined) {
@@ -114,12 +79,17 @@ var __ktjs_core__ = (function (exports) {
114
79
  }
115
80
  delete attr.style;
116
81
  }
117
- const keys = $keys(attr);
118
- for (let i = keys.length - 1; i >= 0; i--) {
119
- const key = keys[i];
82
+ for (const key in attr) {
120
83
  const o = attr[key];
121
84
  // force register on:xxx as an event handler
122
85
  // !if o is not valid, the throwing job will be done by `on`, not kt.js
86
+ // # special handling for kt.js specific events
87
+ const ktEvent = ktEventHandlers[key];
88
+ if (ktEvent) {
89
+ ktEvent(element, o);
90
+ continue;
91
+ }
92
+ // # normal event handler
123
93
  if (key.startsWith('on:')) {
124
94
  element.addEventListener(key.slice(3), o); // chop off the `@`
125
95
  continue;
@@ -137,19 +107,66 @@ var __ktjs_core__ = (function (exports) {
137
107
  if (style !== undefined) {
138
108
  attr.style = style;
139
109
  }
110
+ return true;
140
111
  }
141
112
  function applyAttr(element, attr) {
142
113
  if (typeof attr === 'string') {
143
114
  element.className = attr;
115
+ return true;
144
116
  }
145
117
  else if (typeof attr === 'object' && attr !== null) {
146
- attrIsObject(element, attr);
118
+ return attrIsObject(element, attr);
147
119
  }
148
120
  else {
149
- $throw('attr must be an object/string.');
121
+ throw new Error('kt.js: attr must be an object/string.');
150
122
  }
151
123
  }
152
124
 
125
+ /**
126
+ * & Remove `bind` because it is shockingly slower than wrapper
127
+ * & `window.document` is safe because it is not configurable and its setter is undefined
128
+ */
129
+ const $appendChild = HTMLElement.prototype.appendChild;
130
+ const originAppend = HTMLElement.prototype.append;
131
+ const $append = // for ie 9/10/11
132
+ typeof originAppend === 'function'
133
+ ? function (...args) {
134
+ return originAppend.apply(this, args);
135
+ }
136
+ : function (...nodes) {
137
+ if (nodes.length < 50) {
138
+ for (let i = 0; i < nodes.length; i++) {
139
+ const node = nodes[i];
140
+ if (typeof node === 'string') {
141
+ $appendChild.call(this, document.createTextNode(node));
142
+ }
143
+ else {
144
+ $appendChild.call(this, node);
145
+ }
146
+ }
147
+ }
148
+ else {
149
+ const fragment = document.createDocumentFragment();
150
+ for (let i = 0; i < nodes.length; i++) {
151
+ const node = nodes[i];
152
+ if (typeof node === 'string') {
153
+ $appendChild.call(fragment, document.createTextNode(node));
154
+ }
155
+ else {
156
+ $appendChild.call(fragment, node);
157
+ }
158
+ }
159
+ $appendChild.call(this, fragment);
160
+ }
161
+ };
162
+
163
+ const $isArray = Array.isArray;
164
+ const emptyPromiseHandler = () => ({});
165
+ if (typeof Promise === 'undefined') {
166
+ window.Promise = { resolve: emptyPromiseHandler, reject: emptyPromiseHandler };
167
+ }
168
+ const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
169
+
153
170
  function apdSingle(element, c) {
154
171
  // & JSX should ignore false, undefined, and null
155
172
  if (c === false || c === undefined || c === null) {
@@ -206,7 +223,7 @@ var __ktjs_core__ = (function (exports) {
206
223
  * ## About
207
224
  * @package @ktjs/core
208
225
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
209
- * @version 0.13.0 (Last Update: 2026.01.15 16:05:51.084)
226
+ * @version 0.14.0 (Last Update: 2026.01.16 20:08:50.505)
210
227
  * @license MIT
211
228
  * @link https://github.com/baendlorel/kt.js
212
229
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -220,7 +237,10 @@ var __ktjs_core__ = (function (exports) {
220
237
  // * start creating the element
221
238
  const element = document.createElement(tag);
222
239
  // * Handle content
223
- applyAttr(element, attr);
240
+ const kif = applyAttr(element, attr);
241
+ if (!kif) {
242
+ return document.createComment('k-if');
243
+ }
224
244
  applyContent(element, content);
225
245
  return element;
226
246
  });
@@ -5,78 +5,22 @@ var __ktjs_core__ = (function (exports) {
5
5
  throw new Error('kt.js: ' + message);
6
6
  };
7
7
 
8
- /**
9
- * & Remove `bind` because it is shockingly slower than wrapper
10
- * & `window.document` is safe because it is not configurable and its setter is undefined
11
- */
12
- var $appendChild = HTMLElement.prototype.appendChild;
13
- var originAppend = HTMLElement.prototype.append;
14
- var $append = // for ie 9/10/11
15
- typeof originAppend === 'function'
16
- ? function () {
17
- var args = [];
18
- for (var _i = 0; _i < arguments.length; _i++) {
19
- args[_i] = arguments[_i];
20
- }
21
- return originAppend.apply(this, args);
22
- }
23
- : function () {
24
- var nodes = [];
25
- for (var _i = 0; _i < arguments.length; _i++) {
26
- nodes[_i] = arguments[_i];
27
- }
28
- if (nodes.length < 50) {
29
- for (var i = 0; i < nodes.length; i++) {
30
- var node = nodes[i];
31
- if (typeof node === 'string') {
32
- $appendChild.call(this, document.createTextNode(node));
33
- }
34
- else {
35
- $appendChild.call(this, node);
36
- }
37
- }
38
- }
39
- else {
40
- var fragment = document.createDocumentFragment();
41
- for (var i = 0; i < nodes.length; i++) {
42
- var node = nodes[i];
43
- if (typeof node === 'string') {
44
- $appendChild.call(fragment, document.createTextNode(node));
45
- }
46
- else {
47
- $appendChild.call(fragment, node);
48
- }
49
- }
50
- $appendChild.call(this, fragment);
51
- }
52
- };
53
-
54
- var $isArray = Array.isArray;
55
- var $keys = Object.keys;
56
- var emptyPromiseHandler = function () { return ({}); };
57
- if (typeof Promise === 'undefined') {
58
- window.Promise = { resolve: emptyPromiseHandler, reject: emptyPromiseHandler };
59
- }
60
- var $isThenable = function (o) {
61
- return typeof o === 'object' && o !== null && typeof o.then === 'function';
62
- };
63
-
64
- function booleanHandler(element, key, value) {
8
+ var booleanHandler = function (element, key, value) {
65
9
  if (key in element) {
66
10
  element[key] = !!value;
67
11
  }
68
12
  else {
69
13
  element.setAttribute(key, value);
70
14
  }
71
- }
72
- function valueHandler(element, key, value) {
15
+ };
16
+ var valueHandler = function (element, key, value) {
73
17
  if (key in element) {
74
18
  element[key] = value;
75
19
  }
76
20
  else {
77
21
  element.setAttribute(key, value);
78
22
  }
79
- }
23
+ };
80
24
  // Attribute handlers map for optimized lookup
81
25
  var handlers = {
82
26
  checked: booleanHandler,
@@ -99,14 +43,37 @@ var __ktjs_core__ = (function (exports) {
99
43
  muted: booleanHandler,
100
44
  defer: booleanHandler,
101
45
  async: booleanHandler,
102
- hidden: function (element, _key, value) {
103
- element.hidden = !!value;
104
- },
46
+ hidden: function (element, _key, value) { return (element.hidden = !!value); },
105
47
  };
106
- var defaultHandler = function (element, key, value) {
107
- return element.setAttribute(key, value);
48
+ var ktEventHandlers = {
49
+ 'on:ktchange': function (element, handler) {
50
+ return element.addEventListener('change', function () { return handler(element.value); });
51
+ },
52
+ 'ontrim:ktchange': function (element, handler) {
53
+ return element.addEventListener('change', function () { return handler(element.value.trim()); });
54
+ },
55
+ 'on:ktchangenumber': function (element, handler) {
56
+ return element.addEventListener('change', function () { return handler(Number(element.value)); });
57
+ },
58
+ 'on:ktinput': function (element, handler) {
59
+ return element.addEventListener('input', function () { return handler(element.value); });
60
+ },
61
+ 'ontrim:ktinput': function (element, handler) {
62
+ return element.addEventListener('input', function () { return handler(element.value.trim()); });
63
+ },
64
+ 'on:ktinputnumber': function (element, handler) {
65
+ return element.addEventListener('input', function () { return handler(Number(element.value)); });
66
+ },
108
67
  };
68
+
69
+ var defaultHandler = function (element, key, value) { return element.setAttribute(key, value); };
109
70
  function attrIsObject(element, attr) {
71
+ // & deal k-if first
72
+ if ('k-if' in attr) {
73
+ if (!attr['k-if']) {
74
+ return false;
75
+ }
76
+ }
110
77
  var classValue = attr.class;
111
78
  var style = attr.style;
112
79
  if (classValue !== undefined) {
@@ -124,12 +91,17 @@ var __ktjs_core__ = (function (exports) {
124
91
  }
125
92
  delete attr.style;
126
93
  }
127
- var keys = $keys(attr);
128
- for (var i = keys.length - 1; i >= 0; i--) {
129
- var key = keys[i];
94
+ for (var key in attr) {
130
95
  var o = attr[key];
131
96
  // force register on:xxx as an event handler
132
97
  // !if o is not valid, the throwing job will be done by `on`, not kt.js
98
+ // # special handling for kt.js specific events
99
+ var ktEvent = ktEventHandlers[key];
100
+ if (ktEvent) {
101
+ ktEvent(element, o);
102
+ continue;
103
+ }
104
+ // # normal event handler
133
105
  if (key.startsWith('on:')) {
134
106
  element.addEventListener(key.slice(3), o); // chop off the `@`
135
107
  continue;
@@ -147,19 +119,76 @@ var __ktjs_core__ = (function (exports) {
147
119
  if (style !== undefined) {
148
120
  attr.style = style;
149
121
  }
122
+ return true;
150
123
  }
151
124
  function applyAttr(element, attr) {
152
125
  if (typeof attr === 'string') {
153
126
  element.className = attr;
127
+ return true;
154
128
  }
155
129
  else if (typeof attr === 'object' && attr !== null) {
156
- attrIsObject(element, attr);
130
+ return attrIsObject(element, attr);
157
131
  }
158
132
  else {
159
- $throw('attr must be an object/string.');
133
+ throw new Error('kt.js: attr must be an object/string.');
160
134
  }
161
135
  }
162
136
 
137
+ /**
138
+ * & Remove `bind` because it is shockingly slower than wrapper
139
+ * & `window.document` is safe because it is not configurable and its setter is undefined
140
+ */
141
+ var $appendChild = HTMLElement.prototype.appendChild;
142
+ var originAppend = HTMLElement.prototype.append;
143
+ var $append = // for ie 9/10/11
144
+ typeof originAppend === 'function'
145
+ ? function () {
146
+ var args = [];
147
+ for (var _i = 0; _i < arguments.length; _i++) {
148
+ args[_i] = arguments[_i];
149
+ }
150
+ return originAppend.apply(this, args);
151
+ }
152
+ : function () {
153
+ var nodes = [];
154
+ for (var _i = 0; _i < arguments.length; _i++) {
155
+ nodes[_i] = arguments[_i];
156
+ }
157
+ if (nodes.length < 50) {
158
+ for (var i = 0; i < nodes.length; i++) {
159
+ var node = nodes[i];
160
+ if (typeof node === 'string') {
161
+ $appendChild.call(this, document.createTextNode(node));
162
+ }
163
+ else {
164
+ $appendChild.call(this, node);
165
+ }
166
+ }
167
+ }
168
+ else {
169
+ var fragment = document.createDocumentFragment();
170
+ for (var i = 0; i < nodes.length; i++) {
171
+ var node = nodes[i];
172
+ if (typeof node === 'string') {
173
+ $appendChild.call(fragment, document.createTextNode(node));
174
+ }
175
+ else {
176
+ $appendChild.call(fragment, node);
177
+ }
178
+ }
179
+ $appendChild.call(this, fragment);
180
+ }
181
+ };
182
+
183
+ var $isArray = Array.isArray;
184
+ var emptyPromiseHandler = function () { return ({}); };
185
+ if (typeof Promise === 'undefined') {
186
+ window.Promise = { resolve: emptyPromiseHandler, reject: emptyPromiseHandler };
187
+ }
188
+ var $isThenable = function (o) {
189
+ return typeof o === 'object' && o !== null && typeof o.then === 'function';
190
+ };
191
+
163
192
  function apdSingle(element, c) {
164
193
  // & JSX should ignore false, undefined, and null
165
194
  if (c === false || c === undefined || c === null) {
@@ -219,7 +248,7 @@ var __ktjs_core__ = (function (exports) {
219
248
  * ## About
220
249
  * @package @ktjs/core
221
250
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
222
- * @version 0.13.0 (Last Update: 2026.01.15 16:05:51.084)
251
+ * @version 0.14.0 (Last Update: 2026.01.16 20:08:50.505)
223
252
  * @license MIT
224
253
  * @link https://github.com/baendlorel/kt.js
225
254
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -235,7 +264,10 @@ var __ktjs_core__ = (function (exports) {
235
264
  // * start creating the element
236
265
  var element = document.createElement(tag);
237
266
  // * Handle content
238
- applyAttr(element, attr);
267
+ var kif = applyAttr(element, attr);
268
+ if (!kif) {
269
+ return document.createComment('k-if');
270
+ }
239
271
  applyContent(element, content);
240
272
  return element;
241
273
  });