@ktjs/core 0.14.6 → 0.15.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/README.md +74 -5
- package/dist/index.d.ts +22 -7
- package/dist/index.iife.js +77 -88
- package/dist/index.legacy.js +78 -89
- package/dist/index.mjs +77 -89
- package/dist/jsx/index.d.ts +22 -7
- package/dist/jsx/index.mjs +77 -89
- package/dist/jsx/jsx-runtime.d.ts +22 -7
- package/dist/jsx/jsx-runtime.mjs +79 -82
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Core DOM manipulation utilities for KT.js framework with built-in JSX/TSX suppor
|
|
|
12
12
|
|
|
13
13
|
`@ktjs/core` is the foundation of KT.js, providing the essential `h` function and DOM utilities for building web applications with direct DOM manipulation. It emphasizes performance, type safety, and minimal abstraction over native DOM APIs.
|
|
14
14
|
|
|
15
|
-
**Current Version:** 0.
|
|
15
|
+
**Current Version:** 0.14.6
|
|
16
16
|
|
|
17
17
|
## Features
|
|
18
18
|
|
|
@@ -25,7 +25,9 @@ Core DOM manipulation utilities for KT.js framework with built-in JSX/TSX suppor
|
|
|
25
25
|
- Zero virtual DOM - JSX compiles directly to `h()` function calls
|
|
26
26
|
- Full HTML element type inference (`<button>` returns `HTMLButtonElement`)
|
|
27
27
|
- Support for function components
|
|
28
|
-
-
|
|
28
|
+
- `redraw()` method for controlled re-rendering
|
|
29
|
+
- **k-if directive**: Conditional element creation with `k-if` attribute
|
|
30
|
+
- Array children support for seamless list rendering
|
|
29
31
|
- **KTAsync Component**: Handle async components with ease
|
|
30
32
|
- Automatic handling of Promise-based components
|
|
31
33
|
- Seamless integration with JSX/TSX
|
|
@@ -87,7 +89,7 @@ const button1 = h(
|
|
|
87
89
|
{
|
|
88
90
|
'on:click': () => alert('Clicked!'),
|
|
89
91
|
},
|
|
90
|
-
'Button 1'
|
|
92
|
+
'Button 1',
|
|
91
93
|
);
|
|
92
94
|
|
|
93
95
|
// Function attribute (also treated as event listener)
|
|
@@ -97,7 +99,7 @@ const button2 = h(
|
|
|
97
99
|
click: (e) => console.log('Event:', e),
|
|
98
100
|
'data-id': '123', // Regular attribute
|
|
99
101
|
},
|
|
100
|
-
'Button 2'
|
|
102
|
+
'Button 2',
|
|
101
103
|
);
|
|
102
104
|
|
|
103
105
|
// Both regular and event handler for same name
|
|
@@ -136,9 +138,43 @@ const Greeting = ({ name }: { name: string }) => (
|
|
|
136
138
|
const app = <Greeting name="World" />;
|
|
137
139
|
```
|
|
138
140
|
|
|
141
|
+
### Conditional Rendering with k-if (v0.14.6+)
|
|
142
|
+
|
|
143
|
+
The `k-if` directive allows conditional element creation:
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { h } from '@ktjs/core';
|
|
147
|
+
|
|
148
|
+
// Element will only be created if condition is true
|
|
149
|
+
const isVisible = true;
|
|
150
|
+
const element = <div k-if={isVisible}>This will be rendered</div>;
|
|
151
|
+
|
|
152
|
+
// Element will not be created if condition is false
|
|
153
|
+
const isHidden = false;
|
|
154
|
+
const hidden = <div k-if={isHidden}>This will NOT be rendered</div>;
|
|
155
|
+
// hidden will be undefined/null
|
|
156
|
+
|
|
157
|
+
// Practical example
|
|
158
|
+
const UserProfile = ({ user, isLoggedIn }: { user: any; isLoggedIn: boolean }) => (
|
|
159
|
+
<div>
|
|
160
|
+
<h1>User Profile</h1>
|
|
161
|
+
<div k-if={isLoggedIn}>
|
|
162
|
+
<p>Welcome, {user.name}!</p>
|
|
163
|
+
<button>Logout</button>
|
|
164
|
+
</div>
|
|
165
|
+
<div k-if={!isLoggedIn}>
|
|
166
|
+
<p>Please log in to continue</p>
|
|
167
|
+
<button>Login</button>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Note**: `k-if` is evaluated **once** at element creation time. It's not reactive - if you need dynamic visibility, use CSS or manually recreate the element.
|
|
174
|
+
|
|
139
175
|
### Redraw Mechanism (v0.11+)
|
|
140
176
|
|
|
141
|
-
The
|
|
177
|
+
The `redraw()` method allows you to update components efficiently:
|
|
142
178
|
|
|
143
179
|
```tsx
|
|
144
180
|
import { h, KTHTMLElement } from '@ktjs/core';
|
|
@@ -164,6 +200,39 @@ const div = (<div>Old content</div>) as KTHTMLElement;
|
|
|
164
200
|
div.redraw(undefined, 'New content');
|
|
165
201
|
```
|
|
166
202
|
|
|
203
|
+
### Array Children Support (v0.14.1+)
|
|
204
|
+
|
|
205
|
+
Children can now be arrays for easier list rendering:
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
import { h } from '@ktjs/core';
|
|
209
|
+
|
|
210
|
+
// Map arrays directly as children
|
|
211
|
+
const items = ['Apple', 'Banana', 'Orange'];
|
|
212
|
+
const list = (
|
|
213
|
+
<ul>
|
|
214
|
+
{items.map((item) => (
|
|
215
|
+
<li>{item}</li>
|
|
216
|
+
))}
|
|
217
|
+
</ul>
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
// Mix mapped elements with other elements
|
|
221
|
+
const TodoList = ({ todos }: { todos: string[] }) => (
|
|
222
|
+
<div>
|
|
223
|
+
<h2>Todo List</h2>
|
|
224
|
+
<ul>
|
|
225
|
+
{todos.map((todo) => (
|
|
226
|
+
<li>{todo}</li>
|
|
227
|
+
))}
|
|
228
|
+
<li>
|
|
229
|
+
<button>Add More</button>
|
|
230
|
+
</li>
|
|
231
|
+
</ul>
|
|
232
|
+
</div>
|
|
233
|
+
);
|
|
234
|
+
```
|
|
235
|
+
|
|
167
236
|
### Async Components
|
|
168
237
|
|
|
169
238
|
```typescript
|
package/dist/index.d.ts
CHANGED
|
@@ -16,12 +16,12 @@ interface KTRef<T> {
|
|
|
16
16
|
*/
|
|
17
17
|
declare function ref<T = HTMLElement>(value?: T): KTRef<T>;
|
|
18
18
|
|
|
19
|
-
type KTHTMLElement = HTMLElement & {
|
|
19
|
+
type KTHTMLElement<El extends HTMLElement = HTMLElement> = El & {
|
|
20
20
|
/**
|
|
21
21
|
* Automically generate a redraw function if it is not provided
|
|
22
22
|
* @param props
|
|
23
23
|
*/
|
|
24
|
-
redraw: (props?: KTAttribute,
|
|
24
|
+
redraw: (props?: KTAttribute, ...args: any[]) => KTHTMLElement;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
declare global {
|
|
@@ -153,7 +153,7 @@ type H = (<T extends HTMLTag>(tag: T, attr?: KTRawAttr, content?: KTRawContent)
|
|
|
153
153
|
* ## About
|
|
154
154
|
* @package @ktjs/core
|
|
155
155
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
156
|
-
* @version 0.
|
|
156
|
+
* @version 0.15.1 (Last Update: 2026.01.25 13:09:33.161)
|
|
157
157
|
* @license MIT
|
|
158
158
|
* @link https://github.com/baendlorel/kt.js
|
|
159
159
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -192,14 +192,29 @@ declare const jsxs: typeof jsx;
|
|
|
192
192
|
* let aa = 10;
|
|
193
193
|
* // ...
|
|
194
194
|
* // aa might be changed
|
|
195
|
-
* return
|
|
195
|
+
* return createRedrawableNoref(() => <div>{aa}</div>);
|
|
196
196
|
* }
|
|
197
197
|
* ```
|
|
198
198
|
* Then the returned element has a `redraw` method to redraw itself with new values.
|
|
199
|
-
* @param creator
|
|
199
|
+
* @param creator a simple creator function that returns an element
|
|
200
200
|
* @returns created element
|
|
201
201
|
*/
|
|
202
|
-
declare function
|
|
202
|
+
declare function createRedrawableNoref(creator: () => KTHTMLElement): KTHTMLElement;
|
|
203
|
+
/**
|
|
204
|
+
* A helper to create redrawable elements
|
|
205
|
+
* ```tsx
|
|
206
|
+
* export function MyComponent() {
|
|
207
|
+
* let aa = 10;
|
|
208
|
+
* // ...
|
|
209
|
+
* // aa might be changed
|
|
210
|
+
* return createRedrawable(() => <div>{aa}</div>);
|
|
211
|
+
* }
|
|
212
|
+
* ```
|
|
213
|
+
* Then the returned element has a `redraw` method to redraw itself with new values.
|
|
214
|
+
* @param creator a simple creator function that returns an element
|
|
215
|
+
* @returns created element's ref
|
|
216
|
+
*/
|
|
217
|
+
declare function createRedrawable(creator: () => KTHTMLElement): KTRef<KTHTMLElement>;
|
|
203
218
|
|
|
204
219
|
/**
|
|
205
220
|
* Extract component props type (excluding ref and children)
|
|
@@ -212,5 +227,5 @@ declare function KTAsync<T extends KTComponent>(props: {
|
|
|
212
227
|
children?: KTRawContent;
|
|
213
228
|
} & ExtractComponentProps<T>): KTHTMLElement;
|
|
214
229
|
|
|
215
|
-
export { Fragment, KTAsync, h as createElement, createRedrawable, h, jsx, jsxDEV, jsxs, ref };
|
|
230
|
+
export { Fragment, KTAsync, h as createElement, createRedrawable, createRedrawableNoref, h, jsx, jsxDEV, jsxs, ref };
|
|
216
231
|
export type { EventHandler, HTMLTag, KTAttribute, KTHTMLElement, KTRawAttr, KTRawContent, KTRawContents, KTRef };
|
package/dist/index.iife.js
CHANGED
|
@@ -56,17 +56,11 @@ var __ktjs_core__ = (function (exports) {
|
|
|
56
56
|
|
|
57
57
|
const defaultHandler = (element, key, value) => element.setAttribute(key, value);
|
|
58
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
|
-
}
|
|
65
59
|
const classValue = attr.class;
|
|
66
|
-
const style = attr.style;
|
|
67
60
|
if (classValue !== undefined) {
|
|
68
61
|
element.className = classValue;
|
|
69
62
|
}
|
|
63
|
+
const style = attr.style;
|
|
70
64
|
if (style) {
|
|
71
65
|
if (typeof style === 'string') {
|
|
72
66
|
element.setAttribute('style', style);
|
|
@@ -78,39 +72,31 @@ var __ktjs_core__ = (function (exports) {
|
|
|
78
72
|
}
|
|
79
73
|
}
|
|
80
74
|
for (const key in attr) {
|
|
81
|
-
if (key === 'class' || key === 'style' || key === 'k-if') {
|
|
75
|
+
if (key === 'class' || key === 'style' || key === 'children' || key === 'k-if' || key === 'ref') {
|
|
82
76
|
continue;
|
|
83
77
|
}
|
|
84
78
|
const o = attr[key];
|
|
85
|
-
// force register on:xxx as an event handler
|
|
86
|
-
// !if o is not valid, the throwing job will be done by `on`, not kt.js
|
|
87
79
|
// # special handling for kt.js specific events
|
|
88
80
|
const ktEvent = ktEventHandlers[key];
|
|
89
81
|
if (ktEvent) {
|
|
90
82
|
ktEvent(element, o);
|
|
91
|
-
continue;
|
|
92
83
|
}
|
|
93
|
-
//
|
|
94
|
-
if (key.startsWith('on:')) {
|
|
84
|
+
// normal event handler
|
|
85
|
+
else if (key.startsWith('on:')) {
|
|
95
86
|
element.addEventListener(key.slice(3), o); // chop off the `@`
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
if (typeof o === 'function') {
|
|
99
|
-
(handlers[key] || defaultHandler)(element, key, o());
|
|
100
87
|
}
|
|
88
|
+
// normal attributes
|
|
101
89
|
else {
|
|
102
90
|
(handlers[key] || defaultHandler)(element, key, o);
|
|
103
91
|
}
|
|
104
92
|
}
|
|
105
|
-
return true;
|
|
106
93
|
}
|
|
107
94
|
function applyAttr(element, attr) {
|
|
108
|
-
if (typeof attr === '
|
|
109
|
-
element
|
|
110
|
-
return true;
|
|
95
|
+
if (typeof attr === 'object' && attr !== null) {
|
|
96
|
+
attrIsObject(element, attr);
|
|
111
97
|
}
|
|
112
|
-
else if (typeof attr === '
|
|
113
|
-
|
|
98
|
+
else if (typeof attr === 'string') {
|
|
99
|
+
element.className = attr;
|
|
114
100
|
}
|
|
115
101
|
else {
|
|
116
102
|
throw new Error('kt.js: attr must be an object/string.');
|
|
@@ -218,7 +204,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
218
204
|
* ## About
|
|
219
205
|
* @package @ktjs/core
|
|
220
206
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
221
|
-
* @version 0.
|
|
207
|
+
* @version 0.15.1 (Last Update: 2026.01.25 13:09:33.161)
|
|
222
208
|
* @license MIT
|
|
223
209
|
* @link https://github.com/baendlorel/kt.js
|
|
224
210
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -232,68 +218,52 @@ var __ktjs_core__ = (function (exports) {
|
|
|
232
218
|
// * start creating the element
|
|
233
219
|
const element = document.createElement(tag);
|
|
234
220
|
// * Handle content
|
|
235
|
-
|
|
236
|
-
if (!kif) {
|
|
237
|
-
return document.createComment('k-if');
|
|
238
|
-
}
|
|
221
|
+
applyAttr(element, attr);
|
|
239
222
|
applyContent(element, content);
|
|
240
223
|
return element;
|
|
241
224
|
});
|
|
242
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Reference to the created HTML element.
|
|
228
|
+
* - can alse be used to store normal values, but it is not reactive.
|
|
229
|
+
* @param value mostly an HTMLElement
|
|
230
|
+
*/
|
|
231
|
+
function ref(value) {
|
|
232
|
+
return { value: value, isKT: true };
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const dummyRef = { value: null };
|
|
236
|
+
// todo 是否进一步削减h函数的分支,比如去掉string为attr的情况
|
|
243
237
|
/**
|
|
244
238
|
* @param tag html tag or function component
|
|
245
239
|
* @param props properties/attributes
|
|
246
240
|
*/
|
|
247
241
|
function jsx(tag, props = {}) {
|
|
248
|
-
const ref = props.ref?.isKT ? props.ref :
|
|
249
|
-
|
|
250
|
-
|
|
242
|
+
const ref = props.ref?.isKT ? props.ref : dummyRef;
|
|
243
|
+
let el;
|
|
244
|
+
const redraw = (newProps) => {
|
|
245
|
+
props = newProps ? { ...props, ...newProps } : props;
|
|
246
|
+
const old = el;
|
|
247
|
+
el = jsx(tag, props);
|
|
248
|
+
old.replaceWith(el);
|
|
249
|
+
return el;
|
|
250
|
+
};
|
|
251
|
+
if ('k-if' in props && !props['k-if']) {
|
|
252
|
+
el = document.createComment('k-if');
|
|
253
|
+
ref.value = el;
|
|
254
|
+
el.redraw = redraw;
|
|
255
|
+
return el;
|
|
251
256
|
}
|
|
252
257
|
// Handle function components
|
|
253
258
|
if (typeof tag === 'function') {
|
|
254
|
-
|
|
255
|
-
if (!el.redraw) {
|
|
256
|
-
el.redraw = (newProps) => {
|
|
257
|
-
props = newProps ? { ...props, ...newProps } : props;
|
|
258
|
-
// $ same as below
|
|
259
|
-
const old = el;
|
|
260
|
-
el = tag(props);
|
|
261
|
-
el.redraw = old.redraw; // inherit redraw
|
|
262
|
-
if (ref) {
|
|
263
|
-
ref.value = el;
|
|
264
|
-
}
|
|
265
|
-
old.replaceWith(el);
|
|
266
|
-
return el;
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
if (ref) {
|
|
270
|
-
ref.value = el;
|
|
271
|
-
}
|
|
272
|
-
return el;
|
|
259
|
+
el = tag(props);
|
|
273
260
|
}
|
|
274
261
|
else {
|
|
275
|
-
|
|
276
|
-
let children = props.children;
|
|
277
|
-
delete props.children;
|
|
278
|
-
let el = h(tag, props, children);
|
|
279
|
-
if (ref) {
|
|
280
|
-
ref.value = el;
|
|
281
|
-
}
|
|
282
|
-
el.redraw = (newProps, newChildren) => {
|
|
283
|
-
props = newProps ? { ...props, ...newProps } : props;
|
|
284
|
-
children = (newChildren ?? children);
|
|
285
|
-
// $ same as above
|
|
286
|
-
const old = el;
|
|
287
|
-
el = h(tag, props, children);
|
|
288
|
-
el.redraw = old.redraw; // inherit redraw
|
|
289
|
-
if (ref) {
|
|
290
|
-
ref.value = el;
|
|
291
|
-
}
|
|
292
|
-
old.replaceWith(el);
|
|
293
|
-
return el;
|
|
294
|
-
};
|
|
295
|
-
return el;
|
|
262
|
+
el = h(tag, props, props.children);
|
|
296
263
|
}
|
|
264
|
+
el.redraw ??= redraw;
|
|
265
|
+
ref.value = el;
|
|
266
|
+
return el;
|
|
297
267
|
}
|
|
298
268
|
/**
|
|
299
269
|
* Fragment support - returns an array of children
|
|
@@ -342,33 +312,51 @@ var __ktjs_core__ = (function (exports) {
|
|
|
342
312
|
* let aa = 10;
|
|
343
313
|
* // ...
|
|
344
314
|
* // aa might be changed
|
|
345
|
-
* return
|
|
315
|
+
* return createRedrawableNoref(() => <div>{aa}</div>);
|
|
346
316
|
* }
|
|
347
317
|
* ```
|
|
348
318
|
* Then the returned element has a `redraw` method to redraw itself with new values.
|
|
349
|
-
* @param creator
|
|
319
|
+
* @param creator a simple creator function that returns an element
|
|
350
320
|
* @returns created element
|
|
351
321
|
*/
|
|
352
|
-
function
|
|
353
|
-
let
|
|
322
|
+
function createRedrawableNoref(creator) {
|
|
323
|
+
let el = creator();
|
|
354
324
|
const redraw = () => {
|
|
355
|
-
const old =
|
|
356
|
-
|
|
357
|
-
old.replaceWith(
|
|
358
|
-
|
|
359
|
-
return
|
|
325
|
+
const old = el;
|
|
326
|
+
el = creator();
|
|
327
|
+
old.replaceWith(el);
|
|
328
|
+
el.redraw = redraw;
|
|
329
|
+
return el;
|
|
360
330
|
};
|
|
361
|
-
|
|
362
|
-
return
|
|
331
|
+
el.redraw = redraw;
|
|
332
|
+
return el;
|
|
363
333
|
}
|
|
364
|
-
|
|
365
334
|
/**
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
335
|
+
* A helper to create redrawable elements
|
|
336
|
+
* ```tsx
|
|
337
|
+
* export function MyComponent() {
|
|
338
|
+
* let aa = 10;
|
|
339
|
+
* // ...
|
|
340
|
+
* // aa might be changed
|
|
341
|
+
* return createRedrawable(() => <div>{aa}</div>);
|
|
342
|
+
* }
|
|
343
|
+
* ```
|
|
344
|
+
* Then the returned element has a `redraw` method to redraw itself with new values.
|
|
345
|
+
* @param creator a simple creator function that returns an element
|
|
346
|
+
* @returns created element's ref
|
|
369
347
|
*/
|
|
370
|
-
function
|
|
371
|
-
|
|
348
|
+
function createRedrawable(creator) {
|
|
349
|
+
const elRef = ref();
|
|
350
|
+
elRef.value = creator();
|
|
351
|
+
const redraw = () => {
|
|
352
|
+
const old = elRef.value;
|
|
353
|
+
elRef.value = creator();
|
|
354
|
+
old.replaceWith(elRef.value);
|
|
355
|
+
elRef.value.redraw = redraw;
|
|
356
|
+
return elRef.value;
|
|
357
|
+
};
|
|
358
|
+
elRef.value.redraw = redraw;
|
|
359
|
+
return elRef;
|
|
372
360
|
}
|
|
373
361
|
|
|
374
362
|
function KTAsync(props) {
|
|
@@ -387,6 +375,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
387
375
|
exports.KTAsync = KTAsync;
|
|
388
376
|
exports.createElement = h;
|
|
389
377
|
exports.createRedrawable = createRedrawable;
|
|
378
|
+
exports.createRedrawableNoref = createRedrawableNoref;
|
|
390
379
|
exports.h = h;
|
|
391
380
|
exports.jsx = jsx;
|
|
392
381
|
exports.jsxDEV = jsxDEV;
|