kt.js 0.0.8 → 0.1.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/README.md CHANGED
@@ -1,86 +1,66 @@
1
1
  # KT.js
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/kt.js.svg)](https://www.npmjs.com/package/kt.js)
4
+
3
5
  [![license](https://img.shields.io/github/license/baendlorel/kt.js.svg)](https://github.com/baendlorel/kt.js/blob/main/LICENSE)
4
6
 
5
- [中文](README.zh.md) | [English](README.md) | [CHANGLOG](CHANGELOG.md)
7
+ [中文](README.zh.md) | [English](README.md) | [CHANGLOG](CHANGELOG.md)
6
8
 
7
- > Note: This framework is still under development. APIs, type declarations, and other parts may change. If you use it, please watch for updates in the near future.
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, high-performance DOM utility focused on minimal re-rendering and direct DOM manipulation. It favors not forcing re-renders and aims to keep DOM updates to the absolute minimum for maximum performance.
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. This is a provocation against browsers and the V8 engine(or SpiderMonkey, or JSC). So I created KT.js.
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
- - **Direct DOM**: update only what changes.
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, createApp } from 'kt.js';
38
-
39
- const app = h('div', { id: 'app' }, 'Hello, KT.js!');
30
+ import { h, div } from 'kt.js';
40
31
 
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
- ## Core Api
45
-
46
- - `h` — hyperscript helper
47
- - Creates a KT-enhanced DOM element representation.
48
- - Typical usage:` h('div', { id: 'root' }, 'Hello')`.
49
- - Returns an `HTMLKEnhancedElement` (an HTMLElement with extra `enhance` properties described below).
36
+ This will create the following DOM structure:
50
37
 
51
- - `createApp` — mount helper
52
- - Mounts a root `HTMLKEnhancedElement` to the document.
53
- - Signature: `createApp(rootElement: HTMLKEnhancedElement, mountTo?: HTMLElement)`
54
- - If `mountTo` is omitted, it tries `#app` and falls back to `document.body`.
55
-
56
- ## Enhance-added properties and methods
57
-
58
- After calling `enhance(element)` (done internally by `h` when appropriate), an HTMLElement becomes an `HTMLKEnhancedElement` with the following additions:
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
+ ```
59
47
 
60
- - Properties
61
- - `kid` (number): a per-element unique index generated by an internal `Indexer.nextKid()`.
62
- - `isKT` (true): boolean marker that identifies the element as a KText element.
63
- - `ktext` (string): getter/setter that proxies to an internal Text node stored on the element (reads/writes element text content).
64
- - `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.
48
+ ** Work with `@emotion/css`**
65
49
 
66
- - Methods
67
- - `kon(type, listener, options?)` enhanced addEventListener
68
- - Normalizes options. Supports a `triggerLimit` option which will remove the listener after N triggers (if `triggerLimit === 1` it becomes `once`).
69
- - Returns the listener (or a wrapped listener used for limited triggers).
70
- - `koff(type, listener, options?)` — enhanced removeEventListener
71
- - Removes event listeners respecting provided options.
72
- - `kmount(element)` — append/mount helper
73
- - Equivalent to `element.appendChild(this)` and returns `this` for chaining.
50
+ ```ts
51
+ import { css } from '@emotion/css';
74
52
 
75
- ## Notes and caveats
53
+ const className = css`
54
+ color: red;
55
+ font-size: 20px;
56
+ `;
76
57
 
77
- - This library manipulates the DOM directly and intentionally keeps re-rendering minimal.
78
- - `enhance` augments elements with non-enumerable descriptors for `ktext`, `isKT`, and `kid`, and assigns `kon`, `koff`, and `kmount` methods directly.
79
- - The API is small and low-level by design — it's intended as a performance-focused building block rather than a full component framework.
58
+ h('div', { class: className }, 'Styled text');
59
+ ```
80
60
 
81
- ## Contributing
61
+ ## Notes
82
62
 
83
- PRs and issues are welcome. If you add features that affect the public API, update README and tests accordingly.
63
+ - `call`, `apply` on `Function.prototype` is trusted.
84
64
 
85
65
  ## License
86
66
 
package/README.zh.md CHANGED
@@ -2,28 +2,28 @@
2
2
 
3
3
  [![license](https://img.shields.io/github/license/baendlorel/kt.js.svg)](https://github.com/baendlorel/kt.js/blob/main/LICENSE)
4
4
 
5
- [中文](README.zh.md) | [English](README.md) | [更新日志](CHANGELOG.md)
5
+ [中文](README.zh.md) | [English](README.md) | [CHANGLOG](CHANGELOG.md)
6
6
 
7
- > Note: 本框架还在开发中,api、类型声明等可能会有变化,如果使用,近期请关注更新
7
+ > 注意:本框架仍在开发中。API、类型声明及其它部分可能会经常变更。若在生产中使用,请关注后续更新;有问题也欢迎发邮件联系我。
8
8
 
9
- KT.js 是一个微小的高性能 DOM 工具,专注于最小化重绘和直接操作 DOM。它的设计目标是尽量不强制重绘,只在必要时更新 DOM,从而获得极致性能。
9
+ KT.js 是一个极简、高性能的 DOM 工具库,专注于最小化重渲染和直接的 DOM 操作。它避免不必要的强制重渲染,力求将 DOM 更新控制在最少范围,从而获得最佳性能。
10
10
 
11
- For more awesome packages, check out [my homepage💛](https://baendlorel.github.io/?repoType=npm)
11
+ 更多优秀的项目请访问作者主页:[我的主页💛](https://baendlorel.github.io/?repoType=npm)
12
12
 
13
- ## 核心理念
13
+ ## 设计理念
14
14
 
15
- 作为一个web框架,反复创建大量对象、反复重绘是不可接受的,这是对浏览器和V8引擎(或者SpiderMonkey, 或者说JSC)的挑衅。所以我创建了 KT.js。
15
+ 作为一个前端工具库,频繁创建大量变量与对象会对浏览器及 JS 引擎(如 V8SpiderMonkey JSC)造成负担。因此我设计了 KT.js。
16
16
 
17
- KT.js 遵循一条原则:尽量避免不必要的重绘。它直接按需更新 DOM —— 无虚拟 DOM、无自动 diff。这样能保持界面可预测且高效,同时把更新控制权交给开发者。
17
+ KT.js 遵循一条简单规则:避免不必要的重绘(repaint)。它直接并且只在必要的位置更新 DOM —— 无虚拟 DOM、无自动 diff。这样可以让 UI 更可预测且更快,同时把控制权交还给开发者。
18
18
 
19
- - **直接操作 DOM**:只更新真正改变的部分。
20
- - **最小化更新**:避免不必要的回流与重绘。
21
- - **可预测且高效**:界面稳定,性能优秀。
22
- - **开发者掌控**:什么时候更新由你决定。
19
+ - 直接操作 DOM:仅更新发生变化的部分。
20
+ - 最小化更新:避免不必要的重排(reflow)与重绘(repaint)。
21
+ - 可预测且高性能:界面稳定、响应迅速。
22
+ - 开发者掌控:你决定何时更新。
23
23
 
24
24
  ## 快速开始
25
25
 
26
- 通过 npm 安装,但推荐使用 pnpm
26
+ 推荐使用 pnpm 安装,但也支持 npm
27
27
 
28
28
  ```bash
29
29
  npm install kt.js
@@ -31,7 +31,7 @@ npm install kt.js
31
31
  pnpm add kt.js
32
32
  ```
33
33
 
34
- 将 KT.js 导入到你的项目:
34
+ 在项目中引入并使用:
35
35
 
36
36
  ```ts
37
37
  import { h, createApp } from 'kt.js';
@@ -41,47 +41,69 @@ const app = h('div', { id: 'app' }, 'Hello, KT.js!');
41
41
  createApp(app);
42
42
  ```
43
43
 
44
- ## 核心 API
44
+ ## API 概览
45
45
 
46
- - `h` — hyperscript 辅助函数
47
- - 创建带有 KText 增强属性的 DOM 元素。
48
- - 用法示例:h('div', { id: 'root' }, 'Hello')。
49
- - 返回 `HTMLKEnhancedElement`(一个带有额外 `enhance` 属性的 HTMLElement)。
46
+ - `h` — 创建一个加强版的HTML元素。
47
+ - 常见用法:`h('div', { id: 'root' }, 'Hello')`。
48
+ - 返回一个 `HTMLKElement`(即带有额外 enhance 属性的 HTMLElement,详见下文)。
49
+ - 提供一组别名,例如 `div`、`span`、`ul` 等。
50
+ - `div(attr, content)` 等价于 `h('div', attr, content)`。
50
51
 
51
- - `createApp` — 挂载助手
52
- - 将根 `HTMLKEnhancedElement` 挂载到文档。
53
- - 签名:`createApp(rootElement: HTMLKEnhancedElement, mountTo?: HTMLElement)`
54
- - 若省略 `mountTo`,会尝试 `#app`,找不到则回退到 `document.body`。
52
+ - `createApp` — 将根元素挂载到文档中。
53
+ - 默认查找 `#app`,找不到时回退到 `document.body`,也可以通过`mountTo`入参指定挂载位置。
54
+ - 函数签名:`createApp(rootElement: HTMLKElement, mountTo?: HTMLElement)`
55
55
 
56
- ## enhance 增添的属性和方法
56
+ ** `@emotion/css` 一起使用 **
57
57
 
58
- 当调用 `enhance(element)`(在需要时 `h` 会内部调用)后,HTMLElement 会被增强为 `HTMLKEnhancedElement`,包含以下新增项:
58
+ > 早期我实现过自己的 CSS 处理器,但后来发现没必要。
59
59
 
60
- - 属性
61
- - `kid`(number):由内部 `Indexer.nextKid()` 生成的每个元素唯一索引。
62
- - `isKT`(true):标记元素是 KText 元素的布尔值。
63
- - `ktext`(string):getter/setter,代理内部 Text 节点,可方便地设置文本内容。
64
- - `kchildren`(数组):getter/setter,暴露元素的子项为字符串或增强元素数组。设置 `kchildren` 会替换元素内容,接受字符串、Text 节点或 KT.js 增强元素。
60
+ 示例:
65
61
 
66
- - 方法
67
- - `kon(type, listener, options?)` 增强的 addEventListener
68
- - 规范化 options,支持 `triggerLimit`(监听器在触发 N 次后移除;若 `triggerLimit === 1` 则等同于 `once`)。
69
- - 返回 listener(或用于限制触发次数的包装监听器)。
70
- - `koff(type, listener, options?)` — 增强的 removeEventListener
71
- - 移除事件监听,遵循提供的 options。
72
- - `kmount(element)` — 挂载/追加辅助方法
73
- - 等价于 `element.appendChild(this)`,并返回 `this` 以方便链式调用。
62
+ ```ts
63
+ import { css } from '@emotion/css';
74
64
 
75
- ## 注意
65
+ const className = css`
66
+ color: red;
67
+ font-size: 20px;
68
+ `;
76
69
 
77
- - 本库直接操作 DOM,故意将重绘控制在最低。
78
- - `enhance` 为元素添加了非枚举描述符的属性 `ktext`、`isKT` 和 `kid`,并直接赋值 `kon`、`koff`、`kmount` 方法。
79
- - 该 API 小且低级,旨在作为性能优先的构建块,而非完整的组件框架。
70
+ h('div', { class: className }, 'Styled text');
71
+ ```
80
72
 
81
- ## 贡献
73
+ ## Enhance 增强后新增的属性与方法
82
74
 
83
- 欢迎 PR issue。如果你修改了公共 API,请同步更新 README 和测试。
75
+ 当对一个元素调用 `enhance(element)`(`h` 在需要时会在内部完成该步骤)后,HTMLElement 会变为 `HTMLKElement`,并添加如下扩展:
84
76
 
85
- ## License
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
+ - **重要提示**:当使用 `triggerLimit` 时,`kon` 会返回一个新的包装函数而不是原始监听器。在调用 `koff` 时必须使用这个返回值才能正确移除监听器。示例:
87
+ ```ts
88
+ const wrappedHandler = element.kon('click', handler, { triggerLimit: 3 });
89
+ // 稍后要移除时:
90
+ element.koff('click', wrappedHandler); // 使用 wrappedHandler,而不是原始的 handler
91
+ ```
92
+ - `koff(type, listener, options?)` — 增强版的 removeEventListener
93
+ - 在移除监听器时会考虑传入的选项。
94
+ - `kmount(element)` — 挂载/追加助手
95
+ - 等价于 `element.appendChild(this)`,并返回 `this` 以便链式调用。
96
+
97
+ ## 说明与注意事项
98
+
99
+ - 本库直接操作 DOM,并有意将重渲染控制到最小。
100
+ - API 设计小而精,偏底层 —— 目标是作为构建高性能 UI 的基础工具,而不是完整的组件框架。
101
+ - 本库假设`Function.prototype` 上的 `call`, `apply` 未被改动过。
102
+
103
+ ## 参与贡献
104
+
105
+ 欢迎提交 PR 与 issue。如果你的改动会影响公共 API,请同时更新 README 与相应的测试。
106
+
107
+ ## 许可证
86
108
 
87
109
  MIT
package/dist/index.d.ts CHANGED
@@ -1,50 +1,17 @@
1
- /**
2
- * Create an enhanced HTMLElement.
3
- * @param tag tag of an `HTMLElement`
4
- * @param attr attribute object or className
5
- * @param content a string or an array of HTMLEnhancedElement as child nodes
6
- */
7
- declare function h<T extends HTMLTag>(tag: T, attr?: KAttribute | string, content?: (HTMLKEnhancedElement | string)[] | HTMLKEnhancedElement | string): HTMLKEnhancedElement<T>;
1
+ type otherstring = string & {};
8
2
 
9
3
  /**
10
- * ## About
11
- * @package Kt.js
12
- * @author Kasukabe Tsumugi <futami16237@gmail.com>
13
- * @version 0.0.8 (Last Update: 2025.09.20 15:12:59.928)
14
- * @license MIT
15
- * @link https://github.com/baendlorel/kt.js
16
- * @link https://baendlorel.github.io/ Welcome to my site!
17
- * @description A simple and easy-to-use web framework, never re-render. Abbreviation of Kasukabe Tsumugi.
18
- * @copyright Copyright (c) 2025 Kasukabe Tsumugi. All rights reserved.
19
- *
20
- * ## Usage
21
- * Mount root element to `#app`(`body` if not found) or to the given element.
22
- * @param rootElement an instance of `HTMLKEnhancedElement`, created by `h` function.
23
- * @param mountTo any `HTMLElement` to mount to, if omitted, will mount to `#app` or `body`.
4
+ * Normal HTML tags like `div`, `span`, `a`, etc.
24
5
  */
25
- declare function createApp(rootElement: HTMLKEnhancedElement, mountTo?: HTMLElement): void;
26
-
27
- export { createApp, h };
28
-
29
- // # from: src/global.d.ts
6
+ type HTMLTag = keyof HTMLElementTagNameMap;
30
7
 
31
- // # from: src/types/core.d.ts
32
- type HFunction = <T extends HTMLTag>(
33
- tag: T,
34
- attr?: KAttribute | string,
35
- content?: (HTMLKEnhancedElement | string)[] | HTMLKEnhancedElement | string
36
- ) => HTMLKEnhancedElement<T>;
37
-
38
- type HAlias<T extends HTMLTag> = (
39
- attr?: KAttribute | string,
40
- content?: (HTMLKEnhancedElement | string)[] | HTMLKEnhancedElement | string
41
- ) => HTMLKEnhancedElement<T>;
8
+ type RawContent = (HTMLElement | string | undefined)[] | HTMLElement | string;
9
+ type RawAttr = KAttribute | string;
42
10
 
43
11
  /**
44
12
  * Used to create enhanced HTML elements
45
13
  */
46
- export interface KAttribute {
47
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
+ interface KAttribute {
48
15
  [k: string]: any;
49
16
 
50
17
  id?: string;
@@ -53,152 +20,54 @@ export interface KAttribute {
53
20
  for?: string;
54
21
  name?: string;
55
22
  value?: string;
23
+ valueAsDate?: Date;
24
+ valueAsNumber?: number;
56
25
  label?: string;
57
26
  disabled?: string;
58
27
  min?: string;
59
28
  max?: string;
60
29
  selected?: boolean;
61
30
  checked?: boolean;
62
- class?: string | string[];
31
+ class?: string;
63
32
  style?: string | Partial<CSSStyleDeclaration>;
64
33
  action?: string;
65
- method?:
66
- | 'POST'
67
- | 'GET'
68
- | 'PUT'
69
- | 'DELETE'
70
- | 'PATCH'
71
- | 'HEAD'
72
- | 'OPTIONS'
73
- | 'CONNECT'
74
- | 'TRACE'
75
- | (string & {});
76
- }
77
-
78
- // # from: src/types/enhance.d.ts
79
- export type HTMLTag = keyof HTMLElementTagNameMap;
80
-
81
- export type KChildren = HTMLKEnhancedElement | Text;
82
-
83
- interface KOnOptions extends AddEventListenerOptions {
84
- /**
85
- * This option's priority is higher than `once`.
86
- * - when this is `1`, go with `once: true`.
87
- */
88
- triggerLimit?: number;
34
+ method?: 'POST' | 'GET' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE' | otherstring;
89
35
  }
90
36
 
91
- type KListener<E extends HTMLElement, K extends keyof HTMLElementEventMap> = (
92
- this: E,
93
- ev: HTMLElementEventMap[K]
94
- ) => unknown;
95
-
96
- interface KEnhancedPrivates {
97
- /**
98
- * Unique numeric identifier for a KT.js enhanced element instance.
99
- * Used internally to track and distinguish enhanced elements.
100
- */
101
- id: number;
102
-
103
- text: Text;
104
- }
105
-
106
- interface KEnhanced {
107
- /**
108
- * The element's text content as maintained by KT.js.
109
- * - it is not recommended to use `textContent` any more
110
- */
111
- ktext: string;
112
-
113
- /**
114
- * Array of children for this enhanced element.
115
- * - read as `Array`, not `HTMLCollection`.
116
- * - can be set to replace all child nodes.
117
- */
118
- kchildren: KChildren[];
119
-
120
- /**
121
- * Attach an event listener to the element and return a typed listener
122
- * function. The generic parameters ensure the listener and returned
123
- * function are correctly typed for the element and event.
124
- * - `triggerLimit` option is the max trigger time of a listner.
125
- * - its priority is higher than `once` option.
126
- * - if it is `1`, will fallback to `once` behavior.
127
- *
128
- * @param type event type (e.g., 'click')
129
- * @param listener event listener callback
130
- * @param options listener options or capture flag
131
- * @returns the listener function typed for the specific element and event
132
- */
133
- kon: <El extends HTMLElement, K extends keyof HTMLElementEventMap>(
134
- this: El,
135
- type: K,
136
- listener: KListener<HTMLElement, K>,
137
- options?: KOnOptions
138
- ) => KListener<El, K>;
139
-
140
- /**
141
- * Remove or detach an event listener from the element. Semantically this
142
- * is the counterpart to `kon` and accepts the same arguments. Returns
143
- * nothing.
144
- *
145
- * Note: the original inline comment said "Equivalent to `element.appendChild(this)`"
146
- * which does not apply to event removal — keep this method focused on
147
- * removing listeners according to the project's implementation.
148
- *
149
- * @param type event type
150
- * @param listener event listener to remove
151
- * @param options listener options
152
- */
153
- koff: <El extends HTMLElement, K extends keyof HTMLElementEventMap>(
154
- this: El,
155
- type: K,
156
- listener: KListener<HTMLElement, K>,
157
- options?: KOnOptions
158
- ) => void;
159
-
160
- /**
161
- * Mount this enhanced element onto a host DOM element. This typically
162
- * appends the enhanced element to the supplied `element` and performs any
163
- * needed setup. Returns the mounted enhanced element.
164
- *
165
- * @param element the DOM element to mount into
166
- * @returns the mounted enhanced element (this)
167
- */
168
- kmount: <El extends HTMLKEnhancedElement>(this: El, element: HTMLKEnhancedElement) => El;
169
- }
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;
170
63
 
171
64
  /**
172
- * Get the tags that makes HTMLElementTagNameMap[tag] = HTMLElement
173
- */
174
- type NonSpecialTags = {
175
- [K in keyof HTMLElementTagNameMap]: HTMLElement extends HTMLElementTagNameMap[K] ? K : never;
176
- }[keyof HTMLElementTagNameMap];
177
-
178
- /**
179
- * This is the core feature of KT.js - enhanced HTML elements.
180
- *
181
- * It combines the standard HTMLElement properties and methods
182
- * 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
183
70
  */
184
- export type HTMLKEnhancedElement<T extends HTMLTag = NonSpecialTags> =
185
- (HTMLElement extends HTMLElementTagNameMap[T] ? HTMLElement : HTMLElementTagNameMap[T]) &
186
- KEnhanced;
187
-
188
- // # from: src/types/type-utils.d.ts
189
- type IsSameType<A, B> =
190
- (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2
191
- ? (<T>() => T extends B ? 1 : 2) extends <T>() => T extends A ? 1 : 2
192
- ? true
193
- : false
194
- : false;
195
-
196
- type PickProperty<T> = {
197
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
198
- [K in keyof T as T[K] extends (...args: any[]) => any ? never : K]: T[K];
199
- };
71
+ declare function h<T extends HTMLTag>(tag: T, attr?: RawAttr, content?: RawContent): HTMLElementTagNameMap[T];
200
72
 
201
- type PickMethod<T> = {
202
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
203
- [K in keyof T as T[K] extends (...args: any[]) => any ? K : never]: T[K];
204
- };
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 e=Symbol("NotProvided");class t extends(null){static kid=0;static index=0;static genIndex(){return"data-k-"+(++t.index).toString(36).padStart(6,"0")}static nextKid(){return++t.kid}}const n=e=>document.createTextNode(e),o=HTMLElement.prototype.addEventListener,i=HTMLElement.prototype.removeEventListener,r=HTMLElement.prototype.appendChild,s=HTMLElement.prototype.setAttribute,a=Array.isArray,l=Array.from,c=Object.keys,f=Object.assign,m=Object.defineProperties,u=Object.is,T=Number.isSafeInteger,h=e=>"object"==typeof e&&null!==e,E=new WeakMap,d=e=>E.get(e),p=e=>E.has(e),M={kon(t,n,r=e){if(u(r,e))return o.call(this,t,n),n;if(!h(r)||!("triggerLimit"in r))return o.call(this,t,n,r),n;const s=r.triggerLimit;if(delete r.triggerLimit,!T(s)||s<=0)throw new TypeError("[Kt.js:kon] options.triggerLimit must be a positive safe integer.");if(1===s)return r.once=!0,o.call(this,t,n,r),n;let a=s;const l=function(e){const o=n.call(this,e);return a--,a<=0&&i.call(this,t,l,r),o};return o.call(this,t,l,r),l},koff(t,n,o=e){u(e,o)?i.call(this,t,n):i.call(this,t,n,o)},kmount(e){if(!p(e))throw new TypeError("[Kt.js:kmount] target must be a KText element.");return r.call(e,this)}},L={ktext:{get(){return d(this).text.textContent},set(e){d(this).text.textContent=e}},kchildren:{get(){return l(this.children)},set(e){this.textContent="",r.call(this,d(this).text);const t=e.length;for(let o=0;o<t;o++){const t=e[o];if("string"!=typeof t){if(!(t instanceof Text||p(t)))throw new TypeError(`[Kt.js:kchildren] Invalid child element at index ${o}. Only string, Text nodes or KT.js enhanced elements are allowed.`);r.call(this,t)}else r.call(this,n(t))}}}};class H{t=null;o=null;add(e,t){if("function"!=typeof t)throw new TypeError("Branch must be a function");return e&&(this.t=t),this}nomatch(e){if("function"!=typeof e)throw new TypeError("Branch must be a function");return this.t||e(),this}deferedNomatch(e){if("function"!=typeof e)throw new TypeError("Branch must be a function");return this.o=e,this}run(...e){return this.t?this.t(...e):this.o?this.o(...e):void 0}}const y=()=>new H,w=(e,t)=>e.className=t,g=(e,t)=>{t.class&&(a(t.class)?e.classList.add(...t.class):e.className=t.class,delete t.class),t.style&&("string"==typeof t.style?e.setAttribute("style",t.style):f(e.style,t.style),delete t.style);const n=c(t),o=n.length;for(let i=0;i<o;i++){const o=n[i],r=t[o];"function"!=typeof r&&("checked"!==o?"value"!==o?"selected"!==o?"defaultValue"!==o?"defaultChecked"!==o?"defaultSelected"!==o?"disabled"!==o?"readOnly"!==o?"multiple"!==o?"autofocus"!==o?"required"!==o?"hidden"!==o?"open"===o&&e instanceof HTMLDetailsElement?e.open=Boolean(r):"controls"===o&&e instanceof HTMLMediaElement?e.controls=Boolean(r):"autoplay"===o&&e instanceof HTMLMediaElement?e.autoplay=Boolean(r):"loop"===o&&e instanceof HTMLMediaElement?e.loop=Boolean(r):"muted"===o&&e instanceof HTMLMediaElement?e.muted=Boolean(r):"defer"===o&&e instanceof HTMLScriptElement?e.defer=Boolean(r):"async"===o&&e instanceof HTMLScriptElement?e.async=Boolean(r):s.call(e,String(o),r):e.hidden=Boolean(r):e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement?e.required=Boolean(r):s.call(e,o,r):e instanceof HTMLInputElement||e instanceof HTMLButtonElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement?e.autofocus=Boolean(r):s.call(e,o,r):e instanceof HTMLSelectElement?e.multiple=Boolean(r):s.call(e,o,r):e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement?e.readOnly=Boolean(r):s.call(e,o,r):e instanceof HTMLInputElement||e instanceof HTMLButtonElement||e instanceof HTMLSelectElement||e instanceof HTMLOptGroupElement||e instanceof HTMLOptionElement||e instanceof HTMLFieldSetElement||e instanceof HTMLTextAreaElement?e.disabled=Boolean(r):s.call(e,o,r):e instanceof HTMLOptionElement?e.defaultSelected=Boolean(r):s.call(e,o,r):e instanceof HTMLInputElement?e.defaultChecked=Boolean(r):s.call(e,o,r):e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement?e.defaultValue=String(r):s.call(e,o,r):e instanceof HTMLOptionElement?e.selected=Boolean(r):s.call(e,o,r):e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement?e.value=String(r):s.call(e,o,r):e instanceof HTMLInputElement?e.checked=Boolean(r):s.call(e,o,r))}},B=()=>{throw new TypeError("[Kt.js:h] attr must be an object.")},b=(e,t)=>{e.ktext=t},x=(e,t)=>{const o=t.length;for(let i=0;i<o;i++){const o=t[i];"string"!=typeof o?p(o)?r.call(e,o):k():r.call(e,n(o))}},j=(e,t)=>{p(t)||k(),r.call(e,t)},k=()=>{throw new TypeError("[Kt.js:h] content must be a string, HTMLEnhancedElement or an array of HTMLEnhancedElement.")};function S(e,o="",i=""){if("string"!=typeof e)throw new TypeError("[Kt.js:h] tagName must be a string.");const s=(e=>y().add("string"==typeof e,w).add(h(e),g).nomatch(B))(o),l=(e=>y().add("string"==typeof e,b).add(h(e),j).add(a(e),x).nomatch(k))(i),c=(f=e,document.createElement(f));var f;const u=n("");return r.call(c,u),((e,t)=>{E.set(e,t)})(c,{id:t.nextKid(),text:u}),function(e){m(e,L),e.kon=M.kon,e.koff=M.koff,e.kmount=M.kmount}(c),l.run(c,i),s.run(c,o),c}function I(t,n=e){if(!p(t))throw new TypeError("Root element must be a KText element.");const o=(i="app",document.getElementById(i)??document.body);var i;if(u(n,e))r.call(o,t);else if(!h(n))throw new TypeError("mountTo must be an HTMLElement or omitted.")}export{I as createApp,S as h};
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.0.8",
3
+ "version": "0.1.0",
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": "node ./scripts/rollup.mjs"
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-dts-merger": "^1.3.0",
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.0.2",
69
- "defered-branch": "^1.2.2"
70
66
  }
71
67
  }