@slexkit/mcp 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data/llms-components.txt +2 -1
- package/dist/data/llms-full.txt +73 -42
- package/dist/data/llms-runtime.txt +11 -12
- package/dist/data/llms.txt +1 -1
- package/dist/data/slexkit-ai-manifest.json +77 -73
- package/dist/index.js +3 -2
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slexkit-ai-docs",
|
|
3
3
|
"packageName": "slexkit",
|
|
4
|
-
"version": "0.3.
|
|
5
|
-
"generatedAt": "2026-06-
|
|
4
|
+
"version": "0.3.1",
|
|
5
|
+
"generatedAt": "2026-06-20T08:01:21.373Z",
|
|
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": "1445b5b6"
|
|
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.1",
|
|
17
|
+
"hash": "000eb11f"
|
|
18
18
|
},
|
|
19
19
|
"llms-components.txt": {
|
|
20
20
|
"path": "/llms-components.txt",
|
|
21
21
|
"title": "llms-components.txt",
|
|
22
22
|
"summary": "Use these components inside Markdown `slex` fences. Raw component docs are ordinary `.md` pages that preserve `slex` examples.",
|
|
23
|
-
"hash": "
|
|
23
|
+
"hash": "e2ea8c54"
|
|
24
24
|
},
|
|
25
25
|
"llms-runtime.txt": {
|
|
26
26
|
"path": "/llms-runtime.txt",
|
|
27
27
|
"title": "llms-runtime.txt",
|
|
28
28
|
"summary": "Raw Markdown: /docs/reference/spec.md",
|
|
29
|
-
"hash": "
|
|
29
|
+
"hash": "edb2cc90"
|
|
30
30
|
},
|
|
31
31
|
"llms-capabilities.txt": {
|
|
32
32
|
"path": "/llms-capabilities.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.
|
|
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.1-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": "117cabab"
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
"id": "guides/intro",
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
"href": "/docs/guides/quick-start",
|
|
79
79
|
"rawHref": "/docs/guides/quick-start.md",
|
|
80
80
|
"sourcePath": "site/content/guides/quick-start/en-US.md",
|
|
81
|
-
"body": "---\ntitle: Getting Started\ncategory: Guides\nstatus: ready\norder: 20\nsummary: \"Developer-first SlexKit integration: install the runtime, mount trusted fragments, wire Markdown hosts, and choose the next integration path.\"\nslexkitRenderMode: component\n---\n\n# Getting Started\n\nInstall `slexkit`, mount a trusted fragment, and you're off. Hand off Markdown / React / Obsidian details to dedicated guides — this page keeps the core integration path focused.\n\n## Installation Entry\n\nFor most apps, start by installing the root package:\n\n```sh\nnpm install slexkit\n```\n\n```ts\nimport { mount } from \"slexkit\";\nimport \"slexkit/style.css\";\n```\n\nFor clearer package boundaries, choose scoped packages by host:\n\n| Use case | Install |\n|---|---|\n| Custom components or component-free runtime | `npm install slexkit @slexkit/runtime` |\n| Official Svelte component registration | `npm install slexkit @slexkit/runtime @slexkit/components-svelte` |\n| Standalone shadcn-token theme CSS | `npm install @slexkit/theme-shadcn` |\n| React + Streamdown Markdown host | `npm install slexkit @slexkit/theme-shadcn @slexkit/streamdown streamdown react react-dom` |\n| Obsidian vault rendering |
|
|
82
|
-
"hash": "
|
|
81
|
+
"body": "---\ntitle: Getting Started\ncategory: Guides\nstatus: ready\norder: 20\nsummary: \"Developer-first SlexKit integration: install the runtime, mount trusted fragments, wire Markdown hosts, and choose the next integration path.\"\nslexkitRenderMode: component\n---\n\n# Getting Started\n\n> Just want to install the Obsidian plugin? Open **Settings -> Community plugins**, search for **SlexKit**, then install and enable it. The rest of this page is for developers integrating SlexKit into web apps, Markdown hosts, Streamdown, or custom runtimes.\n\nInstall `slexkit`, mount a trusted fragment, and you're off. Hand off Markdown / React / Obsidian details to dedicated guides — this page keeps the core integration path focused.\n\n## Installation Entry\n\nFor most apps, start by installing the root package:\n\n```sh\nnpm install slexkit\n```\n\n```ts\nimport { mount } from \"slexkit\";\nimport \"slexkit/style.css\";\n```\n\nFor clearer package boundaries, choose scoped packages by host:\n\n| Use case | Install |\n|---|---|\n| Custom components or component-free runtime | `npm install slexkit @slexkit/runtime` |\n| Official Svelte component registration | `npm install slexkit @slexkit/runtime @slexkit/components-svelte` |\n| Standalone shadcn-token theme CSS | `npm install @slexkit/theme-shadcn` |\n| React + Streamdown Markdown host | `npm install slexkit @slexkit/theme-shadcn @slexkit/streamdown streamdown react react-dom` |\n| Obsidian vault rendering | Install **SlexKit** from Obsidian Community Plugins |\n\n`@slexkit/runtime` and `@slexkit/components-svelte` are thin wrappers around the root package, not independent implementations.\n\n## Trusted Fragment\n\nTrusted mode is the minimal integration path. Use it for application-authored source, local examples, repository-maintained content, and reviewed snippets.\n\n```ts\nimport { mount } from \"slexkit\";\nimport \"slexkit/style.css\";\n\nconst source = {\n namespace: \"getting_started_counter\",\n g: {\n count: 0\n },\n layout: {\n \"card:demo\": {\n title: \"Counter\",\n \"text:value\": {\n \"$text\": \"'Count: ' + g.count\"\n },\n \"button:add\": {\n label: \"+1\",\n onclick: \"g.count++\"\n }\n }\n }\n};\n\nconst cleanup = mount(source, document.getElementById(\"app\")!);\n```\n\nCall `cleanup()` when removing containers, replacing messages, or unloading pages. If the namespace won't be reused, call `disposeNamespace(namespace)`.\n\n## Markdown Fallback\n\nWhen source appears in Markdown, handle only explicit `slex` fences and keep readable fallback text after the fence:\n\n````md\n```slex\n{\n namespace: \"release_status\",\n layout: {\n \"badge:status\": { label: \"Ready\", tone: \"success\" },\n \"text:summary\": { text: \"3 of 3 checks passed.\" }\n }\n}\n```\n\n**Release status:** Ready. 3 of 3 checks passed.\n````\n\nSlexKit-capable hosts render the fence. Plain Markdown hosts show the fallback. Do not infer executable SlexKit source from `js`, `json`, or unlabeled code blocks.\n\n## Markdown Host\n\nFor products rendering chat messages, docs pages, or long Markdown artifacts, use `createSlexKitMarkdownRuntimeHost`. It manages artifact scoping, block lifecycle, state-only fences, and trusted/secure mode selection.\n\n```ts\nimport { createSlexKitMarkdownRuntimeHost } from \"slexkit\";\nimport \"slexkit/style.css\";\n\nconst runtime = createSlexKitMarkdownRuntimeHost({\n mode: \"trusted\",\n theme: \"host-shadcn\"\n});\n\nexport function mountSlexFence(source: string, container: HTMLElement) {\n return runtime.mountBlock({\n artifactId: \"message-42\",\n source,\n container\n });\n}\n```\n\nWhen the whole document or message thread is destroyed, call `runtime.disposeArtifact(artifactId)` or `runtime.disposeAll()`.\n\n## Trust Boundary\n\n| Content source | Recommended mode |\n|---|---|\n| App-generated source, repository examples, local vault content | trusted |\n| Unreviewed user input, third-party Markdown, direct agent output | secure |\n\nSecure mode requires a sandbox iframe, a publicly served `slexkit.runtime.js`, and a host policy. See [Secure Runtime Setup](security-runtime).\n\n## Next Steps\n\n- [Integration](integration): React/Streamdown and Obsidian plugins\n- [Secure Runtime Setup](security-runtime): untrusted or agent-generated content\n- [Component Reference](../components/card): built-in component catalog\n- [AI / Agents](ai-agents): SlexKit authoring context for models and agents",
|
|
82
|
+
"hash": "ba82b030"
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
"id": "guides/integration",
|
|
@@ -89,8 +89,8 @@
|
|
|
89
89
|
"href": "/docs/guides/integration",
|
|
90
90
|
"rawHref": "/docs/guides/integration.md",
|
|
91
91
|
"sourcePath": "site/content/guides/integration/en-US.md",
|
|
92
|
-
"body": "---\ntitle: Integration\ncategory: Guides\nstatus: ready\norder: 25\nsummary: \"Plugin setup guide for Streamdown and Obsidian hosts that render explicit Slex fences.\"\nslexkitRenderMode: component\n---\n\n# Integration\n\nSlexKit ships
|
|
93
|
-
"hash": "
|
|
92
|
+
"body": "---\ntitle: Integration\ncategory: Guides\nstatus: ready\norder: 25\nsummary: \"Plugin setup guide for Streamdown and Obsidian hosts that render explicit Slex fences.\"\nslexkitRenderMode: component\n---\n\n# Integration\n\nSlexKit ships the Streamdown package in this repository and maintains the official Obsidian plugin in a separate release repository. Both integrations process only explicit `slex` fences — they don't scan ordinary JavaScript, JSON, or unlabeled code blocks. For the full API and host contract, see the [Host Integration reference](/docs/reference/integration).\n\n## Plugin Selection\n\n| Host | Package | Use case | Runtime boundary |\n|---|---|---|---|\n| React / Streamdown | `@slexkit/streamdown` | Chat messages, AI output, React Markdown pages | trusted or secure |\n| Obsidian | `slexkit/obsidian-slexkit` | Slex fences in local vault reading mode | trusted readonly |\n| Custom Markdown host | `slexkit` | Product-specific Markdown renderer or document viewer | trusted or secure |\n\nUse the packaged plugin when the host is Streamdown. Use the separate [SlexKit plugin repository](https://github.com/slexkit/obsidian-slexkit) for Obsidian installs and releases. Use `createSlexKitMarkdownRuntimeHost` directly for custom Markdown renderers.\n\nPackage installation details and release boundaries are tracked in [Package Boundaries](/docs/reference/packages).\n\n## Streamdown\n\nInstall the runtime, theme, plugin, and React peer dependencies:\n\n```sh\nnpm install slexkit @slexkit/theme-shadcn @slexkit/streamdown streamdown react react-dom\n```\n\nImport styles once in the app entry:\n\n```ts\nimport \"@slexkit/theme-shadcn/style.css\";\nimport \"@slexkit/streamdown/style.css\";\n```\n\nRegister the renderer with Streamdown:\n\n```tsx\nimport { Streamdown } from \"streamdown\";\nimport { slexkitRenderer } from \"@slexkit/streamdown\";\n\nexport function Message({ markdown }: { markdown: string }) {\n return (\n <Streamdown plugins={{ renderers: [slexkitRenderer] }}>\n {markdown}\n </Streamdown>\n );\n}\n```\n\nThe default renderer handles only `slex` fences. Ordinary code blocks pass through to Streamdown.\n\n## Streamdown Options\n\nUse `createSlexKitRenderer` when the host needs explicit domain scoping, source controls, playground mode, or secure mode:\n\n```tsx\nimport { createSlexKitRenderer } from \"@slexkit/streamdown\";\n\nconst renderer = createSlexKitRenderer({\n domain: \"chat-thread-42\",\n showChrome: false,\n showSource: false,\n runtime: \"trusted\"\n});\n```\n\nState-only fences in the same `domain` can seed later layout fences:\n\n````md\n```slex\n{\n namespace: \"calc\",\n g: { value: 21 }\n}\n```\n\n```slex\n{\n namespace: \"calc\",\n layout: {\n \"text:answer\": { \"$text\": \"'answer: ' + (g.value * 2)\" }\n }\n}\n```\n````\n\nFor unreviewed user input, third-party Markdown, or direct agent output, switch to secure mode and configure a host policy:\n\n```tsx\nconst renderer = createSlexKitRenderer({\n runtime: \"secure\",\n secureFrame: {\n runtimeUrl: \"/slexkit.runtime.js\"\n },\n securePolicy: {\n execution: {\n maxUnresponsiveMs: 30000\n }\n }\n});\n```\n\nThe secure runtime deployment checklist lives in [Secure Runtime Setup](security-runtime). Exact policy fields live in the [Security Runtime Contract](/docs/reference/security).\n\n## Obsidian\n\n> If your goal is only to install the Obsidian plugin, you do not need the developer integration material above. Search for **SlexKit** in Obsidian **Community plugins**, then install and enable it.\n\nThe Obsidian plugin targets local vault content. It registers a `slex` code block processor in reading mode, renders the fence as a readonly interactive fragment, and does not write output back to notes.\n\nInstall the plugin from Obsidian Community Plugins:\n\n1. Open **Settings -> Community plugins**.\n2. Disable **Restricted mode** if needed.\n3. Search for **SlexKit**.\n4. Install and enable the plugin.\n\nThe current community release is desktop-only until mobile vault testing is complete. The plugin is compatible with Obsidian 1.5.0+.\n\nBRAT and manual release assets remain useful for testing unreleased builds:\n\n```text\nBRAT repository: https://github.com/slexkit/obsidian-slexkit\n```\n\nManual installs copy the GitHub release assets into the vault:\n\n```text\n.obsidian/plugins/slexkit/\n main.js\n manifest.json\n styles.css\n```\n\nEnable **SlexKit** in Obsidian's community plugin settings.\n\n## Obsidian Example\n\nWrite an explicit `slex` fence in a note:\n\n````md\n```slex\n{\n namespace: \"vault_status\",\n layout: {\n \"card:status\": {\n title: \"Vault status\",\n \"badge:ready\": { label: \"Ready\", tone: \"success\" },\n \"text:note\": { text: \"Rendered by SlexKit in reading mode.\" }\n }\n }\n}\n```\n\nVault status: Ready.\n````\n\nBlocks in the same note share one Markdown artifact runtime, so a state-only fence can affect a later renderable fence.\n\n## Obsidian Boundary\n\nThe official plugin is a trusted readonly adapter. Content comes from the user's local vault; the plugin is not a sandbox for third-party Markdown or agent output.\n\nFor untrusted content, use secure mode in a web host with an explicit sandbox frame and host policy.\n\n## Integration Checklist\n\n- Process only fences whose language is exactly `slex`\n- Keep Markdown fallback for environments without SlexKit\n- Use a stable artifact/domain for each document, message, or note\n- Call cleanup when a container unmounts; dispose the artifact when the document is destroyed\n- Use secure mode for untrusted content instead of trusted mode\n- Link API, lifecycle, package, and security details to the reference pages instead of duplicating them in host guides",
|
|
93
|
+
"hash": "1138bddd"
|
|
94
94
|
},
|
|
95
95
|
{
|
|
96
96
|
"id": "guides/design",
|
|
@@ -111,8 +111,8 @@
|
|
|
111
111
|
"href": "/docs/guides/security-runtime",
|
|
112
112
|
"rawHref": "/docs/guides/security-runtime.md",
|
|
113
113
|
"sourcePath": "site/content/guides/security-runtime/en-US.md",
|
|
114
|
-
"body": "---\ntitle: Secure Runtime Setup\ncategory: Guides\nstatus: ready\norder: 40\nsummary: \"Decision and setup guide for rendering untrusted or agent-generated Slex source.\"\nslexkitRenderMode: component\n---\n\n# Secure Runtime Setup\n\nUse secure mode when the host does not fully control the Slex source: unreviewed user input, third-party Markdown, direct agent output, or shared documents where authorship is unclear.\n\nSecure mode is a deployment and policy choice. The complete threat model, `HostRuntimePolicy`, sandbox attributes, bridge messages, and fail-closed behavior are specified in the [Security Runtime Contract](/docs/reference/security).\n\n## Mode Decision\n\n| Source | Recommended mode | Notes |\n|---|---|---|\n| Application-generated source | trusted | Lowest overhead; source is part of your app boundary. |\n| Repository examples or reviewed snippets | trusted | Keep examples explicit and versioned. |\n| Local Obsidian vault notes | trusted readonly | The Obsidian adapter is not a sandbox boundary. |\n| User-submitted Markdown | secure | Treat source as untrusted even when the Markdown looks harmless. |\n| Direct agent output | secure | Do not grant network, timer, animation, or canvas access by default. |\n\nIf the answer is unclear, start with secure mode and enable capabilities only after the host has a concrete product need.\n\n## Minimal Host Setup\n\nFor Markdown hosts, prefer `createSlexKitMarkdownRuntimeHost`. It keeps artifact scoping, state-only fences, block cleanup, and secure-frame mounting in one place.\n\n```ts\nimport { createSlexKitMarkdownRuntimeHost } from \"slexkit\";\nimport \"slexkit/style.css\";\n\nconst runtime = createSlexKitMarkdownRuntimeHost({\n mode: \"secure\",\n theme: \"host-shadcn\",\n secureFrame: {\n runtimeUrl: \"/slexkit.runtime.js\"\n },\n policy: {\n execution: {\n heartbeatIntervalMs: 1000,\n maxUnresponsiveMs: 30000\n }\n }\n});\n\nexport function mountSlexFence(source: string, container: HTMLElement) {\n return runtime.mountBlock({\n artifactId: \"message-42\",\n source,\n container\n });\n}\n```\n\nCall `disposeBlock(container)` when a fence disappears, and call `disposeArtifact(artifactId)` when the full message, document, or note is destroyed.\n\nOmitted capability policies deny access by default. Add `network`, `timer`, `animation`, or `canvas` policy objects only when the host intentionally enables those capabilities.\n\n## Runtime Module\n\nThe secure iframe imports the runtime from `secureFrame.runtimeUrl`. Serve that file as a public ES module:\n\n```http\nAccess-Control-Allow-Origin: *\nContent-Type: text/javascript\n```\n\nThis is server or deployment configuration. It cannot be repaired from frontend JavaScript after the request has already failed.\n\n## Policy Checklist\n\n- Keep network disabled unless a specific product feature needs it.\n- If network is enabled, allow only required methods, origins, headers, body sizes, response sizes, and content types.\n- Keep timers, animation, and canvas disabled unless the Slex source needs them.\n- Never treat `capabilities`, `permissions`, `api`, or similar fields inside Slex source as authorization.\n- Do not add `allow-same-origin` to solve CORS or debugging issues.\n- Keep unresponsive runtime failures visible to users through the built-in fail-closed diagnostic.\n\nFor exact policy fields and allowed adapter hooks, use the [Security Runtime Contract](/docs/reference/security).\n\n## Host Boundaries\n\n`@slexkit/streamdown` can run trusted or secure. Use secure mode for chat messages and agent output unless the message source is already trusted by the host.\n\
|
|
115
|
-
"hash": "
|
|
114
|
+
"body": "---\ntitle: Secure Runtime Setup\ncategory: Guides\nstatus: ready\norder: 40\nsummary: \"Decision and setup guide for rendering untrusted or agent-generated Slex source.\"\nslexkitRenderMode: component\n---\n\n# Secure Runtime Setup\n\nUse secure mode when the host does not fully control the Slex source: unreviewed user input, third-party Markdown, direct agent output, or shared documents where authorship is unclear.\n\nSecure mode is a deployment and policy choice. The complete threat model, `HostRuntimePolicy`, sandbox attributes, bridge messages, and fail-closed behavior are specified in the [Security Runtime Contract](/docs/reference/security).\n\n## Mode Decision\n\n| Source | Recommended mode | Notes |\n|---|---|---|\n| Application-generated source | trusted | Lowest overhead; source is part of your app boundary. |\n| Repository examples or reviewed snippets | trusted | Keep examples explicit and versioned. |\n| Local Obsidian vault notes | trusted readonly | The Obsidian adapter is not a sandbox boundary. |\n| User-submitted Markdown | secure | Treat source as untrusted even when the Markdown looks harmless. |\n| Direct agent output | secure | Do not grant network, timer, animation, or canvas access by default. |\n\nIf the answer is unclear, start with secure mode and enable capabilities only after the host has a concrete product need.\n\n## Minimal Host Setup\n\nFor Markdown hosts, prefer `createSlexKitMarkdownRuntimeHost`. It keeps artifact scoping, state-only fences, block cleanup, and secure-frame mounting in one place.\n\n```ts\nimport { createSlexKitMarkdownRuntimeHost } from \"slexkit\";\nimport \"slexkit/style.css\";\n\nconst runtime = createSlexKitMarkdownRuntimeHost({\n mode: \"secure\",\n theme: \"host-shadcn\",\n secureFrame: {\n runtimeUrl: \"/slexkit.runtime.js\"\n },\n policy: {\n execution: {\n heartbeatIntervalMs: 1000,\n maxUnresponsiveMs: 30000\n }\n }\n});\n\nexport function mountSlexFence(source: string, container: HTMLElement) {\n return runtime.mountBlock({\n artifactId: \"message-42\",\n source,\n container\n });\n}\n```\n\nCall `disposeBlock(container)` when a fence disappears, and call `disposeArtifact(artifactId)` when the full message, document, or note is destroyed.\n\nOmitted capability policies deny access by default. Add `network`, `timer`, `animation`, or `canvas` policy objects only when the host intentionally enables those capabilities.\n\n## Runtime Module\n\nThe secure iframe imports the runtime from `secureFrame.runtimeUrl`. Serve that file as a public ES module:\n\n```http\nAccess-Control-Allow-Origin: *\nContent-Type: text/javascript\n```\n\nThis is server or deployment configuration. It cannot be repaired from frontend JavaScript after the request has already failed.\n\n## Policy Checklist\n\n- Keep network disabled unless a specific product feature needs it.\n- If network is enabled, allow only required methods, origins, headers, body sizes, response sizes, and content types.\n- Keep timers, animation, and canvas disabled unless the Slex source needs them.\n- Never treat `capabilities`, `permissions`, `api`, or similar fields inside Slex source as authorization.\n- Do not add `allow-same-origin` to solve CORS or debugging issues.\n- Keep unresponsive runtime failures visible to users through the built-in fail-closed diagnostic.\n\nFor exact policy fields and allowed adapter hooks, use the [Security Runtime Contract](/docs/reference/security).\n\n## Host Boundaries\n\n`@slexkit/streamdown` can run trusted or secure. Use secure mode for chat messages and agent output unless the message source is already trusted by the host.\n\nThe official Obsidian plugin is a trusted readonly adapter for local vault content. It should not be used as the isolation boundary for third-party Markdown or direct agent output.\n\nCustom Markdown hosts should still process only fences whose language is exactly `slex` and should preserve readable Markdown fallback for non-SlexKit environments.\n\n## Production Checklist\n\n- Stable `artifactId` per message, document, or note\n- Explicit `slex` fence detection only\n- Public `slexkit.runtime.js` module with CORS and JavaScript content type\n- Deny-by-default host policy\n- Cleanup on block removal and artifact destruction\n- Visible fallback text after each interactive fence\n- Link to the reference contract for policy, bridge, CSP, and sandbox details",
|
|
115
|
+
"hash": "eba73f9f"
|
|
116
116
|
},
|
|
117
117
|
{
|
|
118
118
|
"id": "guides/ai-agents",
|
|
@@ -144,8 +144,8 @@
|
|
|
144
144
|
"href": "/zh-CN/examples/first-interaction",
|
|
145
145
|
"rawHref": "/zh-CN/examples/first-interaction.md",
|
|
146
146
|
"sourcePath": "content/examples/first-interaction/zh-CN.md",
|
|
147
|
-
"body": "# 第一个交互:滑块操控数据\n\n上一节全是静态数据。要让 UI \"活起来\",需要三样东西:\n\n1. **`g` 对象** — 响应式状态容器\n2. **`$value` / `$label` / `$tone`** — 读表达式(从 g 取值渲染)\n3. **`onchange`** — 写表达式(用户操作写入 g)\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"learn_first_interaction\",\n g: { count: 42 },\n layout: {\n \"section:interact\": {\n eyebrow: \"入门教程 · 2/4\",\n title: \"第一个交互:滑块操控数据\",\n subtitle: \"滑动下面的滑块,stat 和 callout 会跟着变。这就是 SlexKit 的响应式核心。\",\n \"column:controls\": {\n \"slider:count\": {\n label: \"选择数值\",\n \"$value\": \"g.count\",\n min: 0,\n max: 100,\n step: 1,\n onchange: \"g.count = Number($event)\"\n },\n \"stat:
|
|
148
|
-
"hash": "
|
|
147
|
+
"body": "# 第一个交互:滑块操控数据\n\n上一节全是静态数据。要让 UI \"活起来\",需要三样东西:\n\n1. **`g` 对象** — 响应式状态容器\n2. **`$value` / `$label` / `$tone`** — 读表达式(从 g 取值渲染)\n3. **`onchange`** — 写表达式(用户操作写入 g)\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"learn_first_interaction\",\n g: { count: 42 },\n layout: {\n \"section:interact\": {\n eyebrow: \"入门教程 · 2/4\",\n title: \"第一个交互:滑块操控数据\",\n subtitle: \"滑动下面的滑块,stat 和 callout 会跟着变。这就是 SlexKit 的响应式核心。\",\n \"column:controls\": {\n \"slider:count\": {\n label: \"选择数值\",\n \"$value\": \"g.count\",\n min: 0,\n max: 100,\n step: 1,\n onchange: \"g.count = Number($event)\"\n },\n \"stat:countStat\": { label: \"当前数值\", \"$value\": \"g.count\" },\n \"badge:level\": {\n \"$label\": \"g.count < 30 ? '低' : g.count < 70 ? '中' : '高'\",\n \"$tone\": \"g.count < 30 ? 'success' : g.count < 70 ? 'warning' : 'danger'\"\n },\n \"callout:note\": {\n \"$tone\": \"g.count < 50 ? 'success' : 'info'\",\n \"$text\": \"g.count < 50 ? '当前值偏低,适合入门级负载。' : '当前值偏高,注意监控资源消耗。'\"\n }\n }\n }\n }\n}\n```\n\n核心公式:\n```\n用户操作 → onchange → g → SlexKit 检测变化 → 所有 $value/$tone/$text 自动重算 → UI 更新\n```\n\n这就是**单向数据流** + **响应式重渲染**。不需要手动 `setState`,不需要 DOM 操作。",
|
|
148
|
+
"hash": "d27f5fc3"
|
|
149
149
|
},
|
|
150
150
|
{
|
|
151
151
|
"id": "examples/multi-input-coordination",
|
|
@@ -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
|
|
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:base\": { label: \"税前工资\", \"$value\": \"g.base\", type: \"number\", unit: \"元/月\", onchange: \"g.base = Number($event || 0)\" },\n \"slider:base\": { 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": "05fd1883"
|
|
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
|
|
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:months\": { label: \"开发周期\", \"$value\": \"g.months\", type: \"number\", unit: \"个月\", onchange: \"g.months = Number($event || 0)\" },\n \"slider:months\": { label: \"开发周期\", \"$value\": \"g.months\", min: 1, max: 24, step: 1, unit: \"月\", onchange: \"g.months = Number($event)\" }\n },\n \"column:salaryField\": {\n \"input:salary\": { label: \"人均月薪\", \"$value\": \"g.salary\", type: \"number\", unit: \"元\", onchange: \"g.salary = Number($event || 0)\" },\n \"slider:salary\": { 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": "9355649f"
|
|
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
|
|
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:r1\": { label: \"R1\", \"$value\": \"g.r1\", type: \"number\", unit: \"Ω\", onchange: \"g.r1 = Number($event || 0)\" }, \"slider:r1\": { label: \"R1\", \"$value\": \"g.r1\", min: 100, max: 1000000, step: 100, unit: \"Ω\", onchange: \"g.r1 = Number($event)\" } },\n \"column:r2Field\": { \"input:r2\": { label: \"R2\", \"$value\": \"g.r2\", type: \"number\", unit: \"Ω\", onchange: \"g.r2 = Number($event || 0)\" }, \"slider:r2\": { 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:vin\": { label: \"输入电压 Vin\", \"$value\": \"g.vin\", type: \"number\", unit: \"V\", onchange: \"g.vin = Number($event || 0)\" }, \"slider:vin\": { label: \"Vin\", \"$value\": \"g.vin\", min: 0.1, max: 48, step: 0.1, unit: \"V\", onchange: \"g.vin = Number($event)\" } },\n \"column:rlField\": { \"input:rl\": { label: \"负载电阻 RL\", \"$value\": \"g.rl\", type: \"number\", unit: \"Ω\", onchange: \"g.rl = Number($event || 0)\" }, \"slider:rl\": { 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": "56dc3618"
|
|
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
|
|
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:r\": { label: \"电阻 R\", \"$value\": \"g.r\", type: \"number\", unit: \"Ω\", onchange: \"g.r = Number($event || 0)\" }, \"slider:r\": { label: \"R\", \"$value\": \"g.r\", min: 100, max: 100000, step: 100, unit: \"Ω\", onchange: \"g.r = Number($event)\" } },\n \"column:cField\": { \"input:c\": { label: \"电容 C\", \"$value\": \"g.c\", type: \"number\", unit: \"nF\", onchange: \"g.c = Number($event || 0)\" }, \"slider:c\": { label: \"C\", \"$value\": \"g.c\", min: 1, max: 1000, step: 1, unit: \"nF\", onchange: \"g.c = Number($event)\" } },\n \"column:fField\": { \"input:f\": { label: \"输入频率 f\", \"$value\": \"g.f\", type: \"number\", unit: \"Hz\", onchange: \"g.f = Number($event || 0)\" }, \"slider:f\": { 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": "52b5fb39"
|
|
215
215
|
},
|
|
216
216
|
{
|
|
217
217
|
"id": "examples/baud-rate-calculator",
|
|
@@ -221,8 +221,8 @@
|
|
|
221
221
|
"href": "/zh-CN/examples/baud-rate-calculator",
|
|
222
222
|
"rawHref": "/zh-CN/examples/baud-rate-calculator.md",
|
|
223
223
|
"sourcePath": "content/examples/baud-rate-calculator/zh-CN.md",
|
|
224
|
-
"body": "# 波特率误差计算器\n\n嵌入式开发中,UART 波特率由系统时钟分频得到。晶振频率不能整除目标波特率时会产生误差,误差超过 ±2% 通信就可能丢帧。\n\n## 核心公式\n\n$$Error = \\frac{|BR_{actual} - BR_{target}|}{BR_{target}} \\times 100\\%$$\n\n实际波特率 $BR_{actual} = f_{osc} / (16 \\times N)$,其中 $N = \\text{round}(f_{osc} / (16 \\times BR_{target}))$ 为分频寄存器整数。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_baud_rate_calculator\",\n g: {\n freq: 8,\n freqUnit: \"MHz\",\n baud: 115200,\n freqHz: function () { var m = { MHz: 1e6, kHz: 1e3, Hz: 1 }; return this.freq * (m[this.freqUnit] || 1e6); },\n divisor: function () { return this.freqHz() / (16 * this.baud); },\n regValue: function () { return Math.round(this.divisor()); },\n actualBaud: function () { return this.freqHz() / (16 * this.regValue()); },\n error: function () { return Math.abs((this.actualBaud() - this.baud) / this.baud * 100); },\n reliability: function () { var e = this.error(); return e < 0.5 ? \"优秀\" : e < 2 ? \"可接受\" : e < 5 ? \"有风险\" : \"不可用\"; },\n tone: function () { var e = this.error(); return e < 0.5 ? \"success\" : e < 2 ? \"info\" : e < 5 ? \"warning\" : \"danger\"; }\n },\n layout: {\n \"section:
|
|
225
|
-
"hash": "
|
|
224
|
+
"body": "# 波特率误差计算器\n\n嵌入式开发中,UART 波特率由系统时钟分频得到。晶振频率不能整除目标波特率时会产生误差,误差超过 ±2% 通信就可能丢帧。\n\n## 核心公式\n\n$$Error = \\frac{|BR_{actual} - BR_{target}|}{BR_{target}} \\times 100\\%$$\n\n实际波特率 $BR_{actual} = f_{osc} / (16 \\times N)$,其中 $N = \\text{round}(f_{osc} / (16 \\times BR_{target}))$ 为分频寄存器整数。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_baud_rate_calculator\",\n g: {\n freq: 8,\n freqUnit: \"MHz\",\n baud: 115200,\n freqHz: function () { var m = { MHz: 1e6, kHz: 1e3, Hz: 1 }; return this.freq * (m[this.freqUnit] || 1e6); },\n divisor: function () { return this.freqHz() / (16 * this.baud); },\n regValue: function () { return Math.round(this.divisor()); },\n actualBaud: function () { return this.freqHz() / (16 * this.regValue()); },\n error: function () { return Math.abs((this.actualBaud() - this.baud) / this.baud * 100); },\n reliability: function () { var e = this.error(); return e < 0.5 ? \"优秀\" : e < 2 ? \"可接受\" : e < 5 ? \"有风险\" : \"不可用\"; },\n tone: function () { var e = this.error(); return e < 0.5 ? \"success\" : e < 2 ? \"info\" : e < 5 ? \"warning\" : \"danger\"; }\n },\n layout: {\n \"section:baudCalculator\": {\n title: \"波特率误差计算器\",\n subtitle: \"输入晶振频率和目标波特率,计算误差。\",\n \"card:baud\": {\n title: \"波特率误差计算器\",\n \"grid:params\": {\n columns: 1, mdColumns: 2,\n \"column:freqField\": {\n \"input:freq\": { label: \"晶振频率\", \"$value\": \"g.freq\", type: \"number\", unit: \"MHz\", onchange: \"g.freq = Number($event || 0)\" }\n },\n \"column:baudField\": {\n \"select:baud\": { label: \"目标波特率\", \"$value\": \"g.baud\", options: [{ label: \"9600\", value: 9600 }, { label: \"19200\", value: 19200 }, { label: \"38400\", value: 38400 }, { label: \"57600\", value: 57600 }, { label: \"115200\", value: 115200 }, { label: \"230400\", value: 230400 }, { label: \"460800\", value: 460800 }], onchange: \"g.baud = Number($event)\" }\n },\n \"column:unitField\": {\n \"select:unit\": { label: \"频率单位\", \"$value\": \"g.freqUnit\", options: [{ label: \"MHz\", value: \"MHz\" }, { label: \"kHz\", value: \"kHz\" }, { label: \"Hz\", value: \"Hz\" }], onchange: \"g.freqUnit = String($event)\" }\n },\n \"column:divField\": {\n \"stat:divisor\": { label: \"分频比\", \"$value\": \"g.divisor().toFixed(3)\" }\n }\n },\n \"formula:equation\": { \"$tex\": \"'\\\\\\\\text{Error} = \\\\\\\\frac{|' + g.actualBaud().toFixed(0) + ' - ' + g.baud + '|}{' + g.baud + '} \\\\\\\\times 100\\\\\\\\% = ' + g.error().toFixed(2) + '\\\\\\\\%'\" },\n \"grid:results\": {\n columns: 1, mdColumns: 4,\n \"stat:actualBaud\": { label: \"实际波特率\", \"$value\": \"g.actualBaud().toFixed(0)\", unit: \"bps\" },\n \"stat:error\": { label: \"误差\", \"$value\": \"g.error().toFixed(2)\", unit: \"%\" },\n \"stat:reliability\": { label: \"可靠性\", \"$value\": \"g.reliability()\", \"$tone\": \"g.tone()\" },\n \"stat:regValue\": { label: \"寄存器值\", \"$value\": \"g.regValue()\" }\n },\n \"callout:advice\": { \"$tone\": \"g.tone()\", \"$text\": \"g.error() < 0.5 ? '误差极小,通信可靠。' : g.error() < 2 ? '误差在可接受范围内(<2%),绝大多数场景可用。' : g.error() < 5 ? '误差偏大,长帧通信可能失败,建议更换晶振或降低波特率。' : '误差过大,通信不可靠。请选择能整除的晶振频率。'\" }\n }\n }\n }\n}\n```\n\n\n## 常用晶振频率与波特率误差表\n\n| 晶振 | 9600 | 19200 | 38400 | 57600 | 115200 |\n|------|------|-------|-------|-------|--------|\n| 1.8432 MHz | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |\n| 3.6864 MHz | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |\n| 4.0000 MHz | 8.51 | 8.51 | 8.51 | 8.51 | 8.51 |\n| 7.3728 MHz | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |\n| 8.0000 MHz | 8.51 | 8.51 | 8.51 | 8.51 | 8.51 |\n| 11.0592 MHz | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |\n| 14.7456 MHz | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |\n| 16.0000 MHz | 8.51 | 8.51 | 8.51 | 8.51 | 8.51 |\n\n**工程笔记**:\n\n- 零误差的关键:晶振频率能被 $16 \\times BR$ 整除\n- **11.0592 MHz** 是 UART 最经典的选择,对所有标准波特率零误差\n- **7.3728 MHz** 和 **14.7456 MHz** 同样零误差\n- 错误 < 2% 在实际工程中通常可工作,但高速长帧场景建议 < 1%",
|
|
225
|
+
"hash": "7ac3d2d9"
|
|
226
226
|
},
|
|
227
227
|
{
|
|
228
228
|
"id": "examples/search-filter-table",
|
|
@@ -243,8 +243,8 @@
|
|
|
243
243
|
"href": "/zh-CN/examples/project-dashboard",
|
|
244
244
|
"rawHref": "/zh-CN/examples/project-dashboard.md",
|
|
245
245
|
"sourcePath": "content/examples/project-dashboard/zh-CN.md",
|
|
246
|
-
"body": "# 项目仪表盘\n\n真实项目需要一览全局——不是单一张计算卡片,而是一个**仪表盘**。用 `section` 做区块分组,`grid` 做多列布局,每个 card 展示一个关注领域。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_dashboard\",\n g: {\n sprint: 8, team: 6, sprintProgress: 72, bugs: 12, resolved: 9,\n scope: \"on-track\",\n bugRate: function () { return this.resolved / this.bugs * 100; },\n teamLoad: function () { return Math.min(100, this.sprint / this.team * 20); },\n scopeStatus: function () { return this.scope === \"on-track\" ? \"正常\" : this.scope === \"at-risk\" ? \"有风险\" : \"已偏离\"; }\n },\n layout: {\n \"section:dashboard\": {\n eyebrow: \"Sprint 概览\",\n title: \"项目仪表盘 · Sprint 24\",\n subtitle: \"数据截止今日 10:00 AM。拖滑动条查看不同假想数据的效果。\",\n \"grid:row1\": {\n columns: 1, mdColumns: 3,\n \"card:sprint\": {\n title: \"Sprint 进度\",\n \"progress:sp\": { label: \"完成度\", \"$value\": \"g.sprintProgress\" },\n \"stat:scope\": {
|
|
247
|
-
"hash": "
|
|
246
|
+
"body": "# 项目仪表盘\n\n真实项目需要一览全局——不是单一张计算卡片,而是一个**仪表盘**。用 `section` 做区块分组,`grid` 做多列布局,每个 card 展示一个关注领域。\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_dashboard\",\n g: {\n sprint: 8, team: 6, sprintProgress: 72, bugs: 12, resolved: 9,\n scope: \"on-track\",\n bugRate: function () { return this.resolved / this.bugs * 100; },\n teamLoad: function () { return Math.min(100, this.sprint / this.team * 20); },\n scopeStatus: function () { return this.scope === \"on-track\" ? \"正常\" : this.scope === \"at-risk\" ? \"有风险\" : \"已偏离\"; }\n },\n layout: {\n \"section:dashboard\": {\n eyebrow: \"Sprint 概览\",\n title: \"项目仪表盘 · Sprint 24\",\n subtitle: \"数据截止今日 10:00 AM。拖滑动条查看不同假想数据的效果。\",\n \"grid:row1\": {\n columns: 1, mdColumns: 3,\n \"card:sprint\": {\n title: \"Sprint 进度\",\n \"progress:sp\": { label: \"完成度\", \"$value\": \"g.sprintProgress\" },\n \"stat:scope\": { label: \"范围状态\", \"$value\": \"g.scopeStatus()\" },\n \"badge:flag\": { \"$label\": \"g.scope === 'on-track' ? '正常' : g.scope === 'at-risk' ? '⚠ 预警' : '🚨 偏离'\", \"$tone\": \"g.scope === 'on-track' ? 'success' : g.scope === 'at-risk' ? 'warning' : 'danger'\" }\n },\n \"card:quality\": {\n title: \"质量指标\",\n \"stat:bugs\": { label: \"剩余缺陷\", value: \"3\", unit: \"个\" },\n \"progress:bugFix\": { label: \"修复率\", \"$value\": \"g.bugRate()\" },\n \"badge:trend\": { label: \"趋势:改善中\", tone: \"success\" }\n },\n \"card:team\": {\n title: \"团队健康度\",\n \"stat:members\": { label: \"团队成员\", value: \"6\", unit: \"人\" },\n \"progress:load\": { label: \"负载指数\", \"$value\": \"g.teamLoad()\" },\n \"callout:note\": { \"$tone\": \"g.teamLoad() > 80 ? 'warning' : 'info'\", \"$text\": \"g.teamLoad() > 80 ? '负载偏高,建议调整任务分配。' : '团队负载在健康范围内。'\" }\n }\n },\n \"card:detail\": {\n title: \"详细数据\",\n \"table:tasks\": {\n columns: [\"任务\", \"负责人\", \"状态\", \"耗时\"],\n rows: [[\"API 重构\", \"张三\", \"已完成\", \"3d\"], [\"前端组件\", \"李四\", \"进行中\", \"2d\"], [\"集成测试\", \"王五\", \"代码审查\", \"1.5d\"], [\"性能优化\", \"赵六\", \"待开始\", \"—\"]]\n },\n \"callout:help\": { \"$tone\": \"g.bugRate() < 80 ? 'warning' : 'success'\", \"$text\": \"g.bugRate() < 80 ? '缺陷修复率低于80%,建议优先处理高优先级缺陷。' : '缺陷修复率良好,项目质量可控。'\" }\n }\n }\n }\n}\n```\n\n**仪表盘的设计思路:**\n\n- 用 `section` 做顶层分组(带 eyebrow 和 subtitle,语义清晰)\n- 用 `grid` 做多列布局,每个格子放一个 `card`\n- 每个 card 内放不同关注维度的 stat / progress / badge\n- 底部放一个详情 card,展示表格数据(任务列表)\n- 通过 `$text` 和 `$tone` 在 callout 中做条件提示\n\n\n这个模式适用于:技术 Leader 周报面板、发布质检看板、团队 OKR 追踪、SRE 服务大盘。",
|
|
247
|
+
"hash": "aacce5f0"
|
|
248
248
|
},
|
|
249
249
|
{
|
|
250
250
|
"id": "examples/form-wizard-steps",
|
|
@@ -298,8 +298,8 @@
|
|
|
298
298
|
"href": "/zh-CN/examples/cross-doc-state-lab",
|
|
299
299
|
"rawHref": "/zh-CN/examples/cross-doc-state-lab.md",
|
|
300
300
|
"sourcePath": "content/examples/cross-doc-state-lab/zh-CN.md",
|
|
301
|
-
"body": "# 跨文档状态实验室\n\n这是 SlexKit 最独特的能力之一:**在同一个 Markdown 文档的不同位置放置多块 `slex` 代码,只要它们使用相同的 `namespace`,就会共享同一份 `g` 状态**。\n\n下面是三个独立的 ` ```slex ` fence——一个控制面板和两个观察面板。试试修改控制面板的值,看下方两个面板实时响应。\n\n## 主控面板\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_cross_doc_lab\",\n g: {\n color: \"blue\", size: 16, theme: \"light\",\n style: function () {\n return 'color: ' + this.color + '; font-size: ' + this.size + 'px;';\n }\n },\n layout: {\n \"section:control\": {\n eyebrow: \"平台能力\",\n title: \"跨文档状态实验室 · 主控面板\",\n subtitle: \"修改以下任何参数——下方两个独立 fence 块的卡片会同步更新。\",\n \"grid:controls\": {\n columns: 1, mdColumns: 3,\n \"select:color\": {\n label: \"文字颜色\",\n \"$value\": \"g.color\",\n options: [\n { label: \"蓝色\", value: \"blue\" },\n { label: \"绿色\", value: \"green\" },\n { label: \"橙色\", value: \"orange\" },\n { label: \"紫色\", value: \"purple\" }\n ],\n onchange: \"g.color = String($event)\"\n },\n \"slider:size\": { label: \"字体大小\", \"$value\": \"g.size\", min: 8, max: 48, step: 2, unit: \"px\", onchange: \"g.size = Number($event)\" },\n \"select:theme\": {\n label: \"卡片主题\",\n \"$value\": \"g.theme\",\n options: [\n { label: \"明亮\", value: \"light\" },\n { label: \"暗色\", value: \"dark\" },\n { label: \"信息\", value: \"info\" }\n ],\n onchange: \"g.theme = String($event)\"\n }\n },\n \"badge:note\": { \"$label\": \"'样式 ' + g.color + ' ' + g.size + 'px'\", tone: \"info\" }\n }\n }\n}\n```\n\n## 观察面板 A(同一 namespace,不同 fence 块)\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_cross_doc_lab\",\n layout: {\n \"card:a\": {\n title: \"观察面板 A — 纯文本样式\",\n \"
|
|
302
|
-
"hash": "
|
|
301
|
+
"body": "# 跨文档状态实验室\n\n这是 SlexKit 最独特的能力之一:**在同一个 Markdown 文档的不同位置放置多块 `slex` 代码,只要它们使用相同的 `namespace`,就会共享同一份 `g` 状态**。\n\n下面是三个独立的 ` ```slex ` fence——一个控制面板和两个观察面板。试试修改控制面板的值,看下方两个面板实时响应。\n\n## 主控面板\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_cross_doc_lab\",\n g: {\n color: \"blue\", size: 16, theme: \"light\",\n style: function () {\n return 'color: ' + this.color + '; font-size: ' + this.size + 'px;';\n }\n },\n layout: {\n \"section:control\": {\n eyebrow: \"平台能力\",\n title: \"跨文档状态实验室 · 主控面板\",\n subtitle: \"修改以下任何参数——下方两个独立 fence 块的卡片会同步更新。\",\n \"grid:controls\": {\n columns: 1, mdColumns: 3,\n \"select:color\": {\n label: \"文字颜色\",\n \"$value\": \"g.color\",\n options: [\n { label: \"蓝色\", value: \"blue\" },\n { label: \"绿色\", value: \"green\" },\n { label: \"橙色\", value: \"orange\" },\n { label: \"紫色\", value: \"purple\" }\n ],\n onchange: \"g.color = String($event)\"\n },\n \"slider:size\": { label: \"字体大小\", \"$value\": \"g.size\", min: 8, max: 48, step: 2, unit: \"px\", onchange: \"g.size = Number($event)\" },\n \"select:theme\": {\n label: \"卡片主题\",\n \"$value\": \"g.theme\",\n options: [\n { label: \"明亮\", value: \"light\" },\n { label: \"暗色\", value: \"dark\" },\n { label: \"信息\", value: \"info\" }\n ],\n onchange: \"g.theme = String($event)\"\n }\n },\n \"badge:note\": { \"$label\": \"'样式 ' + g.color + ' ' + g.size + 'px'\", tone: \"info\" }\n }\n }\n}\n```\n\n## 观察面板 A(同一 namespace,不同 fence 块)\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_cross_doc_lab\",\n layout: {\n \"card:a\": {\n title: \"观察面板 A — 纯文本样式\",\n \"column:stylePreview\": {\n \"text:styleMeta\": { \"$text\": \"'字体大小:' + g.size + 'px'\" },\n \"text:styledValue\": { \"$text\": \"g.color\", \"$color\": \"g.color\", \"$size\": \"g.size\" }\n },\n \"callout:preview\": {\n \"$tone\": \"g.theme === 'dark' ? 'danger' : g.theme === 'info' ? 'info' : 'success'\",\n \"$text\": \"g.theme === 'dark' ? '暗色模式:适合夜间阅读的配色方案。' : g.theme === 'info' ? '信息模式:用于强调技术细节。' : '明亮模式:默认的文档阅读配色。'\"\n }\n }\n }\n}\n```\n\n## 观察面板 B\n\n```slex\n{\n slex: \"0.1\",\n namespace: \"example_cross_doc_lab\",\n layout: {\n \"card:b\": {\n title: \"观察面板 B — 参数详情\",\n \"grid:params\": {\n columns: 1, mdColumns: 3,\n \"stat:col\": { label: \"颜色\", \"$value\": \"g.color\" },\n \"stat:sz\": { label: \"字号\", \"$value\": \"g.size\", unit: \"px\" },\n \"stat:th\": { label: \"主题\", \"$value\": \"g.theme\" }\n },\n \"badge:sync\": { \"$label\": \"'已同步 ' + g.color\", \"$tone\": \"g.color === 'blue' ? 'info' : g.color === 'green' ? 'success' : g.color === 'orange' ? 'warning' : 'info'\" }\n }\n }\n}\n```\n\n**三个 fence 块**,同一个 `namespace: \"example_cross_doc_lab\"`,所有组件共享 `g` 对象。上面你在主控面板改颜色和大小,下面两个观察面板马上更新。\n\n---\n\n### 这意味着什么?\n\n假设你在一篇长篇 Markdown 文档中:\n\n```\n[控制面板 — 选择行业/指标/时间范围]\n... 30 段 Markdown 叙事 ...\n[图表 A — 自动反映控制面板的选项]\n... 更多分析文字 ...\n[图表 B — 同一份状态的不同可视化]\n```\n\n每个 ` ```slex ` 块可以独立渲染,但只要 namespace 相同,它们就共享状态。这对于:\n\n- **技术白皮书**:顶部选参数,中间分析,底部结论,全程联动\n- **项目协作文档**:状态跟踪表格在顶部,各团队任务卡片散布在正文中\n- **AI 输出增强**:模型生成的多个可视化节点共享同一份推理结果\n\n\n都是极其强大的模式。这不是一个 \"组件库\" 能做到的——这是 SlexKit 的核心设计。",
|
|
302
|
+
"hash": "7ac63204"
|
|
303
303
|
},
|
|
304
304
|
{
|
|
305
305
|
"id": "examples/network-policy-fetch-card",
|
|
@@ -463,8 +463,8 @@
|
|
|
463
463
|
"href": "/docs/components/input",
|
|
464
464
|
"rawHref": "/docs/components/input.md",
|
|
465
465
|
"sourcePath": "site/content/components/input/en-US.md",
|
|
466
|
-
"body": "---\ntitle: \"Input\"\ncategory: Input\nstatus: ready\nsummary: \"Single-line text or engineering value input.\"\n---\n# Input\n\nSingle-line text input with controlled value, placeholder, label, description, native types, engineering input, and disabled state.\n\n<!-- slex:spec-example:start component=\"input\" id=\"basic\" sourceHash=\"4215f98a\" -->\n```slex\n{\n \"slex\": \"0.1\",\n \"namespace\": \"doc_input_typical\",\n \"layout\": {\n \"input:name\": {\n \"label\": \"Project\",\n \"value\": \"SlexKit\",\n \"placeholder\": \"Enter name\",\n \"description\": \"Visible labels keep form fields scannable.\"\n }\n }\n}\n```\n<!-- slex:spec-example:end -->\n\n## Usage Notes\n\n- Use for name input, search boxes, email/password, and other single-line text.\n- Use `type: \"engineering\"` for values such as `4.7k`, `2.2uF`, or `1e-3`.\n- Not suitable for numeric range selection (use `slider`).\n- Related components: `select` for option selection, `slider` for numeric ranges.\n- Typically placed inside a `column` to compose forms.\n- Use `$value` and `onchange` for state binding.\n- Numeric
|
|
467
|
-
"hash": "
|
|
466
|
+
"body": "---\ntitle: \"Input\"\ncategory: Input\nstatus: ready\nsummary: \"Single-line text or engineering value input.\"\n---\n# Input\n\nSingle-line text input with controlled value, placeholder, label, description, native types, engineering input, and disabled state.\n\n<!-- slex:spec-example:start component=\"input\" id=\"basic\" sourceHash=\"4215f98a\" -->\n```slex\n{\n \"slex\": \"0.1\",\n \"namespace\": \"doc_input_typical\",\n \"layout\": {\n \"input:name\": {\n \"label\": \"Project\",\n \"value\": \"SlexKit\",\n \"placeholder\": \"Enter name\",\n \"description\": \"Visible labels keep form fields scannable.\"\n }\n }\n}\n```\n<!-- slex:spec-example:end -->\n\n## Usage Notes\n\n- Use for name input, search boxes, email/password, and other single-line text.\n- Use `type: \"engineering\"` for values such as `4.7k`, `2.2uF`, or `1e-3`.\n- Not suitable for numeric range selection (use `slider`).\n- Related components: `select` for option selection, `slider` for numeric ranges.\n- Typically placed inside a `column` to compose forms.\n- Use `$value` and `onchange` for state binding.\n- Numeric and engineering inputs render only the native input. Use `slider` for range adjustment; SlexKit no longer adds custom decrement or increment buttons.\n- `onchange` fires when the user edits the value.\n- `type: \"number\"` still emits a string value. Convert with `Number($event)` or use `type: \"engineering\"` to read parsed results.\n- Use `invalid` plus `error` for validation feedback. Error text is linked through `aria-describedby`.\n\n### Label and unit\n\n`label` renders as a clickable native label; `unit` renders as trailing text, suitable for voltage, resistance, frequency, etc.\n\n```slex\n{\n namespace: \"doc_input_label_unit\",\n layout: {\n \"input:voltage\": {\n label: \"Voltage\",\n value: \"3.3\",\n unit: \"V\",\n description: \"Supply rail\"\n }\n }\n}\n```\n\n### Disabled state\n\n```slex\n{\n namespace: \"doc_input_disabled_diff\",\n layout: {\n \"row:diff\": {\n \"input:enabled\": {\n value: \"Editable\",\n placeholder: \"Type here\"\n },\n \"input:disabled\": {\n value: \"Disabled\",\n disabled: true\n }\n }\n }\n}\n```\n\n### Engineering input\n\n`type: \"engineering\"` uses a text input (not the native number type). Component state retains the raw string and additionally exposes parsed results:\n\n```slex\n{\n namespace: \"doc_input_engineering\",\n layout: {\n \"input:resistance\": {\n type: \"engineering\",\n value: \"4.7kΩ\"\n },\n \"stat:parsed\": {\n label: \"Parsed value\",\n $value: \"resistance.valid ? resistance.number : 'Invalid'\",\n $unit: \"resistance.unit\"\n }\n }\n}\n```\n\nSupports scientific notation and SI prefixes: `p`, `n`, `u`, `µ`, `m`, `k`, `K`, `M`, `meg`, `G`, `T`. Units are captured but not converted across physical dimensions.\n\n## API Reference {#api}\n\n<!-- slex:spec-api:start component=\"input\" sourceHash=\"a1afe57e\" -->\n| Field | Type | Required | Dynamic | Default | Description |\n|---|---|---|---|---|---|\n| `value` | string | No | Yes | | Current input value. |\n| `label` | string | No | Yes | | Input label. |\n| `unit` | string | No | Yes | | Trailing unit text. |\n| `description` | string | No | Yes | | Assistive description below the input. |\n| `help` | string | No | Yes | | Alias for description. |\n| `hint` | string | No | Yes | | Alias for description. |\n| `error` | string | No | Yes | | Error text shown below the input and linked with aria-describedby. |\n| `errorMessage` | string | No | Yes | | Alias for error. |\n| `invalid` | boolean | No | Yes | `false` | Mark the input as invalid with aria-invalid and error styling. |\n| `placeholder` | string | No | No | | Placeholder text for empty values. |\n| `type` | string | No | No | `\"text\"` | Input value kind; use engineering for parsed engineering values. |\n| `disabled` | boolean | No | Yes | `false` | Disable editing. |\n| `readonly` | boolean | No | Yes | `false` | Make the input read-only. |\n| `readOnly` | boolean | No | Yes | `false` | Alias for readonly. |\n| `required` | boolean | No | Yes | `false` | Mark the input as required. |\n| `id` | string | No | No | | Native input id; defaults to a stable id derived from the component name. |\n| `name` | string | No | No | | Native input name attribute. |\n| `min` | string \\| number | No | Yes | | Minimum value used by numeric input controls. |\n| `max` | string \\| number | No | Yes | | Maximum value used by numeric input controls. |\n| `step` | string \\| number | No | Yes | | Step size used by numeric input controls. |\n| `onchange` | write-expression | No | No | | Write expression invoked when the value changes. |\n<!-- slex:spec-api:end -->",
|
|
467
|
+
"hash": "3efa0e53"
|
|
468
468
|
},
|
|
469
469
|
{
|
|
470
470
|
"id": "components/link",
|
|
@@ -617,8 +617,8 @@
|
|
|
617
617
|
"href": "/docs/components/text",
|
|
618
618
|
"rawHref": "/docs/components/text.md",
|
|
619
619
|
"sourcePath": "site/content/components/text/en-US.md",
|
|
620
|
-
"body": "---\ntitle: \"Text\"\ncategory: Display\nstatus: ready\nsummary: \"Short text output for status, description, and results.\"\n---\n# Text\n\nOutput text content for status messages, descriptions, and result display.\n\n<!-- slex:spec-example:start component=\"text\" id=\"basic\" sourceHash=\"bd63ce36\" -->\n```slex\n{\n \"slex\": \"0.1\",\n \"namespace\": \"doc_text_typical\",\n \"layout\": {\n \"text:status\": {\n \"text\": \"System is healthy\"\n }\n }\n}\n```\n<!-- slex:spec-example:end -->\n\n## Usage Notes\n\n- Use for status text, short descriptions, label values, and lightweight output.\n- Not suitable for long paragraphs or structured data (use `table`).\n- Related components: `stat` for numeric metrics, `badge` for status labels.\n- Keep text short; use multiple `text` nodes for longer content.\n- Typically placed inside `row`, `column`, or `card`.\n\n## API Reference {#api}\n\n<!-- slex:spec-api:start component=\"text\" sourceHash=\"
|
|
621
|
-
"hash": "
|
|
620
|
+
"body": "---\ntitle: \"Text\"\ncategory: Display\nstatus: ready\nsummary: \"Short text output for status, description, and results.\"\n---\n# Text\n\nOutput text content for status messages, descriptions, and result display.\n\n<!-- slex:spec-example:start component=\"text\" id=\"basic\" sourceHash=\"bd63ce36\" -->\n```slex\n{\n \"slex\": \"0.1\",\n \"namespace\": \"doc_text_typical\",\n \"layout\": {\n \"text:status\": {\n \"text\": \"System is healthy\"\n }\n }\n}\n```\n<!-- slex:spec-example:end -->\n\n## Usage Notes\n\n- Use for status text, short descriptions, label values, and lightweight output.\n- Not suitable for long paragraphs or structured data (use `table`).\n- Related components: `stat` for numeric metrics, `badge` for status labels.\n- Keep text short; use multiple `text` nodes for longer content.\n- Typically placed inside `row`, `column`, or `card`.\n\n## API Reference {#api}\n\n<!-- slex:spec-api:start component=\"text\" sourceHash=\"745fea9a\" -->\n| Field | Type | Required | Dynamic | Default | Description |\n|---|---|---|---|---|---|\n| `text` | string | No | Yes | | Displayed text. |\n| `content` | string | No | Yes | | Alias for text. |\n| `label` | string | No | Yes | | Alias for text. |\n| `variant` | string: default, muted | No | No | `\"default\"` | Text visual variant. |\n| `color` | string | No | Yes | | Optional CSS color for controlled previews. |\n| `size` | string \\| number | No | Yes | | Optional font size. Numbers are treated as px. |\n| `class` | string | No | No | | Additional host-controlled CSS class. |\n<!-- slex:spec-api:end -->",
|
|
621
|
+
"hash": "c8137ecc"
|
|
622
622
|
},
|
|
623
623
|
{
|
|
624
624
|
"id": "components/toast",
|
|
@@ -672,8 +672,8 @@
|
|
|
672
672
|
"href": "/docs/reference/integration",
|
|
673
673
|
"rawHref": "/docs/reference/integration.md",
|
|
674
674
|
"sourcePath": "site/content/reference/integration/en-US.md",
|
|
675
|
-
"body": "---\ntitle: Host Integration\ncategory: Reference\nstatus: ready\norder: 40\nsummary: \"MarkdownRuntimeHost, trusted and secure host integrations, Streamdown, Obsidian, and custom adapters.\"\nslexkitRenderMode: component\n---\n\n# Host Integration\n\nHow to integrate SlexKit into Markdown renderers, chat hosts, document viewers, and custom platforms.\n\n## Core concepts\n\n### Artifact\n\nAn artifact is a group of Slex blocks belonging to the same document, message, or note. Hosts identify an artifact by an `artifactId` and group related blocks into one runtime domain.\n\nIn **trusted mode**, the runtime prefixes each block's namespace with the artifact ID to prevent cross-document state pollution. `disposeArtifact()` releases all namespace stores for that artifact.\n\nIn **secure mode**, all fences in one artifact are combined into a single sandbox iframe. The runtime maintains artifact slots, syncing rendered heights back to the original Markdown placeholder containers.\n\n### Block\n\nA block is a single Slex block: one renderable unit. It has:\n- A source (Slex expression object or source string).\n- A container element (where the rendered output goes).\n- An optional `artifactId` (for grouping into an artifact).\n\n### Cleanup\n\nEvery block mount returns a cleanup function. The host must call it when the block is removed. For artifact-level cleanup, call `disposeArtifact(artifactId)`. For global cleanup, call `disposeAll()`.\n\n## MarkdownRuntimeHost\n\nThe `SlexKitMarkdownRuntimeHost` is the recommended API for Markdown-based hosts. It handles mode selection, artifact management, and block lifecycle.\n\n```ts\nimport {\n createSlexKitMarkdownRuntimeHost,\n getSlexKitMarkdownRuntimeHost,\n installSlexKitMarkdownRuntimeHost\n} from \"slexkit\";\n```\n\n### Interface\n\n```ts\ntype SlexKitMarkdownRuntimeHost = {\n configure(options: Partial<SlexKitMarkdownRuntimeOptions>): void;\n getMode(): \"trusted\" | \"secure\";\n mountBlock(block: SlexKitMarkdownBlock): () => void;\n disposeBlock(container: HTMLElement): void;\n disposeArtifact(artifactId: string): void;\n disposeAll(): void;\n};\n\ntype SlexKitMarkdownBlock = {\n artifactId?: string;\n blockId?: string;\n source: SlexExpression | string;\n container: HTMLElement;\n stateOnly?: boolean;\n theme?: ThemeMode;\n dir?: MountOptions[\"dir\"];\n labels?: MountOptions[\"labels\"];\n};\n\ntype SlexKitMarkdownRuntimeOptions = {\n mode?: \"trusted\" | \"secure\";\n policy?: HostRuntimePolicy;\n hostAdapter?: HostRuntimeAdapter;\n secureFrame?: boolean | SecureFrameOptions;\n theme?: ThemeMode;\n dir?: MountOptions[\"dir\"];\n labels?: MountOptions[\"labels\"];\n};\n```\n\n### Global singleton\n\nThe module provides a global singleton for convenience:\n\n```ts\n// Install explicitly\nconst runtime = installSlexKitMarkdownRuntimeHost({\n mode: \"secure\",\n policy: { execution: { maxUnresponsiveMs: 30000 } },\n secureFrame: { runtimeUrl: \"/slexkit.runtime.js\" }\n});\n\n// Or use lazy global (auto-creates with defaults on first call)\nconst runtime = getSlexKitMarkdownRuntimeHost();\n```\n\nUse the singleton when the entire application shares one runtime configuration. Avoid it when different host contexts need different policies.\n\n## Trusted mode integration\n\nTrusted mode runs Slex source in the host page realm. Use for local documents, application-generated content, or reviewed Slex source.\n\n```ts\nconst runtime = createSlexKitMarkdownRuntimeHost({\n mode: \"trusted\",\n theme: \"host-shadcn\"\n});\n\n// Detect a slex fence at position <container>\nconst cleanup = runtime.mountBlock({\n artifactId: \"doc-1\",\n source: fenceSource,\n container: fenceContainer\n});\n\n// When the fence container is removed\nruntime.disposeBlock(fenceContainer);\n\n// When the document is closed\nruntime.disposeArtifact(\"doc-1\");\n\n// When the plugin or page unloads\nruntime.disposeAll();\n```\n\nIn trusted mode, the runtime automatically scopes namespaces by artifact ID (`<artifactId>::<namespace>`) to prevent different documents from polluting each other's state.\n\nState-only blocks (no `layout`, only `g` updates) are detected automatically and ingested via `ingest()`. Subsequent renderable blocks in the same artifact can read that state.\n\n## Secure mode integration\n\nSecure mode runs Slex source in a sandbox iframe. Use for untrusted or agent-generated Markdown.\n\n```ts\nconst runtime = createSlexKitMarkdownRuntimeHost({\n mode: \"secure\",\n policy: {\n execution: { maxUnresponsiveMs: 30000 }\n },\n secureFrame: {\n runtimeUrl: \"/slexkit.runtime.js\"\n },\n theme: \"host-shadcn\"\n});\n\nconst cleanup = runtime.mountBlock({\n artifactId: \"agent-msg-1\",\n source: agentGeneratedDsl,\n container: fenceContainer\n});\n```\n\nOmitted capability policies deny access by default. Add `network`, `timer`, `animation`, or `canvas` policy objects only when the host intentionally enables those capabilities.\n\n### Artifact slot bridge\n\nWhen multiple secure blocks belong to the same artifact, they share one sandbox iframe. The first block (in document order) becomes the iframe anchor. Other blocks act as slots -their containers receive position and height updates from the sandbox via the postMessage bridge.\n\n```html\n<!-- In Markdown, the first fence becomes the anchor -->\n<div id=\"fence-1\"><!-- anchor: iframe rendered here --></div>\n<div id=\"fence-2\"><!-- slot: height synced from iframe --></div>\n<div id=\"fence-3\"><!-- slot: height synced from iframe --></div>\n```\n\nThis allows state sharing across fences within one artifact while keeping all execution confined to one sandbox.\n\n### `runtimeUrl` requirements\n\nThe `runtimeUrl` must serve the SlexKit runtime as an ES module with:\n\n```\nAccess-Control-Allow-Origin: *\nContent-Type: text/javascript\n```\n\nThe build output includes `dist/runtime.js` for this purpose. The `slex copy-runtime` command copies that module to `public/slexkit.runtime.js` by default so existing secure-frame URLs can stay stable. Configure your CDN or static file server to serve it with the correct headers.\n\n## Streamdown / React integration\n\nThe `@slexkit/streamdown` package provides a React/Streamdown custom renderer:\n\n```tsx\nimport { Streamdown } from \"streamdown\";\nimport { slexkitRenderer } from \"@slexkit/streamdown\";\nimport \"@slexkit/theme-shadcn/style.css\";\nimport \"@slexkit/streamdown/style.css\";\n\nexport function Message({ markdown }: { markdown: string }) {\n return (\n <Streamdown plugins={{ renderers: [slexkitRenderer] }}>\n {markdown}\n </Streamdown>\n );\n}\n```\n\nThe renderer handles `slex` fences. It supports both trusted and secure runtime modes and can delegate to a shared Markdown runtime host instance.\n\n## Obsidian integration\n\nThe
|
|
676
|
-
"hash": "
|
|
675
|
+
"body": "---\ntitle: Host Integration\ncategory: Reference\nstatus: ready\norder: 40\nsummary: \"MarkdownRuntimeHost, trusted and secure host integrations, Streamdown, Obsidian, and custom adapters.\"\nslexkitRenderMode: component\n---\n\n# Host Integration\n\nHow to integrate SlexKit into Markdown renderers, chat hosts, document viewers, and custom platforms.\n\n## Core concepts\n\n### Artifact\n\nAn artifact is a group of Slex blocks belonging to the same document, message, or note. Hosts identify an artifact by an `artifactId` and group related blocks into one runtime domain.\n\nIn **trusted mode**, the runtime prefixes each block's namespace with the artifact ID to prevent cross-document state pollution. `disposeArtifact()` releases all namespace stores for that artifact.\n\nIn **secure mode**, all fences in one artifact are combined into a single sandbox iframe. The runtime maintains artifact slots, syncing rendered heights back to the original Markdown placeholder containers.\n\n### Block\n\nA block is a single Slex block: one renderable unit. It has:\n- A source (Slex expression object or source string).\n- A container element (where the rendered output goes).\n- An optional `artifactId` (for grouping into an artifact).\n\n### Cleanup\n\nEvery block mount returns a cleanup function. The host must call it when the block is removed. For artifact-level cleanup, call `disposeArtifact(artifactId)`. For global cleanup, call `disposeAll()`.\n\n## MarkdownRuntimeHost\n\nThe `SlexKitMarkdownRuntimeHost` is the recommended API for Markdown-based hosts. It handles mode selection, artifact management, and block lifecycle.\n\n```ts\nimport {\n createSlexKitMarkdownRuntimeHost,\n getSlexKitMarkdownRuntimeHost,\n installSlexKitMarkdownRuntimeHost\n} from \"slexkit\";\n```\n\n### Interface\n\n```ts\ntype SlexKitMarkdownRuntimeHost = {\n configure(options: Partial<SlexKitMarkdownRuntimeOptions>): void;\n getMode(): \"trusted\" | \"secure\";\n mountBlock(block: SlexKitMarkdownBlock): () => void;\n disposeBlock(container: HTMLElement): void;\n disposeArtifact(artifactId: string): void;\n disposeAll(): void;\n};\n\ntype SlexKitMarkdownBlock = {\n artifactId?: string;\n blockId?: string;\n source: SlexExpression | string;\n container: HTMLElement;\n stateOnly?: boolean;\n theme?: ThemeMode;\n dir?: MountOptions[\"dir\"];\n labels?: MountOptions[\"labels\"];\n};\n\ntype SlexKitMarkdownRuntimeOptions = {\n mode?: \"trusted\" | \"secure\";\n policy?: HostRuntimePolicy;\n hostAdapter?: HostRuntimeAdapter;\n secureFrame?: boolean | SecureFrameOptions;\n theme?: ThemeMode;\n dir?: MountOptions[\"dir\"];\n labels?: MountOptions[\"labels\"];\n};\n```\n\n### Global singleton\n\nThe module provides a global singleton for convenience:\n\n```ts\n// Install explicitly\nconst runtime = installSlexKitMarkdownRuntimeHost({\n mode: \"secure\",\n policy: { execution: { maxUnresponsiveMs: 30000 } },\n secureFrame: { runtimeUrl: \"/slexkit.runtime.js\" }\n});\n\n// Or use lazy global (auto-creates with defaults on first call)\nconst runtime = getSlexKitMarkdownRuntimeHost();\n```\n\nUse the singleton when the entire application shares one runtime configuration. Avoid it when different host contexts need different policies.\n\n## Trusted mode integration\n\nTrusted mode runs Slex source in the host page realm. Use for local documents, application-generated content, or reviewed Slex source.\n\n```ts\nconst runtime = createSlexKitMarkdownRuntimeHost({\n mode: \"trusted\",\n theme: \"host-shadcn\"\n});\n\n// Detect a slex fence at position <container>\nconst cleanup = runtime.mountBlock({\n artifactId: \"doc-1\",\n source: fenceSource,\n container: fenceContainer\n});\n\n// When the fence container is removed\nruntime.disposeBlock(fenceContainer);\n\n// When the document is closed\nruntime.disposeArtifact(\"doc-1\");\n\n// When the plugin or page unloads\nruntime.disposeAll();\n```\n\nIn trusted mode, the runtime automatically scopes namespaces by artifact ID (`<artifactId>::<namespace>`) to prevent different documents from polluting each other's state.\n\nState-only blocks (no `layout`, only `g` updates) are detected automatically and ingested via `ingest()`. Subsequent renderable blocks in the same artifact can read that state.\n\n## Secure mode integration\n\nSecure mode runs Slex source in a sandbox iframe. Use for untrusted or agent-generated Markdown.\n\n```ts\nconst runtime = createSlexKitMarkdownRuntimeHost({\n mode: \"secure\",\n policy: {\n execution: { maxUnresponsiveMs: 30000 }\n },\n secureFrame: {\n runtimeUrl: \"/slexkit.runtime.js\"\n },\n theme: \"host-shadcn\"\n});\n\nconst cleanup = runtime.mountBlock({\n artifactId: \"agent-msg-1\",\n source: agentGeneratedDsl,\n container: fenceContainer\n});\n```\n\nOmitted capability policies deny access by default. Add `network`, `timer`, `animation`, or `canvas` policy objects only when the host intentionally enables those capabilities.\n\n### Artifact slot bridge\n\nWhen multiple secure blocks belong to the same artifact, they share one sandbox iframe. The first block (in document order) becomes the iframe anchor. Other blocks act as slots -their containers receive position and height updates from the sandbox via the postMessage bridge.\n\n```html\n<!-- In Markdown, the first fence becomes the anchor -->\n<div id=\"fence-1\"><!-- anchor: iframe rendered here --></div>\n<div id=\"fence-2\"><!-- slot: height synced from iframe --></div>\n<div id=\"fence-3\"><!-- slot: height synced from iframe --></div>\n```\n\nThis allows state sharing across fences within one artifact while keeping all execution confined to one sandbox.\n\n### `runtimeUrl` requirements\n\nThe `runtimeUrl` must serve the SlexKit runtime as an ES module with:\n\n```\nAccess-Control-Allow-Origin: *\nContent-Type: text/javascript\n```\n\nThe build output includes `dist/runtime.js` for this purpose. The `slex copy-runtime` command copies that module to `public/slexkit.runtime.js` by default so existing secure-frame URLs can stay stable. Configure your CDN or static file server to serve it with the correct headers.\n\n## Streamdown / React integration\n\nThe `@slexkit/streamdown` package provides a React/Streamdown custom renderer:\n\n```tsx\nimport { Streamdown } from \"streamdown\";\nimport { slexkitRenderer } from \"@slexkit/streamdown\";\nimport \"@slexkit/theme-shadcn/style.css\";\nimport \"@slexkit/streamdown/style.css\";\n\nexport function Message({ markdown }: { markdown: string }) {\n return (\n <Streamdown plugins={{ renderers: [slexkitRenderer] }}>\n {markdown}\n </Streamdown>\n );\n}\n```\n\nThe renderer handles `slex` fences. It supports both trusted and secure runtime modes and can delegate to a shared Markdown runtime host instance.\n\n## Obsidian integration\n\nThe official Obsidian plugin lives in <https://github.com/slexkit/obsidian-slexkit> and registers the `slex` fenced code block processor:\n\n```ts\n// In the plugin:\nregisterMarkdownCodeBlockProcessor(\"slex\", (source, el, ctx) => { ... });\n```\n\nThe adapter renders blocks in **reading mode only** and does not write back to the vault. Blocks within the same note share a trusted artifact runtime.\n\n**Important**: The Obsidian adapter uses trusted mode because it renders content from the user's local vault. It is not designed as a security boundary for untrusted or agent-generated Markdown.\n\n## Writing a custom host adapter\n\nTo integrate SlexKit into a custom Markdown renderer or chat host:\n\n### 1. Detect fence language\n\nOnly process fences tagged with `slex`. Never scan plain JavaScript, JSON, or untagged code blocks.\n\n### 2. Create a runtime host\n\n```ts\nimport { createSlexKitMarkdownRuntimeHost } from \"slexkit\";\n\nconst runtime = createSlexKitMarkdownRuntimeHost({\n mode: \"trusted\", // or \"secure\"\n theme: \"host-shadcn\"\n});\n```\n\n### 3. Mount blocks\n\nFor each detected fence, create a container element and mount:\n\n```ts\nfunction processFence(source: string, fenceIndex: number) {\n const container = document.createElement(\"div\");\n // Insert container at the fence position in the document\n\n const cleanup = runtime.mountBlock({\n artifactId: \"message-42\",\n source,\n container\n });\n\n return cleanup;\n}\n```\n\n### 4. Manage lifecycle\n\n```ts\n// When a single block is removed\nruntime.disposeBlock(container);\n\n// When the entire artifact (message/document) is removed\nruntime.disposeArtifact(\"message-42\");\n\n// When the plugin/page unloads\nruntime.disposeAll();\n```\n\n### 5. Handle secure mode\n\nIf using secure mode, serve `slexkit.runtime.js` as a public ES module with the correct CORS headers, and configure `secureFrame.runtimeUrl`.\n\n## Fallback rendering\n\nSlexKit-capable hosts should still include the raw fence content or a plain text fallback in the DOM for environments that don't support SlexKit. The runtime replaces the container children, so fallback text is only visible before mount or after disposal.",
|
|
676
|
+
"hash": "31cedb3b"
|
|
677
677
|
},
|
|
678
678
|
{
|
|
679
679
|
"id": "reference/security",
|
|
@@ -694,8 +694,8 @@
|
|
|
694
694
|
"href": "/docs/reference/packages",
|
|
695
695
|
"rawHref": "/docs/reference/packages.md",
|
|
696
696
|
"sourcePath": "site/content/reference/packages/en-US.md",
|
|
697
|
-
"body": "---\ntitle: Package Boundaries\ncategory: Reference\nstatus: ready\norder: 60\nsummary: \"Package relationships, installation matrix, publish contents, and release quality gates.\"\nslexkitRenderMode: component\n---\n\n# Package Boundaries\n\nSlexKit v0/beta npm packages, their relationships, and installation.\n\n## Package relationship\n\n```\nslexkit (root - real code)\n ├── runtime entry\n ├── Svelte component registrations\n ├── ToolHost\n ├── default styles\n └── secure iframe runner\n\n @slexkit/runtime (thin wrapper) ─── re-exports slexkit/runtime\n @slexkit/components-svelte (thin wrapper) ─── re-exports slexkit/components-svelte\n @slexkit/theme-shadcn ─── CSS only\n @slexkit/streamdown ─── React/Streamdown renderer\n @slexkit/
|
|
698
|
-
"hash": "
|
|
697
|
+
"body": "---\ntitle: Package Boundaries\ncategory: Reference\nstatus: ready\norder: 60\nsummary: \"Package relationships, installation matrix, publish contents, and release quality gates.\"\nslexkitRenderMode: component\n---\n\n# Package Boundaries\n\nSlexKit v0/beta npm packages, their relationships, and installation.\n\n## Package relationship\n\n```\nslexkit (root - real code)\n ├── runtime entry\n ├── Svelte component registrations\n ├── ToolHost\n ├── default styles\n └── secure iframe runner\n\n @slexkit/runtime (thin wrapper) ─── re-exports slexkit/runtime\n @slexkit/components-svelte (thin wrapper) ─── re-exports slexkit/components-svelte\n @slexkit/theme-shadcn ─── CSS only\n @slexkit/streamdown ─── React/Streamdown renderer\n @slexkit/mcp ─── read-only MCP server for AI agents\n```\n\n`@slexkit/runtime` and `@slexkit/components-svelte` are thin wrappers that re-export from the root `slexkit` package. They are not standalone physical packages; installing them still requires installing `slexkit`. `@slexkit/theme-shadcn` is CSS-only and contains no runtime implementation.\n\n## slexkit (root)\n\nThe actual implementation package. Contains the runtime engine, official Svelte components, ToolHost, and styles.\n\n```sh\nnpm install slexkit\n```\n\n```js\nimport { mount, disposeNamespace, boot } from \"slexkit\";\nimport \"slexkit/style.css\"; // default styles (includes all component CSS)\nimport \"slexkit/dist/style.css\"; // same distributed CSS bundle via dist alias\n```\n\nVersion helpers are exported from both the root and runtime entries:\n\n```js\nimport { SLEXKIT_VERSION, SLEX_PROTOCOL_VERSION, getSlexKitInfo } from \"slexkit\";\n```\n\n## @slexkit/runtime\n\nComponent-free runtime entry point. Does not auto-register any official Svelte components.\n\n```sh\nnpm install slexkit @slexkit/runtime\n```\n\n```js\nimport { mount, register, createSecureRuntime } from \"@slexkit/runtime\";\n```\n\nUse this when you want to register your own component set instead of the bundled Svelte components.\n\n## @slexkit/components-svelte\n\nSide-effect import that registers all official Svelte components into the runtime registry.\n\n```sh\nnpm install slexkit @slexkit/runtime @slexkit/components-svelte\n```\n\n```js\nimport { mount } from \"@slexkit/runtime\";\nimport \"@slexkit/components-svelte\";\n```\n\nPublic component specs: action (2), component capability (1), content (6), data (1), disclosure (2), display (2), feedback (2), input (6), layout (4), navigation (1), tooling (1).\n\n## @slexkit/theme-shadcn\n\nCSS theme bundle (shadcn/ui compatible).\n\n```sh\nnpm install @slexkit/theme-shadcn\n```\n\n```js\nimport \"@slexkit/theme-shadcn/style.css\";\n```\n\n## @slexkit/streamdown\n\nReact/Streamdown custom renderer for Markdown-hosted SlexKit fences.\n\n```sh\nnpm install slexkit @slexkit/theme-shadcn @slexkit/streamdown streamdown react react-dom\n```\n\n```tsx\nimport { Streamdown } from \"streamdown\";\nimport { slexkitRenderer } from \"@slexkit/streamdown\";\nimport \"@slexkit/theme-shadcn/style.css\";\nimport \"@slexkit/streamdown/style.css\";\n\nexport function Message({ markdown }: { markdown: string }) {\n return (\n <Streamdown plugins={{ renderers: [slexkitRenderer] }}>\n {markdown}\n </Streamdown>\n );\n}\n```\n\nProcesses `slex` fences. Supports both trusted and secure runtime modes.\n\n## Obsidian plugin\n\nThe official Obsidian plugin lives in a separate release repository: <https://github.com/slexkit/obsidian-slexkit>.\n\nInstall **SlexKit** through Obsidian Community Plugins for normal vault use. Use BRAT or manual GitHub release assets only when testing unreleased builds from `slexkit/obsidian-slexkit`.\n\nThe community plugin is currently desktop-only and compatible with Obsidian 1.5.0+. Mobile support should be enabled only after real mobile vault testing.\n\nThe adapter uses trusted runtime mode - it renders content from the user's local vault and is not designed as a sandbox for third-party or agent-generated Markdown. Secure sandbox support is not part of the v0 adapter.\n\n## @slexkit/mcp\n\nRead-only MCP server for AI agents. It serves generated LLM docs, component metadata, examples, runtime docs, ToolHost docs, and Slex source validation.\n\n```sh\nnpx -y @slexkit/mcp\n```\n\nThe server does not modify project files. Use it when an agent needs current SlexKit component or runtime context.\n\n## Installation matrix\n\n| Use case | Install command |\n|----------|----------------|\n| Quick start, everything included | `npm install slexkit` |\n| Component-free, custom components | `npm install slexkit @slexkit/runtime` |\n| With Svelte components | `npm install slexkit @slexkit/runtime @slexkit/components-svelte` |\n| Add shadcn theme | `npm install @slexkit/theme-shadcn` |\n| React/Streamdown host | `npm install slexkit @slexkit/theme-shadcn @slexkit/streamdown streamdown react react-dom` |\n| Obsidian plugin | Install **SlexKit** from Obsidian Community Plugins |\n| AI agent MCP server | `npx -y @slexkit/mcp` |\n\n## v0 packaging strategy\n\nThe current approach keeps the root `slexkit` package as the real code carrier. Scoped `@slexkit/*` wrappers exist to define future package boundaries. If physical package splitting happens in the future, it will involve splitting source code, build output, and publishing workflows.\n\n## Release quality gate\n\nAll scoped packages are release-checked together:\n\n```sh\nbun run build\nbun run test\nbun run smoke:release\n```\n\nThe release smoke packs and installs every scoped package in this repository, verifies public entry points, verifies CSS subpath exports, and starts the MCP stdio binary to check `initialize`, `tools/list`, and `slexkitValidate`.",
|
|
698
|
+
"hash": "93cf14ed"
|
|
699
699
|
},
|
|
700
700
|
{
|
|
701
701
|
"id": "reference/toolhost",
|
|
@@ -727,8 +727,8 @@
|
|
|
727
727
|
"href": "/docs/reference/rationale",
|
|
728
728
|
"rawHref": "/docs/reference/rationale.md",
|
|
729
729
|
"sourcePath": "site/content/reference/rationale/en-US.md",
|
|
730
|
-
"body": "---\ntitle: Design Rationale\ncategory: Reference\nstatus: ready\norder: 80\nsummary: \"Why SlexKit uses object literals, expressions, explicit fences, and a trusted/secure runtime split.\"\nslexkitRenderMode: component\n---\n\n# Design Rationale\n\nWhy JavaScript object literals? Why expressions? Why explicit fences? Why a trusted and secure dual runtime?\n\n## Problem space\n\nSlexKit targets small interactive UI inside chat messages, documents, agent output panels, and tool dashboards. It does not attempt to provide routing, data layers, build systems, or a full application framework.\n\nAn input format for AI-generated UI must be:\n- Short enough to stream token-by-token.\n- Embeddable in Markdown.\n- Runnable without a build step.\n- Host-agnostic (works in React, Svelte, Obsidian, vanilla HTML).\n\n## Why JavaScript object literals\n\nA Slex source is a single object literal:\n\n```js\n{\n namespace: \"demo\",\n g: { count: 0 },\n layout: {\n \"button:add\": { text: \"Add\", onclick: \"g.count++\" },\n \"text:value\": { \"$content\": \"'Count: ' + g.count\" }\n }\n}\n```\n\nA model can emit this in one shot. No project structure, no module imports, no build config, no framework boilerplate. The same content works inside a Markdown fence, a Streamdown renderer, an Obsidian adapter, or a custom runtime host.\n\n## Why `g` and `layout` are separate\n\n`g` holds state and logic. `layout` holds the component tree. Expressions read from `g`, component states, and `$for` context. Event handlers write back to `g`.\n\nThis separation makes model output easier to audit: state and algorithms are centralized in one object; UI structure is centralized in a tree. It also lets the host manage state lifecycle by namespace -same-namespace mounts share and merge state.\n\n## Why expressions (not pure JSON)\n\nSlexKit v0 is not a pure JSON protocol. `$` read-pipes and `on*` write-pipes allow JavaScript expressions and statements:\n\n```js\n\"$content\": \"'Count: ' + g.count\"\nonclick: \"g.count++\"\n```\n\nThis makes simple interactions shorter and more natural for AI generation. A pure-JSON format would require a separate expression language or declarative wiring syntax that adds complexity to both the emitter and the runtime.\n\nThe cost is an explicit trust boundary. Trusted content can execute in the host realm with low integration overhead. Untrusted content must go through the secure runtime (sandbox iframe, opaque origin, policy-gated capabilities).\n\nSlexKit's security choice is not about disabling expressions -it is about requiring the host to choose which trust boundary expressions run in.\n\n## Why only explicit fences\n\nSlexKit hosts must only process explicitly-marked fences (`slex`). Plain JavaScript, JSON, or untagged code blocks could be examples, logs, or user content -they must not be automatically executed or rendered.\n\nA generation should include a plain Markdown fallback so the output degrades gracefully:\n\n~~~~md\n```slex\n{ namespace: \"status\",
|
|
731
|
-
"hash": "
|
|
730
|
+
"body": "---\ntitle: Design Rationale\ncategory: Reference\nstatus: ready\norder: 80\nsummary: \"Why SlexKit uses object literals, expressions, explicit fences, and a trusted/secure runtime split.\"\nslexkitRenderMode: component\n---\n\n# Design Rationale\n\nWhy JavaScript object literals? Why expressions? Why explicit fences? Why a trusted and secure dual runtime?\n\n## Problem space\n\nSlexKit targets small interactive UI inside chat messages, documents, agent output panels, and tool dashboards. It does not attempt to provide routing, data layers, build systems, or a full application framework.\n\nAn input format for AI-generated UI must be:\n- Short enough to stream token-by-token.\n- Embeddable in Markdown.\n- Runnable without a build step.\n- Host-agnostic (works in React, Svelte, Obsidian, vanilla HTML).\n\n## Why JavaScript object literals\n\nA Slex source is a single object literal:\n\n```js\n{\n namespace: \"demo\",\n g: { count: 0 },\n layout: {\n \"button:add\": { text: \"Add\", onclick: \"g.count++\" },\n \"text:value\": { \"$content\": \"'Count: ' + g.count\" }\n }\n}\n```\n\nA model can emit this in one shot. No project structure, no module imports, no build config, no framework boilerplate. The same content works inside a Markdown fence, a Streamdown renderer, an Obsidian adapter, or a custom runtime host.\n\n## Why `g` and `layout` are separate\n\n`g` holds state and logic. `layout` holds the component tree. Expressions read from `g`, component states, and `$for` context. Event handlers write back to `g`.\n\nThis separation makes model output easier to audit: state and algorithms are centralized in one object; UI structure is centralized in a tree. It also lets the host manage state lifecycle by namespace -same-namespace mounts share and merge state.\n\n## Why expressions (not pure JSON)\n\nSlexKit v0 is not a pure JSON protocol. `$` read-pipes and `on*` write-pipes allow JavaScript expressions and statements:\n\n```js\n\"$content\": \"'Count: ' + g.count\"\nonclick: \"g.count++\"\n```\n\nThis makes simple interactions shorter and more natural for AI generation. A pure-JSON format would require a separate expression language or declarative wiring syntax that adds complexity to both the emitter and the runtime.\n\nThe cost is an explicit trust boundary. Trusted content can execute in the host realm with low integration overhead. Untrusted content must go through the secure runtime (sandbox iframe, opaque origin, policy-gated capabilities).\n\nSlexKit's security choice is not about disabling expressions -it is about requiring the host to choose which trust boundary expressions run in.\n\n## Why only explicit fences\n\nSlexKit hosts must only process explicitly-marked fences (`slex`). Plain JavaScript, JSON, or untagged code blocks could be examples, logs, or user content -they must not be automatically executed or rendered.\n\nA generation should include a plain Markdown fallback so the output degrades gracefully:\n\n~~~~md\n```slex\n{ namespace: \"status\", layout: { \"badge:state\": { label: \"3/4 complete\", tone: \"info\" } } }\n```\n\n**Status:** 3/4 complete\n~~~~\n\nOn SlexKit-capable hosts, the fence renders as interactive UI. On plain Markdown hosts, the fallback text still reads correctly.\n\n## Display UI vs ToolHost\n\nMost AI output is display-oriented -status cards, progress indicators, metrics, dashboards. These go through `slex` fences or `mount().`\n\nToolHost exists only for UI that must return structured user input to the host: confirmations, selections, forms. It compiles templates to standard Slex source, but the `submit` component serves as an explicit completion boundary.\n\nThis boundary prevents every display UI from being inadvertently wrapped as a function call.\n\n## Trusted + secure dual runtime\n\n### Trusted runtime\n\nFor application-generated content, repository-maintained Slex source, or already-reviewed snippets. Lowest integration cost -Slex source executes directly in the host page.\n\n### Secure runtime\n\nFor untrusted or agent-generated Slex source. Uses a sandbox iframe with opaque origin, CSP, and locked-down globals. Sensitive capabilities (network, timers, canvas) are gated behind a host policy.\n\nThe host chooses the trust boundary for each mount. The same Slex source syntax works in both modes.\n\n## Why a custom reactivity system\n\nSlexKit ships a minimal reactive engine (~280 lines) rather than depending on a framework:\n\n- **Zero framework dependency for the runtime core** -the `@slexkit/runtime` entry has no external dependencies.\n- **Deep tracking** -arbitrary `g` shapes require Proxy-based property access tracking that maps well to the tree-shaped Slex source model.\n- **Sufficient scope** -signal, effect, batch, memo, root/scope are the only primitives needed for this scale of UI.\n\nThe component layer (Svelte) adds `svelte` as a dependency only when using `@slexkit/components-svelte`.\n\n## How it differs from alternatives\n\n### vs A2UI\n\nA2UI is a cross-platform declarative message protocol with a component catalog approach. SlexKit v0 is browser-focused, Markdown-friendly, and uses executable JavaScript expressions for interactivity rather than declarative wiring. SlexKit does not claim to be a cross-platform UI standard.\n\n### vs application frameworks\n\nSlexKit is not a React/Vue/Svelte alternative. It renders small interactive fragments, not full applications. No router, no data fetching layer, no SSR.\n\n### vs pure JSON UI protocols\n\nSlexKit trades JSON purity for expressive short-form interactivity. The cost is the explicit trust boundary, which is addressed by the sandbox runtime rather than by restricting the expression language.",
|
|
731
|
+
"hash": "dcf53947"
|
|
732
732
|
},
|
|
733
733
|
{
|
|
734
734
|
"id": "releases/changelog",
|
|
@@ -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.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.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": "bc737cc1"
|
|
743
743
|
}
|
|
744
744
|
],
|
|
745
745
|
"expressionContext": [
|
|
@@ -2057,7 +2057,7 @@
|
|
|
2057
2057
|
"summary": "Text or engineering-value input.",
|
|
2058
2058
|
"docsHref": "/docs/components/input",
|
|
2059
2059
|
"rawHref": "/docs/components/input.md",
|
|
2060
|
-
"propCount":
|
|
2060
|
+
"propCount": 21,
|
|
2061
2061
|
"exampleCount": 1,
|
|
2062
2062
|
"props": {
|
|
2063
2063
|
"value": {
|
|
@@ -2162,12 +2162,6 @@
|
|
|
2162
2162
|
"dynamic": true,
|
|
2163
2163
|
"description": "Step size used by numeric input controls."
|
|
2164
2164
|
},
|
|
2165
|
-
"controls": {
|
|
2166
|
-
"type": "boolean",
|
|
2167
|
-
"default": true,
|
|
2168
|
-
"dynamic": true,
|
|
2169
|
-
"description": "Show decrement and increment buttons for numeric inputs."
|
|
2170
|
-
},
|
|
2171
2165
|
"onchange": {
|
|
2172
2166
|
"type": "write-expression",
|
|
2173
2167
|
"description": "Write expression invoked when the value changes."
|
|
@@ -2195,7 +2189,7 @@
|
|
|
2195
2189
|
}
|
|
2196
2190
|
}
|
|
2197
2191
|
],
|
|
2198
|
-
"hash": "
|
|
2192
|
+
"hash": "69ec164d"
|
|
2199
2193
|
},
|
|
2200
2194
|
{
|
|
2201
2195
|
"type": "link",
|
|
@@ -3300,7 +3294,7 @@
|
|
|
3300
3294
|
"summary": "Plain text display.",
|
|
3301
3295
|
"docsHref": "/docs/components/text",
|
|
3302
3296
|
"rawHref": "/docs/components/text.md",
|
|
3303
|
-
"propCount":
|
|
3297
|
+
"propCount": 7,
|
|
3304
3298
|
"exampleCount": 1,
|
|
3305
3299
|
"props": {
|
|
3306
3300
|
"text": {
|
|
@@ -3327,6 +3321,16 @@
|
|
|
3327
3321
|
"default": "default",
|
|
3328
3322
|
"description": "Text visual variant."
|
|
3329
3323
|
},
|
|
3324
|
+
"color": {
|
|
3325
|
+
"type": "string",
|
|
3326
|
+
"dynamic": true,
|
|
3327
|
+
"description": "Optional CSS color for controlled previews."
|
|
3328
|
+
},
|
|
3329
|
+
"size": {
|
|
3330
|
+
"type": "string | number",
|
|
3331
|
+
"dynamic": true,
|
|
3332
|
+
"description": "Optional font size. Numbers are treated as px."
|
|
3333
|
+
},
|
|
3330
3334
|
"class": {
|
|
3331
3335
|
"type": "string",
|
|
3332
3336
|
"description": "Additional host-controlled CSS class."
|
|
@@ -3351,7 +3355,7 @@
|
|
|
3351
3355
|
}
|
|
3352
3356
|
}
|
|
3353
3357
|
],
|
|
3354
|
-
"hash": "
|
|
3358
|
+
"hash": "c99b2de6"
|
|
3355
3359
|
},
|
|
3356
3360
|
{
|
|
3357
3361
|
"type": "toast",
|
|
@@ -3477,40 +3481,40 @@
|
|
|
3477
3481
|
}
|
|
3478
3482
|
],
|
|
3479
3483
|
"sourceHashes": {
|
|
3480
|
-
"README.md": "
|
|
3484
|
+
"README.md": "117cabab",
|
|
3481
3485
|
"site/content/guides/intro/en-US.md": "bff82366",
|
|
3482
|
-
"site/content/guides/quick-start/en-US.md": "
|
|
3483
|
-
"site/content/guides/integration/en-US.md": "
|
|
3486
|
+
"site/content/guides/quick-start/en-US.md": "ba82b030",
|
|
3487
|
+
"site/content/guides/integration/en-US.md": "1138bddd",
|
|
3484
3488
|
"site/content/guides/design/en-US.md": "8a3b35fd",
|
|
3485
|
-
"site/content/guides/security-runtime/en-US.md": "
|
|
3489
|
+
"site/content/guides/security-runtime/en-US.md": "eba73f9f",
|
|
3486
3490
|
"site/content/guides/ai-agents/en-US.md": "c6c70f87",
|
|
3487
3491
|
"content/examples/hello-slexkit/zh-CN.md": "f5b1728f",
|
|
3488
|
-
"content/examples/first-interaction/zh-CN.md": "
|
|
3492
|
+
"content/examples/first-interaction/zh-CN.md": "d27f5fc3",
|
|
3489
3493
|
"content/examples/multi-input-coordination/zh-CN.md": "d16837a3",
|
|
3490
3494
|
"content/examples/tabs-and-branching/zh-CN.md": "2050088b",
|
|
3491
|
-
"content/examples/salary-calculator/zh-CN.md": "
|
|
3492
|
-
"content/examples/project-cost-estimator/zh-CN.md": "
|
|
3493
|
-
"content/examples/voltage-divider/zh-CN.md": "
|
|
3494
|
-
"content/examples/rc-low-pass-filter/zh-CN.md": "
|
|
3495
|
-
"content/examples/baud-rate-calculator/zh-CN.md": "
|
|
3495
|
+
"content/examples/salary-calculator/zh-CN.md": "05fd1883",
|
|
3496
|
+
"content/examples/project-cost-estimator/zh-CN.md": "9355649f",
|
|
3497
|
+
"content/examples/voltage-divider/zh-CN.md": "56dc3618",
|
|
3498
|
+
"content/examples/rc-low-pass-filter/zh-CN.md": "52b5fb39",
|
|
3499
|
+
"content/examples/baud-rate-calculator/zh-CN.md": "7ac3d2d9",
|
|
3496
3500
|
"content/examples/search-filter-table/zh-CN.md": "16e8308e",
|
|
3497
|
-
"content/examples/project-dashboard/zh-CN.md": "
|
|
3501
|
+
"content/examples/project-dashboard/zh-CN.md": "aacce5f0",
|
|
3498
3502
|
"content/examples/form-wizard-steps/zh-CN.md": "3d2ac73e",
|
|
3499
3503
|
"content/examples/tech-selection-evaluator/zh-CN.md": "403c7e46",
|
|
3500
3504
|
"content/examples/toolhost-demo/zh-CN.md": "0d82032b",
|
|
3501
3505
|
"content/examples/roi-estimator/zh-CN.md": "73bc3af9",
|
|
3502
|
-
"content/examples/cross-doc-state-lab/zh-CN.md": "
|
|
3506
|
+
"content/examples/cross-doc-state-lab/zh-CN.md": "7ac63204",
|
|
3503
3507
|
"content/examples/network-policy-fetch-card/zh-CN.md": "7d1daa49",
|
|
3504
3508
|
"site/content/reference/spec/en-US.md": "fa2bd10b",
|
|
3505
3509
|
"site/content/reference/usage/en-US.md": "3cc2177d",
|
|
3506
3510
|
"site/content/reference/runtime/en-US.md": "169041c3",
|
|
3507
|
-
"site/content/reference/integration/en-US.md": "
|
|
3511
|
+
"site/content/reference/integration/en-US.md": "31cedb3b",
|
|
3508
3512
|
"site/content/reference/security/en-US.md": "4cfe36f1",
|
|
3509
|
-
"site/content/reference/packages/en-US.md": "
|
|
3513
|
+
"site/content/reference/packages/en-US.md": "93cf14ed",
|
|
3510
3514
|
"site/content/reference/toolhost/en-US.md": "f62ba8aa",
|
|
3511
3515
|
"site/content/reference/icons/en-US.md": "3d32cbbf",
|
|
3512
|
-
"site/content/reference/rationale/en-US.md": "
|
|
3513
|
-
"site/content/releases/changelog/en-US.md": "
|
|
3516
|
+
"site/content/reference/rationale/en-US.md": "dcf53947",
|
|
3517
|
+
"site/content/releases/changelog/en-US.md": "bc737cc1",
|
|
3514
3518
|
"site/content/components/accordion/en-US.md": "9e90867f",
|
|
3515
3519
|
"site/content/components/badge/en-US.md": "fb8275e7",
|
|
3516
3520
|
"site/content/components/button/en-US.md": "30463322",
|
|
@@ -3524,7 +3528,7 @@
|
|
|
3524
3528
|
"site/content/components/formula/en-US.md": "e2634f4f",
|
|
3525
3529
|
"site/content/components/grid/en-US.md": "07d773b2",
|
|
3526
3530
|
"site/content/components/icon/en-US.md": "a8497d85",
|
|
3527
|
-
"site/content/components/input/en-US.md": "
|
|
3531
|
+
"site/content/components/input/en-US.md": "3efa0e53",
|
|
3528
3532
|
"site/content/components/link/en-US.md": "8eeb87ad",
|
|
3529
3533
|
"site/content/components/playground/en-US.md": "7313ccc4",
|
|
3530
3534
|
"site/content/components/progress/en-US.md": "7d008e59",
|
|
@@ -3538,7 +3542,7 @@
|
|
|
3538
3542
|
"site/content/components/switch/en-US.md": "d72058e4",
|
|
3539
3543
|
"site/content/components/table/en-US.md": "be8190d7",
|
|
3540
3544
|
"site/content/components/tabs/en-US.md": "a0029940",
|
|
3541
|
-
"site/content/components/text/en-US.md": "
|
|
3545
|
+
"site/content/components/text/en-US.md": "c8137ecc",
|
|
3542
3546
|
"site/content/components/toast/en-US.md": "960011bc",
|
|
3543
3547
|
"component:accordion": "ff1be273",
|
|
3544
3548
|
"component:badge": "eece8f49",
|
|
@@ -3553,7 +3557,7 @@
|
|
|
3553
3557
|
"component:formula": "61a9d4ee",
|
|
3554
3558
|
"component:grid": "912458b7",
|
|
3555
3559
|
"component:icon": "0b7a18c9",
|
|
3556
|
-
"component:input": "
|
|
3560
|
+
"component:input": "69ec164d",
|
|
3557
3561
|
"component:link": "1404518b",
|
|
3558
3562
|
"component:playground": "7d8e1d36",
|
|
3559
3563
|
"component:progress": "706fde5e",
|
|
@@ -3567,7 +3571,7 @@
|
|
|
3567
3571
|
"component:switch": "c5fd6169",
|
|
3568
3572
|
"component:table": "546ee458",
|
|
3569
3573
|
"component:tabs": "e5cff5dc",
|
|
3570
|
-
"component:text": "
|
|
3574
|
+
"component:text": "c99b2de6",
|
|
3571
3575
|
"component:toast": "cc0c6b05"
|
|
3572
3576
|
}
|
|
3573
3577
|
}
|