@nativele/ts-dom 0.3.0 → 0.4.6
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/CHANGELOG.md +74 -0
- package/README.md +203 -17
- package/README.zh-TW.md +203 -17
- package/dist/{a11y-CeZcA10z.mjs → a11y-wWL9rie7.mjs} +175 -29
- package/dist/cli.mjs +1143 -22
- package/dist/index.d.mts +67 -8
- package/dist/index.mjs +48 -7
- package/dist/{lint-DS-IOjkf.mjs → lint-CP_i4VPA.mjs} +4 -3
- package/dist/oxlint-plugin.d.mts +12 -1
- package/dist/oxlint-plugin.mjs +59 -19
- package/dist/vite-plugin.d.mts +29 -6
- package/dist/vite-plugin.mjs +98 -19
- package/llms.txt +20 -2
- package/package.json +4 -3
package/llms.txt
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Nativele
|
|
2
2
|
|
|
3
|
-
> A TypeScript-driven, HTML-first UI library. Bind HTML templates to TypeScript custom elements. HTML describes structure and where data goes; TypeScript owns state and behavior; the DOM is the only view. Fully typed by tsc, no virtual DOM, no bundler required.
|
|
3
|
+
> A TypeScript-driven, HTML-first UI library built for type safety and AI agents. Bind HTML templates to TypeScript custom elements. HTML describes structure and where data goes; TypeScript owns state and behavior; the DOM is the only view. Fully typed by tsc, no virtual DOM, no bundler required.
|
|
4
4
|
|
|
5
|
-
Workflow: write `x.html` + `x.ts`, run `npx ts-dom
|
|
5
|
+
Workflow: write `x.html` + `x.ts`, run `npx ts-dom check` (regenerates `x.html.ts`, runs tsc and lint, points errors at the template). Import a template as `import tpl from "./x.html.js"` (note the `.js`). Lint with `npx ts-dom lint` (add `--a11y`). `npx ts-dom rules` lists every rule id. Every diagnostic is `file:line:col severity [rule-id] message` and ends with a `Fix:` hint: read the hint and apply it.
|
|
6
6
|
|
|
7
7
|
## Template syntax (HTML only names things; no expressions)
|
|
8
8
|
- `{{ name }}`: text hole, a single identifier only. NOT `{{ a.b }}` / `{{ a + 1 }}`. Not allowed in attributes.
|
|
@@ -38,6 +38,7 @@ define("my-counter", MyCounter);
|
|
|
38
38
|
Rules the compiler enforces: every `{{ hole }}` / `data-if` name must exist in state, props or derive (error `missingStateKeys`); state/props/derive names must be unique (`conflictingKeys`); a prop must not be named like an HTMLElement/ts-dom member such as `title`, `hidden`, `render` (`reservedPropNames`); emitted event names must not be native events (`nativeEventNames`); every `data-on-*` method must exist as a public method (`missingHandlers`, reported by `define()`).
|
|
39
39
|
|
|
40
40
|
## Data flow (one direction)
|
|
41
|
+
- `state`, `props`, `render`'s `view` and `derive` arguments are `DeepReadonly`: changing an object or array inside them is a tsc error. Replace with new objects (`s.items.map((i) => (i.id === id ? { ...i, done: true } : i))`). Annotate with read-only types (`readonly Item[]`, `DeepReadonly<State>`).
|
|
41
42
|
- State: changed only by its owner with `this.set(patch | s => patch)`; no change => no render. `this.batch(fn)` merges several updates. Rendering is synchronous.
|
|
42
43
|
- Props go DOWN: the parent sets them with an attribute or a property (`this.refs.child.value = v.x`, typed). A component never assigns its own props; to ask for a change it `emit`s an event.
|
|
43
44
|
- Events go UP: `emit` does not bubble; the parent handles it with `data-on-<event>` on the child tag, casting with `EmitEvent<Child, "event-name">`.
|
|
@@ -67,6 +68,23 @@ define("my-counter", MyCounter);
|
|
|
67
68
|
## Template without a component
|
|
68
69
|
`const view = tpl.instantiate()` returns `{ root: DocumentFragment, rootElement, refs, lists, text, show }` typed like a component (`rootElement` exists in the type only when the template has exactly one top-level element, `<style>` excluded), for pieces created in code. No host: `data-on-*` is inert (use `refs.x.addEventListener`) and `<slot>` is not projected.
|
|
69
70
|
|
|
71
|
+
## Lists
|
|
72
|
+
- Rule: an item with anything of its own (state, events, a nested list) is a component filled with `items =`; an item of a few texts and `data-if` is plain elements filled with `replace()`.
|
|
73
|
+
- Subscribe in `connected()`, never in the constructor: without `moveBefore` a moved item is disconnected (its `bind`/`on`/`onCleanup` released) and connected again. Data every item needs goes in a `createStore` the item binds.
|
|
74
|
+
- Full example (add, remove, sort, toggle, child emit): `examples/readme/task-board.ts` and `task-row.ts` in the repository.
|
|
75
|
+
- Items that are components: `<template data-each="todos" data-key="id" data-prop="todo"><todo-row></todo-row></template>`, then `this.lists.todos.items = view.todos` (inside `render`, guarded by `changed.has("todos")`). Keeps the element of each key, creates and removes the rest, sets the `todo` prop of each changed item; `hit.key` in handlers. The item component declares `todo` in its `props`; `tsc` checks the items against that prop type and the `data-key` field; an item component defined in a scanned folder must be exported and listed in `ts-dom-tags.ts` (run `ts-dom gen`), otherwise the assignment is a type error that names the problem.
|
|
76
|
+
- Items that are plain elements: `<template data-each="x">` with `this.lists.x.replace(items, keyFn, (item, { text, show }) => ...)`.
|
|
77
|
+
- `data-each` is never nested: a list inside an item is the item component's own `data-each`.
|
|
78
|
+
|
|
79
|
+
## Rules for agents
|
|
80
|
+
- `npx ts-dom rules --explain=<id>` (or `rules --json`) explains any rule id from a diagnostic: why it exists, a wrong example and the fix.
|
|
81
|
+
- Markup well-formedness is a formatter's job: `oxfmt --check` reports misnested tags that the library's parser would silently repair. Generate with `--whitespace=collapse` when a formatter is used.
|
|
82
|
+
- If checks behave oddly (no types, a template not found), run `npx ts-dom doctor --json` first: it reports tsconfig, import path, runtime, generated file and plugin problems with a `Fix:` each.
|
|
83
|
+
- `npx ts-dom gen --check` (writes nothing, exit 1) tells whether the generated files are stale before you trust `tsc` errors.
|
|
84
|
+
- Never edit `x.html.ts` or `ts-dom-tags.ts` (generated). After any `.html` or component change run `npx ts-dom check --json`: it regenerates, runs tsc, maps template contract errors to the template line/col (`missing-binding`, `missing-handler`, item rules), and runs lint. Fix every issue by its `Fix:` hint; never cast a type error away.
|
|
85
|
+
- No expressions in HTML; computed values go in `derive`. Change state only with `this.set()`. Lists, attributes and focus go in `render(view, changed)`; check `changed.has("items")` before rebuilding a list.
|
|
86
|
+
- Props go down (parent sets them), events go up (`emit`, handled with `data-on-<event>` on the child tag). `data-each` cannot be nested: make the inner list its own component.
|
|
87
|
+
|
|
70
88
|
## Setup
|
|
71
89
|
```sh
|
|
72
90
|
npm i -D typescript && npm i @nativele/ts-dom
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nativele/ts-dom",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A TypeScript-driven, HTML-first UI library
|
|
3
|
+
"version": "0.4.6",
|
|
4
|
+
"description": "A TypeScript-driven, HTML-first UI library built for type safety and AI agents: HTML describes the structure, TypeScript owns behavior and state, the native DOM renders it. No virtual DOM, no template expressions, no bundler required.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"html",
|
|
7
7
|
"typescript",
|
|
@@ -68,7 +68,8 @@
|
|
|
68
68
|
"test:browser": "vp test run browser/",
|
|
69
69
|
"verify:pack": "vp pack --publint --attw",
|
|
70
70
|
"smoke": "bash scripts/consumer-smoke.sh",
|
|
71
|
-
"smoke:no-bundler": "bash scripts/no-bundler-smoke.sh"
|
|
71
|
+
"smoke:no-bundler": "bash scripts/no-bundler-smoke.sh",
|
|
72
|
+
"bench": "node scripts/bench.ts"
|
|
72
73
|
},
|
|
73
74
|
"dependencies": {
|
|
74
75
|
"parse5": "^8.1.0"
|