kt.js 0.0.9 → 0.1.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 +28 -54
- package/dist/index.d.ts +43 -231
- package/dist/index.mjs +1 -1
- package/package.json +7 -11
- package/README.zh.md +0 -103
package/README.md
CHANGED
|
@@ -1,62 +1,60 @@
|
|
|
1
1
|
# KT.js
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/kt.js)
|
|
4
|
+
|
|
3
5
|
[](https://github.com/baendlorel/kt.js/blob/main/LICENSE)
|
|
4
6
|
|
|
5
|
-
[
|
|
7
|
+
[CHANGLOG✨](CHANGELOG.md)
|
|
6
8
|
|
|
7
9
|
> Note: This framework is still under development. APIs, type declarations, and other parts **may change frequently**. If you use it, please watch for updates in the near future. Feel free to mail me if you have any questions!
|
|
8
10
|
|
|
9
|
-
KT.js is a tiny
|
|
11
|
+
KT.js is a tiny(1.3KB runtime without alias helpers and 0.68kb gzipped) DOM utility focused on direct DOM manipulation. It favors not forcing re-renders and aims to keep DOM updates to the absolute minimum for maximum performance.
|
|
10
12
|
|
|
11
13
|
For more awesome packages, check out [my homepage💛](https://baendlorel.github.io/?repoType=npm)
|
|
12
14
|
|
|
13
15
|
## Philosophy
|
|
14
16
|
|
|
15
|
-
As a web framework, repeatedly creating a large number of variables and objects is unacceptable.
|
|
16
|
-
|
|
17
|
-
KT.js follows one rule: avoid repainting unless necessary. It updates the DOM directly and only where needed — no virtual DOM, no automatic diffing. That keeps the UI predictable and fast, while leaving control to the developer.
|
|
17
|
+
As a web framework, repeatedly creating a large number of variables and objects is unacceptable. So I created KT.js.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
- **Minimal updates**: avoid unnecessary reflows and repaints.
|
|
21
|
-
- **Predictable and fast**: stable UI with high performance.
|
|
22
|
-
- **Developer control**: you decide when to update.
|
|
19
|
+
KT.js follows one rule: full controll of dom and avoid unless repainting.
|
|
23
20
|
|
|
24
21
|
## Getting started
|
|
25
22
|
|
|
26
|
-
Install via npm but pnpm is recommended:
|
|
27
|
-
|
|
28
23
|
```bash
|
|
29
24
|
npm install kt.js
|
|
30
25
|
# or
|
|
31
26
|
pnpm add kt.js
|
|
32
27
|
```
|
|
33
28
|
|
|
34
|
-
Import KT.js into your project.
|
|
35
|
-
|
|
36
29
|
```ts
|
|
37
|
-
import { h,
|
|
30
|
+
import { h, div } from 'kt.js';
|
|
38
31
|
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
createApp(app);
|
|
32
|
+
const container = div('container', [div('header'), div('body', 'something'), div('footer')]);
|
|
33
|
+
const app = h('section', { id: 'app' }, container);
|
|
42
34
|
```
|
|
43
35
|
|
|
44
|
-
|
|
36
|
+
This will create the following DOM structure:
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
38
|
+
```html
|
|
39
|
+
<section id="app">
|
|
40
|
+
<div class="container">
|
|
41
|
+
<div class="header"></div>
|
|
42
|
+
<div class="body">something</div>
|
|
43
|
+
<div class="footer"></div>
|
|
44
|
+
</div>
|
|
45
|
+
</section>
|
|
46
|
+
```
|
|
51
47
|
|
|
52
|
-
|
|
53
|
-
- Mounts a root element to the document.
|
|
54
|
-
- Signature: `createApp(rootElement: HTMLKEnhancedElement, mountTo?: HTMLElement)`
|
|
55
|
-
- If `mountTo` is omitted, it tries `#app` and falls back to `document.body`.
|
|
48
|
+
If you give a function in the attributes, it will be treated as an event listener, and the key will be considered as the event name:
|
|
56
49
|
|
|
57
|
-
|
|
50
|
+
```ts
|
|
51
|
+
const button = btn({ click: () => alert('Clicked!') }, 'Click me');
|
|
52
|
+
// this equals
|
|
53
|
+
const button = btn(undefined, 'Click me');
|
|
54
|
+
button.addEventListener('click', () => alert('Clicked!'));
|
|
55
|
+
```
|
|
58
56
|
|
|
59
|
-
|
|
57
|
+
Work with `@emotion/css`
|
|
60
58
|
|
|
61
59
|
```ts
|
|
62
60
|
import { css } from '@emotion/css';
|
|
@@ -69,33 +67,9 @@ const className = css`
|
|
|
69
67
|
h('div', { class: className }, 'Styled text');
|
|
70
68
|
```
|
|
71
69
|
|
|
72
|
-
## Enhance-added properties and methods
|
|
73
|
-
|
|
74
|
-
After calling `enhance(element)` (done internally by `h` when appropriate), an HTMLElement becomes an `HTMLKEnhancedElement` with the following additions:
|
|
75
|
-
|
|
76
|
-
- Properties
|
|
77
|
-
- `ktext` (string): getter/setter that proxies to an internal Text node stored on the element (reads/writes element text content).
|
|
78
|
-
- the text node is stored by a WeakMap, so normally it is not possible to stop it from showing up unless you set ktext to `''`.
|
|
79
|
-
- `kchildren` (array): getter/setter that exposes the element's children as an array of strings / enhanced elements. Setting `kchildren` replaces the element's content and accepts strings, Text nodes or other KT.js enhanced elements.
|
|
80
|
-
|
|
81
|
-
- Methods
|
|
82
|
-
- `kon(type, listener, options?)` — enhanced addEventListener
|
|
83
|
-
- Normalizes options. Supports a `triggerLimit` option which will remove the listener after N triggers (if `triggerLimit === 1` it becomes `once`).
|
|
84
|
-
- Returns the listener (or a wrapped listener used for limited triggers).
|
|
85
|
-
- `koff(type, listener, options?)` — enhanced removeEventListener
|
|
86
|
-
- Removes event listeners respecting provided options.
|
|
87
|
-
- `kmount(element)` — append/mount helper
|
|
88
|
-
- Equivalent to `element.appendChild(this)` and returns `this` for chaining.
|
|
89
|
-
|
|
90
70
|
## Notes
|
|
91
71
|
|
|
92
|
-
-
|
|
93
|
-
- The API is small and low-level by design — it's intended as a performance-focused building block rather than a full component framework.
|
|
94
|
-
- `Function.prototype.call` is trusted.
|
|
95
|
-
|
|
96
|
-
## Contributing
|
|
97
|
-
|
|
98
|
-
PRs and issues are welcome. If you add features that affect the public API, update README and tests accordingly.
|
|
72
|
+
- `call`, `apply` on `Function.prototype` is trusted.
|
|
99
73
|
|
|
100
74
|
## License
|
|
101
75
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,107 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
declare const div: HAlias<'div'>;
|
|
3
|
-
/** Alias for h('span', ...) - Inline container */
|
|
4
|
-
declare const span: HAlias<'span'>;
|
|
5
|
-
/** Alias for h('a', ...) - Hyperlink */
|
|
6
|
-
declare const a: HAlias<'a'>;
|
|
7
|
-
/** Alias for h('img', ...) - Image */
|
|
8
|
-
declare const img: HAlias<'img'>;
|
|
9
|
-
/** Alias for h('p', ...) - Paragraph */
|
|
10
|
-
declare const p: HAlias<'p'>;
|
|
11
|
-
/** Alias for h('ul', ...) - Unordered list */
|
|
12
|
-
declare const ul: HAlias<'ul'>;
|
|
13
|
-
/** Alias for h('li', ...) - List item */
|
|
14
|
-
declare const li: HAlias<'li'>;
|
|
15
|
-
/** Alias for h('mark', ...) - Marked/highlighted text */
|
|
16
|
-
declare const mark: HAlias<'mark'>;
|
|
17
|
-
/** Alias for h('time', ...) - Time/date */
|
|
18
|
-
declare const time: HAlias<'time'>;
|
|
19
|
-
/** Alias for h('code', ...) - Inline code */
|
|
20
|
-
declare const code: HAlias<'code'>;
|
|
21
|
-
/** Alias for h('pre', ...) - Preformatted text */
|
|
22
|
-
declare const pre: HAlias<'pre'>;
|
|
23
|
-
|
|
24
|
-
/** Alias for h('header', ...) - Header section */
|
|
25
|
-
declare const header: HAlias<'header'>;
|
|
26
|
-
/** Alias for h('nav', ...) - Navigation section */
|
|
27
|
-
declare const nav: HAlias<'nav'>;
|
|
28
|
-
/** Alias for h('main', ...) - Main content */
|
|
29
|
-
declare const main: HAlias<'main'>;
|
|
30
|
-
/** Alias for h('article', ...) - Article block */
|
|
31
|
-
declare const article: HAlias<'article'>;
|
|
32
|
-
/** Alias for h('section', ...) - Section block */
|
|
33
|
-
declare const section: HAlias<'section'>;
|
|
34
|
-
/** Alias for h('aside', ...) - Aside (sidebar) */
|
|
35
|
-
declare const aside: HAlias<'aside'>;
|
|
36
|
-
/** Alias for h('footer', ...) - Footer section */
|
|
37
|
-
declare const footer: HAlias<'footer'>;
|
|
38
|
-
/** Alias for h('figure', ...) - Figure with caption */
|
|
39
|
-
declare const figure: HAlias<'figure'>;
|
|
40
|
-
/** Alias for h('figcaption', ...) - Figure caption */
|
|
41
|
-
declare const figcaption: HAlias<'figcaption'>;
|
|
42
|
-
|
|
43
|
-
/** Alias for h('input', ...) - Input field */
|
|
44
|
-
declare const input: HAlias<'input'>;
|
|
45
|
-
/** Alias for h('select', ...) - Select */
|
|
46
|
-
declare const select: HAlias<'select'>;
|
|
47
|
-
/** Alias for h('option', ...) - Options */
|
|
48
|
-
declare const option: HAlias<'option'>;
|
|
49
|
-
/** Alias for h('optgroup', ...) - Option Groups */
|
|
50
|
-
declare const optgroup: HAlias<'optgroup'>;
|
|
51
|
-
/** Alias for h('textarea', ...) - Textarea */
|
|
52
|
-
declare const textarea: HAlias<'textarea'>;
|
|
53
|
-
/** Alias for h('form', ...) - Form */
|
|
54
|
-
declare const form: HAlias<'form'>;
|
|
55
|
-
/** Alias for h('label', ...) - Label */
|
|
56
|
-
declare const label: HAlias<'label'>;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Create an enhanced HTMLElement.
|
|
60
|
-
* @param tag tag of an `HTMLElement`
|
|
61
|
-
* @param attr attribute object or className
|
|
62
|
-
* @param content a string or an array of HTMLEnhancedElement as child nodes
|
|
63
|
-
*/
|
|
64
|
-
declare function h<T extends HTMLTag>(tag: T, attr?: KAttribute | string, content?: (HTMLKEnhancedElement | string)[] | HTMLKEnhancedElement | string): HTMLKEnhancedElement<T>;
|
|
1
|
+
type otherstring = string & {};
|
|
65
2
|
|
|
66
3
|
/**
|
|
67
|
-
*
|
|
68
|
-
* @package Kt.js
|
|
69
|
-
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
70
|
-
* @version 0.0.9 (Last Update: 2025.09.20 16:19:02.366)
|
|
71
|
-
* @license MIT
|
|
72
|
-
* @link https://github.com/baendlorel/kt.js
|
|
73
|
-
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
74
|
-
* @description A simple and easy-to-use web framework, never re-render. Abbreviation of Kasukabe Tsumugi.
|
|
75
|
-
* @copyright Copyright (c) 2025 Kasukabe Tsumugi. All rights reserved.
|
|
76
|
-
*
|
|
77
|
-
* ## Usage
|
|
78
|
-
* Mount root element to `#app`(`body` if not found) or to the given element.
|
|
79
|
-
* @param rootElement an instance of `HTMLKEnhancedElement`, created by `h` function.
|
|
80
|
-
* @param mountTo any `HTMLElement` to mount to, if omitted, will mount to `#app` or `body`.
|
|
4
|
+
* Normal HTML tags like `div`, `span`, `a`, etc.
|
|
81
5
|
*/
|
|
82
|
-
|
|
6
|
+
type HTMLTag = keyof HTMLElementTagNameMap;
|
|
83
7
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// # from: src/global.d.ts
|
|
87
|
-
|
|
88
|
-
// # from: src/types/core.d.ts
|
|
89
|
-
type HFunction = <T extends HTMLTag>(
|
|
90
|
-
tag: T,
|
|
91
|
-
attr?: KAttribute | string,
|
|
92
|
-
content?: (HTMLKEnhancedElement | string)[] | HTMLKEnhancedElement | string
|
|
93
|
-
) => HTMLKEnhancedElement<T>;
|
|
94
|
-
|
|
95
|
-
type HAlias<T extends HTMLTag> = (
|
|
96
|
-
attr?: KAttribute | string,
|
|
97
|
-
content?: (HTMLKEnhancedElement | string)[] | HTMLKEnhancedElement | string
|
|
98
|
-
) => HTMLKEnhancedElement<T>;
|
|
8
|
+
type RawContent = (HTMLElement | string | undefined)[] | HTMLElement | string;
|
|
9
|
+
type RawAttr = KAttribute | string;
|
|
99
10
|
|
|
100
11
|
/**
|
|
101
12
|
* Used to create enhanced HTML elements
|
|
102
13
|
*/
|
|
103
|
-
|
|
104
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
+
interface KAttribute {
|
|
105
15
|
[k: string]: any;
|
|
106
16
|
|
|
107
17
|
id?: string;
|
|
@@ -110,152 +20,54 @@ export interface KAttribute {
|
|
|
110
20
|
for?: string;
|
|
111
21
|
name?: string;
|
|
112
22
|
value?: string;
|
|
23
|
+
valueAsDate?: Date;
|
|
24
|
+
valueAsNumber?: number;
|
|
113
25
|
label?: string;
|
|
114
26
|
disabled?: string;
|
|
115
27
|
min?: string;
|
|
116
28
|
max?: string;
|
|
117
29
|
selected?: boolean;
|
|
118
30
|
checked?: boolean;
|
|
119
|
-
class?: string
|
|
31
|
+
class?: string;
|
|
120
32
|
style?: string | Partial<CSSStyleDeclaration>;
|
|
121
33
|
action?: string;
|
|
122
|
-
method?:
|
|
123
|
-
| 'POST'
|
|
124
|
-
| 'GET'
|
|
125
|
-
| 'PUT'
|
|
126
|
-
| 'DELETE'
|
|
127
|
-
| 'PATCH'
|
|
128
|
-
| 'HEAD'
|
|
129
|
-
| 'OPTIONS'
|
|
130
|
-
| 'CONNECT'
|
|
131
|
-
| 'TRACE'
|
|
132
|
-
| (string & {});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// # from: src/types/enhance.d.ts
|
|
136
|
-
export type HTMLTag = keyof HTMLElementTagNameMap;
|
|
137
|
-
|
|
138
|
-
export type KChildren = HTMLKEnhancedElement | Text;
|
|
139
|
-
|
|
140
|
-
interface KOnOptions extends AddEventListenerOptions {
|
|
141
|
-
/**
|
|
142
|
-
* This option's priority is higher than `once`.
|
|
143
|
-
* - when this is `1`, go with `once: true`.
|
|
144
|
-
*/
|
|
145
|
-
triggerLimit?: number;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
type KListener<E extends HTMLElement, K extends keyof HTMLElementEventMap> = (
|
|
149
|
-
this: E,
|
|
150
|
-
ev: HTMLElementEventMap[K]
|
|
151
|
-
) => unknown;
|
|
152
|
-
|
|
153
|
-
interface KEnhancedPrivates {
|
|
154
|
-
/**
|
|
155
|
-
* Unique numeric identifier for a KT.js enhanced element instance.
|
|
156
|
-
* Used internally to track and distinguish enhanced elements.
|
|
157
|
-
*/
|
|
158
|
-
id: number;
|
|
159
|
-
|
|
160
|
-
text: Text;
|
|
34
|
+
method?: 'POST' | 'GET' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE' | otherstring;
|
|
161
35
|
}
|
|
162
36
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
*/
|
|
190
|
-
kon: <El extends HTMLElement, K extends keyof HTMLElementEventMap>(
|
|
191
|
-
this: El,
|
|
192
|
-
type: K,
|
|
193
|
-
listener: KListener<HTMLElement, K>,
|
|
194
|
-
options?: KOnOptions
|
|
195
|
-
) => KListener<El, K>;
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Remove or detach an event listener from the element. Semantically this
|
|
199
|
-
* is the counterpart to `kon` and accepts the same arguments. Returns
|
|
200
|
-
* nothing.
|
|
201
|
-
*
|
|
202
|
-
* Note: the original inline comment said "Equivalent to `element.appendChild(this)`"
|
|
203
|
-
* which does not apply to event removal — keep this method focused on
|
|
204
|
-
* removing listeners according to the project's implementation.
|
|
205
|
-
*
|
|
206
|
-
* @param type event type
|
|
207
|
-
* @param listener event listener to remove
|
|
208
|
-
* @param options listener options
|
|
209
|
-
*/
|
|
210
|
-
koff: <El extends HTMLElement, K extends keyof HTMLElementEventMap>(
|
|
211
|
-
this: El,
|
|
212
|
-
type: K,
|
|
213
|
-
listener: KListener<HTMLElement, K>,
|
|
214
|
-
options?: KOnOptions
|
|
215
|
-
) => void;
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Mount this enhanced element onto a host DOM element. This typically
|
|
219
|
-
* appends the enhanced element to the supplied `element` and performs any
|
|
220
|
-
* needed setup. Returns the mounted enhanced element.
|
|
221
|
-
*
|
|
222
|
-
* @param element the DOM element to mount into
|
|
223
|
-
* @returns the mounted enhanced element (this)
|
|
224
|
-
*/
|
|
225
|
-
kmount: <El extends HTMLKEnhancedElement>(this: El, element: HTMLKEnhancedElement) => El;
|
|
226
|
-
}
|
|
37
|
+
declare const div: (attr?: RawAttr, content?: RawContent) => HTMLDivElement;
|
|
38
|
+
declare const span: (attr?: RawAttr, content?: RawContent) => HTMLSpanElement;
|
|
39
|
+
declare const label: (attr?: RawAttr, content?: RawContent) => HTMLLabelElement;
|
|
40
|
+
declare const p: (attr?: RawAttr, content?: RawContent) => HTMLParagraphElement;
|
|
41
|
+
declare const h1: (attr?: RawAttr, content?: RawContent) => HTMLHeadingElement;
|
|
42
|
+
declare const h2: (attr?: RawAttr, content?: RawContent) => HTMLHeadingElement;
|
|
43
|
+
declare const h3: (attr?: RawAttr, content?: RawContent) => HTMLHeadingElement;
|
|
44
|
+
declare const h4: (attr?: RawAttr, content?: RawContent) => HTMLHeadingElement;
|
|
45
|
+
declare const h5: (attr?: RawAttr, content?: RawContent) => HTMLHeadingElement;
|
|
46
|
+
declare const h6: (attr?: RawAttr, content?: RawContent) => HTMLHeadingElement;
|
|
47
|
+
declare const ul: (attr?: RawAttr, content?: RawContent) => HTMLUListElement;
|
|
48
|
+
declare const ol: (attr?: RawAttr, content?: RawContent) => HTMLOListElement;
|
|
49
|
+
declare const li: (attr?: RawAttr, content?: RawContent) => HTMLLIElement;
|
|
50
|
+
declare const btn: (attr?: RawAttr, content?: RawContent) => HTMLButtonElement;
|
|
51
|
+
declare const form: (attr?: RawAttr, content?: RawContent) => HTMLFormElement;
|
|
52
|
+
declare const input: (attr?: RawAttr, content?: RawContent) => HTMLInputElement;
|
|
53
|
+
declare const select: (attr?: RawAttr, content?: RawContent) => HTMLSelectElement;
|
|
54
|
+
declare const option: (attr?: RawAttr, content?: RawContent) => HTMLOptionElement;
|
|
55
|
+
declare const table: (attr?: RawAttr, content?: RawContent) => HTMLTableElement;
|
|
56
|
+
declare const thead: (attr?: RawAttr, content?: RawContent) => HTMLTableSectionElement;
|
|
57
|
+
declare const tbody: (attr?: RawAttr, content?: RawContent) => HTMLTableSectionElement;
|
|
58
|
+
declare const tr: (attr?: RawAttr, content?: RawContent) => HTMLTableRowElement;
|
|
59
|
+
declare const th: (attr?: RawAttr, content?: RawContent) => HTMLTableCellElement;
|
|
60
|
+
declare const td: (attr?: RawAttr, content?: RawContent) => HTMLTableCellElement;
|
|
61
|
+
declare const a: (attr?: RawAttr, content?: RawContent) => HTMLAnchorElement;
|
|
62
|
+
declare const img: (attr?: RawAttr, content?: RawContent) => HTMLImageElement;
|
|
227
63
|
|
|
228
64
|
/**
|
|
229
|
-
*
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* This is the core feature of KT.js - enhanced HTML elements.
|
|
237
|
-
*
|
|
238
|
-
* It combines the standard HTMLElement properties and methods
|
|
239
|
-
* with KT.js enhancements defined in KEnhanced.
|
|
65
|
+
* Create an enhanced HTMLElement.
|
|
66
|
+
* - Only supports HTMLElements, **NOT** SVGElements or other Elements.
|
|
67
|
+
* @param tag tag of an `HTMLElement`
|
|
68
|
+
* @param attr attribute object or className
|
|
69
|
+
* @param content a string or an array of HTMLEnhancedElement as child nodes
|
|
240
70
|
*/
|
|
241
|
-
|
|
242
|
-
(HTMLElement extends HTMLElementTagNameMap[T] ? HTMLElement : HTMLElementTagNameMap[T]) &
|
|
243
|
-
KEnhanced;
|
|
244
|
-
|
|
245
|
-
// # from: src/types/type-utils.d.ts
|
|
246
|
-
type IsSameType<A, B> =
|
|
247
|
-
(<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2
|
|
248
|
-
? (<T>() => T extends B ? 1 : 2) extends <T>() => T extends A ? 1 : 2
|
|
249
|
-
? true
|
|
250
|
-
: false
|
|
251
|
-
: false;
|
|
252
|
-
|
|
253
|
-
type PickProperty<T> = {
|
|
254
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
255
|
-
[K in keyof T as T[K] extends (...args: any[]) => any ? never : K]: T[K];
|
|
256
|
-
};
|
|
71
|
+
declare function h<T extends HTMLTag>(tag: T, attr?: RawAttr, content?: RawContent): HTMLElementTagNameMap[T];
|
|
257
72
|
|
|
258
|
-
|
|
259
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
260
|
-
[K in keyof T as T[K] extends (...args: any[]) => any ? K : never]: T[K];
|
|
261
|
-
};
|
|
73
|
+
export { a, btn, div, form, h, h1, h2, h3, h4, h5, h6, img, input, label, li, ol, option, p, select, span, table, tbody, td, th, thead, tr, ul };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const t=document.createElement,e=HTMLElement.prototype.append,n=HTMLElement.prototype.addEventListener,o=HTMLElement.prototype.setAttribute,l=Array.isArray,a=Object.keys,c=Object.assign,d=t=>{throw new Error("Kt.js:"+t)},i=(t,e,n)=>{e in t?t[e]=!!n:o.call(t,e,n)},u=(t,e,n)=>{e in t?t[e]=n:o.call(t,e,n)},r={checked:i,selected:i,value:u,valueAsDate:u,valueAsNumber:u,defaultValue:u,defaultChecked:i,defaultSelected:i,disabled:i,readOnly:i,multiple:i,required:i,autofocus:i,open:i,controls:i,autoplay:i,loop:i,muted:i,defer:i,async:i,hidden:(t,e,n)=>t.hidden=!!n},s=(t,e,n)=>o.call(t,e,n);function f(t,e){"string"==typeof e?t.className=e:"object"==typeof e&&null!==e?function(t,e){const l=e.class,d=e.style;void 0!==l&&(t.className=l,delete e.class),void 0!==d&&("string"==typeof d?o.call(t,"style",d):c(t.style,d),delete e.style);const i=a(e);for(let o=i.length-1;o>=0;o--){const l=i[o],a=e[l];"function"!=typeof a?(r[l]||s)(t,l,a):n.call(t,l,a)}void 0!==l&&(e.style=l),void 0!==d&&(e.style=d)}(t,e):d("applyAttr attr must be an object.")}function p(n,o="",a=""){"string"!=typeof n&&d("h tagName must be a string.");const c=(i=n,t.call(document,i));var i;return f(c,o),function(t,n){"string"==typeof n?t.ktext=n:l(n)?e.apply(t,n):n instanceof HTMLElement?e.call(t,n):d("applyContent invalid content.")}(c,a),c}const m=t=>(e,n)=>p(t,e,n),y=m("div"),h=m("span"),b=m("label"),v=m("p"),g=m("h1"),j=m("h2"),E=m("h3"),A=m("h4"),H=m("h5"),L=m("h6"),M=m("ul"),T=m("ol"),O=m("li"),k=m("button"),w=m("form"),C=m("input"),N=m("select"),q=m("option"),x=m("table"),D=m("thead"),K=m("tbody"),S=m("tr"),V=m("th"),z=m("td"),B=m("a"),F=m("img");export{B as a,k as btn,y as div,w as form,p as h,g as h1,j as h2,E as h3,A as h4,H as h5,L as h6,F as img,C as input,b as label,O as li,T as ol,q as option,v as p,N as select,h as span,x as table,K as tbody,z as td,V as th,D as thead,S as tr,M as ul};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kt.js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Kasukabe Tsumugi",
|
|
6
6
|
"email": "futami16237@gmail.com"
|
|
@@ -33,18 +33,16 @@
|
|
|
33
33
|
"javascript"
|
|
34
34
|
],
|
|
35
35
|
"scripts": {
|
|
36
|
+
"gsize": "cat dist/index.mjs | wc -c && gzip -c dist/index.mjs | wc -c",
|
|
37
|
+
"lines": "clear && find ./src -type f \\( -name \"*.ts\" -o -name \"*.tsx\" -o -name \"*.js\" -o -name \"*.mjs\" -o -name \"*.cjs\" -o -name \"*.cpp\" -o -name \"*.h\" -o -name \"*.py\" -o -name \"*.css\" -o -name \"*.rs\" -o -name \"*.rc\" \\) | xargs wc -l",
|
|
36
38
|
"test": "clear & vitest",
|
|
37
39
|
"lint": "oxlint .",
|
|
38
40
|
"cover": "clear & vitest --coverage",
|
|
39
|
-
"build": "
|
|
41
|
+
"build": "tsx ./.scripts/rollup.ts"
|
|
40
42
|
},
|
|
41
43
|
"license": "MIT",
|
|
42
44
|
"devDependencies": {
|
|
43
|
-
"@babel/plugin-proposal-decorators": "^7.28.0",
|
|
44
|
-
"@babel/preset-env": "^7.28.3",
|
|
45
|
-
"@emotion/css": "^11.13.5",
|
|
46
45
|
"@rollup/plugin-alias": "^5.1.1",
|
|
47
|
-
"@rollup/plugin-babel": "^6.0.4",
|
|
48
46
|
"@rollup/plugin-commonjs": "^28.0.6",
|
|
49
47
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
50
48
|
"@rollup/plugin-replace": "^6.0.2",
|
|
@@ -57,15 +55,13 @@
|
|
|
57
55
|
"prettier": "^3.6.2",
|
|
58
56
|
"rimraf": "^6.0.1",
|
|
59
57
|
"rollup": "^4.50.2",
|
|
58
|
+
"rollup-plugin-conditional-compilation": "^1.0.6",
|
|
59
|
+
"rollup-plugin-const-enum": "^1.1.4",
|
|
60
60
|
"rollup-plugin-dts": "^6.2.3",
|
|
61
|
-
"rollup-plugin-
|
|
61
|
+
"rollup-plugin-func-macro": "^1.1.1",
|
|
62
62
|
"tinyrainbow": "^3.0.3",
|
|
63
63
|
"tslib": "^2.8.1",
|
|
64
64
|
"typescript": "^5.9.2",
|
|
65
65
|
"vitest": "^3.2.4"
|
|
66
|
-
},
|
|
67
|
-
"dependencies": {
|
|
68
|
-
"bind-params": "^1.1.0",
|
|
69
|
-
"defered-branch": "^1.2.2"
|
|
70
66
|
}
|
|
71
67
|
}
|
package/README.zh.md
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
# KT.js
|
|
2
|
-
|
|
3
|
-
[](https://github.com/baendlorel/kt.js/blob/main/LICENSE)
|
|
4
|
-
|
|
5
|
-
[中文](README.zh.md) | [English](README.md) | [CHANGLOG](CHANGELOG.md)
|
|
6
|
-
|
|
7
|
-
> 注意:本框架仍在开发中。API、类型声明及其它部分可能会经常变更。若在生产中使用,请关注后续更新;有问题也欢迎发邮件联系我。
|
|
8
|
-
|
|
9
|
-
KT.js 是一个极简、高性能的 DOM 工具库,专注于最小化重渲染和直接的 DOM 操作。它避免不必要的强制重渲染,力求将 DOM 更新控制在最少范围,从而获得最佳性能。
|
|
10
|
-
|
|
11
|
-
更多优秀的项目请访问作者主页:[我的主页💛](https://baendlorel.github.io/?repoType=npm)
|
|
12
|
-
|
|
13
|
-
## 设计理念
|
|
14
|
-
|
|
15
|
-
作为一个前端工具库,频繁创建大量变量与对象会对浏览器及 JS 引擎(如 V8、SpiderMonkey 或 JSC)造成负担。因此我设计了 KT.js。
|
|
16
|
-
|
|
17
|
-
KT.js 遵循一条简单规则:避免不必要的重绘(repaint)。它直接并且只在必要的位置更新 DOM —— 无虚拟 DOM、无自动 diff。这样可以让 UI 更可预测且更快,同时把控制权交还给开发者。
|
|
18
|
-
|
|
19
|
-
- 直接操作 DOM:仅更新发生变化的部分。
|
|
20
|
-
- 最小化更新:避免不必要的重排(reflow)与重绘(repaint)。
|
|
21
|
-
- 可预测且高性能:界面稳定、响应迅速。
|
|
22
|
-
- 开发者掌控:你决定何时更新。
|
|
23
|
-
|
|
24
|
-
## 快速开始
|
|
25
|
-
|
|
26
|
-
推荐使用 pnpm 安装,但也支持 npm:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npm install kt.js
|
|
30
|
-
# or
|
|
31
|
-
pnpm add kt.js
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
在项目中引入并使用:
|
|
35
|
-
|
|
36
|
-
```ts
|
|
37
|
-
import { h, createApp } from 'kt.js';
|
|
38
|
-
|
|
39
|
-
const app = h('div', { id: 'app' }, 'Hello, KT.js!');
|
|
40
|
-
|
|
41
|
-
createApp(app);
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## API 概览
|
|
45
|
-
|
|
46
|
-
- `h` — 创建一个加强版的HTML元素。
|
|
47
|
-
- 常见用法:`h('div', { id: 'root' }, 'Hello')`。
|
|
48
|
-
- 返回一个 `HTMLKEnhancedElement`(即带有额外 enhance 属性的 HTMLElement,详见下文)。
|
|
49
|
-
- 提供一组别名,例如 `div`、`span`、`ul` 等。
|
|
50
|
-
- `div(attr, content)` 等价于 `h('div', attr, content)`。
|
|
51
|
-
|
|
52
|
-
- `createApp` — 将根元素挂载到文档中。
|
|
53
|
-
- 默认查找 `#app`,找不到时回退到 `document.body`,也可以通过`mountTo`入参指定挂载位置。
|
|
54
|
-
- 函数签名:`createApp(rootElement: HTMLKEnhancedElement, mountTo?: HTMLElement)`
|
|
55
|
-
|
|
56
|
-
** 与 `@emotion/css` 一起使用 **
|
|
57
|
-
|
|
58
|
-
> 早期我实现过自己的 CSS 处理器,但后来发现没必要。
|
|
59
|
-
|
|
60
|
-
示例:
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
import { css } from '@emotion/css';
|
|
64
|
-
|
|
65
|
-
const className = css`
|
|
66
|
-
color: red;
|
|
67
|
-
font-size: 20px;
|
|
68
|
-
`;
|
|
69
|
-
|
|
70
|
-
h('div', { class: className }, 'Styled text');
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Enhance 增强后新增的属性与方法
|
|
74
|
-
|
|
75
|
-
当对一个元素调用 `enhance(element)`(`h` 在需要时会在内部完成该步骤)后,HTMLElement 会变为 `HTMLKEnhancedElement`,并添加如下扩展:
|
|
76
|
-
|
|
77
|
-
- 属性
|
|
78
|
-
- `ktext`(字符串):getter/setter,代理到存放在元素内部的 Text 节点(用于读写元素文本内容)。
|
|
79
|
-
- 该 Text 节点由 WeakMap 存储,因此通常无法移除它。将 `ktext` 设为空字符串 `''`可以让它看不见。
|
|
80
|
-
- `kchildren`(数组):getter/setter,将元素的子节点以字符串或增强元素数组的形式暴露。设置 `kchildren` 会替换元素的内容,接受字符串、Text 节点或其它 KT.js 的增强元素。
|
|
81
|
-
|
|
82
|
-
- 方法
|
|
83
|
-
- `kon(type, listener, options?)` — 增强版的 addEventListener
|
|
84
|
-
- 规范化事件选项。支持 `triggerLimit` 选项:当事件触发次数达到限制时会自动移除监听器(若 `triggerLimit === 1` 则等同于 `once`)。
|
|
85
|
-
- 返回实际注册的监听器(可能是包裹器以支持触发次数限制)。
|
|
86
|
-
- `koff(type, listener, options?)` — 增强版的 removeEventListener
|
|
87
|
-
- 在移除监听器时会考虑传入的选项。
|
|
88
|
-
- `kmount(element)` — 挂载/追加助手
|
|
89
|
-
- 等价于 `element.appendChild(this)`,并返回 `this` 以便链式调用。
|
|
90
|
-
|
|
91
|
-
## 说明与注意事项
|
|
92
|
-
|
|
93
|
-
- 本库直接操作 DOM,并有意将重渲染控制到最小。
|
|
94
|
-
- API 设计小而精,偏底层 —— 目标是作为构建高性能 UI 的基础工具,而不是完整的组件框架。
|
|
95
|
-
- `Function.prototype.call` 被信任,这在某些环境或代码审计中需要注意。
|
|
96
|
-
|
|
97
|
-
## 参与贡献
|
|
98
|
-
|
|
99
|
-
欢迎提交 PR 与 issue。如果你的改动会影响公共 API,请同时更新 README 与相应的测试。
|
|
100
|
-
|
|
101
|
-
## 许可证
|
|
102
|
-
|
|
103
|
-
MIT
|