@nativele/ts-dom 0.2.0 → 0.3.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/CHANGELOG.md +10 -1
- package/README.md +10 -4
- package/README.zh-TW.md +10 -4
- package/dist/{a11y-DZvViTVA.mjs → a11y-CeZcA10z.mjs} +22 -0
- package/dist/cli.mjs +2 -2
- package/dist/index.d.mts +6 -1
- package/dist/index.mjs +30 -1
- package/dist/{lint-B7SIRo0c.mjs → lint-DS-IOjkf.mjs} +1 -1
- package/dist/oxlint-plugin.mjs +2 -2
- package/dist/vite-plugin.mjs +1 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Version
|
|
|
10
10
|
- Adding a lint rule is a minor change; lint rules are warnings or opt-in and do not count as breaking.
|
|
11
11
|
- Before every release run `npm run verify:pack` (`publint` and `attw`), `tsc`, the unit tests, the browser tests, `npm run smoke` and `npm run smoke:no-bundler`; all of them run in `.github/workflows/ci.yml`.
|
|
12
12
|
|
|
13
|
+
## 0.3.0
|
|
14
|
+
|
|
15
|
+
- `ts-dom gen` rejects `<html>`, `<head>` and `<body>` inside a template (rule `document-tag`) instead of silently dropping them; a file that starts with `<!doctype html>` or `<html>` is still a page entry whatever its name.
|
|
16
|
+
- `tpl.instantiate().rootElement` is the template's only top-level element, typed by its tag; the type has it only for a template with exactly one top-level element (generated `x.html.ts` files carry a `rootElement` field, so regenerate them with `ts-dom gen`).
|
|
17
|
+
- Non-bubbling events such as media events (`canplay`, `loadeddata`, ...), `close`, `cancel` and `invalid` now reach `data-on-*` handlers; they were listened for in the bubble phase and never fired.
|
|
18
|
+
|
|
19
|
+
## 0.2.1
|
|
20
|
+
|
|
21
|
+
- Releases are published through npm Trusted Publishing: the release workflow stages the version without an npm token, and a maintainer approves it on npm. No library code changes.
|
|
22
|
+
|
|
13
23
|
## 0.2.0
|
|
14
24
|
|
|
15
25
|
First release.
|
|
@@ -33,7 +43,6 @@ First release.
|
|
|
33
43
|
- `whitespace: "collapse"` (CLI `--whitespace=collapse`, Vite plugin option) collapses whitespace runs and drops line-break-only text between tags; the default keeps text as written.
|
|
34
44
|
- `replace()` throws `[duplicate-key]` for two items with the same key and leaves the list untouched. `EventHit<Item>` types `hit.item` when the handler annotates it. `bind` accepts any source with `get` and `subscribe` (`ReadableStore`).
|
|
35
45
|
- `ts-dom gen --include=<glob> --exclude=<glob>` (and the Vite plugin options) generate only the selected templates, for migrating a project in steps.
|
|
36
|
-
|
|
37
46
|
### Composition
|
|
38
47
|
|
|
39
48
|
- Child components used in a template are imported automatically by the generated `x.html.ts`; HTML is the only source of dependencies.
|
package/README.md
CHANGED
|
@@ -352,7 +352,7 @@ export default template<{
|
|
|
352
352
|
}>([["h2", {}, ["Hello, {{ name }}!"]], /* ... */]);
|
|
353
353
|
```
|
|
354
354
|
|
|
355
|
-
Whole-page documents
|
|
355
|
+
Whole-page documents are page entry points, not templates, and are not processed. A file is a page when its content starts with `<!doctype html>` or `<html>` (comments before it are fine); the file name does not matter, so `index.html`, `main.html` and `login.html` all work. A template is a fragment of a component, so `<html>`, `<head>` and `<body>` are rejected in it (rule `document-tag`): the browser would drop them from the fragment and whatever you put on them would have no effect. To keep a file out of generation in another way, use `--exclude`.
|
|
356
356
|
|
|
357
357
|
## HTML Syntax
|
|
358
358
|
|
|
@@ -656,14 +656,16 @@ const off = store.subscribe((s) => console.log(s)); // returns an unsubscribe fu
|
|
|
656
656
|
```ts
|
|
657
657
|
import itemTpl from "./menu-item.html.js";
|
|
658
658
|
|
|
659
|
-
function menuItem(label: string):
|
|
659
|
+
function menuItem(label: string): HTMLLIElement {
|
|
660
660
|
const view = itemTpl.instantiate();
|
|
661
661
|
view.text.label = label;
|
|
662
662
|
view.refs.button.addEventListener("click", () => select(label));
|
|
663
|
-
return view.
|
|
663
|
+
return view.rootElement; // typed by the template's top-level tag
|
|
664
664
|
}
|
|
665
665
|
```
|
|
666
666
|
|
|
667
|
+
`rootElement` is the template's only top-level element (a top-level `<style>` does not count); it exists in the type only when the template has exactly one, so a template that later gains a second root element makes `tsc` report the use.
|
|
668
|
+
|
|
667
669
|
There is no host element, so `data-on-*` attributes do nothing here (listen on `refs`) and `<slot>` is not projected; use a component when you need those.
|
|
668
670
|
|
|
669
671
|
## Lists
|
|
@@ -704,6 +706,10 @@ Notes:
|
|
|
704
706
|
- `data-each` cannot be nested. Split it into two templates: put the inner list in its own `.html` (a child component with its own `data-each`) and use that component's tag inside the outer item.
|
|
705
707
|
- `<slot>` cannot be placed inside an item.
|
|
706
708
|
|
|
709
|
+
### Order of list updates
|
|
710
|
+
|
|
711
|
+
`replace()` and `upsert()` put a new item's element into the document first and then call `update`, so a child component placed in an item is connected before the parent has set its properties. Build per-item state in the child when it first receives data (for example in a property setter), and guard a render in `connected()` with the data it needs.
|
|
712
|
+
|
|
707
713
|
## Trusted Types, Translations and Icons
|
|
708
714
|
|
|
709
715
|
- Trusted Types: pages that enforce `require-trusted-types-for 'script'` work with no policy, because `ts-dom gen` writes the markup as data and the runtime builds it with DOM calls. Your own code must avoid `innerHTML` too.
|
|
@@ -720,7 +726,7 @@ Notes:
|
|
|
720
726
|
|
|
721
727
|
Four complementary checks. **Every message has a stable rule id and explains what is wrong, why, and how to fix it**; `npx ts-dom rules` lists all rules.
|
|
722
728
|
|
|
723
|
-
1. **codegen diagnostics** (`ts-dom gen` and the Vite plugin, with line and column numbers; on errors they abort and write no files): duplicate `data-ref`, `data-each` without a single root element, `data-each` not on a `<template>`, nested `data-each`, `data-if` on an item root element, `<slot>` inside an item, `<style>` not at the first level, invalid holes, holes inside attributes, invalid `data-on-*` (including names that collide with DOM or ts-dom members), and markup that runs code or Trusted Types blocks: `<script>`, `on*` attributes, `srcdoc`, and `javascript:` URLs.
|
|
729
|
+
1. **codegen diagnostics** (`ts-dom gen` and the Vite plugin, with line and column numbers; on errors they abort and write no files): duplicate `data-ref`, `data-each` without a single root element, `data-each` not on a `<template>`, nested `data-each`, `data-if` on an item root element, `<slot>` inside an item, `<style>` not at the first level, invalid holes, holes inside attributes, invalid `data-on-*` (including names that collide with DOM or ts-dom members), `<html>`, `<head>` and `<body>` inside a template, and markup that runs code or Trusted Types blocks: `<script>`, `on*` attributes, `srcdoc`, and `javascript:` URLs.
|
|
724
730
|
2. **tsc**: an error when TypeScript uses a name the HTML does not declare (`this.refs.nope`, `this.show("nope", true)`); all constraints between `state`, `props`, `derive`, `emits` and the HTML (see "Data Flow"); child component prop names and types; `define()` checks that the methods for `data-on-*` exist.
|
|
725
731
|
3. **Runtime**: `Component()` and components, at definition, connection, and use, throw errors that carry a `[rule id]` and a fix for the same problems.
|
|
726
732
|
4. **lint** (`ts-dom/unused-markup`, `ts-dom/data-flow`, `ts-dom/a11y`): markup declared in the HTML but never used (errors, with the HTML location), data flow suggestions and child component contracts (warnings), ARIA (warnings).
|
package/README.zh-TW.md
CHANGED
|
@@ -354,7 +354,7 @@ export default template<{
|
|
|
354
354
|
}>([["h2", {}, ["Hello, {{ name }}!"]], /* ... */]);
|
|
355
355
|
```
|
|
356
356
|
|
|
357
|
-
|
|
357
|
+
整頁文件是頁面入口,不是範本,不會被處理。判斷依據是檔案內容:以 `<!doctype html>` 或 `<html>` 開頭(前面可以有註解)就是頁面,與檔名無關,所以 `index.html`、`main.html`、`login.html` 都可以。範本是元件的片段,因此其中的 `<html>`、`<head>`、`<body>` 會被拒絕(規則 `document-tag`):瀏覽器會把它們從片段中丟掉,放在上面的任何東西都不會有效果。想用別的方式讓檔案不被處理,可以用 `--exclude`。
|
|
358
358
|
|
|
359
359
|
## HTML 語法
|
|
360
360
|
|
|
@@ -658,14 +658,16 @@ const off = store.subscribe((s) => console.log(s)); // 回傳取消函式
|
|
|
658
658
|
```ts
|
|
659
659
|
import itemTpl from "./menu-item.html.js";
|
|
660
660
|
|
|
661
|
-
function menuItem(label: string):
|
|
661
|
+
function menuItem(label: string): HTMLLIElement {
|
|
662
662
|
const view = itemTpl.instantiate();
|
|
663
663
|
view.text.label = label;
|
|
664
664
|
view.refs.button.addEventListener("click", () => select(label));
|
|
665
|
-
return view.
|
|
665
|
+
return view.rootElement; // 型別由範本第一層的標籤決定
|
|
666
666
|
}
|
|
667
667
|
```
|
|
668
668
|
|
|
669
|
+
`rootElement` 是範本第一層唯一的元素(第一層的 `<style>` 不算);只有範本剛好一個根元素時型別上才有它,所以範本日後多出第二個根元素時,`tsc` 會在使用處報錯。
|
|
670
|
+
|
|
669
671
|
這種用法沒有宿主元素,所以 `data-on-*` 不會生效(請在 `refs` 上自行監聽),`<slot>` 也不會投影;需要這些時請用元件。
|
|
670
672
|
|
|
671
673
|
## 清單
|
|
@@ -706,6 +708,10 @@ this.lists.tags.replace(
|
|
|
706
708
|
- `data-each` 不能巢狀,要分成兩套模板:把內層清單放進自己的 `.html`(有自己 `data-each` 的子元件),在外層項目裡使用該元件的標籤。
|
|
707
709
|
- `<slot>` 不能放在項目內。
|
|
708
710
|
|
|
711
|
+
### 清單更新的順序
|
|
712
|
+
|
|
713
|
+
`replace()` 與 `upsert()` 會先把新項目的元素放進文件,再呼叫 `update`,所以放在項目內的子元件會在父元件設定屬性之前就已經連接。每列自己的狀態請等子元件第一次拿到資料時再建立(例如在屬性的 setter 裡),`connected()` 裡的渲染要先確認需要的資料已經存在。
|
|
714
|
+
|
|
709
715
|
## Trusted Types、翻譯與圖示
|
|
710
716
|
|
|
711
717
|
- Trusted Types:啟用 `require-trusted-types-for 'script'` 的頁面不需要設定任何 policy 就能用,因為 `ts-dom gen` 把標記寫成資料,執行期只用 DOM 呼叫建立。你自己的程式碼也要避免 `innerHTML`。
|
|
@@ -722,7 +728,7 @@ this.lists.tags.replace(
|
|
|
722
728
|
|
|
723
729
|
四道檢查,互補。**每一則訊息都有穩定的規則代號,並說明哪裡錯、為什麼、怎麼修**;`npx ts-dom rules` 列出全部規則。
|
|
724
730
|
|
|
725
|
-
1. **codegen 診斷**(`ts-dom gen` 與 Vite 外掛,帶行列號,有錯誤時中斷、不寫檔):重複的 `data-ref`、`data-each` 沒有單一根元素、`data-each` 不在 `<template>` 上、`data-each` 巢狀、`data-if` 在項目根元素、`<slot>` 在項目內、`<style>` 不在第一層、不合法的洞、屬性內的洞、不合法的 `data-on-*`(含與 DOM 或 ts-dom
|
|
731
|
+
1. **codegen 診斷**(`ts-dom gen` 與 Vite 外掛,帶行列號,有錯誤時中斷、不寫檔):重複的 `data-ref`、`data-each` 沒有單一根元素、`data-each` 不在 `<template>` 上、`data-each` 巢狀、`data-if` 在項目根元素、`<slot>` 在項目內、`<style>` 不在第一層、不合法的洞、屬性內的洞、不合法的 `data-on-*`(含與 DOM 或 ts-dom 成員同名),範本內的 `<html>`、`<head>`、`<body>`,以及會執行程式碼或被 Trusted Types 擋下的標記:`<script>`、`on*` 屬性、`srcdoc`、`javascript:` 網址。
|
|
726
732
|
2. **tsc**:TypeScript 使用了 HTML 沒有宣告的名稱就報錯(`this.refs.nope`、`this.show("nope", true)`);`state`、`props`、`derive`、`emits` 與 HTML 之間的所有約束(見「資料流」);子元件 prop 的名稱與型別;`define()` 檢查 `data-on-*` 的方法存在。
|
|
727
733
|
3. **執行期**:`Component()` 與元件在定義、連接與使用時,對同樣的問題丟出帶 `[規則代號]` 與修正方式的錯誤。
|
|
728
734
|
4. **lint**(`ts-dom/unused-markup`、`ts-dom/data-flow`、`ts-dom/a11y`):HTML 宣告了卻沒被使用的標記(錯誤,附 HTML 位置)、資料流建議與子元件契約(警告)、ARIA(警告)。
|
|
@@ -22,6 +22,7 @@ const CODEGEN_RULES = {
|
|
|
22
22
|
"nested-each": "data-each templates cannot be nested",
|
|
23
23
|
"duplicate-each": "data-each names must be unique",
|
|
24
24
|
"each-root-count": "a data-each template needs exactly one root element",
|
|
25
|
+
"document-tag": "<html>, <head> and <body> cannot be in a template (the browser drops them from fragments)",
|
|
25
26
|
"forbidden-tag": "<script> cannot be in a template (it would run code)",
|
|
26
27
|
"forbidden-attribute": "on* event attributes and srcdoc cannot be in a template (they run code or are blocked by Trusted Types)",
|
|
27
28
|
"unsafe-url": "href / src / action / formaction cannot start with javascript:",
|
|
@@ -66,6 +67,17 @@ function analyze(html) {
|
|
|
66
67
|
...locOf(n)
|
|
67
68
|
});
|
|
68
69
|
};
|
|
70
|
+
const blanked = html.replace(/<!--[\s\S]*?-->/g, (c) => c.replace(/[^\n]/g, " "));
|
|
71
|
+
for (const m of blanked.matchAll(/<(html|head|body)(?=[\s/>])/gi)) {
|
|
72
|
+
const before = blanked.slice(0, m.index);
|
|
73
|
+
a.diagnostics.push({
|
|
74
|
+
rule: "document-tag",
|
|
75
|
+
severity: "error",
|
|
76
|
+
message: `<${m[1]?.toLowerCase()}> cannot be in a template: a template is a fragment of a component, and the browser drops <html>, <head> and <body> from fragments, so nothing you put on them has any effect. Fix: remove the tag and keep its content. If this file is a whole page, start it with <!doctype html> and it is treated as a page entry and skipped (or leave it out with --exclude).`,
|
|
77
|
+
line: before.split("\n").length,
|
|
78
|
+
col: m.index - before.lastIndexOf("\n")
|
|
79
|
+
});
|
|
80
|
+
}
|
|
69
81
|
const mark = (key, n) => {
|
|
70
82
|
if (!a.locs.has(key)) a.locs.set(key, locOf(n));
|
|
71
83
|
};
|
|
@@ -176,6 +188,15 @@ const union = (xs) => {
|
|
|
176
188
|
return arr.length ? arr.map(q).join(" | ") : "never";
|
|
177
189
|
};
|
|
178
190
|
const obj = (m) => `{ ${[...m].map(([n, t]) => `${q(n)}: ${t}`).join("; ")} }`;
|
|
191
|
+
/** The type of the template's only top-level element (a `<style>` does not count); `never` when there is not exactly one, or other text sits beside it. */
|
|
192
|
+
function rootElementType(html) {
|
|
193
|
+
const tops = parseFragment(html).childNodes.filter((n) => n.nodeName !== "#comment" && !(n.nodeName === "#text" && !n.value.trim()));
|
|
194
|
+
const elements = tops.filter((n) => isEl$1(n) && !(n.tagName === "style" && n.namespaceURI === HTML_NS) && !(n.tagName === "template" && n.attrs.some((a) => a.name === "data-each")));
|
|
195
|
+
const others = tops.filter((n) => !(isEl$1(n) && (n.tagName === "style" || n.tagName === "template")));
|
|
196
|
+
if (elements.length !== 1 || others.length !== 1) return "never";
|
|
197
|
+
const el = elements[0];
|
|
198
|
+
return el.namespaceURI === HTML_NS ? `El<${JSON.stringify(el.tagName)}>` : "SVGElement";
|
|
199
|
+
}
|
|
179
200
|
function globToRegExp(glob) {
|
|
180
201
|
let re = "";
|
|
181
202
|
for (let i = 0; i < glob.length; i++) {
|
|
@@ -240,6 +261,7 @@ function generateModule(html, options = {}, imports = []) {
|
|
|
240
261
|
lists: { ${lists} };
|
|
241
262
|
ifs: ${union(a.scope.ifs)};
|
|
242
263
|
slots: ${union(a.slots)};
|
|
264
|
+
rootElement: ${rootElementType(html)};
|
|
243
265
|
text: ${union(a.scope.text)};
|
|
244
266
|
events: ${union(a.events)};
|
|
245
267
|
}`;
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { d as listHtml, i as CodegenError, n as checkA11y, p as watchAll, r as CODEGEN_RULES, s as generateAll, t as A11Y_RULES } from "./a11y-
|
|
3
|
-
import { c as lintUsage, n as UNUSED_MARKUP_RULES, o as formatIssue, s as lintDataFlow, t as DATA_FLOW_RULES } from "./lint-
|
|
2
|
+
import { d as listHtml, i as CodegenError, n as checkA11y, p as watchAll, r as CODEGEN_RULES, s as generateAll, t as A11Y_RULES } from "./a11y-CeZcA10z.mjs";
|
|
3
|
+
import { c as lintUsage, n as UNUSED_MARKUP_RULES, o as formatIssue, s as lintDataFlow, t as DATA_FLOW_RULES } from "./lint-DS-IOjkf.mjs";
|
|
4
4
|
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
5
5
|
import { join, relative } from "node:path";
|
|
6
6
|
// src/cli.ts
|
package/dist/index.d.mts
CHANGED
|
@@ -68,6 +68,8 @@ interface Schema {
|
|
|
68
68
|
events: string;
|
|
69
69
|
ifs: string;
|
|
70
70
|
slots: string;
|
|
71
|
+
/** The template's only top-level element (a `<style>` does not count), or `never` when there is not exactly one. */
|
|
72
|
+
rootElement: Element;
|
|
71
73
|
}
|
|
72
74
|
/**
|
|
73
75
|
* A template's parsed markup, written by codegen: a string is a text node, `["#comment", text]` a comment,
|
|
@@ -75,7 +77,10 @@ interface Schema {
|
|
|
75
77
|
*/
|
|
76
78
|
type TemplateNode = string | readonly [tag: string, attrs: Readonly<Record<string, string>>, children: readonly TemplateNode[], ns?: string] | readonly ["#comment", string];
|
|
77
79
|
/** A template built without a component: the nodes, and the typed handles to the places the template names. */
|
|
78
|
-
|
|
80
|
+
type TemplateInstance<S extends Schema> = TemplateInstanceBase<S> & ([S["rootElement"]] extends [never] ? unknown : {
|
|
81
|
+
readonly rootElement: S["rootElement"];
|
|
82
|
+
});
|
|
83
|
+
interface TemplateInstanceBase<S extends Schema> {
|
|
79
84
|
/** The built nodes; insert it (or its children) where it should show. */
|
|
80
85
|
readonly root: DocumentFragment;
|
|
81
86
|
/** The elements marked with `data-ref`. */
|
package/dist/index.mjs
CHANGED
|
@@ -357,7 +357,33 @@ const NON_BUBBLING = /* @__PURE__ */ new Set([
|
|
|
357
357
|
"load",
|
|
358
358
|
"error",
|
|
359
359
|
"scroll",
|
|
360
|
-
"
|
|
360
|
+
"scrollend",
|
|
361
|
+
"toggle",
|
|
362
|
+
"beforetoggle",
|
|
363
|
+
"cancel",
|
|
364
|
+
"close",
|
|
365
|
+
"invalid",
|
|
366
|
+
"abort",
|
|
367
|
+
"canplay",
|
|
368
|
+
"canplaythrough",
|
|
369
|
+
"durationchange",
|
|
370
|
+
"emptied",
|
|
371
|
+
"ended",
|
|
372
|
+
"loadeddata",
|
|
373
|
+
"loadedmetadata",
|
|
374
|
+
"loadstart",
|
|
375
|
+
"pause",
|
|
376
|
+
"play",
|
|
377
|
+
"playing",
|
|
378
|
+
"progress",
|
|
379
|
+
"ratechange",
|
|
380
|
+
"seeked",
|
|
381
|
+
"seeking",
|
|
382
|
+
"stalled",
|
|
383
|
+
"suspend",
|
|
384
|
+
"timeupdate",
|
|
385
|
+
"volumechange",
|
|
386
|
+
"waiting"
|
|
361
387
|
]);
|
|
362
388
|
function Component(tpl, opts = {}) {
|
|
363
389
|
const shadow = opts.shadow === true;
|
|
@@ -698,10 +724,13 @@ function template(nodes) {
|
|
|
698
724
|
build: () => buildNodes(nodes),
|
|
699
725
|
instantiate() {
|
|
700
726
|
const root = buildNodes(nodes);
|
|
727
|
+
const tops = [...root.children].filter((el) => el.localName !== "style" && !(el instanceof HTMLTemplateElement && el.hasAttribute("data-each")));
|
|
728
|
+
const rootElement = tops.length === 1 ? tops[0] : void 0;
|
|
701
729
|
const { refs, lists, text, conds } = mountTemplate(root);
|
|
702
730
|
conds.hideAll();
|
|
703
731
|
return {
|
|
704
732
|
root,
|
|
733
|
+
rootElement,
|
|
705
734
|
refs,
|
|
706
735
|
lists,
|
|
707
736
|
text,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as analyze, d as listHtml, f as scanDefines } from "./a11y-
|
|
1
|
+
import { a as analyze, d as listHtml, f as scanDefines } from "./a11y-CeZcA10z.mjs";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { basename, dirname, relative } from "node:path";
|
|
4
4
|
// src/lib/lint.ts
|
package/dist/oxlint-plugin.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as checkA11y } from "./a11y-
|
|
2
|
-
import { a as dataFlow, i as contractsFor, l as templateCode, r as componentClasses, u as unusedMarkup } from "./lint-
|
|
1
|
+
import { n as checkA11y } from "./a11y-CeZcA10z.mjs";
|
|
2
|
+
import { a as dataFlow, i as contractsFor, l as templateCode, r as componentClasses, u as unusedMarkup } from "./lint-DS-IOjkf.mjs";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { dirname, resolve } from "node:path";
|
|
5
5
|
// src/lib/oxlint-plugin.ts
|
package/dist/vite-plugin.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as generateFile, d as listHtml, i as CodegenError, l as isFullPage, n as checkA11y, o as formatDiagnostics, s as generateAll, u as isSelected } from "./a11y-
|
|
1
|
+
import { c as generateFile, d as listHtml, i as CodegenError, l as isFullPage, n as checkA11y, o as formatDiagnostics, s as generateAll, u as isSelected } from "./a11y-CeZcA10z.mjs";
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import { resolve, sep } from "node:path";
|
|
4
4
|
// src/lib/vite-plugin.ts
|
package/llms.txt
CHANGED
|
@@ -65,7 +65,7 @@ define("my-counter", MyCounter);
|
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
## Template without a component
|
|
68
|
-
`const view = tpl.instantiate()` returns `{ root: DocumentFragment, refs, lists, text, show }` typed like a component, for pieces created in code. No host: `data-on-*` is inert (use `refs.x.addEventListener`) and `<slot>` is not projected.
|
|
68
|
+
`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
69
|
|
|
70
70
|
## Setup
|
|
71
71
|
```sh
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nativele/ts-dom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A TypeScript-driven, HTML-first UI library. Bind HTML to TypeScript: HTML describes the structure, TypeScript owns behavior and state, and the DOM is the single source of truth. Fully typed, no virtual DOM, no bundler required.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"html",
|