slexkit 0.3.1 → 0.3.3
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 +18 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/ai/llms-full.txt +53 -21
- package/dist/ai/llms.txt +1 -1
- package/dist/ai/slexkit-ai-manifest.json +29 -29
- package/dist/base.css +0 -46
- package/dist/components/index.js +12 -10
- package/dist/components/input.css +85 -13
- package/dist/components/slider.css +56 -13
- package/dist/components/slider.js +12 -10
- package/dist/components/text-input.css +29 -0
- package/dist/runtime.cjs +46 -24
- package/dist/runtime.js +46 -24
- package/dist/slexkit.cjs +58 -34
- package/dist/slexkit.css +85 -59
- package/dist/slexkit.js +58 -34
- package/dist/types/engine/types.d.ts +1 -1
- package/dist/types/version.d.ts +2 -2
- package/dist/umd/slexkit.tooling.umd.js +57 -33
- package/dist/umd/slexkit.umd.js +58 -34
- package/package.json +1 -1
- package/src/components/svelte/input/Slider.svelte +15 -13
- package/src/styles/components/slider.css +56 -13
- package/src/styles/components/text-input.css +29 -0
- package/src/styles/layout.css +0 -46
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slexkit-ai-docs",
|
|
3
3
|
"packageName": "slexkit",
|
|
4
|
-
"version": "0.3.
|
|
5
|
-
"generatedAt": "2026-06-
|
|
4
|
+
"version": "0.3.3",
|
|
5
|
+
"generatedAt": "2026-06-20T10:49:17.610Z",
|
|
6
6
|
"docs": {
|
|
7
7
|
"llms.txt": {
|
|
8
8
|
"path": "/llms.txt",
|
|
9
9
|
"title": "llms.txt",
|
|
10
10
|
"summary": "- [Full documentation](/llms-full.txt): all canonical English docs pages in one text file.",
|
|
11
|
-
"hash": "
|
|
11
|
+
"hash": "8003ec64"
|
|
12
12
|
},
|
|
13
13
|
"llms-full.txt": {
|
|
14
14
|
"path": "/llms-full.txt",
|
|
15
15
|
"title": "llms-full.txt",
|
|
16
|
-
"summary": "Version: 0.3.
|
|
17
|
-
"hash": "
|
|
16
|
+
"summary": "Version: 0.3.3",
|
|
17
|
+
"hash": "8ad843a0"
|
|
18
18
|
},
|
|
19
19
|
"llms-components.txt": {
|
|
20
20
|
"path": "/llms-components.txt",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"href": "/",
|
|
57
57
|
"rawHref": "/README.md",
|
|
58
58
|
"sourcePath": "README.md",
|
|
59
|
-
"body": "<div align=\"center\">\n <p>\n <img src=\"site/assets/logo.svg\" alt=\"SlexKit\" width=\"84\" height=\"84\" />\n </p>\n <h1>SlexKit</h1>\n <p><strong>Streaming Live EXpressions Kit</strong></p>\n <p>\n \"Docs as tools, tools as docs.\" Give Markdown interactive power and make every AI output come alive.\n </p>\n <p>\n <a href=\"site/content/guides/intro/en-US.md\">Documentation</a> ·\n <a href=\"site/content/components/accordion/en-US.md\">Components</a> ·\n <a href=\"site/content/reference/spec/en-US.md\">Specification</a> ·\n <a href=\"site/content/guides/ai-agents/en-US.md\">AI / Agents</a> ·\n <a href=\"README.zh-CN.md\">简体中文</a>\n </p>\n <p>\n <img alt=\"version\" src=\"https://img.shields.io/badge/version-0.3.
|
|
60
|
-
"hash": "
|
|
59
|
+
"body": "<div align=\"center\">\n <p>\n <img src=\"site/assets/logo.svg\" alt=\"SlexKit\" width=\"84\" height=\"84\" />\n </p>\n <h1>SlexKit</h1>\n <p><strong>Streaming Live EXpressions Kit</strong></p>\n <p>\n \"Docs as tools, tools as docs.\" Give Markdown interactive power and make every AI output come alive.\n </p>\n <p>\n <a href=\"site/content/guides/intro/en-US.md\">Documentation</a> ·\n <a href=\"site/content/components/accordion/en-US.md\">Components</a> ·\n <a href=\"site/content/reference/spec/en-US.md\">Specification</a> ·\n <a href=\"site/content/guides/ai-agents/en-US.md\">AI / Agents</a> ·\n <a href=\"README.zh-CN.md\">简体中文</a>\n </p>\n <p>\n <img alt=\"version\" src=\"https://img.shields.io/badge/version-0.3.3-18181b\">\n <img alt=\"script\" src=\"https://img.shields.io/badge/Slex-v0.1-18181b\">\n <img alt=\"TypeScript\" src=\"https://img.shields.io/badge/runtime-TypeScript-3178c6\">\n <img alt=\"Svelte 5\" src=\"https://img.shields.io/badge/components-Svelte_5-ff3e00\">\n <img alt=\"license\" src=\"https://img.shields.io/badge/license-MIT-16a34a\">\n </p>\n</div>\n\n## Live interface blocks inside Markdown\n\n**SlexKit** turns explicit `slex` Markdown fences into live, stateful UI blocks. A Slex source is just a JavaScript object literal: `g` holds state and logic, `layout` describes the component tree, and the browser runtime renders the result in place.\n\nIt is built for chat messages, documents, agent panels, tool results, and AI-authored dashboards. It is not a full application framework.\n\n## Installation\n\n> Just want to use SlexKit in Obsidian? Open **Settings -> Community plugins**, search for **SlexKit**, then install and enable it. The npm package below is for developers integrating SlexKit into web apps, Markdown renderers, Streamdown, or custom hosts.\n\n```sh\nnpm install slexkit\n```\n\n```ts\nimport { mount } from \"slexkit\";\nimport \"slexkit/style.css\";\n```\n\n## Usage\n\n```html\n<div id=\"app\"></div>\n\n<script type=\"module\">\n import { mount } from \"slexkit\";\n import \"slexkit/style.css\";\n\n mount(\n {\n slex: \"0.1\",\n namespace: \"hello\",\n g: { name: \"World\", count: 0 },\n layout: {\n \"card:greeting\": {\n title: \"Greeting\",\n \"text:message\": {\n \"$text\": \"'Hello, ' + g.name + '! Count: ' + g.count\"\n },\n \"button:add\": {\n label: \"+1\",\n onclick: \"g.count++\"\n }\n }\n }\n },\n document.getElementById(\"app\")\n );\n</script>\n```\n\n## Markdown Native\n\nSlexKit-capable hosts process explicit `slex` fences only. Plain `js`, `json`, and unlabeled code blocks stay inert.\n\n````md\n```slex\n{\n slex: \"0.1\",\n namespace: \"status\",\n g: { done: 3, total: 4 },\n layout: {\n \"badge:state\": { label: \"Ready\", tone: \"success\" },\n \"text:summary\": { \"$text\": \"g.done + '/' + g.total + ' complete'\" }\n }\n}\n```\n\n**Status:** Ready. 3/4 complete.\n````\n\nMarkdown platforms without SlexKit support show the fallback text. Hosts with SlexKit render the interactive UI.\n\n## What You Get\n\n- **Zero-build Slex source**: object literals with no imports, scaffolding, or component bundling in the generated output.\n- **Reactive `g` / `layout` model**: centralized state and logic with declarative component trees.\n- **Expression pipes**: `$` read expressions for dynamic props and `on*` write expressions for events.\n- **Directives**: `$if` and `$for` for conditional rendering and keyed list reconciliation.\n- **Official Svelte components**: 40+ layout, input, content, display, disclosure, feedback, and tooling components.\n- **Extensible registry**: custom component types, Svelte renderers, and component state modes.\n- **Trusted and secure runtimes**: host-realm rendering for trusted content, sandbox iframe rendering for untrusted source.\n- **ToolHost**: confirm, choose, and fill-form templates for structured AI tool-call UX.\n- **AI-friendly docs surface**: `llms.txt`, skills, and the `@slexkit/mcp` read-only MCP server.\n\n## Packages\n\n| Package | Install | Contents |\n| --- | --- | --- |\n| `slexkit` | `npm install slexkit` | Runtime, Svelte components, ToolHost, styles |\n| `@slexkit/runtime` | `npm install slexkit @slexkit/runtime` | Component-free runtime wrapper |\n| `@slexkit/components-svelte` | `npm install slexkit @slexkit/runtime @slexkit/components-svelte` | Svelte component registration |\n| `@slexkit/theme-shadcn` | `npm install @slexkit/theme-shadcn` | CSS theme tokens |\n| `@slexkit/streamdown` | `npm install slexkit @slexkit/theme-shadcn @slexkit/streamdown streamdown react react-dom` | React / Streamdown Markdown renderer |\n| `@slexkit/mcp` | `npx -y @slexkit/mcp` | Read-only MCP server for docs, examples, and source validation |\n\nSee [Package Boundaries](site/content/reference/packages/en-US.md) for details.\n\n## Integrations\n\n| Host | Path |\n| --- | --- |\n| Browser DOM | `mount()`, `ingest()`, `boot()`, `disposeNamespace()` |\n| Markdown renderers | `createSlexKitMarkdownRuntimeHost()` |\n| React / Streamdown | `@slexkit/streamdown` |\n| Obsidian | Install **SlexKit** from Community Plugins; release repo: <https://github.com/slexkit/obsidian-slexkit> |\n| AI agents | `@slexkit/mcp`, `llms.txt`, SlexKit skill docs |\n| Custom components | `register()`, `registerSvelteComponent()`, `registerSubset()` |\n\n## Security Runtime\n\nTrusted mode runs inside the host realm and is intended for application-authored or reviewed source. Secure mode isolates untrusted Slex source in a sandbox iframe with an opaque origin, nonce-based CSP, locked-down globals, host-mediated network access, and a heartbeat watchdog.\n\nRead the [Security Runtime](site/content/reference/security/en-US.md) docs before rendering unreviewed user or model output.\n\n## Documentation\n\n| Document | Topic |\n| --- | --- |\n| [Getting Started](site/content/guides/quick-start/en-US.md) | Install and render a first Markdown-friendly Slex source |\n| [Integration](site/content/guides/integration/en-US.md) | Streamdown, Obsidian, and custom host paths |\n| [Runtime model](site/content/reference/runtime/en-US.md) | Mounting, updates, namespace store, lifecycle |\n| [Slex usage reference](site/content/reference/usage/en-US.md) | Source structure, directives, expressions, events, custom components |\n| [Security runtime](site/content/reference/security/en-US.md) | Threat model, sandbox iframe, policy, postMessage bridge |\n| [Slex Specification](site/content/reference/spec/en-US.md) | Protocol v0.1, types, merge rules, lifecycle hooks |\n| [ToolHost](site/content/reference/toolhost/en-US.md) | Tool-call rendering and custom templates |\n| [Icon system](site/content/reference/icons/en-US.md) | Phosphor icons, custom registration, Iconify fallback |\n| [AI / Agents](site/content/guides/ai-agents/en-US.md) | `llms.txt`, MCP server, skills, and authoring rules |\n| [Changelog](CHANGELOG.md) | Release notes and notable changes |\n\n## Version Information\n\n```ts\nimport { SLEXKIT_VERSION, SLEX_PROTOCOL_VERSION, getSlexKitInfo } from \"slexkit\";\n```\n\nThe npm package version, component implementation version, and Slex protocol version are exposed separately. The current public protocol is `v0.1`.\n\n## License\n\nMIT",
|
|
60
|
+
"hash": "b19850c1"
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
"id": "guides/intro",
|
|
@@ -155,8 +155,8 @@
|
|
|
155
155
|
"href": "/zh-CN/examples/multi-input-coordination",
|
|
156
156
|
"rawHref": "/zh-CN/examples/multi-input-coordination.md",
|
|
157
157
|
"sourcePath": "content/examples/multi-input-coordination/zh-CN.md",
|
|
158
|
-
"body": "# 多输入协同:两个滑块联动\n\n真实场景中往往有多个输入变量,它们相互影响。这需要引入两样新东西:\n1. **`g.method()`** — 依赖其他状态的计算值(类似 Vue computed)\n2. **`$if`** — 条件渲染(根据状态决定显示或隐藏组件)\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"learn_multi_coordination\",\n g: {\n width: 120,\n height: 80,\n area: function () { return this.width * this.height; },\n isLandscape: function () { return this.width > this.height; },\n ratio: function () { return (this.width / this.height).toFixed(2); }\n },\n layout: {\n \"section:coordinated\": {\n eyebrow: \"入门教程 · 3/4\",\n title: \"多输入协同:矩形尺寸联动\",\n subtitle: \"同时调整宽和高,面积和宽高比自动重新计算。这就是 g 方法的力量。\",\n \"grid:params\": {\n columns: 1, mdColumns: 2,\n \"column:w\": {\n \"input:
|
|
159
|
-
"hash": "
|
|
158
|
+
"body": "# 多输入协同:两个滑块联动\n\n真实场景中往往有多个输入变量,它们相互影响。这需要引入两样新东西:\n1. **`g.method()`** — 依赖其他状态的计算值(类似 Vue computed)\n2. **`$if`** — 条件渲染(根据状态决定显示或隐藏组件)\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"learn_multi_coordination\",\n g: {\n width: 120,\n height: 80,\n area: function () { return this.width * this.height; },\n isLandscape: function () { return this.width > this.height; },\n ratio: function () { return (this.width / this.height).toFixed(2); }\n },\n layout: {\n \"section:coordinated\": {\n eyebrow: \"入门教程 · 3/4\",\n title: \"多输入协同:矩形尺寸联动\",\n subtitle: \"同时调整宽和高,面积和宽高比自动重新计算。这就是 g 方法的力量。\",\n \"grid:params\": {\n columns: 1, mdColumns: 2,\n \"column:w\": {\n \"input:widthInput\": { label: \"宽度\", \"$value\": \"g.width\", type: \"number\", unit: \"px\", onchange: \"g.width = Number($event || 0)\" },\n \"slider:widthSlider\": { label: \"宽度\", \"$value\": \"g.width\", min: 20, max: 300, step: 5, unit: \"px\", onchange: \"g.width = Number($event)\" }\n },\n \"column:h\": {\n \"input:heightInput\": { label: \"高度\", \"$value\": \"g.height\", type: \"number\", unit: \"px\", onchange: \"g.height = Number($event || 0)\" },\n \"slider:heightSlider\": { label: \"高度\", \"$value\": \"g.height\", min: 20, max: 300, step: 5, unit: \"px\", onchange: \"g.height = Number($event)\" }\n }\n },\n \"grid:results\": {\n columns: 1, mdColumns: 3,\n \"stat:area\": { label: \"面积\", \"$value\": \"g.area()\", unit: \"px²\" },\n \"stat:ratio\": { label: \"宽高比\", \"$value\": \"g.ratio()\" },\n \"badge:orientation\": {\n \"$label\": \"g.isLandscape() ? '横向' : g.width === g.height ? '正方形' : '纵向'\",\n \"$tone\": \"g.isLandscape() ? 'info' : g.width === g.height ? 'success' : 'warning'\"\n }\n },\n \"formula:areaEq\": { \"$tex\": \"'\\\\\\\\text{面积} = ' + g.width + ' \\\\\\\\times ' + g.height + ' = ' + g.area() + '\\\\\\\\text{ px}^2'\" },\n \"callout:tip\": {\n \"$tone\": \"g.isLandscape() ? 'info' : 'warning'\",\n \"$text\": \"g.isLandscape() ? '当前为横向(Landscape)。横向更适用于宽屏展示。' : '当前为纵向(Portrait)。纵向更适用于移动端阅读。'\"\n },\n \"callout:squareTip\": {\n \"$if\": \"g.width === g.height\",\n tone: \"success\",\n text: \"这是一个正方形!宽高完全相等。\"\n }\n }\n }\n}\n```\n\n**三个新知识点:**\n\n| 概念 | 写法 | 含义 |\n|:---|:---|:---|\n| g 方法 | `area: function() { return this.width * this.height; }` | `this` 指向 g 对象本身,返回动态计算值 |\n| 动态公式 | `\"$tex\": \"'...' + g.width + '...'\"` | formula 组件可根据 g 值实时渲染 KaTeX |\n| 条件渲染 | `\"$if\": \"g.width === g.height\"` | 只有表达式返回 true 时该组件才渲染 |",
|
|
159
|
+
"hash": "8bbfb723"
|
|
160
160
|
},
|
|
161
161
|
{
|
|
162
162
|
"id": "examples/tabs-and-branching",
|
|
@@ -177,8 +177,8 @@
|
|
|
177
177
|
"href": "/zh-CN/examples/salary-calculator",
|
|
178
178
|
"rawHref": "/zh-CN/examples/salary-calculator.md",
|
|
179
179
|
"sourcePath": "content/examples/salary-calculator/zh-CN.md",
|
|
180
|
-
"body": "# 五险一金计算器\n\n你面试拿到一个offer,月薪2万,到手能拿多少?HR说五险一金要扣一大笔,但具体扣多少、怎么算,每个城市还不一样。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_salary_calculator\",\n g: {\n base: 20000,\n city: \"beijing\",\n rates: {\n beijing: { pensionP: 8, medicalP: 2, unemploymentP: 0.5, pensionC: 16, medicalC: 8, unemploymentC: 0.5, injury: 0.2, maternity: 0.8, housing: 12 },\n shanghai: { pensionP: 8, medicalP: 2, unemploymentP: 0.5, pensionC: 16, medicalC: 8, unemploymentC: 0.5, injury: 0.2, maternity: 0.8, housing: 7 },\n guangzhou: { pensionP: 8, medicalP: 2, unemploymentP: 0.5, pensionC: 16, medicalC: 8, unemploymentC: 0.5, injury: 0.2, maternity: 0.8, housing: 5 },\n shenzhen: { pensionP: 8, medicalP: 2, unemploymentP: 0.5, pensionC: 16, medicalC: 8, unemploymentC: 0.5, injury: 0.2, maternity: 0.8, housing: 5 }\n },\n currentRate: function () { return this.rates[this.city] || this.rates.beijing; },\n personalRate: function () { var r = this.currentRate(); return r.pensionP + r.medicalP + r.unemploymentP + r.housing; },\n companyRate: function () { var r = this.currentRate(); return r.pensionC + r.medicalC + r.unemploymentC + r.injury + r.maternity + r.housing; },\n personalTotal: function () { return this.base * this.personalRate() / 100; },\n companyTotal: function () { return this.base * this.companyRate() / 100; },\n total: function () { return this.personalTotal() + this.companyTotal(); },\n takeHome: function () { return this.base - this.personalTotal(); },\n cityLabel: function () { return { beijing: \"北京\", shanghai: \"上海\", guangzhou: \"广州\", shenzhen: \"深圳\" }[this.city] || this.city; }\n },\n layout: {\n \"section:salary\": {\n title: \"五险一金计算器\",\n subtitle: \"输入税前工资和城市,实时计算五险一金明细。\",\n \"grid:params\": {\n columns: 1, mdColumns: 2,\n \"column:baseField\": {\n \"input:
|
|
181
|
-
"hash": "
|
|
180
|
+
"body": "# 五险一金计算器\n\n你面试拿到一个offer,月薪2万,到手能拿多少?HR说五险一金要扣一大笔,但具体扣多少、怎么算,每个城市还不一样。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_salary_calculator\",\n g: {\n base: 20000,\n city: \"beijing\",\n rates: {\n beijing: { pensionP: 8, medicalP: 2, unemploymentP: 0.5, pensionC: 16, medicalC: 8, unemploymentC: 0.5, injury: 0.2, maternity: 0.8, housing: 12 },\n shanghai: { pensionP: 8, medicalP: 2, unemploymentP: 0.5, pensionC: 16, medicalC: 8, unemploymentC: 0.5, injury: 0.2, maternity: 0.8, housing: 7 },\n guangzhou: { pensionP: 8, medicalP: 2, unemploymentP: 0.5, pensionC: 16, medicalC: 8, unemploymentC: 0.5, injury: 0.2, maternity: 0.8, housing: 5 },\n shenzhen: { pensionP: 8, medicalP: 2, unemploymentP: 0.5, pensionC: 16, medicalC: 8, unemploymentC: 0.5, injury: 0.2, maternity: 0.8, housing: 5 }\n },\n currentRate: function () { return this.rates[this.city] || this.rates.beijing; },\n personalRate: function () { var r = this.currentRate(); return r.pensionP + r.medicalP + r.unemploymentP + r.housing; },\n companyRate: function () { var r = this.currentRate(); return r.pensionC + r.medicalC + r.unemploymentC + r.injury + r.maternity + r.housing; },\n personalTotal: function () { return this.base * this.personalRate() / 100; },\n companyTotal: function () { return this.base * this.companyRate() / 100; },\n total: function () { return this.personalTotal() + this.companyTotal(); },\n takeHome: function () { return this.base - this.personalTotal(); },\n cityLabel: function () { return { beijing: \"北京\", shanghai: \"上海\", guangzhou: \"广州\", shenzhen: \"深圳\" }[this.city] || this.city; }\n },\n layout: {\n \"section:salary\": {\n title: \"五险一金计算器\",\n subtitle: \"输入税前工资和城市,实时计算五险一金明细。\",\n \"grid:params\": {\n columns: 1, mdColumns: 2,\n \"column:baseField\": {\n \"input:baseInput\": { label: \"税前工资\", \"$value\": \"g.base\", type: \"number\", unit: \"元/月\", onchange: \"g.base = Number($event || 0)\" },\n \"slider:baseSlider\": { label: \"税前工资\", \"$value\": \"g.base\", min: 3000, max: 50000, step: 500, unit: \"元\", onchange: \"g.base = Number($event)\" }\n },\n \"column:cityField\": {\n \"select:city\": {\n label: \"缴纳城市\",\n \"$value\": \"g.city\",\n options: [\n { label: \"北京\", value: \"beijing\" },\n { label: \"上海\", value: \"shanghai\" },\n { label: \"广州\", value: \"guangzhou\" },\n { label: \"深圳\", value: \"shenzhen\" }\n ],\n onchange: \"g.city = String($event)\"\n }\n }\n },\n \"grid:summary\": {\n columns: 1, mdColumns: 3,\n \"stat:personal\": { label: \"个人扣除\", \"$value\": \"g.personalTotal().toFixed(0)\", unit: \"元\" },\n \"stat:company\": { label: \"公司缴纳\", \"$value\": \"g.companyTotal().toFixed(0)\", unit: \"元\" },\n \"stat:takehome\": { label: \"到手工资\", \"$value\": \"g.takeHome().toFixed(0)\", unit: \"元\" }\n }\n }\n }\n}\n```\n\n换个城市看看,公积金比例差很多——北京12%,上海7%,到手工资能差好几百。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_salary_calculator\",\n layout: {\n \"card:detail\": {\n title: \"各项明细\",\n \"grid:personal\": {\n columns: 1, mdColumns: 4,\n \"stat:pension_p\": { label: \"养老(8%)\", \"$value\": \"(g.base * 0.08).toFixed(0)\", unit: \"元\" },\n \"stat:medical_p\": { label: \"医疗(2%)\", \"$value\": \"(g.base * 0.02).toFixed(0)\", unit: \"元\" },\n \"stat:unemployment_p\": { label: \"失业(0.5%)\", \"$value\": \"(g.base * 0.005).toFixed(0)\", unit: \"元\" },\n \"stat:housing_p\": { label: \"公积金\", \"$value\": \"(g.base * g.currentRate().housing / 100).toFixed(0)\", unit: \"元\" }\n },\n \"grid:company\": {\n columns: 1, mdColumns: 4,\n \"stat:pension_c\": { label: \"养老(16%)\", \"$value\": \"(g.base * 0.16).toFixed(0)\", unit: \"元\" },\n \"stat:medical_c\": { label: \"医疗(8%)\", \"$value\": \"(g.base * 0.08).toFixed(0)\", unit: \"元\" },\n \"stat:unemployment_c\": { label: \"失业(0.5%)\", \"$value\": \"(g.base * 0.005).toFixed(0)\", unit: \"元\" },\n \"stat:other_c\": { label: \"工伤+生育\", \"$value\": \"(g.base * 0.01).toFixed(0)\", unit: \"元\" }\n },\n \"callout:note\": {\n \"$tone\": \"g.personalTotal() > 3000 ? 'warning' : 'info'\",\n \"$text\": \"g.personalTotal() > 3000 ? '个人扣除超过3000元,到手工资可能低于预期。' : '公积金比例越高,到手工资越少,但公积金可以提取使用。'\"\n }\n }\n }\n}\n```\n\n| 城市 | 养老 | 医疗 | 失业 | 公积金 | 个人合计 |\n|------|------|------|------|--------|----------|\n| 北京 | 8% | 2% | 0.5% | 12% | 22.5% |\n| 上海 | 8% | 2% | 0.5% | 7% | 17.5% |\n| 广州 | 8% | 2% | 0.5% | 5% | 15.5% |\n| 深圳 | 8% | 2% | 0.5% | 5% | 15.5% |",
|
|
181
|
+
"hash": "bbc62fda"
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
184
|
"id": "examples/project-cost-estimator",
|
|
@@ -188,8 +188,8 @@
|
|
|
188
188
|
"href": "/zh-CN/examples/project-cost-estimator",
|
|
189
189
|
"rawHref": "/zh-CN/examples/project-cost-estimator.md",
|
|
190
190
|
"sourcePath": "content/examples/project-cost-estimator/zh-CN.md",
|
|
191
|
-
"body": "# 软件项目成本估算器\n\n老板问你:\"这个项目要多少钱?\"你说:\"我算算。\"然后打开Excel,填一堆公式。其实不用——输入团队配置和周期,成本自动算出来。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_project_cost\",\n g: {\n frontend: 2, backend: 3, tester: 1, designer: 1,\n months: 6,\n salary: 15000,\n teamSize: function () { return this.frontend + this.backend + this.tester + this.designer; },\n laborCost: function () { return this.teamSize() * this.salary * this.months; },\n equipmentCost: function () { return this.teamSize() * 5000; },\n officeCost: function () { return this.teamSize() * 2000 * this.months; },\n subtotal: function () { return this.laborCost() + this.equipmentCost() + this.officeCost(); },\n riskBuffer: function () { return this.subtotal() * 0.15; },\n totalCost: function () { return this.subtotal() + this.riskBuffer(); },\n perPersonCost: function () { return this.teamSize() > 0 ? this.totalCost() / this.teamSize() : 0; },\n monthlyBurn: function () { return this.months > 0 ? this.totalCost() / this.months : 0; }\n },\n layout: {\n \"section:estimator\": {\n title: \"软件项目成本估算器\",\n subtitle: \"输入团队配置和周期,成本自动算出来。\",\n \"card:estimator\": {\n title: \"项目成本估算\",\n \"grid:team\": {\n columns: 1, mdColumns: 4,\n \"column:fe\": {\n \"input:frontend\": { label: \"前端\", \"$value\": \"g.frontend\", type: \"number\", unit: \"人\", onchange: \"g.frontend = Number($event || 0)\" }\n },\n \"column:be\": {\n \"input:backend\": { label: \"后端\", \"$value\": \"g.backend\", type: \"number\", unit: \"人\", onchange: \"g.backend = Number($event || 0)\" }\n },\n \"column:qa\": {\n \"input:tester\": { label: \"测试\", \"$value\": \"g.tester\", type: \"number\", unit: \"人\", onchange: \"g.tester = Number($event || 0)\" }\n },\n \"column:ui\": {\n \"input:designer\": { label: \"设计\", \"$value\": \"g.designer\", type: \"number\", unit: \"人\", onchange: \"g.designer = Number($event || 0)\" }\n }\n },\n \"grid:params\": {\n columns: 1, mdColumns: 2,\n \"column:period\": {\n \"input:
|
|
192
|
-
"hash": "
|
|
191
|
+
"body": "# 软件项目成本估算器\n\n老板问你:\"这个项目要多少钱?\"你说:\"我算算。\"然后打开Excel,填一堆公式。其实不用——输入团队配置和周期,成本自动算出来。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_project_cost\",\n g: {\n frontend: 2, backend: 3, tester: 1, designer: 1,\n months: 6,\n salary: 15000,\n teamSize: function () { return this.frontend + this.backend + this.tester + this.designer; },\n laborCost: function () { return this.teamSize() * this.salary * this.months; },\n equipmentCost: function () { return this.teamSize() * 5000; },\n officeCost: function () { return this.teamSize() * 2000 * this.months; },\n subtotal: function () { return this.laborCost() + this.equipmentCost() + this.officeCost(); },\n riskBuffer: function () { return this.subtotal() * 0.15; },\n totalCost: function () { return this.subtotal() + this.riskBuffer(); },\n perPersonCost: function () { return this.teamSize() > 0 ? this.totalCost() / this.teamSize() : 0; },\n monthlyBurn: function () { return this.months > 0 ? this.totalCost() / this.months : 0; }\n },\n layout: {\n \"section:estimator\": {\n title: \"软件项目成本估算器\",\n subtitle: \"输入团队配置和周期,成本自动算出来。\",\n \"card:estimator\": {\n title: \"项目成本估算\",\n \"grid:team\": {\n columns: 1, mdColumns: 4,\n \"column:fe\": {\n \"input:frontend\": { label: \"前端\", \"$value\": \"g.frontend\", type: \"number\", unit: \"人\", onchange: \"g.frontend = Number($event || 0)\" }\n },\n \"column:be\": {\n \"input:backend\": { label: \"后端\", \"$value\": \"g.backend\", type: \"number\", unit: \"人\", onchange: \"g.backend = Number($event || 0)\" }\n },\n \"column:qa\": {\n \"input:tester\": { label: \"测试\", \"$value\": \"g.tester\", type: \"number\", unit: \"人\", onchange: \"g.tester = Number($event || 0)\" }\n },\n \"column:ui\": {\n \"input:designer\": { label: \"设计\", \"$value\": \"g.designer\", type: \"number\", unit: \"人\", onchange: \"g.designer = Number($event || 0)\" }\n }\n },\n \"grid:params\": {\n columns: 1, mdColumns: 2,\n \"column:period\": {\n \"input:monthsInput\": { label: \"开发周期\", \"$value\": \"g.months\", type: \"number\", unit: \"个月\", onchange: \"g.months = Number($event || 0)\" },\n \"slider:monthsSlider\": { label: \"开发周期\", \"$value\": \"g.months\", min: 1, max: 24, step: 1, unit: \"月\", onchange: \"g.months = Number($event)\" }\n },\n \"column:salaryField\": {\n \"input:salaryInput\": { label: \"人均月薪\", \"$value\": \"g.salary\", type: \"number\", unit: \"元\", onchange: \"g.salary = Number($event || 0)\" },\n \"slider:salarySlider\": { label: \"人均月薪\", \"$value\": \"g.salary\", min: 8000, max: 50000, step: 1000, unit: \"元\", onchange: \"g.salary = Number($event)\" }\n }\n },\n \"grid:results\": {\n columns: 1, mdColumns: 4,\n \"stat:team\": { label: \"团队\", \"$value\": \"g.teamSize()\", unit: \"人\" },\n \"stat:total\": { label: \"总成本\", \"$value\": \"g.totalCost().toFixed(0)\", unit: \"元\" },\n \"stat:perperson\": { label: \"人均成本\", \"$value\": \"g.perPersonCost().toFixed(0)\", unit: \"元\" },\n \"stat:monthly\": { label: \"月均消耗\", \"$value\": \"g.monthlyBurn().toFixed(0)\", unit: \"元\" }\n }\n }\n }\n }\n}\n```\n\n7个人做半年,月均消耗多少?加个测试人员会不会超预算?拖一下就知道。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_project_cost\",\n layout: {\n \"card:breakdown\": {\n title: \"成本构成\",\n \"grid:costs\": {\n columns: 1, mdColumns: 3,\n \"stat:labor\": { label: \"人力成本\", \"$value\": \"g.laborCost().toFixed(0)\", unit: \"元\" },\n \"stat:equipment\": { label: \"设备成本\", \"$value\": \"g.equipmentCost().toFixed(0)\", unit: \"元\" },\n \"stat:office\": { label: \"办公成本\", \"$value\": \"g.officeCost().toFixed(0)\", unit: \"元\" }\n },\n \"grid:extra\": {\n columns: 1, mdColumns: 2,\n \"stat:risk\": { label: \"风险缓冲(15%)\", \"$value\": \"g.riskBuffer().toFixed(0)\", unit: \"元\" },\n \"stat:total\": { label: \"总计\", \"$value\": \"g.totalCost().toFixed(0)\", unit: \"元\" }\n },\n \"callout:tip\": {\n \"$tone\": \"g.months > 12 ? 'warning' : 'info'\",\n \"$text\": \"g.months > 12 ? '项目周期超过1年,建议分阶段交付以降低风险。' : '风险缓冲15%是经验值,复杂项目可调高到20-25%。'\"\n }\n }\n }\n}\n```\n\n\n常见配置参考:\n\n| 团队 | 周期 | 月薪 | 总成本 |\n|------|------|------|--------|\n| 3人 | 3个月 | 15k | 196,650 |\n| 5人 | 6个月 | 15k | 655,500 |\n| 8人 | 9个月 | 20k | 1,989,000 |\n| 10人 | 12个月 | 25k | 4,140,000 |\n\n风险缓冲15%是经验值,复杂项目可以调到20-25%。设备和办公成本按人头估算,不含服务器和第三方服务。",
|
|
192
|
+
"hash": "d0ebc08b"
|
|
193
193
|
},
|
|
194
194
|
{
|
|
195
195
|
"id": "examples/voltage-divider",
|
|
@@ -199,8 +199,8 @@
|
|
|
199
199
|
"href": "/zh-CN/examples/voltage-divider",
|
|
200
200
|
"rawHref": "/zh-CN/examples/voltage-divider.md",
|
|
201
201
|
"sourcePath": "content/examples/voltage-divider/zh-CN.md",
|
|
202
|
-
"body": "# 分压器计算器\n\n两个电阻串联,从中间引出电压——模拟电路中最简单的信号调理手段。做 ADC 电平转换、设定阈值电压、生成偏置电压,处处都在用。\n\n## 核心公式\n\n空载分压:$V_{out} = V_{in} \\times \\frac{R_2}{R_1 + R_2}$\n\n带负载 $R_L$ 时:$V_{out,loaded} = V_{in} \\times \\frac{R_2 \\parallel R_L}{R_1 + R_2 \\parallel R_L}$\n\n**关键经验**:分压器阻抗($R_1 \\parallel R_2$)应至少 < 后级输入阻抗的 1/10。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_voltage_divider\",\n g: {\n vin: 5, r1: 10000, r2: 10000, rl: 100000,\n rParallel: function () { return this.r2 * this.rl / (this.r2 + this.rl); },\n vout: function () { return this.vin * this.r2 / (this.r1 + this.r2); },\n voutLoaded: function () { return this.vin * this.rParallel() / (this.r1 + this.rParallel()); },\n errorPercent: function () { return Math.abs((this.voutLoaded() - this.vout()) / this.vout() * 100); },\n impedanceRatio: function () { var zout = this.r1 * this.r2 / (this.r1 + this.r2); return this.rl / zout; },\n loadWarning: function () { return this.impedanceRatio() < 10 ? \"负载效应显著,增大 RL 或减小 R1/R2\" : \"分压器阻抗足够低\"; }\n },\n layout: {\n \"section:divider\": {\n title: \"分压器计算器\",\n subtitle: \"两个电阻串联,从中间引出电压。\",\n \"card:divider\": {\n title: \"分压器计算器\",\n \"grid:params\": {\n columns: 1, mdColumns: 2,\n \"column:r1Field\": { \"input:
|
|
203
|
-
"hash": "
|
|
202
|
+
"body": "# 分压器计算器\n\n两个电阻串联,从中间引出电压——模拟电路中最简单的信号调理手段。做 ADC 电平转换、设定阈值电压、生成偏置电压,处处都在用。\n\n## 核心公式\n\n空载分压:$V_{out} = V_{in} \\times \\frac{R_2}{R_1 + R_2}$\n\n带负载 $R_L$ 时:$V_{out,loaded} = V_{in} \\times \\frac{R_2 \\parallel R_L}{R_1 + R_2 \\parallel R_L}$\n\n**关键经验**:分压器阻抗($R_1 \\parallel R_2$)应至少 < 后级输入阻抗的 1/10。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_voltage_divider\",\n g: {\n vin: 5, r1: 10000, r2: 10000, rl: 100000,\n rParallel: function () { return this.r2 * this.rl / (this.r2 + this.rl); },\n vout: function () { return this.vin * this.r2 / (this.r1 + this.r2); },\n voutLoaded: function () { return this.vin * this.rParallel() / (this.r1 + this.rParallel()); },\n errorPercent: function () { return Math.abs((this.voutLoaded() - this.vout()) / this.vout() * 100); },\n impedanceRatio: function () { var zout = this.r1 * this.r2 / (this.r1 + this.r2); return this.rl / zout; },\n loadWarning: function () { return this.impedanceRatio() < 10 ? \"负载效应显著,增大 RL 或减小 R1/R2\" : \"分压器阻抗足够低\"; }\n },\n layout: {\n \"section:divider\": {\n title: \"分压器计算器\",\n subtitle: \"两个电阻串联,从中间引出电压。\",\n \"card:divider\": {\n title: \"分压器计算器\",\n \"grid:params\": {\n columns: 1, mdColumns: 2,\n \"column:r1Field\": { \"input:r1Input\": { label: \"R1\", \"$value\": \"std.units.si(g.r1, 'Ω', 1)\", type: \"engineering\", unit: \"Ω\", placeholder: \"10kΩ\", onchange: \"if ($event.valid && $event.number > 0) g.r1 = $event.number\" }, \"slider:r1Slider\": { label: \"R1\", \"$value\": \"g.r1\", min: 100, max: 1000000, step: 100, unit: \"Ω\", onchange: \"g.r1 = Number($event)\" } },\n \"column:r2Field\": { \"input:r2Input\": { label: \"R2\", \"$value\": \"std.units.si(g.r2, 'Ω', 1)\", type: \"engineering\", unit: \"Ω\", placeholder: \"10kΩ\", onchange: \"if ($event.valid && $event.number > 0) g.r2 = $event.number\" }, \"slider:r2Slider\": { label: \"R2\", \"$value\": \"g.r2\", min: 100, max: 1000000, step: 100, unit: \"Ω\", onchange: \"g.r2 = Number($event)\" } }\n },\n \"grid:params2\": {\n columns: 1, mdColumns: 2,\n \"column:vinField\": { \"input:vinInput\": { label: \"输入电压 Vin\", \"$value\": \"std.units.si(g.vin, 'V', 1)\", type: \"engineering\", unit: \"V\", placeholder: \"5V\", onchange: \"if ($event.valid && $event.number > 0) g.vin = $event.number\" }, \"slider:vinSlider\": { label: \"Vin\", \"$value\": \"g.vin\", min: 0.1, max: 48, step: 0.1, unit: \"V\", onchange: \"g.vin = Number($event)\" } },\n \"column:rlField\": { \"input:rlInput\": { label: \"负载电阻 RL\", \"$value\": \"std.units.si(g.rl, 'Ω', 1)\", type: \"engineering\", unit: \"Ω\", placeholder: \"100kΩ\", onchange: \"if ($event.valid && $event.number > 0) g.rl = $event.number\" }, \"slider:rlSlider\": { label: \"RL\", \"$value\": \"g.rl\", min: 1000, max: 10000000, step: 1000, unit: \"Ω\", onchange: \"g.rl = Number($event)\" } }\n },\n \"formula:eq1\": { \"$tex\": \"'V_{out} = ' + g.vin.toFixed(1) + ' \\\\\\\\times \\\\\\\\frac{' + (g.r2/1000).toFixed(1) + '\\\\\\\\text{k}}{' + (g.r1/1000).toFixed(1) + '\\\\\\\\text{k} + ' + (g.r2/1000).toFixed(1) + '\\\\\\\\text{k}} = ' + g.vout().toFixed(3) + '\\\\\\\\text{ V}'\" },\n \"grid:results\": {\n columns: 1, mdColumns: 4,\n \"stat:vout\": { label: \"空载 Vout\", \"$value\": \"g.vout().toFixed(3)\", unit: \"V\" },\n \"stat:voutLoaded\": { label: \"带载 Vout\", \"$value\": \"g.voutLoaded().toFixed(3)\", unit: \"V\" },\n \"stat:error\": { label: \"负载误差\", \"$value\": \"g.errorPercent().toFixed(2)\", unit: \"%\" },\n \"badge:ratio\": { \"$label\": \"g.impedanceRatio() < 10 ? '⚠ 负载效应' : '✓ 匹配良好'\", \"$tone\": \"g.impedanceRatio() < 10 ? 'warning' : 'success'\" }\n },\n \"callout:warning\": { \"$tone\": \"g.impedanceRatio() < 10 ? 'warning' : 'info'\", \"$text\": \"g.loadWarning()\" }\n }\n }\n }\n}\n```\n\n\n## 工程笔记\n\n| R1 | R2 | Vout/Vin | 阻抗 |\n|----|----|---------|------|\n| 10k | 10k | 0.50 | 5k |\n| 10k | 3.3k | 0.25 | 2.5k |\n| 10k | 1k | 0.09 | 909 |\n| 33k | 10k | 0.23 | 7.7k |\n\n- **ADC 应用**:分压器阻抗应 < ADC 输入阻抗的 1/10,必要时加缓冲运放\n- **高精度场景**:用 1% 精度电阻,R1 和 R2 用同一批次减少温漂差异\n- **功率限制**:$P = V^2/R$,小阻值分压器注意发热",
|
|
203
|
+
"hash": "df047545"
|
|
204
204
|
},
|
|
205
205
|
{
|
|
206
206
|
"id": "examples/rc-low-pass-filter",
|
|
@@ -210,8 +210,8 @@
|
|
|
210
210
|
"href": "/zh-CN/examples/rc-low-pass-filter",
|
|
211
211
|
"rawHref": "/zh-CN/examples/rc-low-pass-filter.md",
|
|
212
212
|
"sourcePath": "content/examples/rc-low-pass-filter/zh-CN.md",
|
|
213
|
-
"body": "# RC 低通滤波器\n\nRC 低通滤波器是模拟电路中最基础的无源滤波器——一个电阻加一个电容,就能把高频噪声从信号路径上滤掉。做 ADC 前端抗混叠、音频去嘶声、PWM 平滑输出,都会用到它。\n\n## 核心公式\n\n截止频率 $f_c$(-3dB 点):\n\n$$f_c = \\frac{1}{2\\pi RC}$$\n\n对于任意频率 $f$ 的输入信号,输出幅度增益为:\n\n$$|H(f)| = \\frac{1}{\\sqrt{1 + (f/f_c)^2}}$$\n\n## 参数区\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_rc_low_pass_filter\",\n g: {\n r: 10000,\n c: 100,\n f: 1000,\n cutoff: function () { return 1 / (2 * Math.PI * this.r * this.c * 1e-9); },\n gain: function () { return 1 / Math.sqrt(1 + Math.pow(this.f / this.cutoff(), 2)); },\n gainDb: function () { return (20 * Math.log10(this.gain())).toFixed(1); },\n regimeLabel: function () { return this.f < this.cutoff() * 0.1 ? \"通带\" : this.f > this.cutoff() * 10 ? \"阻带\" : \"过渡带\"; }\n },\n layout: {\n \"section:params\": {\n title: \"RC 低通滤波器\",\n subtitle: \"一个电阻加一个电容,把高频噪声滤掉。\",\n \"card:params\": {\n title: \"参数输入\",\n \"grid:inputs\": {\n columns: 1, mdColumns: 2,\n \"column:rField\": { \"input:
|
|
214
|
-
"hash": "
|
|
213
|
+
"body": "# RC 低通滤波器\n\nRC 低通滤波器是模拟电路中最基础的无源滤波器——一个电阻加一个电容,就能把高频噪声从信号路径上滤掉。做 ADC 前端抗混叠、音频去嘶声、PWM 平滑输出,都会用到它。\n\n## 核心公式\n\n截止频率 $f_c$(-3dB 点):\n\n$$f_c = \\frac{1}{2\\pi RC}$$\n\n对于任意频率 $f$ 的输入信号,输出幅度增益为:\n\n$$|H(f)| = \\frac{1}{\\sqrt{1 + (f/f_c)^2}}$$\n\n## 参数区\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_rc_low_pass_filter\",\n g: {\n r: 10000,\n c: 100,\n f: 1000,\n cutoff: function () { return 1 / (2 * Math.PI * this.r * this.c * 1e-9); },\n gain: function () { return 1 / Math.sqrt(1 + Math.pow(this.f / this.cutoff(), 2)); },\n gainDb: function () { return (20 * Math.log10(this.gain())).toFixed(1); },\n regimeLabel: function () { return this.f < this.cutoff() * 0.1 ? \"通带\" : this.f > this.cutoff() * 10 ? \"阻带\" : \"过渡带\"; }\n },\n layout: {\n \"section:params\": {\n title: \"RC 低通滤波器\",\n subtitle: \"一个电阻加一个电容,把高频噪声滤掉。\",\n \"card:params\": {\n title: \"参数输入\",\n \"grid:inputs\": {\n columns: 1, mdColumns: 2,\n \"column:rField\": { \"input:rInput\": { label: \"电阻 R\", \"$value\": \"std.units.si(g.r, 'Ω', 1)\", type: \"engineering\", unit: \"Ω\", placeholder: \"10kΩ\", onchange: \"if ($event.valid && $event.number > 0) g.r = $event.number\" }, \"slider:rSlider\": { label: \"R\", \"$value\": \"g.r\", min: 100, max: 100000, step: 100, unit: \"Ω\", onchange: \"g.r = Number($event)\" } },\n \"column:cField\": { \"input:cInput\": { label: \"电容 C\", \"$value\": \"g.c + 'nF'\", type: \"engineering\", unit: \"nF\", placeholder: \"100nF\", onchange: \"if ($event.valid && $event.number > 0) g.c = $event.unit ? $event.number * 1e9 : $event.number\" }, \"slider:cSlider\": { label: \"C\", \"$value\": \"g.c\", min: 1, max: 1000, step: 1, unit: \"nF\", onchange: \"g.c = Number($event)\" } },\n \"column:fField\": { \"input:fInput\": { label: \"输入频率 f\", \"$value\": \"std.units.si(g.f, 'Hz', 1)\", type: \"engineering\", unit: \"Hz\", placeholder: \"1kHz\", onchange: \"if ($event.valid && $event.number >= 0) g.f = $event.number\" }, \"slider:fSlider\": { label: \"f\", \"$value\": \"g.f\", min: 1, max: 100000, step: 1, unit: \"Hz\", onchange: \"g.f = Number($event)\" } }\n },\n \"stat:fc\": { label: \"截止频率\", \"$value\": \"g.cutoff().toFixed(1)\", unit: \"Hz\" },\n \"badge:regime\": { \"$label\": \"g.regimeLabel()\", \"$tone\": \"g.f < g.cutoff() * 0.1 ? 'success' : g.f > g.cutoff() * 10 ? 'danger' : 'warning'\" }\n }\n }\n }\n}\n```\n\n\n## 计算结果\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_rc_low_pass_filter\",\n layout: {\n \"card:results\": {\n title: \"计算结果\",\n \"formula:fc_eq\": { \"$tex\": \"'f_c = \\\\\\\\frac{1}{2\\\\\\\\pi \\\\\\\\times ' + (g.r/1000).toFixed(1) + 'k\\\\\\\\Omega \\\\\\\\times ' + g.c + '\\\\\\\\text{nF}} = ' + g.cutoff().toFixed(1) + '\\\\\\\\text{ Hz}'\" },\n \"stat:gain_val\": { label: \"幅值增益 |H(f)|\", \"$value\": \"g.gain().toFixed(4)\" },\n \"stat:gain_db\": { label: \"增益\", \"$value\": \"g.gainDb()\", unit: \"dB\" },\n \"callout:verdict\": { \"$tone\": \"g.f < g.cutoff() * 0.1 ? 'success' : g.f > g.cutoff() * 10 ? 'danger' : 'warning'\", \"$text\": \"g.f < g.cutoff() * 0.1 ? '信号完整通过,衰减 < 0.04 dB。' : g.f > g.cutoff() * 10 ? '信号被强烈衰减超过 20 dB,滤波器有效工作。' : '信号处于过渡带,衰减约 ' + (-20 * Math.log10(1 / Math.sqrt(1 + Math.pow(g.f / g.cutoff(), 2)))).toFixed(1) + ' dB。'\" }\n }\n }\n}\n```\n\n\n## 选型参考\n\n下表是常见场景下的经验参数组合。把截止频率设为目标信号最高频率的 5-10 倍,可以保证通带平坦。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_rc_low_pass_filter\",\n layout: {\n \"card:selection\": {\n title: \"选型建议\",\n \"table:guide\": {\n columns: [\"R\", \"C\", \"fc\", \"典型用途\"],\n rows: [\n [\"1 kΩ\", \"100 nF\", \"1592 Hz\", \"音频低通\"],\n [\"10 kΩ\", \"100 nF\", \"159 Hz\", \"ADC 抗混叠\"],\n [\"100 kΩ\", \"10 nF\", \"159 Hz\", \"PWM 平滑\"],\n [\"1 kΩ\", \"1 µF\", \"159 Hz\", \"电源纹波滤波\"],\n [\"10 kΩ\", \"1 nF\", \"15915 Hz\", \"高频噪声抑制\"]\n ]\n },\n \"callout:tip\": { \"$tone\": \"g.cutoff() < 100 ? 'info' : g.cutoff() > 10000 ? 'warning' : 'success'\", \"$text\": \"g.cutoff() < 100 ? '低截止频率适合电源滤波和慢信号。' : g.cutoff() > 10000 ? '高截止频率可能无法有效滤除高频噪声。' : '当前截止频率适合大多数应用场景。'\" }\n }\n }\n}\n```\n\n\n## 工程笔记\n\n- **R 取值**:太大会增加输出阻抗和后级负载效应;太大会增大热噪声。1kΩ–100kΩ 是常用范围\n- **C 取值**:nF 级 NP0/C0G 陶瓷电容温漂小、精度高;超过 100nF 考虑薄膜电容\n- **负载效应**:后级输入阻抗应至少 > 10 × R,否则 $f_c$ 会偏移\n- **级联**:两级 RC 串联可得到 -40dB/dec 的二阶滚降,但截止频率会降低到约 $0.37f_c$\n\n| $f/f_c$ | 增益 | 衰减 |\n|:---:|:---:|:---:|\n| 0.1 | 0.995 | -0.04 dB |\n| 1.0 | 0.707 | -3 dB |\n| 5.0 | 0.196 | -14.2 dB |\n| 10.0 | 0.100 | -20 dB |",
|
|
214
|
+
"hash": "5b383ac7"
|
|
215
215
|
},
|
|
216
216
|
{
|
|
217
217
|
"id": "examples/baud-rate-calculator",
|
|
@@ -276,8 +276,8 @@
|
|
|
276
276
|
"href": "/zh-CN/examples/toolhost-demo",
|
|
277
277
|
"rawHref": "/zh-CN/examples/toolhost-demo.md",
|
|
278
278
|
"sourcePath": "content/examples/toolhost-demo/zh-CN.md",
|
|
279
|
-
"body": "
|
|
280
|
-
"hash": "
|
|
279
|
+
"body": "# ToolHost 对话演示\n\nAI 对话中需要收集用户信息时,会调用 **ToolHost** 弹出交互式表单卡片。用户填写并提交后,表单数据以结构化的 `ToolResult` 返回给 AI,AI 继续处理。\n\n下方是一个完整的对话演示——模拟用户请求创建项目,AI 调用 `fill-form` 模板收集项目信息,提交后返回 ToolResult。\n\n**流程:** 用户发起请求 → AI 判断需要工具调用 → ToolHost 弹出表单 → 用户填写并提交 → 返回 ToolResult → AI 继续响应\n\nAI 端调用 ToolHost 的代码如下:\n\n```js\nimport { renderToolCall } from \"slexkit/toolhost\";\n\nconst { promise } = renderToolCall({\n name: \"fill-form\",\n arguments: {\n title: \"创建新项目\",\n description: \"请填写项目的基本信息。\",\n submitLabel: \"提交\",\n ignoreLabel: \"取消\",\n fields: [\n { name: \"name\", label: \"项目名称\", type: \"text\", required: true },\n { name: \"type\", label: \"项目类型\", type: \"select\", options: [\n { label: \"Web 应用\", value: \"web\" },\n { label: \"API 服务\", value: \"api\" },\n { label: \"CLI 工具\", value: \"cli\" },\n ]},\n { name: \"priority\", label: \"优先级\", type: \"select\", options: [\n { label: \"低\", value: \"low\" },\n { label: \"中\", value: \"medium\" },\n { label: \"高\", value: \"high\" },\n ]},\n ],\n },\n}, container);\n\n// 用户提交后,promise resolve 为 ToolResult\nconst result = await promise;\n// → { toolName: \"fill-form\", status: \"submitted\", value: { name, type, priority } }\n```",
|
|
280
|
+
"hash": "fd28647c"
|
|
281
281
|
},
|
|
282
282
|
{
|
|
283
283
|
"id": "examples/roi-estimator",
|
|
@@ -738,8 +738,8 @@
|
|
|
738
738
|
"href": "/docs/releases/changelog",
|
|
739
739
|
"rawHref": "/docs/releases/changelog.md",
|
|
740
740
|
"sourcePath": "site/content/releases/changelog/en-US.md",
|
|
741
|
-
"body": "---\ntitle: Changelog\ncategory: Releases\nstatus: ready\norder: 10\nsummary: \"Release notes and notable changes for SlexKit.\"\nslexkitRenderMode: component\n---\n\n# Changelog\n\nAll notable changes to SlexKit.\n\n## v0.3.1 - Host stability and control rendering hardening\n\n### Added\n- Runtime style safety tests that block broad `:has()` selectors, `clip-path`, and slider track regressions in shipped CSS.\n- Regression coverage for disabled Switch, Checkbox, and Radio state attributes.\n\n### Changed\n- CI now installs dependencies with `bun install --frozen-lockfile` and runs lint before tests.\n- Disabled Switch, Checkbox, and Radio styling now uses explicit `data-disabled` attributes instead of broad relational selectors.\n- Select and sr-only helper styles avoid `clip-path` for better host and Obsidian CSS compatibility.\n\n### Fixed\n- Slider thumb rendering artifacts caused by painting the range track on the native input box.\n- Input focus visibility after removing custom engineering steppers.\n- Home RC example input labels now use native Input component labels instead of separate text labels.\n- Stat cards no longer clip updated text during cross-document state examples.\n- Markdown calculator examples no longer render duplicate section labels.\n\n## v0.3.0 - Examples overhaul with component audit and i18n\n\n### Added\n- Example gallery: 17 high-quality examples organized by usage scenario (Getting Started, Calculators, Data Browsing, Dashboards, Config Wizards, Decision Support, Platform Features)\n- English translations for all 17 example pages\n- `toolhost-demo`: real `renderToolCall` API with chat-style conversation UI\n- Example rendering infrastructure: `site/routes/examples.js`, `site/pages/examples.slex.js`, `site/data/examples.js`\n- Formula component (`src/components/svelte/content/Formula.svelte`) with KaTeX rendering\n- `src/engine/capabilities.ts`: structured capability docs for AI agents\n- `src/engine/validation.ts`: SPEC contract validation\n- `src/engine/stdlib.ts`: standard library with `math.clamp`, `math.safeDivide`, and other utilities\n- `src/engine/sandbox-runner.ts`: sandbox runner for secure runtime\n- Component state eval context shadowing test suite (`component-state-shadowing.test.ts`)\n- Collapsible and Callout double-rendering regression tests\n- Slider component name shadowing regression test\n\n### Changed\n- Examples reduced from 64 to 17 high-quality examples, organized by user story\n- Example source locale: `zh-CN` (with `en-US` translations)\n- `renderChildren` (`helpers.ts`) now clears existing content when children are present\n- Switch component now accepts `checked`/`value` props for initialization consistency with Checkbox\n- Site UI: DocsShell, DocRail, router, shell improvements\n- Components: Input, Select, Tabs, Table, PlaygroundMarkdown refinements\n- CSS: theme-shadcn, text-input, docs-shell styling updates\n\n### Fixed\n- Eval context shadowing: component names `g` and `api` no longer overwrite reserved context keys\n- `renderChildren` double rendering in Collapsible and Callout\n- Voltage divider summary typo (\"输入输入电压\")\n- Salary calculator fallback numbers to match actual calculator output\n- Tabs-and-branching: title and length conversion mismatch\n- 4 pre-existing test failures (ai-docs, page-structure, theme, markdown-content)\n\n### Removed\n- 47 low-quality/duplicate examples (reduced from 64 to 17)\n- Dead \"Fallback\" copywriting from all example files\n- Unused `DialogShell.svelte` component\n\n## v0.2.0 - First public release\n\n### Added\n- `@slexkit/mcp`: AI Agent Model Context Protocol server with `slexkitDocs`, `slexkitExamples`, `slexkitValidate` tools\n- Protocol marker: `\"slex\": \"0.1\"` required on all Slex expressions and ToolHost templates\n- SPEC contract validation: component specs are now validated against the runtime contract\n- Version sync automation (`scripts/sync-version.ts`) and changelog sync (`scripts/sync-changelog.ts`)\n- AI documentation generation pipeline with structured LLM-friendly output\n- Static site export with SEO metadata engine (`site/data/seo.js`, `site/scripts/export-static.ts`)\n- Chinese documentation for all reference and guide pages\n- Enhanced component state management with lifecycle hooks (`onMount`, `onUnmount`, `onUpdate`)\n\n### Changed\n- Switch component migrated from `checked` to `enabled` state mode\n- Documentation: restructured site content, synced en-US with zh-CN, added reference section\n- Theme: refined select styling, dropdown shadows, footer and info tone polish\n- AI docs generation enhanced with Chinese/English locale awareness\n\n### Fixed\n- Component spec alignment with documentation across all 28 components\n- Site routing and code block highlighting\n- Introduction and quick-start guide wording for clarity\n- Broken links and factual errors in component and reference documentation\n\n## v0.1.9\n\n### Added\n- Icon manager with Phosphor icon system (`registerIcon`, `registerIcons`, `getIcon`, `loadIcon`)\n- Expanded icon support across labeled components (badge, button, callout, etc.)\n- Icon docs page with registration API reference\n\n### Fixed\n- Refined component interactions in static site export\n- Tabs indicator animation restored\n- Callout and toast icon placement in titles\n- Numeric value display formatting\n\n### Changed\n- Site docs shell refactored for static export\n- Site navigation and theme controls alignment\n- Slex naming standardized across codebase\n\n## v0.1.8\n\n### Added\n- CSP-hardened secure runtime sandbox with heartbeat watchdog\n- `mountSecureArtifact()` for isolated iframe rendering\n- `createSlexKitMarkdownRuntimeHost()` for Markdown-hosted SlexKit blocks\n- Streamdown React renderer (`@slexkit/streamdown`)\n- Obsidian plugin adapter (`@slexkit/obsidian`)\n- Shadcn-compatible CSS theme (`@slexkit/theme-shadcn`)\n- Package boundary wrappers (`@slexkit/runtime`, `@slexkit/components-svelte`)\n- ToolHost with built-in templates: `confirm-action`, `choose-options`, `fill-form`\n\n### Changed\n- Component registration model: side-effect import registers all components\n- Styles reorganized into per-component CSS files\n- Build system: Bun.build with Svelte plugin, split ESM entries\n\n## v0.1.7\n\n### Added\n- `$for` list rendering with keyed reconciliation (delete / add-update-reorder / trim phases)\n- `$if` conditional rendering with enter/leave animation support\n- `$key` strategy: `$value`, property-based, or fallback to index\n- Component instance state modes: `value`, `checked`, `enabled`, `readable`, `none`\n- Lifecycle hooks: `g.onMount_<name>()`, `g.onUnmount_<name>()`, `g.onUpdate_<name>()`\n- Engineering number input with SI prefix parsing\n- Rich error diagnostics with line/column/excerpt display\n\n### Changed\n- Expression evaluation: `new Function()` compilation with reactive dependency tracking\n- Layout tree renderer now supports three rendering paths (normal, `$if`, `$for`)\n- `g` deep-merge preserves keys not present in the new state\n\n## v0.1.6 and earlier\n\n### Added\n- Reactive `g`/`layout` split with expression pipes (`$` read-pipes, `on*` write-pipes)\n- Custom fine-grained reactivity system (~280 lines, no external dependency)\n- Component registry with extensible renderer interface\n- Svelte 5 component adapter (creates stores from props, flushSync DOM)\n- `mount()`, `ingest()`, `boot()` entry points\n- 28 built-in Svelte components across 8 categories\n- `parseSlexSource()` DSL parser with `diagnoseSlexKitSource()` error reporting\n- Documentation site with interactive playground",
|
|
742
|
-
"hash": "
|
|
741
|
+
"body": "---\ntitle: Changelog\ncategory: Releases\nstatus: ready\norder: 10\nsummary: \"Release notes and notable changes for SlexKit.\"\nslexkitRenderMode: component\n---\n\n# Changelog\n\nAll notable changes to SlexKit.\n\n## v0.3.3 - Obsidian input control hardening\n\n### Fixed\n- Slider now renders its visual track outside the native range input while keeping the native input for interaction and accessibility, avoiding square thumb artifacts in Obsidian and other host themes.\n- Input fields with trailing units now reset host input chrome with scoped selectors so unit add-ons stay aligned with the text field in Obsidian dark themes.\n\n## v0.3.2 - Host CSS isolation and repeated layout hardening\n\n### Changed\n- `$for` rendering now uses comment anchors and direct child insertion instead of a wrapper element that depended on `display: contents`.\n- Site-only mobile navigation CSS moved out of the runtime base stylesheet and into the documentation site shell.\n- Component accessors now share one reactive effect across subscribers instead of creating duplicate subscriber fan-out work.\n\n### Fixed\n- Obsidian and other Markdown hosts no longer need to rewrite `$for` wrapper CSS to avoid `display: contents`, preserving grid and row layouts for repeated items.\n- Published runtime base CSS no longer leaks `#mobileNav` or `body[data-mobile-nav-open]` selectors into host pages.\n- Custom renderers that return no element no longer leave invalid `$for` slots behind during diffing or cleanup.\n\n## v0.3.1 - Host stability and control rendering hardening\n\n### Added\n- Runtime style safety tests that block broad `:has()` selectors, `clip-path`, and slider track regressions in shipped CSS.\n- Regression coverage for disabled Switch, Checkbox, and Radio state attributes.\n\n### Changed\n- CI now installs dependencies with `bun install --frozen-lockfile` and runs lint before tests.\n- Disabled Switch, Checkbox, and Radio styling now uses explicit `data-disabled` attributes instead of broad relational selectors.\n- Select and sr-only helper styles avoid `clip-path` for better host and Obsidian CSS compatibility.\n\n### Fixed\n- Slider thumb rendering artifacts caused by painting the range track on the native input box.\n- Input focus visibility after removing custom engineering steppers.\n- Home RC example input labels now use native Input component labels instead of separate text labels.\n- Stat cards no longer clip updated text during cross-document state examples.\n- Markdown calculator examples no longer render duplicate section labels.\n\n## v0.3.0 - Examples overhaul with component audit and i18n\n\n### Added\n- Example gallery: 17 high-quality examples organized by usage scenario (Getting Started, Calculators, Data Browsing, Dashboards, Config Wizards, Decision Support, Platform Features)\n- English translations for all 17 example pages\n- `toolhost-demo`: real `renderToolCall` API with chat-style conversation UI\n- Example rendering infrastructure: `site/routes/examples.js`, `site/pages/examples.slex.js`, `site/data/examples.js`\n- Content discovery: `site/data/content-discovery.js` with locale fallback and allowed-slug filtering\n- `site/data/content-discovery.js`: `discoverExampleMarkdown()` with per-locale discovery\n- SEO metadata for example pages\n- `examples/minimal-cdn/index.html`: zero-build CDN usage example\n- Formula component (`src/components/svelte/content/Formula.svelte`) with KaTeX rendering\n- `src/engine/capabilities.ts`: structured capability docs for AI agents\n- `src/engine/validation.ts`: SPEC contract validation for component specs\n- `src/engine/stdlib.ts`: standard library with `math.clamp`, `math.safeDivide`, and other utilities\n- `src/engine/sandbox-runner.ts`: sandbox runner for secure runtime\n- Component state eval context shadowing test suite (`component-state-shadowing.test.ts`)\n- Collapsible and Callout double-rendering regression tests\n- Slider component name shadowing regression test\n- Tests for content, playground, select, tabs, slider, disclosure, feedback, policy-api\n\n### Changed\n- Examples reduced from 64 to 17 high-quality examples, organized by user story\n- Example source locale: `zh-CN` (with `en-US` translations)\n- `renderChildren` (`helpers.ts`) now clears existing content when children are present\n- Switch component now accepts `checked`/`value` props for initialization consistency with Checkbox\n- Site UI: DocsShell, DocRail, router, shell improvements\n- Components: Input, Select, Tabs, Table, PlaygroundMarkdown refinements\n- CSS: theme-shadcn, text-input, docs-shell styling updates\n- MCP: enhanced with structured capability docs\n\n### Fixed\n- Eval context shadowing: component names `g` and `api` no longer overwrite reserved context keys\n- `renderChildren` double rendering in Collapsible and Callout\n- Voltage divider summary typo (\"输入输入电压\")\n- Salary calculator fallback numbers to match actual calculator output\n- Tabs-and-branching: title and length conversion mismatch\n- 4 pre-existing test failures (ai-docs, page-structure, theme, markdown-content)\n- Toolhost test: added setup import to fix `document is not defined`\n- Badge stretching in grid layout\n- Project-dashboard syntax error\n- Salary-calculator rate configuration\n\n### Removed\n- 47 low-quality/duplicate examples (reduced from 64 to 17)\n- Dead \"Fallback\" copywriting from all example files\n- Post-slex explanatory text from example files\n- Unused `DialogShell.svelte` component\n- Orphaned `test-if` example directory\n- Agent-generated `docs/compose` planning files\n- Temporary `screenshot-*.png` files\n\n## v0.2.0 - First public release\n\n### Added\n- `@slexkit/mcp`: AI Agent Model Context Protocol server with `slexkitDocs`, `slexkitExamples`, `slexkitValidate` tools\n- Protocol marker: `\"slex\": \"0.1\"` required on all Slex expressions and ToolHost templates\n- SPEC contract validation: component specs are now validated against the runtime contract\n- Version sync automation (`scripts/sync-version.ts`) and changelog sync (`scripts/sync-changelog.ts`)\n- AI documentation generation pipeline with structured LLM-friendly output\n- Static site export with SEO metadata engine (`site/data/seo.js`, `site/scripts/export-static.ts`)\n- Chinese documentation for all reference and guide pages\n- Enhanced component state management with lifecycle hooks (`onMount`, `onUnmount`, `onUpdate`)\n\n### Changed\n- Switch component migrated from `checked` to `enabled` state mode\n- Documentation: restructured site content, synced en-US with zh-CN, added reference section\n- Theme: refined select styling, dropdown shadows, footer and info tone polish\n- AI docs generation enhanced with Chinese/English locale awareness\n\n### Fixed\n- Component spec alignment with documentation across all 28 components\n- Site routing and code block highlighting\n- Introduction and quick-start guide wording for clarity\n- Broken links and factual errors in component and reference documentation\n\n## v0.1.9\n\n### Added\n- Icon manager with Phosphor icon system (`registerIcon`, `registerIcons`, `getIcon`, `loadIcon`)\n- Expanded icon support across labeled components (badge, button, callout, etc.)\n- Icon docs page with registration API reference\n\n### Fixed\n- Refined component interactions in static site export\n- Tabs indicator animation restored\n- Callout and toast icon placement in titles\n- Numeric value display formatting\n\n### Changed\n- Site docs shell refactored for static export\n- Site navigation and theme controls alignment\n- Slex naming standardized across codebase\n\n## v0.1.8\n\n### Added\n- CSP-hardened secure runtime sandbox with heartbeat watchdog\n- `mountSecureArtifact()` for isolated iframe rendering\n- `createSlexKitMarkdownRuntimeHost()` for Markdown-hosted SlexKit blocks\n- Streamdown React renderer (`@slexkit/streamdown`)\n- Obsidian plugin adapter (`@slexkit/obsidian`)\n- Shadcn-compatible CSS theme (`@slexkit/theme-shadcn`)\n- Package boundary wrappers (`@slexkit/runtime`, `@slexkit/components-svelte`)\n- ToolHost with built-in templates: `confirm-action`, `choose-options`, `fill-form`\n\n### Changed\n- Component registration model: side-effect import registers all components\n- Styles reorganized into per-component CSS files\n- Build system: Bun.build with Svelte plugin, split ESM entries\n\n## v0.1.7\n\n### Added\n- `$for` list rendering with keyed reconciliation (delete / add-update-reorder / trim phases)\n- `$if` conditional rendering with enter/leave animation support\n- `$key` strategy: `$value`, property-based, or fallback to index\n- Component instance state modes: `value`, `checked`, `enabled`, `readable`, `none`\n- Lifecycle hooks: `g.onMount_<name>()`, `g.onUnmount_<name>()`, `g.onUpdate_<name>()`\n- Engineering number input with SI prefix parsing\n- Rich error diagnostics with line/column/excerpt display\n\n### Changed\n- Expression evaluation: `new Function()` compilation with reactive dependency tracking\n- Layout tree renderer now supports three rendering paths (normal, `$if`, `$for`)\n- `g` deep-merge preserves keys not present in the new state\n\n## v0.1.6 and earlier\n\n### Added\n- Reactive `g`/`layout` split with expression pipes (`$` read-pipes, `on*` write-pipes)\n- Custom fine-grained reactivity system (~280 lines, no external dependency)\n- Component registry with extensible renderer interface\n- Svelte 5 component adapter (creates stores from props, flushSync DOM)\n- `mount()`, `ingest()`, `boot()` entry points\n- 28 built-in Svelte components across 8 categories\n- `parseSlexSource()` DSL parser with `diagnoseSlexKitSource()` error reporting\n- Documentation site with interactive playground",
|
|
742
|
+
"hash": "32aa70c5"
|
|
743
743
|
}
|
|
744
744
|
],
|
|
745
745
|
"expressionContext": [
|
|
@@ -3481,7 +3481,7 @@
|
|
|
3481
3481
|
}
|
|
3482
3482
|
],
|
|
3483
3483
|
"sourceHashes": {
|
|
3484
|
-
"README.md": "
|
|
3484
|
+
"README.md": "b19850c1",
|
|
3485
3485
|
"site/content/guides/intro/en-US.md": "bff82366",
|
|
3486
3486
|
"site/content/guides/quick-start/en-US.md": "ba82b030",
|
|
3487
3487
|
"site/content/guides/integration/en-US.md": "1138bddd",
|
|
@@ -3490,18 +3490,18 @@
|
|
|
3490
3490
|
"site/content/guides/ai-agents/en-US.md": "c6c70f87",
|
|
3491
3491
|
"content/examples/hello-slexkit/zh-CN.md": "f5b1728f",
|
|
3492
3492
|
"content/examples/first-interaction/zh-CN.md": "d27f5fc3",
|
|
3493
|
-
"content/examples/multi-input-coordination/zh-CN.md": "
|
|
3493
|
+
"content/examples/multi-input-coordination/zh-CN.md": "8bbfb723",
|
|
3494
3494
|
"content/examples/tabs-and-branching/zh-CN.md": "2050088b",
|
|
3495
|
-
"content/examples/salary-calculator/zh-CN.md": "
|
|
3496
|
-
"content/examples/project-cost-estimator/zh-CN.md": "
|
|
3497
|
-
"content/examples/voltage-divider/zh-CN.md": "
|
|
3498
|
-
"content/examples/rc-low-pass-filter/zh-CN.md": "
|
|
3495
|
+
"content/examples/salary-calculator/zh-CN.md": "bbc62fda",
|
|
3496
|
+
"content/examples/project-cost-estimator/zh-CN.md": "d0ebc08b",
|
|
3497
|
+
"content/examples/voltage-divider/zh-CN.md": "df047545",
|
|
3498
|
+
"content/examples/rc-low-pass-filter/zh-CN.md": "5b383ac7",
|
|
3499
3499
|
"content/examples/baud-rate-calculator/zh-CN.md": "7ac3d2d9",
|
|
3500
3500
|
"content/examples/search-filter-table/zh-CN.md": "16e8308e",
|
|
3501
3501
|
"content/examples/project-dashboard/zh-CN.md": "aacce5f0",
|
|
3502
3502
|
"content/examples/form-wizard-steps/zh-CN.md": "3d2ac73e",
|
|
3503
3503
|
"content/examples/tech-selection-evaluator/zh-CN.md": "403c7e46",
|
|
3504
|
-
"content/examples/toolhost-demo/zh-CN.md": "
|
|
3504
|
+
"content/examples/toolhost-demo/zh-CN.md": "fd28647c",
|
|
3505
3505
|
"content/examples/roi-estimator/zh-CN.md": "73bc3af9",
|
|
3506
3506
|
"content/examples/cross-doc-state-lab/zh-CN.md": "7ac63204",
|
|
3507
3507
|
"content/examples/network-policy-fetch-card/zh-CN.md": "7d1daa49",
|
|
@@ -3514,7 +3514,7 @@
|
|
|
3514
3514
|
"site/content/reference/toolhost/en-US.md": "f62ba8aa",
|
|
3515
3515
|
"site/content/reference/icons/en-US.md": "3d32cbbf",
|
|
3516
3516
|
"site/content/reference/rationale/en-US.md": "dcf53947",
|
|
3517
|
-
"site/content/releases/changelog/en-US.md": "
|
|
3517
|
+
"site/content/releases/changelog/en-US.md": "32aa70c5",
|
|
3518
3518
|
"site/content/components/accordion/en-US.md": "9e90867f",
|
|
3519
3519
|
"site/content/components/badge/en-US.md": "fb8275e7",
|
|
3520
3520
|
"site/content/components/button/en-US.md": "30463322",
|
package/dist/base.css
CHANGED
|
@@ -133,52 +133,6 @@ color-scheme: dark;
|
|
|
133
133
|
box-sizing: border-box;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
body[data-mobile-nav-open] {
|
|
137
|
-
overflow: hidden;
|
|
138
|
-
overscroll-behavior: contain;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
#mobileNav {
|
|
142
|
-
--mobile-nav-backdrop-opacity: 0;
|
|
143
|
-
--mobile-nav-panel-translate: -100%;
|
|
144
|
-
pointer-events: none;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
#mobileNav[data-open="true"] {
|
|
148
|
-
--mobile-nav-backdrop-opacity: 1;
|
|
149
|
-
--mobile-nav-panel-translate: 0px;
|
|
150
|
-
pointer-events: auto;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
#mobileNav [data-mobile-nav-backdrop] {
|
|
154
|
-
opacity: var(--mobile-nav-backdrop-opacity);
|
|
155
|
-
touch-action: pan-y;
|
|
156
|
-
transition: opacity 180ms ease;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
#mobileNav [data-mobile-nav-panel] {
|
|
160
|
-
transform: translateX(var(--mobile-nav-panel-translate));
|
|
161
|
-
touch-action: pan-y;
|
|
162
|
-
transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
|
|
163
|
-
will-change: transform;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
#mobileNav[data-dragging="true"] [data-mobile-nav-backdrop],
|
|
167
|
-
#mobileNav[data-dragging="true"] [data-mobile-nav-panel] {
|
|
168
|
-
transition: none;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
@media (prefers-reduced-motion: reduce) {
|
|
172
|
-
#mobileNav [data-mobile-nav-backdrop],
|
|
173
|
-
#mobileNav [data-mobile-nav-panel] {
|
|
174
|
-
transition: none;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.slexkit-for-wrapper {
|
|
179
|
-
display: contents;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
136
|
.slexkit-source-toolbar {
|
|
183
137
|
display: flex;
|
|
184
138
|
align-items: center;
|
package/dist/components/index.js
CHANGED
|
@@ -7255,7 +7255,7 @@ function Row($$anchor, $$props) {
|
|
|
7255
7255
|
}
|
|
7256
7256
|
|
|
7257
7257
|
// src/components/svelte/input/Slider.svelte
|
|
7258
|
-
var root5 = from_html(`<div class="slex-slider-field"><div class="slex-slider-label"><span class="slex-slider-label-text"><!> <span> </span></span> <span class="slex-slider-value"> <!></span></div> <input type="range" class="slex-slider"/></div>`);
|
|
7258
|
+
var root5 = from_html(`<div class="slex-slider-field"><div class="slex-slider-label"><span class="slex-slider-label-text"><!> <span> </span></span> <span class="slex-slider-value"> <!></span></div> <div class="slex-slider-control"><span class="slex-slider-track" aria-hidden="true"></span> <input type="range" class="slex-slider"/></div></div>`);
|
|
7259
7259
|
function Slider($$anchor, $$props) {
|
|
7260
7260
|
push($$props, true);
|
|
7261
7261
|
let p = state(proxy({}));
|
|
@@ -7355,30 +7355,32 @@ function Slider($$anchor, $$props) {
|
|
|
7355
7355
|
}
|
|
7356
7356
|
reset(span_2);
|
|
7357
7357
|
reset(div_1);
|
|
7358
|
-
var
|
|
7358
|
+
var div_2 = sibling(div_1, 2);
|
|
7359
|
+
var input_1 = sibling(child(div_2), 2);
|
|
7359
7360
|
remove_input_defaults(input_1);
|
|
7361
|
+
reset(div_2);
|
|
7360
7362
|
reset(div);
|
|
7361
7363
|
template_effect(($0, $1, $2, $3, $4, $5, $6, $7, $8) => {
|
|
7362
7364
|
set_attribute2(div, "data-orientation", $0);
|
|
7363
7365
|
set_text(text_1, $1);
|
|
7364
7366
|
set_text(text_2, $2);
|
|
7365
|
-
|
|
7366
|
-
set_attribute2(input_1, "
|
|
7367
|
-
set_attribute2(input_1, "
|
|
7368
|
-
|
|
7367
|
+
set_style(div_2, $3);
|
|
7368
|
+
set_attribute2(input_1, "min", $4);
|
|
7369
|
+
set_attribute2(input_1, "max", $5);
|
|
7370
|
+
set_attribute2(input_1, "step", $6);
|
|
7371
|
+
set_value(input_1, $7);
|
|
7369
7372
|
input_1.disabled = !!get2(p).disabled;
|
|
7370
|
-
set_attribute2(input_1, "aria-label", $
|
|
7371
|
-
set_style(input_1, $8);
|
|
7373
|
+
set_attribute2(input_1, "aria-label", $8);
|
|
7372
7374
|
}, [
|
|
7373
7375
|
() => text2(get2(p).orientation, "horizontal"),
|
|
7374
7376
|
() => text2(get2(p).label ?? $$props.componentName),
|
|
7375
7377
|
() => text2(get2(value) ?? 0),
|
|
7378
|
+
() => `--slex-slider-progress: ${sliderProgress(get2(value), get2(p).min, get2(p).max)}`,
|
|
7376
7379
|
() => Number(get2(p).min ?? 0),
|
|
7377
7380
|
() => Number(get2(p).max ?? 100),
|
|
7378
7381
|
() => Number(get2(p).step ?? 1),
|
|
7379
7382
|
() => Number(get2(value) ?? 0),
|
|
7380
|
-
() => text2(get2(p)["aria-label"] ?? get2(p).ariaLabel ?? get2(p).label ?? $$props.componentName)
|
|
7381
|
-
() => `--slex-slider-progress: ${sliderProgress(get2(value), get2(p).min, get2(p).max)}`
|
|
7383
|
+
() => text2(get2(p)["aria-label"] ?? get2(p).ariaLabel ?? get2(p).label ?? $$props.componentName)
|
|
7382
7384
|
]);
|
|
7383
7385
|
delegated("pointerdown", input_1, grabSlider);
|
|
7384
7386
|
delegated("input", input_1, (event2) => choose(Number(event2.target.value)));
|
|
@@ -161,22 +161,71 @@
|
|
|
161
161
|
font-weight: 600;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
.slex-slider-control {
|
|
165
|
+
position: relative;
|
|
166
|
+
box-sizing: border-box;
|
|
167
|
+
width: 100%;
|
|
168
|
+
height: 1rem;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.slex-slider-track {
|
|
172
|
+
position: absolute;
|
|
173
|
+
inset-inline: 0;
|
|
174
|
+
top: 50%;
|
|
175
|
+
height: 0.5rem;
|
|
176
|
+
border-radius: 999px;
|
|
177
|
+
background: linear-gradient(
|
|
178
|
+
to right,
|
|
179
|
+
var(--primary) 0%,
|
|
180
|
+
var(--primary) var(--slex-slider-progress, 0%),
|
|
181
|
+
var(--secondary) var(--slex-slider-progress, 0%),
|
|
182
|
+
var(--secondary) 100%
|
|
183
|
+
);
|
|
184
|
+
pointer-events: none;
|
|
185
|
+
transform: translateY(-50%);
|
|
186
|
+
}
|
|
187
|
+
|
|
164
188
|
.slex-slider {
|
|
189
|
+
position: relative;
|
|
190
|
+
z-index: 1;
|
|
165
191
|
box-sizing: border-box;
|
|
192
|
+
display: block;
|
|
166
193
|
width: 100%;
|
|
167
194
|
height: 1rem;
|
|
195
|
+
margin: 0;
|
|
168
196
|
padding: 0;
|
|
169
197
|
border: 0;
|
|
170
198
|
border-radius: 999px;
|
|
171
199
|
-webkit-appearance: none;
|
|
172
200
|
appearance: none;
|
|
173
201
|
background: transparent;
|
|
202
|
+
color: transparent;
|
|
174
203
|
accent-color: var(--primary);
|
|
175
204
|
cursor: pointer;
|
|
176
205
|
overflow: visible;
|
|
177
206
|
transition: box-shadow 150ms ease, filter 150ms ease;
|
|
178
207
|
}
|
|
179
208
|
|
|
209
|
+
.slexkit-root .slex-slider-control input.slex-slider {
|
|
210
|
+
position: relative;
|
|
211
|
+
z-index: 1;
|
|
212
|
+
box-sizing: border-box;
|
|
213
|
+
display: block;
|
|
214
|
+
width: 100%;
|
|
215
|
+
height: 1rem;
|
|
216
|
+
min-height: 0;
|
|
217
|
+
margin: 0;
|
|
218
|
+
padding: 0;
|
|
219
|
+
border: 0;
|
|
220
|
+
border-radius: 999px;
|
|
221
|
+
box-shadow: none;
|
|
222
|
+
background: transparent;
|
|
223
|
+
color: transparent;
|
|
224
|
+
-webkit-appearance: none;
|
|
225
|
+
appearance: none;
|
|
226
|
+
overflow: visible;
|
|
227
|
+
}
|
|
228
|
+
|
|
180
229
|
.slex-slider:focus-visible {
|
|
181
230
|
outline: 2px solid var(--ring);
|
|
182
231
|
outline-offset: 4px;
|
|
@@ -186,7 +235,7 @@
|
|
|
186
235
|
box-sizing: border-box;
|
|
187
236
|
width: 1rem;
|
|
188
237
|
height: 1rem;
|
|
189
|
-
margin-top:
|
|
238
|
+
margin-top: 0;
|
|
190
239
|
border: 2px solid var(--primary);
|
|
191
240
|
border-radius: 999px;
|
|
192
241
|
background-color: var(--background);
|
|
@@ -200,16 +249,10 @@
|
|
|
200
249
|
.slex-slider::-webkit-slider-runnable-track {
|
|
201
250
|
box-sizing: border-box;
|
|
202
251
|
width: 100%;
|
|
203
|
-
height:
|
|
252
|
+
height: 1rem;
|
|
204
253
|
border: 0;
|
|
205
254
|
border-radius: 999px;
|
|
206
|
-
background:
|
|
207
|
-
to right,
|
|
208
|
-
var(--primary) 0%,
|
|
209
|
-
var(--primary) var(--slex-slider-progress, 0%),
|
|
210
|
-
var(--secondary) var(--slex-slider-progress, 0%),
|
|
211
|
-
var(--secondary) 100%
|
|
212
|
-
);
|
|
255
|
+
background: transparent;
|
|
213
256
|
}
|
|
214
257
|
|
|
215
258
|
.slex-slider::-moz-range-thumb {
|
|
@@ -245,16 +288,16 @@
|
|
|
245
288
|
}
|
|
246
289
|
|
|
247
290
|
.slex-slider::-moz-range-track {
|
|
248
|
-
height:
|
|
291
|
+
height: 1rem;
|
|
249
292
|
border: 0;
|
|
250
293
|
border-radius: 999px;
|
|
251
|
-
background:
|
|
294
|
+
background: transparent;
|
|
252
295
|
}
|
|
253
296
|
|
|
254
297
|
.slex-slider::-moz-range-progress {
|
|
255
|
-
height:
|
|
298
|
+
height: 1rem;
|
|
256
299
|
border-radius: 999px;
|
|
257
|
-
background:
|
|
300
|
+
background: transparent;
|
|
258
301
|
}
|
|
259
302
|
|
|
260
303
|
.slex-slider-label-text {
|
|
@@ -441,11 +484,40 @@
|
|
|
441
484
|
transition: border-color 150ms ease, box-shadow 150ms ease;
|
|
442
485
|
}
|
|
443
486
|
|
|
487
|
+
.slexkit-root .slex-input-control input.slex-input {
|
|
488
|
+
box-sizing: border-box;
|
|
489
|
+
display: block;
|
|
490
|
+
flex: 1 1 auto;
|
|
491
|
+
width: 100%;
|
|
492
|
+
min-width: 0;
|
|
493
|
+
min-height: 2.5625rem;
|
|
494
|
+
height: auto;
|
|
495
|
+
margin: 0;
|
|
496
|
+
padding: 0.5rem 0.75rem;
|
|
497
|
+
border: 1px solid var(--input);
|
|
498
|
+
border-radius: var(--radius);
|
|
499
|
+
box-shadow: none;
|
|
500
|
+
background: var(--background);
|
|
501
|
+
background-clip: padding-box;
|
|
502
|
+
color: var(--foreground);
|
|
503
|
+
font-family: inherit;
|
|
504
|
+
font-size: 0.875rem;
|
|
505
|
+
line-height: 1.5;
|
|
506
|
+
outline: none;
|
|
507
|
+
-webkit-appearance: none;
|
|
508
|
+
appearance: none;
|
|
509
|
+
}
|
|
510
|
+
|
|
444
511
|
.slex-input-control[data-has-unit="true"] .slex-input {
|
|
445
512
|
border-top-right-radius: 0;
|
|
446
513
|
border-bottom-right-radius: 0;
|
|
447
514
|
}
|
|
448
515
|
|
|
516
|
+
.slexkit-root .slex-input-control[data-has-unit="true"] input.slex-input {
|
|
517
|
+
border-top-right-radius: 0;
|
|
518
|
+
border-bottom-right-radius: 0;
|
|
519
|
+
}
|
|
520
|
+
|
|
449
521
|
.slex-input-unit {
|
|
450
522
|
box-sizing: border-box;
|
|
451
523
|
display: inline-flex;
|