@morya-ui/mcp 0.2.7 → 0.2.8

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/data/catalog.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
- "generatedAt": "2026-09-18T07:52:49.105Z",
2
+ "generatedAt": "2026-09-21T01:38:25.787Z",
3
3
  "library": {
4
4
  "name": "morya-ui",
5
- "version": "0.2.7"
5
+ "version": "0.2.8"
6
6
  },
7
7
  "mcp": {
8
8
  "name": "@morya-ui/mcp",
9
- "version": "0.2.7"
9
+ "version": "0.2.8"
10
10
  },
11
11
  "components": [
12
12
  {
@@ -6821,7 +6821,7 @@
6821
6821
  "sectionId": "内置插图",
6822
6822
  "lang": "vue",
6823
6823
  "preview": true,
6824
- "code": "<script setup lang=\"ts\">\r\nimport { MEmpty } from 'morya-ui'\r\n</script>\r\n\r\n<template>\r\n <div class=\"grid gap-8\">\r\n <MEmpty\r\n illustration=\"no-content\"\r\n title=\"暂无相关内容\"\r\n description=\"这里还没有可展示的内容。\"\r\n />\r\n <MEmpty\r\n illustration=\"no-result\"\r\n title=\"搜索结果为空\"\r\n description=\"试试调整关键词或筛选条件。\"\r\n />\r\n <MEmpty\r\n illustration=\"no-message\"\r\n title=\"没有新消息\"\r\n description=\"有新动态时会第一时间通知你。\"\r\n />\r\n </div>\r\n</template>",
6824
+ "code": "<script setup lang=\"ts\">\nimport { MEmpty } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-8\">\n <MEmpty\n illustration=\"no-content\"\n title=\"暂无相关内容\"\n description=\"这里还没有可展示的内容。\"\n />\n <MEmpty\n illustration=\"no-result\"\n title=\"搜索结果为空\"\n description=\"试试调整关键词或筛选条件。\"\n />\n <MEmpty\n illustration=\"no-message\"\n title=\"没有新消息\"\n description=\"有新动态时会第一时间通知你。\"\n />\n </div>\n</template>",
6825
6825
  "locale": "zh-CN"
6826
6826
  },
6827
6827
  {
@@ -6830,7 +6830,7 @@
6830
6830
  "sectionId": "紧凑模式",
6831
6831
  "lang": "vue",
6832
6832
  "preview": true,
6833
- "code": "<script setup lang=\"ts\">\r\nimport { MEmpty } from 'morya-ui'\r\n</script>\r\n\r\n<template>\r\n <MEmpty\r\n simple\r\n title=\"\"\r\n description=\"该分组下暂无成员\"\r\n />\r\n</template>",
6833
+ "code": "<script setup lang=\"ts\">\nimport { MEmpty } from 'morya-ui'\n</script>\n\n<template>\n <MEmpty\n simple\n title=\"\"\n description=\"该分组下暂无成员\"\n />\n</template>",
6834
6834
  "locale": "zh-CN"
6835
6835
  },
6836
6836
  {
@@ -6875,7 +6875,7 @@
6875
6875
  "sectionId": "built-in-illustrations",
6876
6876
  "lang": "vue",
6877
6877
  "preview": true,
6878
- "code": "<script setup lang=\"ts\">\r\nimport { MEmpty } from 'morya-ui'\r\n</script>\r\n\r\n<template>\r\n <div class=\"grid gap-8\">\r\n <MEmpty\r\n illustration=\"no-content\"\r\n title=\"暂无相关内容\"\r\n description=\"这里还没有可展示的内容。\"\r\n />\r\n <MEmpty\r\n illustration=\"no-result\"\r\n title=\"搜索结果为空\"\r\n description=\"试试调整关键词或筛选条件。\"\r\n />\r\n <MEmpty\r\n illustration=\"no-message\"\r\n title=\"没有新消息\"\r\n description=\"有新动态时会第一时间通知你。\"\r\n />\r\n </div>\r\n</template>",
6878
+ "code": "<script setup lang=\"ts\">\nimport { MEmpty } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-8\">\n <MEmpty\n illustration=\"no-content\"\n title=\"暂无相关内容\"\n description=\"这里还没有可展示的内容。\"\n />\n <MEmpty\n illustration=\"no-result\"\n title=\"搜索结果为空\"\n description=\"试试调整关键词或筛选条件。\"\n />\n <MEmpty\n illustration=\"no-message\"\n title=\"没有新消息\"\n description=\"有新动态时会第一时间通知你。\"\n />\n </div>\n</template>",
6879
6879
  "locale": "en-US"
6880
6880
  },
6881
6881
  {
@@ -6884,7 +6884,7 @@
6884
6884
  "sectionId": "compact",
6885
6885
  "lang": "vue",
6886
6886
  "preview": true,
6887
- "code": "<script setup lang=\"ts\">\r\nimport { MEmpty } from 'morya-ui'\r\n</script>\r\n\r\n<template>\r\n <MEmpty\r\n simple\r\n title=\"\"\r\n description=\"No members in this group yet\"\r\n />\r\n</template>",
6887
+ "code": "<script setup lang=\"ts\">\nimport { MEmpty } from 'morya-ui'\n</script>\n\n<template>\n <MEmpty\n simple\n title=\"\"\n description=\"No members in this group yet\"\n />\n</template>",
6888
6888
  "locale": "en-US"
6889
6889
  }
6890
6890
  ],
@@ -12400,6 +12400,358 @@
12400
12400
  }
12401
12401
  }
12402
12402
  },
12403
+ {
12404
+ "id": "Loading",
12405
+ "name": "Loading",
12406
+ "exportName": "MLoading",
12407
+ "category": "05 / FEEDBACK",
12408
+ "description": "加载指示与遮罩:多种动效、区域加载、v-loading 指令和命令式 service。",
12409
+ "descriptionEn": "Loading indicator and mask, with multiple effects, a region overlay, the v-loading directive, and an imperative service.",
12410
+ "import": "import { MLoading } from 'morya-ui'",
12411
+ "props": [
12412
+ {
12413
+ "name": "loading",
12414
+ "type": "boolean",
12415
+ "default": "true",
12416
+ "description": "包裹内容或 `fullscreen` 时是否显示遮罩。单独指示器始终显示。"
12417
+ },
12418
+ {
12419
+ "name": "effect",
12420
+ "type": "'circular' | 'aurora' | 'bounce' | 'wave' | 'pulse' | 'stardust'",
12421
+ "default": "'circular'",
12422
+ "description": "动效。可用 `componentDefaults.Loading.effect` 改默认值。"
12423
+ },
12424
+ {
12425
+ "name": "text",
12426
+ "type": "string",
12427
+ "default": "—",
12428
+ "description": "指示器下方文案。不传则不显示。"
12429
+ },
12430
+ {
12431
+ "name": "ariaLabel",
12432
+ "type": "string",
12433
+ "default": "locale `loading",
12434
+ "description": "无文案时的可访问名称。有文案时以文案为准。"
12435
+ },
12436
+ {
12437
+ "name": "size",
12438
+ "type": "'small' | 'large' | 'sm' | 'md' | 'lg'",
12439
+ "default": "—",
12440
+ "description": "指示器缩放。"
12441
+ },
12442
+ {
12443
+ "name": "background",
12444
+ "type": "string",
12445
+ "default": "—",
12446
+ "description": "遮罩背景,任意 CSS 颜色。"
12447
+ },
12448
+ {
12449
+ "name": "customClass",
12450
+ "type": "string",
12451
+ "default": "—",
12452
+ "description": "加在遮罩上的类名。"
12453
+ },
12454
+ {
12455
+ "name": "fullscreen",
12456
+ "type": "boolean",
12457
+ "default": "false",
12458
+ "description": "遮罩铺满视口(Teleport 到 `body`)。"
12459
+ },
12460
+ {
12461
+ "name": "lock",
12462
+ "type": "boolean",
12463
+ "default": "false",
12464
+ "description": "显示时禁止页面滚动。"
12465
+ },
12466
+ {
12467
+ "name": "delay",
12468
+ "type": "number",
12469
+ "default": "0",
12470
+ "description": "显示前延迟(ms)。"
12471
+ },
12472
+ {
12473
+ "name": "pt",
12474
+ "type": "[RootPassThrough](/docs/types#RootPassThrough) `{ root? }",
12475
+ "default": "—",
12476
+ "description": "DOM 透传,见 [样式与 attrs](/docs/attrs)。"
12477
+ }
12478
+ ],
12479
+ "events": [],
12480
+ "slots": [
12481
+ {
12482
+ "name": "default",
12483
+ "description": "被遮罩盖住的内容。"
12484
+ },
12485
+ {
12486
+ "name": "indicator",
12487
+ "description": "替换遮罩中的指示器。仅在有默认插槽或 `fullscreen` 时生效。"
12488
+ }
12489
+ ],
12490
+ "examples": [
12491
+ {
12492
+ "id": "引入-1",
12493
+ "section": "引入",
12494
+ "sectionId": "引入",
12495
+ "lang": "ts",
12496
+ "preview": false,
12497
+ "code": "import { loading, MLoading, useLoading, vLoading } from 'morya-ui'",
12498
+ "locale": "zh-CN"
12499
+ },
12500
+ {
12501
+ "id": "动效-1",
12502
+ "section": "动效",
12503
+ "sectionId": "动效",
12504
+ "lang": "vue",
12505
+ "preview": true,
12506
+ "code": "<script setup lang=\"ts\">\nimport { MLoading } from 'morya-ui'\n\nconst effects = [\n { id: 'circular', label: '圆环' },\n { id: 'aurora', label: '极光环' },\n { id: 'bounce', label: '弹跳球' },\n { id: 'wave', label: '波浪条' },\n { id: 'pulse', label: '脉冲环' },\n { id: 'stardust', label: '星尘' },\n] as const\n</script>\n\n<template>\n <div class=\"grid grid-cols-2 gap-4 md:grid-cols-3\">\n <div\n v-for=\"item in effects\"\n :key=\"item.id\"\n class=\"flex min-h-36 items-center justify-center rounded-md border border-solid border-[var(--m-color-border)] bg-[var(--m-color-surface)] p-4\"\n >\n <MLoading :effect=\"item.id\" :text=\"item.label\" />\n </div>\n </div>\n</template>",
12507
+ "locale": "zh-CN"
12508
+ },
12509
+ {
12510
+ "id": "区域加载-1",
12511
+ "section": "区域加载",
12512
+ "sectionId": "区域加载",
12513
+ "lang": "vue",
12514
+ "preview": true,
12515
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MLoading, vLoading } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst loading = ref(true)\n</script>\n\n<template>\n <div class=\"grid gap-4\">\n <MLoading :loading=\"loading\" text=\"加载中\" effect=\"wave\">\n <div class=\"min-h-32 p-4\">\n 区域内容\n </div>\n </MLoading>\n <div\n v-loading=\"loading\"\n m-loading-text=\"加载中\"\n m-loading-effect=\"circular\"\n class=\"min-h-32 rounded-md border border-solid border-[var(--m-color-border)] p-4\"\n >\n 指令覆盖的区域\n </div>\n <div>\n <MButton size=\"small\" :label=\"loading ? '结束加载' : '开始加载'\" @click=\"loading = !loading\" />\n </div>\n </div>\n</template>",
12516
+ "locale": "zh-CN"
12517
+ },
12518
+ {
12519
+ "id": "服务式调用-1",
12520
+ "section": "服务式调用",
12521
+ "sectionId": "服务式调用",
12522
+ "lang": "vue",
12523
+ "preview": true,
12524
+ "code": "<script setup lang=\"ts\">\nimport { MButton, useLoading } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst panel = ref<HTMLElement>()\nconst { open } = useLoading()\n\nfunction openRegion() {\n const instance = open({\n target: panel.value,\n text: '加载中',\n effect: 'wave',\n })\n window.setTimeout(() => instance.close(), 1600)\n}\n\nfunction openFullscreen() {\n const instance = open({\n text: '正在提交',\n effect: 'aurora',\n lock: true,\n })\n window.setTimeout(() => instance.close(), 1600)\n}\n</script>\n\n<template>\n <div class=\"grid gap-4\">\n <div\n ref=\"panel\"\n class=\"min-h-32 rounded-md border border-solid border-[var(--m-color-border)] p-4\"\n >\n 可被服务盖住的区域\n </div>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"区域加载\" severity=\"secondary\" @click=\"openRegion\" />\n <MButton label=\"全屏加载\" @click=\"openFullscreen\" />\n </div>\n </div>\n</template>",
12525
+ "locale": "zh-CN"
12526
+ },
12527
+ {
12528
+ "id": "服务式调用-2",
12529
+ "section": "服务式调用",
12530
+ "sectionId": "服务式调用",
12531
+ "lang": "ts",
12532
+ "preview": false,
12533
+ "code": "const instance = loading.service({\n text: '正在提交',\n effect: 'wave',\n lock: true,\n})\ninstance.setText('即将完成')\ninstance.close()",
12534
+ "locale": "zh-CN"
12535
+ },
12536
+ {
12537
+ "id": "服务式调用-3",
12538
+ "section": "服务式调用",
12539
+ "sectionId": "服务式调用",
12540
+ "lang": "ts",
12541
+ "preview": false,
12542
+ "code": "loading.service({\n target: '#panel',\n text: '加载中',\n})\n\nloading.service({\n spinner: () => h('span', '…'),\n text: '自定义',\n})",
12543
+ "locale": "zh-CN"
12544
+ },
12545
+ {
12546
+ "id": "服务式调用-4",
12547
+ "section": "服务式调用",
12548
+ "sectionId": "服务式调用",
12549
+ "lang": "ts",
12550
+ "preview": false,
12551
+ "code": "const { open, close } = useLoading({ effect: 'wave' })\nopen({ text: '保存中' })\nclose()",
12552
+ "locale": "zh-CN"
12553
+ },
12554
+ {
12555
+ "id": "import-1",
12556
+ "section": "Import",
12557
+ "sectionId": "import",
12558
+ "lang": "ts",
12559
+ "preview": false,
12560
+ "code": "import { loading, MLoading, useLoading, vLoading } from 'morya-ui'",
12561
+ "locale": "en-US"
12562
+ },
12563
+ {
12564
+ "id": "effects-1",
12565
+ "section": "Effects",
12566
+ "sectionId": "effects",
12567
+ "lang": "vue",
12568
+ "preview": true,
12569
+ "code": "<script setup lang=\"ts\">\nimport { MLoading } from 'morya-ui'\n\nconst effects = [\n { id: 'circular', label: '圆环' },\n { id: 'aurora', label: '极光环' },\n { id: 'bounce', label: '弹跳球' },\n { id: 'wave', label: '波浪条' },\n { id: 'pulse', label: '脉冲环' },\n { id: 'stardust', label: '星尘' },\n] as const\n</script>\n\n<template>\n <div class=\"grid grid-cols-2 gap-4 md:grid-cols-3\">\n <div\n v-for=\"item in effects\"\n :key=\"item.id\"\n class=\"flex min-h-36 items-center justify-center rounded-md border border-solid border-[var(--m-color-border)] bg-[var(--m-color-surface)] p-4\"\n >\n <MLoading :effect=\"item.id\" :text=\"item.label\" />\n </div>\n </div>\n</template>",
12570
+ "locale": "en-US"
12571
+ },
12572
+ {
12573
+ "id": "region-1",
12574
+ "section": "Region",
12575
+ "sectionId": "region",
12576
+ "lang": "vue",
12577
+ "preview": true,
12578
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MLoading, vLoading } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst loading = ref(true)\n</script>\n\n<template>\n <div class=\"grid gap-4\">\n <MLoading :loading=\"loading\" text=\"Loading\" effect=\"wave\">\n <div class=\"min-h-32 p-4\">\n Region content\n </div>\n </MLoading>\n <div\n v-loading=\"loading\"\n m-loading-text=\"Loading\"\n m-loading-effect=\"circular\"\n class=\"min-h-32 rounded-md border border-solid border-[var(--m-color-border)] p-4\"\n >\n Directive target\n </div>\n <div>\n <MButton size=\"small\" :label=\"loading ? 'Stop' : 'Start'\" @click=\"loading = !loading\" />\n </div>\n </div>\n</template>",
12579
+ "locale": "en-US"
12580
+ },
12581
+ {
12582
+ "id": "service-1",
12583
+ "section": "Service",
12584
+ "sectionId": "service",
12585
+ "lang": "vue",
12586
+ "preview": true,
12587
+ "code": "<script setup lang=\"ts\">\nimport { MButton, useLoading } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst panel = ref<HTMLElement>()\nconst { open } = useLoading()\n\nfunction openRegion() {\n const instance = open({\n target: panel.value,\n text: 'Loading',\n effect: 'wave',\n })\n window.setTimeout(() => instance.close(), 1600)\n}\n\nfunction openFullscreen() {\n const instance = open({\n text: 'Submitting',\n effect: 'aurora',\n lock: true,\n })\n window.setTimeout(() => instance.close(), 1600)\n}\n</script>\n\n<template>\n <div class=\"grid gap-4\">\n <div\n ref=\"panel\"\n class=\"min-h-32 rounded-md border border-solid border-[var(--m-color-border)] p-4\"\n >\n Region covered by the service\n </div>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Cover region\" severity=\"secondary\" @click=\"openRegion\" />\n <MButton label=\"Fullscreen\" @click=\"openFullscreen\" />\n </div>\n </div>\n</template>",
12588
+ "locale": "en-US"
12589
+ },
12590
+ {
12591
+ "id": "service-2",
12592
+ "section": "Service",
12593
+ "sectionId": "service",
12594
+ "lang": "ts",
12595
+ "preview": false,
12596
+ "code": "const instance = loading.service({\n text: 'Submitting',\n effect: 'wave',\n lock: true,\n})\ninstance.setText('Almost done')\ninstance.close()",
12597
+ "locale": "en-US"
12598
+ },
12599
+ {
12600
+ "id": "service-3",
12601
+ "section": "Service",
12602
+ "sectionId": "service",
12603
+ "lang": "ts",
12604
+ "preview": false,
12605
+ "code": "loading.service({\n target: '#panel',\n text: 'Loading',\n})\n\nloading.service({\n spinner: () => h('span', '…'),\n text: 'Custom',\n})",
12606
+ "locale": "en-US"
12607
+ },
12608
+ {
12609
+ "id": "service-4",
12610
+ "section": "Service",
12611
+ "sectionId": "service",
12612
+ "lang": "ts",
12613
+ "preview": false,
12614
+ "code": "const { open, close } = useLoading({ effect: 'wave' })\nopen({ text: 'Saving' })\nclose()",
12615
+ "locale": "en-US"
12616
+ }
12617
+ ],
12618
+ "locales": {
12619
+ "zh-CN": {
12620
+ "title": "Loading",
12621
+ "description": "加载指示与遮罩:多种动效、区域加载、v-loading 指令和命令式 service。",
12622
+ "sections": [
12623
+ {
12624
+ "id": "overview",
12625
+ "title": "",
12626
+ "body": "# Loading\n\n用于区域或全屏的加载反馈。可以只渲染指示器,也可以盖住一块内容,或用指令和服务在任意节点上打开遮罩。\n\n内置圆环、极光环、弹跳球、波浪条、脉冲环和星尘。默认是圆环(`effect=\"circular\"`)。要改全局默认动效,设置 `componentDefaults.Loading.effect`。\n\n全屏遮罩会 Teleport 到 `body`,避免被父级 `overflow` / `transform` 裁切。同一时间只保留一个全屏实例。"
12627
+ },
12628
+ {
12629
+ "id": "引入",
12630
+ "title": "引入",
12631
+ "body": "```ts\nimport { loading, MLoading, useLoading, vLoading } from 'morya-ui'\n```\n\n`app.use(MoryaUI)` 会注册 `v-loading`。按需引入时,在 `<script setup>` 里导入 `vLoading` 即可在模板中使用该指令。"
12632
+ },
12633
+ {
12634
+ "id": "动效",
12635
+ "title": "动效",
12636
+ "body": "```vue preview src=\"./demos/Effects.vue\"\n```"
12637
+ },
12638
+ {
12639
+ "id": "区域加载",
12640
+ "title": "区域加载",
12641
+ "body": "组件包住内容,或在元素上使用 `v-loading`。未传 `text` 时不显示文案,读屏仍使用 locale 的 `loading`。可用 `delay` 避免短请求闪一下。\n\n```vue preview src=\"./demos/Region.zh.vue\"\n```"
12642
+ },
12643
+ {
12644
+ "id": "服务式调用",
12645
+ "title": "服务式调用",
12646
+ "body": "不传 `target` 时遮罩铺满视口。`close()` 会先播放离场再卸载,`setText()` 改文案。也可用 `useLoading()`,在组件卸载时自动关闭。\n\n```vue preview src=\"./demos/Service.zh.vue\"\n```\n\n```ts\nconst instance = loading.service({\n text: '正在提交',\n effect: 'wave',\n lock: true,\n})\ninstance.setText('即将完成')\ninstance.close()\n```\n\n覆盖某个节点,或传入自定义指示器:\n\n```ts\nloading.service({\n target: '#panel',\n text: '加载中',\n})\n\nloading.service({\n spinner: () => h('span', '…'),\n text: '自定义',\n})\n```\n\n```ts\nconst { open, close } = useLoading({ effect: 'wave' })\nopen({ text: '保存中' })\nclose()\n```"
12647
+ },
12648
+ {
12649
+ "id": "指令",
12650
+ "title": "指令",
12651
+ "body": "| 写法 | 说明 |\n| --- | --- |\n| `v-loading` | 布尔值,或带 `text` / `effect` / `background` / `lock` / `delay` / `spinner` 等字段的对象。 |\n| `v-loading.fullscreen` | 全屏遮罩。 |\n| `v-loading.lock` | 打开时锁定页面滚动。 |\n| `v-loading.body` | 遮罩挂到 `body`,并盖住当前元素(跟随尺寸变化)。 |\n| `m-loading-text` | 文案。 |\n| `m-loading-effect` | `circular` / `aurora` / `bounce` / `wave` / `pulse` / `stardust`。 |\n| `m-loading-background` | 遮罩背景色。 |\n| `m-loading-custom-class` | 加在遮罩上的类名。 |\n| `m-loading-delay` | 显示前延迟(ms)。 |"
12652
+ },
12653
+ {
12654
+ "id": "props",
12655
+ "title": "Props",
12656
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `loading` | `boolean` | `true` | 包裹内容或 `fullscreen` 时是否显示遮罩。单独指示器始终显示。 |\n| `effect` | `'circular' \\| 'aurora' \\| 'bounce' \\| 'wave' \\| 'pulse' \\| 'stardust'` | `'circular'` | 动效。可用 `componentDefaults.Loading.effect` 改默认值。 |\n| `text` | `string` | — | 指示器下方文案。不传则不显示。 |\n| `ariaLabel` | `string` | locale `loading` | 无文案时的可访问名称。有文案时以文案为准。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 指示器缩放。 |\n| `background` | `string` | — | 遮罩背景,任意 CSS 颜色。 |\n| `customClass` | `string` | — | 加在遮罩上的类名。 |\n| `fullscreen` | `boolean` | `false` | 遮罩铺满视口(Teleport 到 `body`)。 |\n| `lock` | `boolean` | `false` | 显示时禁止页面滚动。 |\n| `delay` | `number` | `0` | 显示前延迟(ms)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs)。 |"
12657
+ },
12658
+ {
12659
+ "id": "events",
12660
+ "title": "Events",
12661
+ "body": "无自定义事件。"
12662
+ },
12663
+ {
12664
+ "id": "slots",
12665
+ "title": "Slots",
12666
+ "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 被遮罩盖住的内容。 |\n| `indicator` | 替换遮罩中的指示器。仅在有默认插槽或 `fullscreen` 时生效。 |"
12667
+ },
12668
+ {
12669
+ "id": "服务",
12670
+ "title": "服务",
12671
+ "body": "`loading.service(options)` 返回 `{ close, setText }`。`useLoading(defaults)` 返回 `{ open, close, setText }`。\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `target` | `string \\| HTMLElement` | — | 要盖住的元素或选择器。省略则为全屏。 |\n| `fullscreen` | `boolean` | 无 `target` 时为 `true` | 铺满视口。 |\n| `body` | `boolean` | `false` | 遮罩挂到 `body`,定位到 `target` 上。 |\n| `lock` | `boolean` | `false` | 锁定页面滚动。 |\n| `text` | `string` | — | 文案。 |\n| `effect` | 同组件 | `'circular'` | 动效。 |\n| `spinner` | `MRenderable` | — | 自定义指示器;设置后忽略内置 `effect`。 |\n| `background` | `string` | — | 遮罩背景。 |\n| `customClass` | `string` | — | 遮罩类名。 |\n| `size` | 同组件 | — | 指示器尺寸。 |\n| `delay` | `number` | — | 显示前延迟(ms)。 |"
12672
+ },
12673
+ {
12674
+ "id": "主题",
12675
+ "title": "主题",
12676
+ "body": "指示器颜色走语义色:`--m-color-primary`、`--m-color-success`、`--m-color-warning`、`--m-color-danger`、`--m-color-text-muted`。遮罩默认是表面色的半透明混合,可用 `background` 或 `--m-loading-mask-bg` 覆盖。全屏层级是 `--m-loading-z-index`(默认 `--m-z-base + 200`)。\n\n`prefers-reduced-motion: reduce` 时循环动效关闭。"
12677
+ },
12678
+ {
12679
+ "id": "无障碍",
12680
+ "title": "无障碍",
12681
+ "body": "- 指示器使用 `role=\"status\"`。\n- 遮罩区域设置 `aria-busy`,被盖住的内容设为 `inert`。\n- 不要只靠动画表示加载;需要说明时传入 `text`。"
12682
+ }
12683
+ ],
12684
+ "markdown": "---\ntitle: Loading\ncategory: 05 / FEEDBACK\ndescription: 加载指示与遮罩:多种动效、区域加载、v-loading 指令和命令式 service。\n---\n\n# Loading\n\n用于区域或全屏的加载反馈。可以只渲染指示器,也可以盖住一块内容,或用指令和服务在任意节点上打开遮罩。\n\n内置圆环、极光环、弹跳球、波浪条、脉冲环和星尘。默认是圆环(`effect=\"circular\"`)。要改全局默认动效,设置 `componentDefaults.Loading.effect`。\n\n全屏遮罩会 Teleport 到 `body`,避免被父级 `overflow` / `transform` 裁切。同一时间只保留一个全屏实例。\n\n## 引入\n\n```ts\nimport { loading, MLoading, useLoading, vLoading } from 'morya-ui'\n```\n\n`app.use(MoryaUI)` 会注册 `v-loading`。按需引入时,在 `<script setup>` 里导入 `vLoading` 即可在模板中使用该指令。\n\n## 动效\n\n```vue preview src=\"./demos/Effects.vue\"\n```\n\n## 区域加载\n\n组件包住内容,或在元素上使用 `v-loading`。未传 `text` 时不显示文案,读屏仍使用 locale 的 `loading`。可用 `delay` 避免短请求闪一下。\n\n```vue preview src=\"./demos/Region.zh.vue\"\n```\n\n## 服务式调用\n\n不传 `target` 时遮罩铺满视口。`close()` 会先播放离场再卸载,`setText()` 改文案。也可用 `useLoading()`,在组件卸载时自动关闭。\n\n```vue preview src=\"./demos/Service.zh.vue\"\n```\n\n```ts\nconst instance = loading.service({\n text: '正在提交',\n effect: 'wave',\n lock: true,\n})\ninstance.setText('即将完成')\ninstance.close()\n```\n\n覆盖某个节点,或传入自定义指示器:\n\n```ts\nloading.service({\n target: '#panel',\n text: '加载中',\n})\n\nloading.service({\n spinner: () => h('span', '…'),\n text: '自定义',\n})\n```\n\n```ts\nconst { open, close } = useLoading({ effect: 'wave' })\nopen({ text: '保存中' })\nclose()\n```\n\n## 指令\n\n| 写法 | 说明 |\n| --- | --- |\n| `v-loading` | 布尔值,或带 `text` / `effect` / `background` / `lock` / `delay` / `spinner` 等字段的对象。 |\n| `v-loading.fullscreen` | 全屏遮罩。 |\n| `v-loading.lock` | 打开时锁定页面滚动。 |\n| `v-loading.body` | 遮罩挂到 `body`,并盖住当前元素(跟随尺寸变化)。 |\n| `m-loading-text` | 文案。 |\n| `m-loading-effect` | `circular` / `aurora` / `bounce` / `wave` / `pulse` / `stardust`。 |\n| `m-loading-background` | 遮罩背景色。 |\n| `m-loading-custom-class` | 加在遮罩上的类名。 |\n| `m-loading-delay` | 显示前延迟(ms)。 |\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `loading` | `boolean` | `true` | 包裹内容或 `fullscreen` 时是否显示遮罩。单独指示器始终显示。 |\n| `effect` | `'circular' \\| 'aurora' \\| 'bounce' \\| 'wave' \\| 'pulse' \\| 'stardust'` | `'circular'` | 动效。可用 `componentDefaults.Loading.effect` 改默认值。 |\n| `text` | `string` | — | 指示器下方文案。不传则不显示。 |\n| `ariaLabel` | `string` | locale `loading` | 无文案时的可访问名称。有文案时以文案为准。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 指示器缩放。 |\n| `background` | `string` | — | 遮罩背景,任意 CSS 颜色。 |\n| `customClass` | `string` | — | 加在遮罩上的类名。 |\n| `fullscreen` | `boolean` | `false` | 遮罩铺满视口(Teleport 到 `body`)。 |\n| `lock` | `boolean` | `false` | 显示时禁止页面滚动。 |\n| `delay` | `number` | `0` | 显示前延迟(ms)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs)。 |\n\n## Events\n\n无自定义事件。\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 被遮罩盖住的内容。 |\n| `indicator` | 替换遮罩中的指示器。仅在有默认插槽或 `fullscreen` 时生效。 |\n\n## 服务\n\n`loading.service(options)` 返回 `{ close, setText }`。`useLoading(defaults)` 返回 `{ open, close, setText }`。\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `target` | `string \\| HTMLElement` | — | 要盖住的元素或选择器。省略则为全屏。 |\n| `fullscreen` | `boolean` | 无 `target` 时为 `true` | 铺满视口。 |\n| `body` | `boolean` | `false` | 遮罩挂到 `body`,定位到 `target` 上。 |\n| `lock` | `boolean` | `false` | 锁定页面滚动。 |\n| `text` | `string` | — | 文案。 |\n| `effect` | 同组件 | `'circular'` | 动效。 |\n| `spinner` | `MRenderable` | — | 自定义指示器;设置后忽略内置 `effect`。 |\n| `background` | `string` | — | 遮罩背景。 |\n| `customClass` | `string` | — | 遮罩类名。 |\n| `size` | 同组件 | — | 指示器尺寸。 |\n| `delay` | `number` | — | 显示前延迟(ms)。 |\n\n## 主题\n\n指示器颜色走语义色:`--m-color-primary`、`--m-color-success`、`--m-color-warning`、`--m-color-danger`、`--m-color-text-muted`。遮罩默认是表面色的半透明混合,可用 `background` 或 `--m-loading-mask-bg` 覆盖。全屏层级是 `--m-loading-z-index`(默认 `--m-z-base + 200`)。\n\n`prefers-reduced-motion: reduce` 时循环动效关闭。\n\n## 无障碍\n\n- 指示器使用 `role=\"status\"`。\n- 遮罩区域设置 `aria-busy`,被盖住的内容设为 `inert`。\n- 不要只靠动画表示加载;需要说明时传入 `text`。\n"
12685
+ },
12686
+ "en-US": {
12687
+ "title": "Loading",
12688
+ "description": "Loading indicator and mask, with multiple effects, a region overlay, the v-loading directive, and an imperative service.",
12689
+ "sections": [
12690
+ {
12691
+ "id": "overview",
12692
+ "title": "",
12693
+ "body": "# Loading\n\nRegion or fullscreen loading feedback. Render an indicator on its own, cover a block of content, or open a mask on any node with the directive or service.\n\nBuilt-in graphics are a circular spinner, aurora ring, bouncing balls, wave bars, pulse rings, and stardust. The default is the circular spinner (`effect=\"circular\"`). Set `componentDefaults.Loading.effect` to change the global default.\n\nFullscreen masks teleport to `body` so parent `overflow` / `transform` cannot clip them. Only one fullscreen instance stays open at a time."
12694
+ },
12695
+ {
12696
+ "id": "import",
12697
+ "title": "Import",
12698
+ "body": "```ts\nimport { loading, MLoading, useLoading, vLoading } from 'morya-ui'\n```\n\n`app.use(MoryaUI)` registers `v-loading`. For on-demand usage, import `vLoading` in `<script setup>` and the template can use the directive."
12699
+ },
12700
+ {
12701
+ "id": "effects",
12702
+ "title": "Effects",
12703
+ "body": "```vue preview src=\"./demos/Effects.vue\"\n```"
12704
+ },
12705
+ {
12706
+ "id": "region",
12707
+ "title": "Region",
12708
+ "body": "Wrap content with the component, or put `v-loading` on an element. Omit `text` to hide the caption; screen readers still get the locale `loading` string. Use `delay` to avoid a flash on short requests.\n\n```vue preview src=\"./demos/Region.en.vue\"\n```"
12709
+ },
12710
+ {
12711
+ "id": "service",
12712
+ "title": "Service",
12713
+ "body": "With no `target`, the mask covers the viewport. `close()` plays the leave transition before unmounting, and `setText()` changes the caption. `useLoading()` closes automatically when the caller unmounts.\n\n```vue preview src=\"./demos/Service.en.vue\"\n```\n\n```ts\nconst instance = loading.service({\n text: 'Submitting',\n effect: 'wave',\n lock: true,\n})\ninstance.setText('Almost done')\ninstance.close()\n```\n\nCover one node, or pass a custom indicator:\n\n```ts\nloading.service({\n target: '#panel',\n text: 'Loading',\n})\n\nloading.service({\n spinner: () => h('span', '…'),\n text: 'Custom',\n})\n```\n\n```ts\nconst { open, close } = useLoading({ effect: 'wave' })\nopen({ text: 'Saving' })\nclose()\n```"
12714
+ },
12715
+ {
12716
+ "id": "directive",
12717
+ "title": "Directive",
12718
+ "body": "| Form | Description |\n| --- | --- |\n| `v-loading` | A boolean, or an object with `text`, `effect`, `background`, `lock`, `delay`, `spinner`, and related fields. |\n| `v-loading.fullscreen` | Fullscreen mask. |\n| `v-loading.lock` | Lock page scrolling while open. |\n| `v-loading.body` | Mount the mask on `body`, positioned over the element (tracks size changes). |\n| `m-loading-text` | Caption. |\n| `m-loading-effect` | `circular` / `aurora` / `bounce` / `wave` / `pulse` / `stardust`. |\n| `m-loading-background` | Mask background. |\n| `m-loading-custom-class` | Extra class on the mask. |\n| `m-loading-delay` | Delay before showing (ms). |"
12719
+ },
12720
+ {
12721
+ "id": "props",
12722
+ "title": "Props",
12723
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `loading` | `boolean` | `true` | Mask visibility when wrapping content or using `fullscreen`. A bare indicator is always shown. |\n| `effect` | `'circular' \\| 'aurora' \\| 'bounce' \\| 'wave' \\| 'pulse' \\| 'stardust'` | `'circular'` | Graphic. Override the default with `componentDefaults.Loading.effect`. |\n| `text` | `string` | — | Caption under the indicator. Hidden when omitted. |\n| `ariaLabel` | `string` | locale `loading` | Accessible name when there is no caption. A caption is used as the name when present. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Indicator scale. |\n| `background` | `string` | — | Mask background, any CSS color. |\n| `customClass` | `string` | — | Extra class on the mask. |\n| `fullscreen` | `boolean` | `false` | Cover the viewport (teleported to `body`). |\n| `lock` | `boolean` | `false` | Prevent page scrolling while visible. |\n| `delay` | `number` | `0` | Delay before showing (ms). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
12724
+ },
12725
+ {
12726
+ "id": "events",
12727
+ "title": "Events",
12728
+ "body": "No custom events."
12729
+ },
12730
+ {
12731
+ "id": "slots",
12732
+ "title": "Slots",
12733
+ "body": "| Slot | Description |\n| --- | --- |\n| `default` | Content covered by the mask. |\n| `indicator` | Replaces the indicator inside the mask. Used when there is a default slot or `fullscreen`. |"
12734
+ },
12735
+ {
12736
+ "id": "service",
12737
+ "title": "Service",
12738
+ "body": "`loading.service(options)` returns `{ close, setText }`. `useLoading(defaults)` returns `{ open, close, setText }`.\n\n| Option | Type | Default | Description |\n| --- | --- | --- | --- |\n| `target` | `string \\| HTMLElement` | — | Element or selector to cover. Omit for fullscreen. |\n| `fullscreen` | `boolean` | `true` when `target` is omitted | Cover the viewport. |\n| `body` | `boolean` | `false` | Mount the mask on `body`, positioned over `target`. |\n| `lock` | `boolean` | `false` | Lock page scrolling. |\n| `text` | `string` | — | Caption. |\n| `effect` | same as the component | `'circular'` | Graphic. |\n| `spinner` | `MRenderable` | — | Custom indicator; skips built-in effects when set. |\n| `background` | `string` | — | Mask background. |\n| `customClass` | `string` | — | Extra mask class. |\n| `size` | same as the component | — | Indicator size. |\n| `delay` | `number` | — | Delay before showing (ms). |"
12739
+ },
12740
+ {
12741
+ "id": "theme",
12742
+ "title": "Theme",
12743
+ "body": "Indicator colors use semantic tokens: `--m-color-primary`, `--m-color-success`, `--m-color-warning`, `--m-color-danger`, and `--m-color-text-muted`. The mask defaults to a translucent surface mix. Override it with `background` or `--m-loading-mask-bg`. Fullscreen stacking uses `--m-loading-z-index` (default `--m-z-base + 200`).\n\nLooping motion is disabled under `prefers-reduced-motion: reduce`."
12744
+ },
12745
+ {
12746
+ "id": "accessibility",
12747
+ "title": "Accessibility",
12748
+ "body": "- The indicator uses `role=\"status\"`.\n- The masked region sets `aria-busy`, and covered content is `inert`.\n- Do not rely on motion alone; pass `text` when the wait needs an explanation."
12749
+ }
12750
+ ],
12751
+ "markdown": "---\ntitle: Loading\ncategory: 05 / FEEDBACK\ndescription: Loading indicator and mask, with multiple effects, a region overlay, the v-loading directive, and an imperative service.\n---\n\n# Loading\n\nRegion or fullscreen loading feedback. Render an indicator on its own, cover a block of content, or open a mask on any node with the directive or service.\n\nBuilt-in graphics are a circular spinner, aurora ring, bouncing balls, wave bars, pulse rings, and stardust. The default is the circular spinner (`effect=\"circular\"`). Set `componentDefaults.Loading.effect` to change the global default.\n\nFullscreen masks teleport to `body` so parent `overflow` / `transform` cannot clip them. Only one fullscreen instance stays open at a time.\n\n## Import\n\n```ts\nimport { loading, MLoading, useLoading, vLoading } from 'morya-ui'\n```\n\n`app.use(MoryaUI)` registers `v-loading`. For on-demand usage, import `vLoading` in `<script setup>` and the template can use the directive.\n\n## Effects\n\n```vue preview src=\"./demos/Effects.vue\"\n```\n\n## Region\n\nWrap content with the component, or put `v-loading` on an element. Omit `text` to hide the caption; screen readers still get the locale `loading` string. Use `delay` to avoid a flash on short requests.\n\n```vue preview src=\"./demos/Region.en.vue\"\n```\n\n## Service\n\nWith no `target`, the mask covers the viewport. `close()` plays the leave transition before unmounting, and `setText()` changes the caption. `useLoading()` closes automatically when the caller unmounts.\n\n```vue preview src=\"./demos/Service.en.vue\"\n```\n\n```ts\nconst instance = loading.service({\n text: 'Submitting',\n effect: 'wave',\n lock: true,\n})\ninstance.setText('Almost done')\ninstance.close()\n```\n\nCover one node, or pass a custom indicator:\n\n```ts\nloading.service({\n target: '#panel',\n text: 'Loading',\n})\n\nloading.service({\n spinner: () => h('span', '…'),\n text: 'Custom',\n})\n```\n\n```ts\nconst { open, close } = useLoading({ effect: 'wave' })\nopen({ text: 'Saving' })\nclose()\n```\n\n## Directive\n\n| Form | Description |\n| --- | --- |\n| `v-loading` | A boolean, or an object with `text`, `effect`, `background`, `lock`, `delay`, `spinner`, and related fields. |\n| `v-loading.fullscreen` | Fullscreen mask. |\n| `v-loading.lock` | Lock page scrolling while open. |\n| `v-loading.body` | Mount the mask on `body`, positioned over the element (tracks size changes). |\n| `m-loading-text` | Caption. |\n| `m-loading-effect` | `circular` / `aurora` / `bounce` / `wave` / `pulse` / `stardust`. |\n| `m-loading-background` | Mask background. |\n| `m-loading-custom-class` | Extra class on the mask. |\n| `m-loading-delay` | Delay before showing (ms). |\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `loading` | `boolean` | `true` | Mask visibility when wrapping content or using `fullscreen`. A bare indicator is always shown. |\n| `effect` | `'circular' \\| 'aurora' \\| 'bounce' \\| 'wave' \\| 'pulse' \\| 'stardust'` | `'circular'` | Graphic. Override the default with `componentDefaults.Loading.effect`. |\n| `text` | `string` | — | Caption under the indicator. Hidden when omitted. |\n| `ariaLabel` | `string` | locale `loading` | Accessible name when there is no caption. A caption is used as the name when present. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Indicator scale. |\n| `background` | `string` | — | Mask background, any CSS color. |\n| `customClass` | `string` | — | Extra class on the mask. |\n| `fullscreen` | `boolean` | `false` | Cover the viewport (teleported to `body`). |\n| `lock` | `boolean` | `false` | Prevent page scrolling while visible. |\n| `delay` | `number` | `0` | Delay before showing (ms). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n## Events\n\nNo custom events.\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Content covered by the mask. |\n| `indicator` | Replaces the indicator inside the mask. Used when there is a default slot or `fullscreen`. |\n\n## Service\n\n`loading.service(options)` returns `{ close, setText }`. `useLoading(defaults)` returns `{ open, close, setText }`.\n\n| Option | Type | Default | Description |\n| --- | --- | --- | --- |\n| `target` | `string \\| HTMLElement` | — | Element or selector to cover. Omit for fullscreen. |\n| `fullscreen` | `boolean` | `true` when `target` is omitted | Cover the viewport. |\n| `body` | `boolean` | `false` | Mount the mask on `body`, positioned over `target`. |\n| `lock` | `boolean` | `false` | Lock page scrolling. |\n| `text` | `string` | — | Caption. |\n| `effect` | same as the component | `'circular'` | Graphic. |\n| `spinner` | `MRenderable` | — | Custom indicator; skips built-in effects when set. |\n| `background` | `string` | — | Mask background. |\n| `customClass` | `string` | — | Extra mask class. |\n| `size` | same as the component | — | Indicator size. |\n| `delay` | `number` | — | Delay before showing (ms). |\n\n## Theme\n\nIndicator colors use semantic tokens: `--m-color-primary`, `--m-color-success`, `--m-color-warning`, `--m-color-danger`, and `--m-color-text-muted`. The mask defaults to a translucent surface mix. Override it with `background` or `--m-loading-mask-bg`. Fullscreen stacking uses `--m-loading-z-index` (default `--m-z-base + 200`).\n\nLooping motion is disabled under `prefers-reduced-motion: reduce`.\n\n## Accessibility\n\n- The indicator uses `role=\"status\"`.\n- The masked region sets `aria-busy`, and covered content is `inert`.\n- Do not rely on motion alone; pass `text` when the wait needs an explanation.\n"
12752
+ }
12753
+ }
12754
+ },
12403
12755
  {
12404
12756
  "id": "MegaMenu",
12405
12757
  "name": "MegaMenu",
@@ -13447,7 +13799,7 @@
13447
13799
  {
13448
13800
  "id": "overview",
13449
13801
  "title": "",
13450
- "body": "# Message\n\n从窗口顶部正中滑入的轻量提示(可通过 `placement` 改到六向位置),适合简短操作反馈。推荐用 `message` API;也可挂载 `<MMessage />` 作为自定义挂载点。\n\n与 [Toast](/components/Toast) 的分工:\n\n- **Message(默认)**:轻量单行反馈,默认顶部居中,无标题/详情。**大多数 CRUD / 保存 / 删除回执应使用此项。**\n- **Toast**:四角通知,带 `summary` / `detail`;仅在有补充说明或异步通知感时使用。\n- **`<MMessage>` 组件**:页面内嵌条,用于表单区常驻错误(见下方「内嵌 Message」)。\n\n> AI / 业务代码选型细则见 [`feedback-message-vs-toast.md`](../../../../design-kit/docs/feedback-message-vs-toast.md)。\n\n**快速判断**:只有一句话 → `message.success('已保存')`;有标题 + 详情 → `toast.success({ summary, detail })`。"
13802
+ "body": "# Message\n\n从窗口顶部正中滑入的轻量提示(可通过 `placement` 改到六向位置),适合简短操作反馈。推荐用 `message` API;也可挂载 `<MMessage />` 作为自定义挂载点。\n\n与 [Toast](/components/Toast) 的分工:\n\n- **Message(默认)**:轻量单行反馈,默认顶部居中,无标题/详情。**大多数 CRUD / 保存 / 删除回执应使用此项。**\n- **Toast**:四角通知,带 `summary` / `detail`;仅在有补充说明或异步通知感时使用。\n- **`<MMessage>` 组件**:页面内嵌条,用于表单区常驻错误(见下方「内嵌 Message」)。\n\n> AI / 业务代码选型细则见 [`feedback.md`](../../../../design-kit/.agents/skills/morya-ui-pages/references/feedback.md)。\n\n**快速判断**:只有一句话 → `message.success('已保存')`;有标题 + 详情 → `toast.success({ summary, detail })`。"
13451
13803
  },
13452
13804
  {
13453
13805
  "id": "引入",
@@ -13495,7 +13847,7 @@
13495
13847
  "body": "<h4 id=\"MessageItem\">MessageItem</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface MessageItem {\n id: string | number\n content: MRenderable\n severity?: MessageSeverity\n closable?: boolean\n /** Auto-close delay in ms. `0` keeps it open. Default `3000` for API calls. */\n life?: number\n icon?: boolean\n}\n```"
13496
13848
  }
13497
13849
  ],
13498
- "markdown": "---\ntitle: Message\ncategory: 05 / FEEDBACK\ndescription: 顶部居中浮层提示,支持 API 调用。\n---\n\n# Message\n\n从窗口顶部正中滑入的轻量提示(可通过 `placement` 改到六向位置),适合简短操作反馈。推荐用 `message` API;也可挂载 `<MMessage />` 作为自定义挂载点。\n\n与 [Toast](/components/Toast) 的分工:\n\n- **Message(默认)**:轻量单行反馈,默认顶部居中,无标题/详情。**大多数 CRUD / 保存 / 删除回执应使用此项。**\n- **Toast**:四角通知,带 `summary` / `detail`;仅在有补充说明或异步通知感时使用。\n- **`<MMessage>` 组件**:页面内嵌条,用于表单区常驻错误(见下方「内嵌 Message」)。\n\n> AI / 业务代码选型细则见 [`feedback-message-vs-toast.md`](../../../../design-kit/docs/feedback-message-vs-toast.md)。\n\n**快速判断**:只有一句话 → `message.success('已保存')`;有标题 + 详情 → `toast.success({ summary, detail })`。\n\n## 引入\n\n```ts\nimport { message, MMessage, useMessage } from 'morya-ui'\n```\n\n## API\n\n首次调用时会自动挂载浮层容器,无需在模板里放置组件。\n\n```vue preview src=\"./demos/Api.zh.vue\"\n```\n\n## 自定义内容\n\n`content`(以及 Toast 的 `summary` / `detail`)支持字符串、`h()` 返回的 VNode、组件,或 `() => VNode` 工厂函数。\n\n```vue preview src=\"./demos/CustomContent.zh.vue\"\n```\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `message.success(content \\| options)` | 成功提示 |\n| `message.info(content \\| options)` | 信息提示 |\n| `message.warn(content \\| options)` | 警告提示(`warning` 同义) |\n| `message.error(content \\| options)` | 错误提示 |\n| `message.open(content \\| options)` | 自定义打开 |\n| `message.close(id?)` | 关闭指定 / 全部 |\n| `message.closeAll()` / `message.destroyAll()` | 关闭全部(二者等价) |\n| `message.config({ placement, max })` | 宿主位置与并发上限 |\n\n返回值:`{ id, close }`。\n\n### MessageOptions\n\n| 字段 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `content` | `string \\| number \\| VNode \\| Component \\| (() => VNodeChild)` | — | 正文;也可把可渲染值直接当作入参 |\n| `severity` | `'success' \\| 'info' \\| 'warn' \\| 'error' \\| 'secondary' \\| 'contrast'` | `'info'` | 语义色 |\n| `closable` | `boolean` | `false` | 显示关闭按钮 |\n| `life` | `number` | `3000` | 自动关闭毫秒;`0` 不自动关闭 |\n| `icon` | `boolean` | `true` | 显示语义图标 |\n| `id` | `string \\| number` | 自动生成 | 唯一键 |\n\n## 可选宿主\n\n需要自定义 `appendTo` 时,可在应用根部放置:\n\n```vue\n<MMessage append-to=\"body\" />\n```\n\n存在手动宿主时,API 不会再自动挂载第二份。\n\n## Props(`MMessage`)\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `teleport` | `boolean` | `true` | 是否 Teleport |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标 |\n| `placement` | `'top' \\| 'top-left' \\| 'top-right' \\| 'bottom' \\| 'bottom-left' \\| 'bottom-right'` | `'top'` | 宿主位置 |\n| `max` | `number` | — | 同时可见条数;超出丢掉最旧一条 |\n| `auto` | `boolean` | — | — |\n| `messages` | `MessageItem[]` | — | — |\n\n## Events\n\n`<MMessage />` 宿主本身无 Vue 事件;请通过 `message.*` API 的返回值 `{ id, close }` 管理生命周期。\n\n## Slots\n\n无插槽;通过 `message.*` API 注入内容。\n\n## 类型\n\n<h4 id=\"MessageItem\">MessageItem</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface MessageItem {\n id: string | number\n content: MRenderable\n severity?: MessageSeverity\n closable?: boolean\n /** Auto-close delay in ms. `0` keeps it open. Default `3000` for API calls. */\n life?: number\n icon?: boolean\n}\n```\n"
13850
+ "markdown": "---\ntitle: Message\ncategory: 05 / FEEDBACK\ndescription: 顶部居中浮层提示,支持 API 调用。\n---\n\n# Message\n\n从窗口顶部正中滑入的轻量提示(可通过 `placement` 改到六向位置),适合简短操作反馈。推荐用 `message` API;也可挂载 `<MMessage />` 作为自定义挂载点。\n\n与 [Toast](/components/Toast) 的分工:\n\n- **Message(默认)**:轻量单行反馈,默认顶部居中,无标题/详情。**大多数 CRUD / 保存 / 删除回执应使用此项。**\n- **Toast**:四角通知,带 `summary` / `detail`;仅在有补充说明或异步通知感时使用。\n- **`<MMessage>` 组件**:页面内嵌条,用于表单区常驻错误(见下方「内嵌 Message」)。\n\n> AI / 业务代码选型细则见 [`feedback.md`](../../../../design-kit/.agents/skills/morya-ui-pages/references/feedback.md)。\n\n**快速判断**:只有一句话 → `message.success('已保存')`;有标题 + 详情 → `toast.success({ summary, detail })`。\n\n## 引入\n\n```ts\nimport { message, MMessage, useMessage } from 'morya-ui'\n```\n\n## API\n\n首次调用时会自动挂载浮层容器,无需在模板里放置组件。\n\n```vue preview src=\"./demos/Api.zh.vue\"\n```\n\n## 自定义内容\n\n`content`(以及 Toast 的 `summary` / `detail`)支持字符串、`h()` 返回的 VNode、组件,或 `() => VNode` 工厂函数。\n\n```vue preview src=\"./demos/CustomContent.zh.vue\"\n```\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `message.success(content \\| options)` | 成功提示 |\n| `message.info(content \\| options)` | 信息提示 |\n| `message.warn(content \\| options)` | 警告提示(`warning` 同义) |\n| `message.error(content \\| options)` | 错误提示 |\n| `message.open(content \\| options)` | 自定义打开 |\n| `message.close(id?)` | 关闭指定 / 全部 |\n| `message.closeAll()` / `message.destroyAll()` | 关闭全部(二者等价) |\n| `message.config({ placement, max })` | 宿主位置与并发上限 |\n\n返回值:`{ id, close }`。\n\n### MessageOptions\n\n| 字段 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `content` | `string \\| number \\| VNode \\| Component \\| (() => VNodeChild)` | — | 正文;也可把可渲染值直接当作入参 |\n| `severity` | `'success' \\| 'info' \\| 'warn' \\| 'error' \\| 'secondary' \\| 'contrast'` | `'info'` | 语义色 |\n| `closable` | `boolean` | `false` | 显示关闭按钮 |\n| `life` | `number` | `3000` | 自动关闭毫秒;`0` 不自动关闭 |\n| `icon` | `boolean` | `true` | 显示语义图标 |\n| `id` | `string \\| number` | 自动生成 | 唯一键 |\n\n## 可选宿主\n\n需要自定义 `appendTo` 时,可在应用根部放置:\n\n```vue\n<MMessage append-to=\"body\" />\n```\n\n存在手动宿主时,API 不会再自动挂载第二份。\n\n## Props(`MMessage`)\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `teleport` | `boolean` | `true` | 是否 Teleport |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标 |\n| `placement` | `'top' \\| 'top-left' \\| 'top-right' \\| 'bottom' \\| 'bottom-left' \\| 'bottom-right'` | `'top'` | 宿主位置 |\n| `max` | `number` | — | 同时可见条数;超出丢掉最旧一条 |\n| `auto` | `boolean` | — | — |\n| `messages` | `MessageItem[]` | — | — |\n\n## Events\n\n`<MMessage />` 宿主本身无 Vue 事件;请通过 `message.*` API 的返回值 `{ id, close }` 管理生命周期。\n\n## Slots\n\n无插槽;通过 `message.*` API 注入内容。\n\n## 类型\n\n<h4 id=\"MessageItem\">MessageItem</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface MessageItem {\n id: string | number\n content: MRenderable\n severity?: MessageSeverity\n closable?: boolean\n /** Auto-close delay in ms. `0` keeps it open. Default `3000` for API calls. */\n life?: number\n icon?: boolean\n}\n```\n"
13499
13851
  },
13500
13852
  "en-US": {
13501
13853
  "title": "Message",
@@ -13504,7 +13856,7 @@
13504
13856
  {
13505
13857
  "id": "overview",
13506
13858
  "title": "",
13507
- "body": "# Message\n\nA lightweight notice that slides in from the top center by default (`placement` can move it). Prefer the `message` API; you can also mount `<MMessage />` as a custom host.\n\nVs [Toast](/components/Toast):\n\n- **Message (default)**: short single-line feedback; no title/detail. Use for most CRUD / save / delete confirmations.\n- **Toast**: corner notifications with `summary` / `detail`; use only when supplementary detail is needed.\n- **`<MMessage>` component**: inline banner for persistent form/auth errors.\n\n> Selection guide: [`feedback-message-vs-toast.md`](../../../../design-kit/docs/feedback-message-vs-toast.md).\n\n**Rule of thumb**: one short sentence → `message.success('Saved')`; title + detail → `toast.success({ summary, detail })`."
13859
+ "body": "# Message\n\nA lightweight notice that slides in from the top center by default (`placement` can move it). Prefer the `message` API; you can also mount `<MMessage />` as a custom host.\n\nVs [Toast](/components/Toast):\n\n- **Message (default)**: short single-line feedback; no title/detail. Use for most CRUD / save / delete confirmations.\n- **Toast**: corner notifications with `summary` / `detail`; use only when supplementary detail is needed.\n- **`<MMessage>` component**: inline banner for persistent form/auth errors.\n\n> Selection guide: [`feedback.md`](../../../../design-kit/.agents/skills/morya-ui-pages/references/feedback.md).\n\n**Rule of thumb**: one short sentence → `message.success('Saved')`; title + detail → `toast.success({ summary, detail })`."
13508
13860
  },
13509
13861
  {
13510
13862
  "id": "import",
@@ -13547,7 +13899,7 @@
13547
13899
  "body": "No slots; content is injected through the `message.*` API."
13548
13900
  }
13549
13901
  ],
13550
- "markdown": "---\ntitle: Message\ncategory: 05 / FEEDBACK\ndescription: Top-center floating notice with an imperative API.\n---\n\n# Message\n\nA lightweight notice that slides in from the top center by default (`placement` can move it). Prefer the `message` API; you can also mount `<MMessage />` as a custom host.\n\nVs [Toast](/components/Toast):\n\n- **Message (default)**: short single-line feedback; no title/detail. Use for most CRUD / save / delete confirmations.\n- **Toast**: corner notifications with `summary` / `detail`; use only when supplementary detail is needed.\n- **`<MMessage>` component**: inline banner for persistent form/auth errors.\n\n> Selection guide: [`feedback-message-vs-toast.md`](../../../../design-kit/docs/feedback-message-vs-toast.md).\n\n**Rule of thumb**: one short sentence → `message.success('Saved')`; title + detail → `toast.success({ summary, detail })`.\n\n## Import\n\n```ts\nimport { message, MMessage, useMessage } from 'morya-ui'\n```\n\n## API\n\nThe first call auto-mounts a floating host; no template component is required.\n\n```vue preview src=\"./demos/Api.en.vue\"\n```\n\n## Custom content\n\n`content` (and Toast `summary` / `detail`) accepts a string, a VNode from `h()`, a component, or a `() => VNode` factory.\n\n```vue preview src=\"./demos/CustomContent.en.vue\"\n```\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `message.success(content \\| options)` | Success |\n| `message.info(content \\| options)` | Info |\n| `message.warn(content \\| options)` | Warn (`warning` alias) |\n| `message.error(content \\| options)` | Error |\n| `message.open(content \\| options)` | Open with options |\n| `message.close(id?)` | Close one / all |\n| `message.closeAll()` / `message.destroyAll()` | Close all (aliases of each other) |\n| `message.config({ placement, max })` | Host placement and concurrency cap |\n\nReturns `{ id, close }`.\n\n### MessageOptions\n\n| Field | Type | Default | Description |\n| --- | --- | --- | --- |\n| `content` | `string \\| number \\| VNode \\| Component \\| (() => VNodeChild)` | — | Body; a renderable value may also be passed directly |\n| `severity` | `'success' \\| 'info' \\| 'warn' \\| 'error' \\| 'secondary' \\| 'contrast'` | `'info'` | Tone |\n| `closable` | `boolean` | `false` | Show close button |\n| `life` | `number` | `3000` | Auto-close ms; `0` keeps open |\n| `icon` | `boolean` | `true` | Show severity icon |\n| `id` | `string \\| number` | auto | Unique key |\n\n## Optional host\n\nFor a custom `appendTo`, place this at the app root:\n\n```vue\n<MMessage append-to=\"body\" />\n```\n\nWhen a manual host exists, the API will not mount a second one.\n\n## Props (`MMessage`)\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `teleport` | `boolean` | `true` | Whether to Teleport |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target |\n| `placement` | `'top' \\| 'top-left' \\| 'top-right' \\| 'bottom' \\| 'bottom-left' \\| 'bottom-right'` | `'top'` | Host placement |\n| `max` | `number` | — | Max visible items; oldest is dropped |\n\n## Events\n\nThe `<MMessage />` host emits no Vue events. Use the `{ id, close }` return value from `message.*` APIs to control lifetime.\n\n## Slots\n\nNo slots; content is injected through the `message.*` API.\n"
13902
+ "markdown": "---\ntitle: Message\ncategory: 05 / FEEDBACK\ndescription: Top-center floating notice with an imperative API.\n---\n\n# Message\n\nA lightweight notice that slides in from the top center by default (`placement` can move it). Prefer the `message` API; you can also mount `<MMessage />` as a custom host.\n\nVs [Toast](/components/Toast):\n\n- **Message (default)**: short single-line feedback; no title/detail. Use for most CRUD / save / delete confirmations.\n- **Toast**: corner notifications with `summary` / `detail`; use only when supplementary detail is needed.\n- **`<MMessage>` component**: inline banner for persistent form/auth errors.\n\n> Selection guide: [`feedback.md`](../../../../design-kit/.agents/skills/morya-ui-pages/references/feedback.md).\n\n**Rule of thumb**: one short sentence → `message.success('Saved')`; title + detail → `toast.success({ summary, detail })`.\n\n## Import\n\n```ts\nimport { message, MMessage, useMessage } from 'morya-ui'\n```\n\n## API\n\nThe first call auto-mounts a floating host; no template component is required.\n\n```vue preview src=\"./demos/Api.en.vue\"\n```\n\n## Custom content\n\n`content` (and Toast `summary` / `detail`) accepts a string, a VNode from `h()`, a component, or a `() => VNode` factory.\n\n```vue preview src=\"./demos/CustomContent.en.vue\"\n```\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `message.success(content \\| options)` | Success |\n| `message.info(content \\| options)` | Info |\n| `message.warn(content \\| options)` | Warn (`warning` alias) |\n| `message.error(content \\| options)` | Error |\n| `message.open(content \\| options)` | Open with options |\n| `message.close(id?)` | Close one / all |\n| `message.closeAll()` / `message.destroyAll()` | Close all (aliases of each other) |\n| `message.config({ placement, max })` | Host placement and concurrency cap |\n\nReturns `{ id, close }`.\n\n### MessageOptions\n\n| Field | Type | Default | Description |\n| --- | --- | --- | --- |\n| `content` | `string \\| number \\| VNode \\| Component \\| (() => VNodeChild)` | — | Body; a renderable value may also be passed directly |\n| `severity` | `'success' \\| 'info' \\| 'warn' \\| 'error' \\| 'secondary' \\| 'contrast'` | `'info'` | Tone |\n| `closable` | `boolean` | `false` | Show close button |\n| `life` | `number` | `3000` | Auto-close ms; `0` keeps open |\n| `icon` | `boolean` | `true` | Show severity icon |\n| `id` | `string \\| number` | auto | Unique key |\n\n## Optional host\n\nFor a custom `appendTo`, place this at the app root:\n\n```vue\n<MMessage append-to=\"body\" />\n```\n\nWhen a manual host exists, the API will not mount a second one.\n\n## Props (`MMessage`)\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `teleport` | `boolean` | `true` | Whether to Teleport |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target |\n| `placement` | `'top' \\| 'top-left' \\| 'top-right' \\| 'bottom' \\| 'bottom-left' \\| 'bottom-right'` | `'top'` | Host placement |\n| `max` | `number` | — | Max visible items; oldest is dropped |\n\n## Events\n\nThe `<MMessage />` host emits no Vue events. Use the `{ id, close }` return value from `message.*` APIs to control lifetime.\n\n## Slots\n\nNo slots; content is injected through the `message.*` API.\n"
13551
13903
  }
13552
13904
  }
13553
13905
  },
@@ -14003,7 +14355,7 @@
14003
14355
  {
14004
14356
  "id": "组合规则",
14005
14357
  "title": "组合规则",
14006
- "body": "| 场景 | 推荐组件 | 避免 |\n| --- | --- | --- |\n| 内容区垂直堆叠 | `MPageContent` | 手写 `gap` / `padding` |\n| 筛选区 | `MPageFilters` + `MSpace` / `MFlex` | 额外包一层 `MCard` |\n| 标题 + 主操作 | `MPageToolbar` | 裸 `div` + `justify-content` |\n| 页面说明 | `MPageHeader` | 无层级的裸 `h1` |\n| 表单主体 | `MPageSection variant=\"form\"` | 重复边框的 `MCard` 嵌套 |\n| 列表表格 | 直接放 `MTable` | `MCard` 再包 `MTable bordered` |\n| KPI | `MPageStat` | 每页自定义 stat CSS |\n| 图表占位 | `MPagePlaceholder` | dashed border 手写样式 |\n\n完整黄金样例见 `docs/golden-pages/`(MCP:`get_golden_page`)。**局部修改**时用 MCP `get_page_snippet`(如 `filters`、`toolbar`、`form-actions`)。"
14358
+ "body": "| 场景 | 推荐组件 | 避免 |\n| --- | --- | --- |\n| 内容区垂直堆叠 | `MPageContent` | 手写 `gap` / `padding` |\n| 筛选区 | `MPageFilters` + `MSpace` / `MFlex` | 额外包一层 `MCard` |\n| 标题 + 主操作 | `MPageToolbar` | 裸 `div` + `justify-content` |\n| 页面说明 | `MPageHeader` | 无层级的裸 `h1` |\n| 表单主体 | `MPageSection variant=\"form\"` | 重复边框的 `MCard` 嵌套 |\n| 列表表格 | 直接放 `MTable` | `MCard` 再包 `MTable bordered` |\n| KPI | `MPageStat` | 每页自定义 stat CSS |\n| 图表占位 | `MPagePlaceholder` | dashed border 手写样式 |\n\n完整黄金样例用 MCP `get_golden_page`。**局部修改**时用 MCP `get_page_snippet`(如 `filters`、`toolbar`、`form-actions`)。"
14007
14359
  },
14008
14360
  {
14009
14361
  "id": "api",
@@ -14011,7 +14363,7 @@
14011
14363
  "body": "### MPageContent\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `density` | `'default' \\| 'compact' \\| 'spacious'` | `'default'` | 子区块垂直间距。 |\n| `width` | `'full' \\| 'narrow'` | `'full'` | `narrow` 约 42rem,适合表单页。 |\n\n### MPageFilters\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `ariaLabel` | `string` | — | 筛选区无障碍名称。 |\n\n### MPageToolbar\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 无 `title` 时的左侧内容。 |\n| `actions` | 右侧操作区。 |\n\n### MPageHeader\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题。 |\n| `description` | `string` | — | 副标题/说明。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `actions` | 右侧操作。 |\n\n### MPageSection\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `variant` | `'default' \\| 'muted' \\| 'form' \\| 'actions'` | `'default'` | 视觉变体。 |\n| `title` | `string` | — | 可选分组标题。 |\n\n### MPageStat\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 指标名称。 |\n| `value` | `string \\| number` | — | 主数值。 |\n| `trend` | `string` | — | 变化量或说明。 |\n| `trendSeverity` | `'primary' \\| 'success' \\| 'warn' \\| 'danger' \\| 'secondary'` | `'primary'` | 趋势色。 |\n| `icon` | `string` | — | 右侧图标名。 |\n\n### MPagePlaceholder\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `description` | `string` | — | 占位说明。 |\n| `ariaLabel` | `string` | `'Placeholder'` | 无障碍标签。 |\n| `minHeight` | `number \\| string` | `'12rem'` | 最小高度。 |"
14012
14364
  }
14013
14365
  ],
14014
- "markdown": "---\ntitle: Page\ncategory: 06 / LAYOUT\ndescription: 业务页面组合区块,封装间距、边框与标题层级,少写或不写页面 CSS。\n---\n\n# Page\n\n业务页面组合组件。与 `MLayout` 搭配使用,把列表页筛选区、工具栏、表单分组、KPI 卡片等常见区块的间距和边框内聚到组件内,**优先用 Page 组件拼装页面,而不是每页手写 scoped CSS**。\n\n## 引入\n\n```ts\nimport {\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```\n\n## 列表页组合\n\n`MPageContent` 负责内容区 **padding**(默认 `--m-space-6`)与子区块 **gap**(默认 `--m-space-4`),文档预览中外框仅模拟 `MLayoutContent` 边界。\n\n```vue preview src=\"./demos/ListPageStack.zh.vue\"\n```\n\n## 表单页组合\n\n`MPageContent width=\"narrow\"` 限制表单宽度;`MPageSection variant=\"form\"` 提供表单表面;`variant=\"actions\"` 用于底栏操作。\n\n```vue preview src=\"./demos/Demo2.vue\"\n```\n\n## 仪表盘 KPI\n\n```vue preview src=\"./demos/Kpi.vue\"\n```\n\n## 组合规则\n\n| 场景 | 推荐组件 | 避免 |\n| --- | --- | --- |\n| 内容区垂直堆叠 | `MPageContent` | 手写 `gap` / `padding` |\n| 筛选区 | `MPageFilters` + `MSpace` / `MFlex` | 额外包一层 `MCard` |\n| 标题 + 主操作 | `MPageToolbar` | 裸 `div` + `justify-content` |\n| 页面说明 | `MPageHeader` | 无层级的裸 `h1` |\n| 表单主体 | `MPageSection variant=\"form\"` | 重复边框的 `MCard` 嵌套 |\n| 列表表格 | 直接放 `MTable` | `MCard` 再包 `MTable bordered` |\n| KPI | `MPageStat` | 每页自定义 stat CSS |\n| 图表占位 | `MPagePlaceholder` | dashed border 手写样式 |\n\n完整黄金样例见 `docs/golden-pages/`(MCP:`get_golden_page`)。**局部修改**时用 MCP `get_page_snippet`(如 `filters`、`toolbar`、`form-actions`)。\n\n## API\n\n### MPageContent\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `density` | `'default' \\| 'compact' \\| 'spacious'` | `'default'` | 子区块垂直间距。 |\n| `width` | `'full' \\| 'narrow'` | `'full'` | `narrow` 约 42rem,适合表单页。 |\n\n### MPageFilters\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `ariaLabel` | `string` | — | 筛选区无障碍名称。 |\n\n### MPageToolbar\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 无 `title` 时的左侧内容。 |\n| `actions` | 右侧操作区。 |\n\n### MPageHeader\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题。 |\n| `description` | `string` | — | 副标题/说明。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `actions` | 右侧操作。 |\n\n### MPageSection\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `variant` | `'default' \\| 'muted' \\| 'form' \\| 'actions'` | `'default'` | 视觉变体。 |\n| `title` | `string` | — | 可选分组标题。 |\n\n### MPageStat\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 指标名称。 |\n| `value` | `string \\| number` | — | 主数值。 |\n| `trend` | `string` | — | 变化量或说明。 |\n| `trendSeverity` | `'primary' \\| 'success' \\| 'warn' \\| 'danger' \\| 'secondary'` | `'primary'` | 趋势色。 |\n| `icon` | `string` | — | 右侧图标名。 |\n\n### MPagePlaceholder\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `description` | `string` | — | 占位说明。 |\n| `ariaLabel` | `string` | `'Placeholder'` | 无障碍标签。 |\n| `minHeight` | `number \\| string` | `'12rem'` | 最小高度。 |\n"
14366
+ "markdown": "---\ntitle: Page\ncategory: 06 / LAYOUT\ndescription: 业务页面组合区块,封装间距、边框与标题层级,少写或不写页面 CSS。\n---\n\n# Page\n\n业务页面组合组件。与 `MLayout` 搭配使用,把列表页筛选区、工具栏、表单分组、KPI 卡片等常见区块的间距和边框内聚到组件内,**优先用 Page 组件拼装页面,而不是每页手写 scoped CSS**。\n\n## 引入\n\n```ts\nimport {\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```\n\n## 列表页组合\n\n`MPageContent` 负责内容区 **padding**(默认 `--m-space-6`)与子区块 **gap**(默认 `--m-space-4`),文档预览中外框仅模拟 `MLayoutContent` 边界。\n\n```vue preview src=\"./demos/ListPageStack.zh.vue\"\n```\n\n## 表单页组合\n\n`MPageContent width=\"narrow\"` 限制表单宽度;`MPageSection variant=\"form\"` 提供表单表面;`variant=\"actions\"` 用于底栏操作。\n\n```vue preview src=\"./demos/Demo2.vue\"\n```\n\n## 仪表盘 KPI\n\n```vue preview src=\"./demos/Kpi.vue\"\n```\n\n## 组合规则\n\n| 场景 | 推荐组件 | 避免 |\n| --- | --- | --- |\n| 内容区垂直堆叠 | `MPageContent` | 手写 `gap` / `padding` |\n| 筛选区 | `MPageFilters` + `MSpace` / `MFlex` | 额外包一层 `MCard` |\n| 标题 + 主操作 | `MPageToolbar` | 裸 `div` + `justify-content` |\n| 页面说明 | `MPageHeader` | 无层级的裸 `h1` |\n| 表单主体 | `MPageSection variant=\"form\"` | 重复边框的 `MCard` 嵌套 |\n| 列表表格 | 直接放 `MTable` | `MCard` 再包 `MTable bordered` |\n| KPI | `MPageStat` | 每页自定义 stat CSS |\n| 图表占位 | `MPagePlaceholder` | dashed border 手写样式 |\n\n完整黄金样例用 MCP `get_golden_page`。**局部修改**时用 MCP `get_page_snippet`(如 `filters`、`toolbar`、`form-actions`)。\n\n## API\n\n### MPageContent\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `density` | `'default' \\| 'compact' \\| 'spacious'` | `'default'` | 子区块垂直间距。 |\n| `width` | `'full' \\| 'narrow'` | `'full'` | `narrow` 约 42rem,适合表单页。 |\n\n### MPageFilters\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `ariaLabel` | `string` | — | 筛选区无障碍名称。 |\n\n### MPageToolbar\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 无 `title` 时的左侧内容。 |\n| `actions` | 右侧操作区。 |\n\n### MPageHeader\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题。 |\n| `description` | `string` | — | 副标题/说明。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `actions` | 右侧操作。 |\n\n### MPageSection\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `variant` | `'default' \\| 'muted' \\| 'form' \\| 'actions'` | `'default'` | 视觉变体。 |\n| `title` | `string` | — | 可选分组标题。 |\n\n### MPageStat\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 指标名称。 |\n| `value` | `string \\| number` | — | 主数值。 |\n| `trend` | `string` | — | 变化量或说明。 |\n| `trendSeverity` | `'primary' \\| 'success' \\| 'warn' \\| 'danger' \\| 'secondary'` | `'primary'` | 趋势色。 |\n| `icon` | `string` | — | 右侧图标名。 |\n\n### MPagePlaceholder\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `description` | `string` | — | 占位说明。 |\n| `ariaLabel` | `string` | `'Placeholder'` | 无障碍标签。 |\n| `minHeight` | `number \\| string` | `'12rem'` | 最小高度。 |\n"
14015
14367
  },
14016
14368
  "en-US": {
14017
14369
  "title": "Page",
@@ -14040,10 +14392,10 @@
14040
14392
  {
14041
14393
  "id": "composition-rules",
14042
14394
  "title": "Composition rules",
14043
- "body": "| Scenario | Use | Avoid |\n| --- | --- | --- |\n| Vertical page stack | `MPageContent` | Hand-written `gap` / `padding` |\n| Filters | `MPageFilters` | Extra bordered `MCard` wrapper |\n| Title + actions | `MPageToolbar` | Raw flex divs |\n| Form surface | `MPageSection variant=\"form\"` | Nested bordered cards |\n| Data table | `MTable` directly | `MCard` around bordered table |\n| KPI metric | `MPageStat` | Custom stat CSS per page |\n\nGolden references: `docs/golden-pages/` (MCP: `get_golden_page`)."
14395
+ "body": "| Scenario | Use | Avoid |\n| --- | --- | --- |\n| Vertical page stack | `MPageContent` | Hand-written `gap` / `padding` |\n| Filters | `MPageFilters` | Extra bordered `MCard` wrapper |\n| Title + actions | `MPageToolbar` | Raw flex divs |\n| Form surface | `MPageSection variant=\"form\"` | Nested bordered cards |\n| Data table | `MTable` directly | `MCard` around bordered table |\n| KPI metric | `MPageStat` | Custom stat CSS per page |\n\nGolden references: MCP `get_golden_page`."
14044
14396
  }
14045
14397
  ],
14046
- "markdown": "---\ntitle: Page\ncategory: 06 / LAYOUT\ndescription: Composable page sections for spacing, borders, and headings with little or no custom CSS.\n---\n\n# Page\n\nPage composition components. Use them with `MLayout` to encode filter bars, toolbars, form surfaces, KPI cards, and other admin-page blocks **without rewriting scoped CSS on every page**.\n\n## Import\n\n```ts\nimport {\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```\n\n## List page stack\n\n`MPageContent` owns content **padding** (default `--m-space-6`) and section **gap** (default `--m-space-4`). The bordered frame in previews simulates `MLayoutContent` only.\n\n```vue preview src=\"./demos/ListPageStack.en.vue\"\n```\n\n## Form page stack\n\nUse `MPageContent width=\"narrow\"`, `MPageSection variant=\"form\"`, and `variant=\"actions\"` for the footer.\n\n## Composition rules\n\n| Scenario | Use | Avoid |\n| --- | --- | --- |\n| Vertical page stack | `MPageContent` | Hand-written `gap` / `padding` |\n| Filters | `MPageFilters` | Extra bordered `MCard` wrapper |\n| Title + actions | `MPageToolbar` | Raw flex divs |\n| Form surface | `MPageSection variant=\"form\"` | Nested bordered cards |\n| Data table | `MTable` directly | `MCard` around bordered table |\n| KPI metric | `MPageStat` | Custom stat CSS per page |\n\nGolden references: `docs/golden-pages/` (MCP: `get_golden_page`).\n"
14398
+ "markdown": "---\ntitle: Page\ncategory: 06 / LAYOUT\ndescription: Composable page sections for spacing, borders, and headings with little or no custom CSS.\n---\n\n# Page\n\nPage composition components. Use them with `MLayout` to encode filter bars, toolbars, form surfaces, KPI cards, and other admin-page blocks **without rewriting scoped CSS on every page**.\n\n## Import\n\n```ts\nimport {\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```\n\n## List page stack\n\n`MPageContent` owns content **padding** (default `--m-space-6`) and section **gap** (default `--m-space-4`). The bordered frame in previews simulates `MLayoutContent` only.\n\n```vue preview src=\"./demos/ListPageStack.en.vue\"\n```\n\n## Form page stack\n\nUse `MPageContent width=\"narrow\"`, `MPageSection variant=\"form\"`, and `variant=\"actions\"` for the footer.\n\n## Composition rules\n\n| Scenario | Use | Avoid |\n| --- | --- | --- |\n| Vertical page stack | `MPageContent` | Hand-written `gap` / `padding` |\n| Filters | `MPageFilters` | Extra bordered `MCard` wrapper |\n| Title + actions | `MPageToolbar` | Raw flex divs |\n| Form surface | `MPageSection variant=\"form\"` | Nested bordered cards |\n| Data table | `MTable` directly | `MCard` around bordered table |\n| KPI metric | `MPageStat` | Custom stat CSS per page |\n\nGolden references: MCP `get_golden_page`.\n"
14047
14399
  }
14048
14400
  }
14049
14401
  },
@@ -16067,7 +16419,7 @@
16067
16419
  "sectionId": "尺寸",
16068
16420
  "lang": "vue",
16069
16421
  "preview": true,
16070
- "code": "<script setup lang=\"ts\">\r\nimport { MButton, MResult } from 'morya-ui'\r\n</script>\r\n\r\n<template>\r\n <div class=\"grid gap-6\" style=\"grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\">\r\n <MResult\r\n size=\"small\"\r\n status=\"success\"\r\n title=\"保存成功\"\r\n >\r\n <template #footer>\r\n <MButton\r\n label=\"知道了\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n />\r\n </template>\r\n </MResult>\r\n <MResult\r\n size=\"small\"\r\n status=\"error\"\r\n title=\"上传失败\"\r\n >\r\n <template #footer>\r\n <MButton\r\n label=\"重试\"\r\n size=\"small\"\r\n />\r\n </template>\r\n </MResult>\r\n </div>\r\n</template>",
16422
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MResult } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-6\" style=\"grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\">\n <MResult\n size=\"small\"\n status=\"success\"\n title=\"保存成功\"\n >\n <template #footer>\n <MButton\n label=\"知道了\"\n size=\"small\"\n severity=\"secondary\"\n />\n </template>\n </MResult>\n <MResult\n size=\"small\"\n status=\"error\"\n title=\"上传失败\"\n >\n <template #footer>\n <MButton\n label=\"重试\"\n size=\"small\"\n />\n </template>\n </MResult>\n </div>\n</template>",
16071
16423
  "locale": "zh-CN"
16072
16424
  },
16073
16425
  {
@@ -16112,7 +16464,7 @@
16112
16464
  "sectionId": "size",
16113
16465
  "lang": "vue",
16114
16466
  "preview": true,
16115
- "code": "<script setup lang=\"ts\">\r\nimport { MButton, MResult } from 'morya-ui'\r\n</script>\r\n\r\n<template>\r\n <div class=\"grid gap-6\" style=\"grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\">\r\n <MResult\r\n size=\"small\"\r\n status=\"success\"\r\n title=\"Saved\"\r\n >\r\n <template #footer>\r\n <MButton\r\n label=\"OK\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n />\r\n </template>\r\n </MResult>\r\n <MResult\r\n size=\"small\"\r\n status=\"error\"\r\n title=\"Upload failed\"\r\n >\r\n <template #footer>\r\n <MButton\r\n label=\"Retry\"\r\n size=\"small\"\r\n />\r\n </template>\r\n </MResult>\r\n </div>\r\n</template>",
16467
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MResult } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-6\" style=\"grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\">\n <MResult\n size=\"small\"\n status=\"success\"\n title=\"Saved\"\n >\n <template #footer>\n <MButton\n label=\"OK\"\n size=\"small\"\n severity=\"secondary\"\n />\n </template>\n </MResult>\n <MResult\n size=\"small\"\n status=\"error\"\n title=\"Upload failed\"\n >\n <template #footer>\n <MButton\n label=\"Retry\"\n size=\"small\"\n />\n </template>\n </MResult>\n </div>\n</template>",
16116
16468
  "locale": "en-US"
16117
16469
  }
16118
16470
  ],
@@ -19473,7 +19825,7 @@
19473
19825
  "sectionId": "标签-纯文字-自定义图标",
19474
19826
  "lang": "vue",
19475
19827
  "preview": true,
19476
- "code": "<script setup lang=\"ts\">\r\nimport { MStatus } from 'morya-ui'\r\n</script>\r\n\r\n<template>\r\n <div class=\"grid gap-4\">\r\n <div class=\"flex flex-wrap gap-4 items-center\">\r\n <MStatus label=\"已完成\" severity=\"success\" variant=\"tag\" />\r\n <MStatus label=\"运行中\" severity=\"info\" variant=\"tag\" processing />\r\n <MStatus label=\"待审核\" severity=\"warn\" variant=\"tag\" />\r\n <MStatus label=\"失败\" severity=\"danger\" variant=\"tag\" />\r\n <MStatus label=\"已归档\" variant=\"tag\" />\r\n <MStatus label=\"已禁用\" variant=\"tag\" disabled />\r\n </div>\r\n <div class=\"flex flex-wrap gap-4 items-center\">\r\n <MStatus label=\"自定义图标\" severity=\"success\" icon=\"check\" />\r\n <MStatus label=\"已完成\" severity=\"success\" variant=\"text\" />\r\n <MStatus label=\"同步中…\" severity=\"info\" variant=\"text\" />\r\n <MStatus label=\"—\" variant=\"text\" />\r\n </div>\r\n </div>\r\n</template>",
19828
+ "code": "<script setup lang=\"ts\">\nimport { MStatus } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-4\">\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MStatus label=\"已完成\" severity=\"success\" variant=\"tag\" />\n <MStatus label=\"运行中\" severity=\"info\" variant=\"tag\" processing />\n <MStatus label=\"待审核\" severity=\"warn\" variant=\"tag\" />\n <MStatus label=\"失败\" severity=\"danger\" variant=\"tag\" />\n <MStatus label=\"已归档\" variant=\"tag\" />\n <MStatus label=\"已禁用\" variant=\"tag\" disabled />\n </div>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MStatus label=\"自定义图标\" severity=\"success\" icon=\"check\" />\n <MStatus label=\"已完成\" severity=\"success\" variant=\"text\" />\n <MStatus label=\"同步中…\" severity=\"info\" variant=\"text\" />\n <MStatus label=\"—\" variant=\"text\" />\n </div>\n </div>\n</template>",
19477
19829
  "locale": "zh-CN"
19478
19830
  },
19479
19831
  {
@@ -19518,7 +19870,7 @@
19518
19870
  "sectionId": "tag-text-custom-icon",
19519
19871
  "lang": "vue",
19520
19872
  "preview": true,
19521
- "code": "<script setup lang=\"ts\">\r\nimport { MStatus } from 'morya-ui'\r\n</script>\r\n\r\n<template>\r\n <div class=\"grid gap-4\">\r\n <div class=\"flex flex-wrap gap-4 items-center\">\r\n <MStatus label=\"已完成\" severity=\"success\" variant=\"tag\" />\r\n <MStatus label=\"运行中\" severity=\"info\" variant=\"tag\" processing />\r\n <MStatus label=\"待审核\" severity=\"warn\" variant=\"tag\" />\r\n <MStatus label=\"失败\" severity=\"danger\" variant=\"tag\" />\r\n <MStatus label=\"已归档\" variant=\"tag\" />\r\n <MStatus label=\"已禁用\" variant=\"tag\" disabled />\r\n </div>\r\n <div class=\"flex flex-wrap gap-4 items-center\">\r\n <MStatus label=\"自定义图标\" severity=\"success\" icon=\"check\" />\r\n <MStatus label=\"已完成\" severity=\"success\" variant=\"text\" />\r\n <MStatus label=\"同步中…\" severity=\"info\" variant=\"text\" />\r\n <MStatus label=\"—\" variant=\"text\" />\r\n </div>\r\n </div>\r\n</template>",
19873
+ "code": "<script setup lang=\"ts\">\nimport { MStatus } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-4\">\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MStatus label=\"已完成\" severity=\"success\" variant=\"tag\" />\n <MStatus label=\"运行中\" severity=\"info\" variant=\"tag\" processing />\n <MStatus label=\"待审核\" severity=\"warn\" variant=\"tag\" />\n <MStatus label=\"失败\" severity=\"danger\" variant=\"tag\" />\n <MStatus label=\"已归档\" variant=\"tag\" />\n <MStatus label=\"已禁用\" variant=\"tag\" disabled />\n </div>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MStatus label=\"自定义图标\" severity=\"success\" icon=\"check\" />\n <MStatus label=\"已完成\" severity=\"success\" variant=\"text\" />\n <MStatus label=\"同步中…\" severity=\"info\" variant=\"text\" />\n <MStatus label=\"—\" variant=\"text\" />\n </div>\n </div>\n</template>",
19522
19874
  "locale": "en-US"
19523
19875
  }
19524
19876
  ],
@@ -21240,7 +21592,7 @@
21240
21592
  "body": "<h4 id=\"TabItem\">TabItem</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface TabItem {\n label: string\n value: string\n disabled?: boolean\n /** When set, overrides the Tabs `closable` prop for this item. */\n closable?: boolean\n}\n```"
21241
21593
  }
21242
21594
  ],
21243
- "markdown": "---\ntitle: Tabs\ncategory: 04 / NAVIGATION\ndescription: 标签页切换。支持 line/card、关闭/新增、extra 与溢出滚动。\n---\n\n# Tabs\n\n标签页用于在同一视图内切换内容分区。\n\n## 引入\n\n```ts\nimport { MTabs } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Card / closable / extra\n\n```vue preview src=\"./demos/CardClosableExtra.zh.vue\"\n```\n\n标签过多超出容器时,两端会出现滚动按钮。\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `string` | — | 当前活动 tab。 |\n| `tabs` | `TabItem[]` | — | 标签列表;支持 `disabled` / `closable`。 |\n| `type` | `'line' \\| 'card'` | `'line'` | 外观。 |\n| `closable` | `boolean` | `false` | 显示关闭按钮;单项 `closable` 优先。 |\n| `addable` | `boolean` | `false` | 显示新增按钮。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `string` | 活动项变化。 |\n| `change` | `string` | 切换完成。 |\n| `close` | `string` | 点击关闭。 |\n| `add` | — | 点击新增。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 面板内容,作用域 `{ activeValue }`。 |\n| `extra` | 标签栏右侧额外内容。 |\n\n## 类型\n\n<h4 id=\"TabItem\">TabItem</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface TabItem {\r\n label: string\r\n value: string\r\n disabled?: boolean\r\n /** When set, overrides the Tabs `closable` prop for this item. */\r\n closable?: boolean\r\n}\n```\n"
21595
+ "markdown": "---\ntitle: Tabs\ncategory: 04 / NAVIGATION\ndescription: 标签页切换。支持 line/card、关闭/新增、extra 与溢出滚动。\n---\n\n# Tabs\n\n标签页用于在同一视图内切换内容分区。\n\n## 引入\n\n```ts\nimport { MTabs } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Card / closable / extra\n\n```vue preview src=\"./demos/CardClosableExtra.zh.vue\"\n```\n\n标签过多超出容器时,两端会出现滚动按钮。\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `string` | — | 当前活动 tab。 |\n| `tabs` | `TabItem[]` | — | 标签列表;支持 `disabled` / `closable`。 |\n| `type` | `'line' \\| 'card'` | `'line'` | 外观。 |\n| `closable` | `boolean` | `false` | 显示关闭按钮;单项 `closable` 优先。 |\n| `addable` | `boolean` | `false` | 显示新增按钮。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `string` | 活动项变化。 |\n| `change` | `string` | 切换完成。 |\n| `close` | `string` | 点击关闭。 |\n| `add` | — | 点击新增。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 面板内容,作用域 `{ activeValue }`。 |\n| `extra` | 标签栏右侧额外内容。 |\n\n## 类型\n\n<h4 id=\"TabItem\">TabItem</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface TabItem {\n label: string\n value: string\n disabled?: boolean\n /** When set, overrides the Tabs `closable` prop for this item. */\n closable?: boolean\n}\n```\n"
21244
21596
  },
21245
21597
  "en-US": {
21246
21598
  "title": "Tabs",
@@ -21287,7 +21639,7 @@
21287
21639
  "body": "<h4 id=\"TabItem\">TabItem</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface TabItem {\n label: string\n value: string\n disabled?: boolean\n /** When set, overrides the Tabs `closable` prop for this item. */\n closable?: boolean\n}\n```"
21288
21640
  }
21289
21641
  ],
21290
- "markdown": "---\ntitle: Tabs\ncategory: 04 / NAVIGATION\ndescription: Tab switcher with line/card types, closable/addable tabs, extra slot, and overflow scrolling.\n---\n\n# Tabs\n\nTabs switch content panels within the same view.\n\n## Import\n\n```ts\nimport { MTabs } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Card / closable / extra\n\n```vue preview src=\"./demos/CardClosableExtra.en.vue\"\n```\n\nWhen tabs overflow the container, scroll buttons appear at both ends.\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `string` | — | Currently active tab. |\n| `tabs` | `TabItem[]` | — | Tab list; supports `disabled` / `closable`. |\n| `type` | `'line' \\| 'card'` | `'line'` | Appearance. |\n| `closable` | `boolean` | `false` | Show close buttons; per-item `closable` wins. |\n| `addable` | `boolean` | `false` | Show an add button. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `update:modelValue` | `string` | Emitted when the active item changes. |\n| `change` | `string` | Emitted after the switch completes. |\n| `close` | `string` | Emitted when a close button is clicked. |\n| `add` | — | Emitted when the add button is clicked. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Panel content; scoped slot `{ activeValue }`. |\n| `extra` | Extra content on the right of the tab bar. |\n\n## Types\n\n<h4 id=\"TabItem\">TabItem</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface TabItem {\r\n label: string\r\n value: string\r\n disabled?: boolean\r\n /** When set, overrides the Tabs `closable` prop for this item. */\r\n closable?: boolean\r\n}\n```\n"
21642
+ "markdown": "---\ntitle: Tabs\ncategory: 04 / NAVIGATION\ndescription: Tab switcher with line/card types, closable/addable tabs, extra slot, and overflow scrolling.\n---\n\n# Tabs\n\nTabs switch content panels within the same view.\n\n## Import\n\n```ts\nimport { MTabs } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Card / closable / extra\n\n```vue preview src=\"./demos/CardClosableExtra.en.vue\"\n```\n\nWhen tabs overflow the container, scroll buttons appear at both ends.\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `string` | — | Currently active tab. |\n| `tabs` | `TabItem[]` | — | Tab list; supports `disabled` / `closable`. |\n| `type` | `'line' \\| 'card'` | `'line'` | Appearance. |\n| `closable` | `boolean` | `false` | Show close buttons; per-item `closable` wins. |\n| `addable` | `boolean` | `false` | Show an add button. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `update:modelValue` | `string` | Emitted when the active item changes. |\n| `change` | `string` | Emitted after the switch completes. |\n| `close` | `string` | Emitted when a close button is clicked. |\n| `add` | — | Emitted when the add button is clicked. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Panel content; scoped slot `{ activeValue }`. |\n| `extra` | Extra content on the right of the tab bar. |\n\n## Types\n\n<h4 id=\"TabItem\">TabItem</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface TabItem {\n label: string\n value: string\n disabled?: boolean\n /** When set, overrides the Tabs `closable` prop for this item. */\n closable?: boolean\n}\n```\n"
21291
21643
  }
21292
21644
  }
21293
21645
  },
@@ -22815,7 +23167,7 @@
22815
23167
  {
22816
23168
  "id": "overview",
22817
23169
  "title": "",
22818
- "body": "# Toast\n\n带标题 / 详情的四角通知。可用 `toast` API,或继续用 `:messages` 受控渲染。\n\n与 [Message](/components/Message) 的分工:Message 是**默认**的轻量单行反馈;Toast 仅在需要 `summary` / `detail` 或角落通知时使用。受控 `:messages` 时请自行限制条数,`max` 只作用于服务队列。\n\n> AI / 业务代码选型细则见 [`feedback-message-vs-toast.md`](../../../../design-kit/docs/feedback-message-vs-toast.md)。\n\n**不要**用 `toast.add({ summary: '已保存' })` 代替 `message.success('已保存')`。"
23170
+ "body": "# Toast\n\n带标题 / 详情的四角通知。可用 `toast` API,或继续用 `:messages` 受控渲染。\n\n与 [Message](/components/Message) 的分工:Message 是**默认**的轻量单行反馈;Toast 仅在需要 `summary` / `detail` 或角落通知时使用。受控 `:messages` 时请自行限制条数,`max` 只作用于服务队列。\n\n> AI / 业务代码选型细则见 [`feedback.md`](../../../../design-kit/.agents/skills/morya-ui-pages/references/feedback.md)。\n\n**不要**用 `toast.add({ summary: '已保存' })` 代替 `message.success('已保存')`。"
22819
23171
  },
22820
23172
  {
22821
23173
  "id": "引入",
@@ -22863,7 +23215,7 @@
22863
23215
  "body": "<h4 id=\"ToastMessage\">ToastMessage</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface ToastMessage {\n id: string | number\n summary: MRenderable\n detail?: MRenderable\n severity?: ToastSeverity\n closable?: boolean\n /** Auto-close delay in ms. `0` keeps it open. Default `3000` for API calls. */\n life?: number\n}\n```"
22864
23216
  }
22865
23217
  ],
22866
- "markdown": "---\ntitle: Toast\ncategory: 05 / FEEDBACK\ndescription: 四角浮层通知,支持 API 与受控列表。\n---\n\n# Toast\n\n带标题 / 详情的四角通知。可用 `toast` API,或继续用 `:messages` 受控渲染。\n\n与 [Message](/components/Message) 的分工:Message 是**默认**的轻量单行反馈;Toast 仅在需要 `summary` / `detail` 或角落通知时使用。受控 `:messages` 时请自行限制条数,`max` 只作用于服务队列。\n\n> AI / 业务代码选型细则见 [`feedback-message-vs-toast.md`](../../../../design-kit/docs/feedback-message-vs-toast.md)。\n\n**不要**用 `toast.add({ summary: '已保存' })` 代替 `message.success('已保存')`。\n\n## 引入\n\n```ts\nimport { MToast, toast, useToast } from 'morya-ui'\n```\n\n## API\n\n```vue preview src=\"./demos/Api.zh.vue\"\n```\n\n## 自定义内容\n\n`summary` / `detail` 同样支持字符串、`h()`、组件或渲染工厂。\n\n```vue preview src=\"./demos/CustomContent.zh.vue\"\n```\n\n## Controlled\n\n仍可通过 `messages` + `close` 自行管理列表。\n\n```vue preview src=\"./demos/Controlled.vue\"\n```\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `toast.success / info / warn / error` | 按语义添加 |\n| `toast.add(options)` | 添加一条 |\n| `toast.remove(id)` / `toast.close(id)` | 移除 |\n| `toast.clear()` / `toast.closeAll()` / `toast.destroyAll()` | 清空 |\n| `toast.setDefaults({ position, max })` | 默认角落位置与并发上限 |\n\n字符串入参视为 `summary`。默认 `life` 为 `3000`;`0` 表示不自动关闭。\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `messages` | `ToastMessage[]` | — | 受控列表;省略则绑定 `toast` 服务队列 |\n| `position` | `'top-right' \\| 'top-left' \\| 'bottom-right' \\| 'bottom-left'` | `'top-right'` | 容器定位 |\n| `max` | `number` | — | 同时可见条数;超出丢掉最旧一条(仅服务队列) |\n| `teleport` | `boolean` | `true` | 浮层 Teleport |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标 |\n| `auto` | `boolean` | — | — |\n\n### ToastMessage\n\n| 字段 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `id` | `string \\| number` | — | 唯一键 |\n| `summary` | `string \\| number \\| VNode \\| Component \\| (() => VNodeChild)` | — | 标题 |\n| `detail` | 同上 | — | 详情 |\n| `severity` | `'success' \\| 'info' \\| 'warn' \\| 'error' \\| …` | `'info'` | 语义色 |\n| `closable` | `boolean` | `true` | 关闭按钮 |\n| `life` | `number` | API 默认 `3000` | 自动关闭毫秒 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `close` | `ToastMessage` | 点击关闭;受控模式下由调用方移除 |\n\n## Slots\n\n无插槽;通过 `messages` prop 或 toast API 驱动。\n\n## 类型\n\n<h4 id=\"ToastMessage\">ToastMessage</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface ToastMessage {\r\n id: string | number\r\n summary: MRenderable\r\n detail?: MRenderable\r\n severity?: ToastSeverity\r\n closable?: boolean\r\n /** Auto-close delay in ms. `0` keeps it open. Default `3000` for API calls. */\r\n life?: number\r\n}\n```\n"
23218
+ "markdown": "---\ntitle: Toast\ncategory: 05 / FEEDBACK\ndescription: 四角浮层通知,支持 API 与受控列表。\n---\n\n# Toast\n\n带标题 / 详情的四角通知。可用 `toast` API,或继续用 `:messages` 受控渲染。\n\n与 [Message](/components/Message) 的分工:Message 是**默认**的轻量单行反馈;Toast 仅在需要 `summary` / `detail` 或角落通知时使用。受控 `:messages` 时请自行限制条数,`max` 只作用于服务队列。\n\n> AI / 业务代码选型细则见 [`feedback.md`](../../../../design-kit/.agents/skills/morya-ui-pages/references/feedback.md)。\n\n**不要**用 `toast.add({ summary: '已保存' })` 代替 `message.success('已保存')`。\n\n## 引入\n\n```ts\nimport { MToast, toast, useToast } from 'morya-ui'\n```\n\n## API\n\n```vue preview src=\"./demos/Api.zh.vue\"\n```\n\n## 自定义内容\n\n`summary` / `detail` 同样支持字符串、`h()`、组件或渲染工厂。\n\n```vue preview src=\"./demos/CustomContent.zh.vue\"\n```\n\n## Controlled\n\n仍可通过 `messages` + `close` 自行管理列表。\n\n```vue preview src=\"./demos/Controlled.vue\"\n```\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `toast.success / info / warn / error` | 按语义添加 |\n| `toast.add(options)` | 添加一条 |\n| `toast.remove(id)` / `toast.close(id)` | 移除 |\n| `toast.clear()` / `toast.closeAll()` / `toast.destroyAll()` | 清空 |\n| `toast.setDefaults({ position, max })` | 默认角落位置与并发上限 |\n\n字符串入参视为 `summary`。默认 `life` 为 `3000`;`0` 表示不自动关闭。\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `messages` | `ToastMessage[]` | — | 受控列表;省略则绑定 `toast` 服务队列 |\n| `position` | `'top-right' \\| 'top-left' \\| 'bottom-right' \\| 'bottom-left'` | `'top-right'` | 容器定位 |\n| `max` | `number` | — | 同时可见条数;超出丢掉最旧一条(仅服务队列) |\n| `teleport` | `boolean` | `true` | 浮层 Teleport |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标 |\n| `auto` | `boolean` | — | — |\n\n### ToastMessage\n\n| 字段 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `id` | `string \\| number` | — | 唯一键 |\n| `summary` | `string \\| number \\| VNode \\| Component \\| (() => VNodeChild)` | — | 标题 |\n| `detail` | 同上 | — | 详情 |\n| `severity` | `'success' \\| 'info' \\| 'warn' \\| 'error' \\| …` | `'info'` | 语义色 |\n| `closable` | `boolean` | `true` | 关闭按钮 |\n| `life` | `number` | API 默认 `3000` | 自动关闭毫秒 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `close` | `ToastMessage` | 点击关闭;受控模式下由调用方移除 |\n\n## Slots\n\n无插槽;通过 `messages` prop 或 toast API 驱动。\n\n## 类型\n\n<h4 id=\"ToastMessage\">ToastMessage</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface ToastMessage {\n id: string | number\n summary: MRenderable\n detail?: MRenderable\n severity?: ToastSeverity\n closable?: boolean\n /** Auto-close delay in ms. `0` keeps it open. Default `3000` for API calls. */\n life?: number\n}\n```\n"
22867
23219
  },
22868
23220
  "en-US": {
22869
23221
  "title": "Toast",
@@ -22872,7 +23224,7 @@
22872
23224
  {
22873
23225
  "id": "overview",
22874
23226
  "title": "",
22875
- "body": "# Toast\n\nCorner notifications with a title and optional detail. Use the `toast` API, or keep rendering with a controlled `:messages` list.\n\nVs [Message](/components/Message): Message is the **default** for short single-line feedback; Toast is for `summary` / `detail` or corner notifications. `max` applies to the service queue only.\n\n> Selection guide: [`feedback-message-vs-toast.md`](../../../../design-kit/docs/feedback-message-vs-toast.md).\n\nDo **not** use `toast.add({ summary: 'Saved' })` when `message.success('Saved')` is enough."
23227
+ "body": "# Toast\n\nCorner notifications with a title and optional detail. Use the `toast` API, or keep rendering with a controlled `:messages` list.\n\nVs [Message](/components/Message): Message is the **default** for short single-line feedback; Toast is for `summary` / `detail` or corner notifications. `max` applies to the service queue only.\n\n> Selection guide: [`feedback.md`](../../../../design-kit/.agents/skills/morya-ui-pages/references/feedback.md).\n\nDo **not** use `toast.add({ summary: 'Saved' })` when `message.success('Saved')` is enough."
22876
23228
  },
22877
23229
  {
22878
23230
  "id": "import",
@@ -22920,7 +23272,7 @@
22920
23272
  "body": "<h4 id=\"ToastMessage\">ToastMessage</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface ToastMessage {\n id: string | number\n summary: MRenderable\n detail?: MRenderable\n severity?: ToastSeverity\n closable?: boolean\n /** Auto-close delay in ms. `0` keeps it open. Default `3000` for API calls. */\n life?: number\n}\n```"
22921
23273
  }
22922
23274
  ],
22923
- "markdown": "---\ntitle: Toast\ncategory: 05 / FEEDBACK\ndescription: Corner floating notifications with API and controlled lists.\n---\n\n# Toast\n\nCorner notifications with a title and optional detail. Use the `toast` API, or keep rendering with a controlled `:messages` list.\n\nVs [Message](/components/Message): Message is the **default** for short single-line feedback; Toast is for `summary` / `detail` or corner notifications. `max` applies to the service queue only.\n\n> Selection guide: [`feedback-message-vs-toast.md`](../../../../design-kit/docs/feedback-message-vs-toast.md).\n\nDo **not** use `toast.add({ summary: 'Saved' })` when `message.success('Saved')` is enough.\n\n## Import\n\n```ts\nimport { MToast, toast, useToast } from 'morya-ui'\n```\n\n## API\n\n```vue preview src=\"./demos/Api.en.vue\"\n```\n\n## Custom content\n\n`summary` / `detail` also accept strings, `h()` VNodes, components, or render factories.\n\n```vue preview src=\"./demos/CustomContent.en.vue\"\n```\n\n## Controlled\n\nYou can still manage the list yourself with `messages` + `close`.\n\n```vue preview src=\"./demos/Controlled.vue\"\n```\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `toast.success / info / warn / error` | Add by severity |\n| `toast.add(options)` | Add one |\n| `toast.remove(id)` / `toast.close(id)` | Remove |\n| `toast.clear()` / `toast.closeAll()` / `toast.destroyAll()` | Clear all |\n| `toast.setDefaults({ position, max })` | Default corner and concurrency cap |\n\nA string argument is treated as `summary`. Default `life` is `3000`; use `0` to keep open.\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `messages` | `ToastMessage[]` | — | Controlled list; omit to bind the `toast` service queue |\n| `position` | `'top-right' \\| 'top-left' \\| 'bottom-right' \\| 'bottom-left'` | `'top-right'` | Container placement |\n| `max` | `number` | — | Max visible items; oldest is dropped (service queue only) |\n| `teleport` | `boolean` | `true` | Whether to Teleport |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target |\n\n### ToastMessage\n\n| Field | Type | Default | Description |\n| --- | --- | --- | --- |\n| `id` | `string \\| number` | — | Unique key |\n| `summary` | `string \\| number \\| VNode \\| Component \\| (() => VNodeChild)` | — | Title |\n| `detail` | same as above | — | Detail |\n| `severity` | `'success' \\| 'info' \\| 'warn' \\| 'error' \\| …` | `'info'` | Tone |\n| `closable` | `boolean` | `true` | Close button |\n| `life` | `number` | API default `3000` | Auto-close ms |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `close` | `ToastMessage` | Close clicked; remove it yourself in controlled mode |\n\n## Slots\n\nNo slots; driven by the `messages` prop or toast API.\n\n## Types\n\n<h4 id=\"ToastMessage\">ToastMessage</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface ToastMessage {\r\n id: string | number\r\n summary: MRenderable\r\n detail?: MRenderable\r\n severity?: ToastSeverity\r\n closable?: boolean\r\n /** Auto-close delay in ms. `0` keeps it open. Default `3000` for API calls. */\r\n life?: number\r\n}\n```\n"
23275
+ "markdown": "---\ntitle: Toast\ncategory: 05 / FEEDBACK\ndescription: Corner floating notifications with API and controlled lists.\n---\n\n# Toast\n\nCorner notifications with a title and optional detail. Use the `toast` API, or keep rendering with a controlled `:messages` list.\n\nVs [Message](/components/Message): Message is the **default** for short single-line feedback; Toast is for `summary` / `detail` or corner notifications. `max` applies to the service queue only.\n\n> Selection guide: [`feedback.md`](../../../../design-kit/.agents/skills/morya-ui-pages/references/feedback.md).\n\nDo **not** use `toast.add({ summary: 'Saved' })` when `message.success('Saved')` is enough.\n\n## Import\n\n```ts\nimport { MToast, toast, useToast } from 'morya-ui'\n```\n\n## API\n\n```vue preview src=\"./demos/Api.en.vue\"\n```\n\n## Custom content\n\n`summary` / `detail` also accept strings, `h()` VNodes, components, or render factories.\n\n```vue preview src=\"./demos/CustomContent.en.vue\"\n```\n\n## Controlled\n\nYou can still manage the list yourself with `messages` + `close`.\n\n```vue preview src=\"./demos/Controlled.vue\"\n```\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `toast.success / info / warn / error` | Add by severity |\n| `toast.add(options)` | Add one |\n| `toast.remove(id)` / `toast.close(id)` | Remove |\n| `toast.clear()` / `toast.closeAll()` / `toast.destroyAll()` | Clear all |\n| `toast.setDefaults({ position, max })` | Default corner and concurrency cap |\n\nA string argument is treated as `summary`. Default `life` is `3000`; use `0` to keep open.\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `messages` | `ToastMessage[]` | — | Controlled list; omit to bind the `toast` service queue |\n| `position` | `'top-right' \\| 'top-left' \\| 'bottom-right' \\| 'bottom-left'` | `'top-right'` | Container placement |\n| `max` | `number` | — | Max visible items; oldest is dropped (service queue only) |\n| `teleport` | `boolean` | `true` | Whether to Teleport |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target |\n\n### ToastMessage\n\n| Field | Type | Default | Description |\n| --- | --- | --- | --- |\n| `id` | `string \\| number` | — | Unique key |\n| `summary` | `string \\| number \\| VNode \\| Component \\| (() => VNodeChild)` | — | Title |\n| `detail` | same as above | — | Detail |\n| `severity` | `'success' \\| 'info' \\| 'warn' \\| 'error' \\| …` | `'info'` | Tone |\n| `closable` | `boolean` | `true` | Close button |\n| `life` | `number` | API default `3000` | Auto-close ms |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `close` | `ToastMessage` | Close clicked; remove it yourself in controlled mode |\n\n## Slots\n\nNo slots; driven by the `messages` prop or toast API.\n\n## Types\n\n<h4 id=\"ToastMessage\">ToastMessage</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface ToastMessage {\n id: string | number\n summary: MRenderable\n detail?: MRenderable\n severity?: ToastSeverity\n closable?: boolean\n /** Auto-close delay in ms. `0` keeps it open. Default `3000` for API calls. */\n life?: number\n}\n```\n"
22924
23276
  }
22925
23277
  }
22926
23278
  },
@@ -24745,7 +25097,7 @@
24745
25097
  "zh-CN": {
24746
25098
  "title": "快速上手",
24747
25099
  "description": "安装依赖、引入样式,并渲染第一个组件。",
24748
- "markdown": "---\ntitle: 快速上手\norder: 2\ndescription: 安装依赖、引入样式,并渲染第一个组件。\n---\n\n# 快速上手\n\n> 在线文档:[morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/) · 源码:[GitHub](https://github.com/morya-space/morya-ui) · npm:[`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## 安装\n\n**在应用项目中(npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\n也可以用:\n\n```bash\nnpx @morya-ui/setup app\n```\n\n会安装依赖,并尽量在入口注入样式。更多命令与选项见 [一键接入](/docs/setup)。需要 Vue 3(推荐 3.5 及以上)。主题 token、亮暗切换与动效 API 均包含在 `morya-ui` 中。Agent Skill / MCP 见 [AI 接入](/docs/ai-setup)。\n\n## 选择使用方式\n\n本库同时支持**全量**与**按需**两种消费方式,按项目需求任选其一(同一应用内建议保持一致)。\n\n| | 全量 | 按需 |\n| --- | --- | --- |\n| 典型场景 | 组件用得较多、希望快速上手 | 打包体积敏感、只用少量组件 |\n| 组件来源 | `app.use(MoryaUI)` 或 `morya-ui` 按名导入 | `morya-ui/button` 等子路径,或 Vite 自动解析 |\n| 样式 | 入口引入 `morya-ui/styles.css` | 子路径自动带入(含 theme + 依赖组件样式) |\n| JS 体积 | 全量注册会打入完整组件;按名导入可 tree-shake | 仅打入用到的组件及其依赖 |\n\n## 全量用法\n\n### 1. 插件注册(推荐的全量方式)\n\n在应用入口引入**全量样式**,并通过插件一次注册所有组件:\n\n```ts\nimport MoryaUI from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).use(MoryaUI).mount('#app')\n```\n\n模板中可直接使用 `<MButton>`、`<MInput>` 等,无需逐个 import。\n\n### 2. 按名导入 + 全量样式\n\n不注册插件、在 SFC 中按需写 import,JS 可由构建工具 tree-shake,但样式仍需全量 CSS:\n\n```ts\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).mount('#app')\n```\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton, MInput } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst name = ref('')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 1rem; max-width: 20rem\">\n <MInput v-model=\"name\" label=\"名称\" placeholder=\"输入名称\" />\n <MButton label=\"提交\" @click=\"() => undefined\" />\n </div>\n</template>\n```\n\n## 按需用法\n\n### 1. 子路径导入\n\n从 kebab-case 子路径导入(如 `button`、`input-password`、`tree-select`)。会带上组件 JS、内部依赖与对应样式,**无需**再引 `morya-ui/styles.css`:\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\n仅要样式时:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. 自动按需(Vite)\n\n安装 `unplugin-vue-components` 后,在 `vite.config.ts` 中配置解析器,模板里可直接写 `<MButton>`:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({\n resolvers: [MoryaUIResolver()],\n }),\n ],\n})\n```\n\n按需模式下,`createMoryaUI({ components: false })` 仍可注入全局配置而不注册组件。\n\n## 可选:应用级全局配置\n\n`createMoryaUI` 会写入全局默认值,并默认注册全部组件:\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 1100,\n }),\n )\n .mount('#app')\n```\n\n仅配置、不注册组件时使用 `components: false`。\n\n更多说明见 [全局配置](/docs/config)。\n\n## 主题 API\n\n亮暗切换等能力从同一包引入:\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { toggleTheme } = useTheme()\n```\n\n详见 [主题](/docs/theme)。\n\n## 启动本仓库文档站\n\n```bash\npnpm --filter morya-ui dev\n# http://localhost:5182\n\n# 构建静态文档站\npnpm --filter morya-ui build:docs\n```\n",
25100
+ "markdown": "---\ntitle: 快速上手\norder: 2\ndescription: 安装依赖、引入样式,并渲染第一个组件。\n---\n\n# 快速上手\n\n> 在线文档:[morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/) · 源码:[GitHub](https://github.com/morya-space/morya-ui) · npm:[`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## 安装\n\n**在应用项目中(npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\n也可以用:\n\n```bash\nnpx @morya-ui/setup app\n```\n\n会安装依赖,并尽量在入口注入样式。更多命令与选项见 [一键接入](/docs/setup)。需要 Vue 3(推荐 3.5 及以上)。主题 token、亮暗切换与动效 API 均包含在 `morya-ui` 中。Agent Skill / MCP 见 [AI 接入](/docs/ai-setup)。\n\n## 选择使用方式\n\n本库同时支持**全量**与**按需**两种消费方式,按项目需求任选其一(同一应用内建议保持一致)。\n\n| | 全量 | 按需 |\n| --- | --- | --- |\n| 典型场景 | 组件用得较多、希望快速上手 | 打包体积敏感、只用少量组件 |\n| 组件来源 | `app.use(MoryaUI)` 或 `morya-ui` 按名导入 | `morya-ui/button` 等子路径,或 Vite 自动解析 |\n| 样式 | 入口引入 `morya-ui/styles.css` | 子路径自动带入(含 theme + 依赖组件样式) |\n| JS 体积 | 全量注册会打入完整组件;按名导入可 tree-shake | 仅打入用到的组件及其依赖 |\n\n## 全量用法\n\n### 1. 插件注册(推荐的全量方式)\n\n在应用入口引入**全量样式**,并通过插件一次注册所有组件:\n\n```ts\nimport MoryaUI from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).use(MoryaUI).mount('#app')\n```\n\n模板中可直接使用 `<MButton>`、`<MInput>` 等,无需逐个 import。\n\n### 2. 按名导入 + 全量样式\n\n不注册插件、在 SFC 中按需写 import,JS 可由构建工具 tree-shake,但样式仍需全量 CSS:\n\n```ts\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).mount('#app')\n```\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton, MInput } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst name = ref('')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 1rem; max-width: 20rem\">\n <MInput v-model=\"name\" label=\"名称\" placeholder=\"输入名称\" />\n <MButton label=\"提交\" @click=\"() => undefined\" />\n </div>\n</template>\n```\n\n## 按需用法\n\n### 1. 子路径导入\n\n从 kebab-case 子路径导入(如 `button`、`input-password`、`tree-select`)。会带上组件 JS、类型声明、内部依赖与对应样式,**无需**再引 `morya-ui/styles.css`。Props 等类型从同一路径导入,例如 `import type { ButtonProps } from 'morya-ui/button'`。\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\n仅要样式时:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. 自动按需(Vite)\n\n安装 `unplugin-vue-components` 后,在 `vite.config.ts` 中配置解析器,模板里可直接写 `<MButton>`:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({\n dts: 'src/components.d.ts',\n resolvers: [MoryaUIResolver()],\n }),\n ],\n})\n```\n\n`dts` 会写出组件声明,编辑器和 `vue-tsc` 据此识别模板里的组件;该文件需落在 `tsconfig.json` 的 `include` 中。按需模式下,`createMoryaUI({ components: false })` 仍可注入全局配置而不注册组件。\n\n## 可选:应用级全局配置\n\n`createMoryaUI` 会写入全局默认值,并默认注册全部组件:\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 1100,\n }),\n )\n .mount('#app')\n```\n\n仅配置、不注册组件时使用 `components: false`。\n\n更多说明见 [全局配置](/docs/config)。\n\n## 主题 API\n\n亮暗切换等能力从同一包引入:\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { toggleTheme } = useTheme()\n```\n\n详见 [主题](/docs/theme)。\n\n## 启动本仓库文档站\n\n```bash\npnpm --filter morya-ui dev\n# http://localhost:5182\n\n# 构建静态文档站\npnpm --filter morya-ui build:docs\n```\n",
24749
25101
  "sections": [
24750
25102
  {
24751
25103
  "title": "",
@@ -24770,7 +25122,7 @@
24770
25122
  {
24771
25123
  "title": "按需用法",
24772
25124
  "id": "按需用法",
24773
- "body": "### 1. 子路径导入\n\n从 kebab-case 子路径导入(如 `button`、`input-password`、`tree-select`)。会带上组件 JS、内部依赖与对应样式,**无需**再引 `morya-ui/styles.css`:\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\n仅要样式时:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. 自动按需(Vite)\n\n安装 `unplugin-vue-components` 后,在 `vite.config.ts` 中配置解析器,模板里可直接写 `<MButton>`:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({\n resolvers: [MoryaUIResolver()],\n }),\n ],\n})\n```\n\n按需模式下,`createMoryaUI({ components: false })` 仍可注入全局配置而不注册组件。"
25125
+ "body": "### 1. 子路径导入\n\n从 kebab-case 子路径导入(如 `button`、`input-password`、`tree-select`)。会带上组件 JS、类型声明、内部依赖与对应样式,**无需**再引 `morya-ui/styles.css`。Props 等类型从同一路径导入,例如 `import type { ButtonProps } from 'morya-ui/button'`。\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\n仅要样式时:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. 自动按需(Vite)\n\n安装 `unplugin-vue-components` 后,在 `vite.config.ts` 中配置解析器,模板里可直接写 `<MButton>`:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({\n dts: 'src/components.d.ts',\n resolvers: [MoryaUIResolver()],\n }),\n ],\n})\n```\n\n`dts` 会写出组件声明,编辑器和 `vue-tsc` 据此识别模板里的组件;该文件需落在 `tsconfig.json` 的 `include` 中。按需模式下,`createMoryaUI({ components: false })` 仍可注入全局配置而不注册组件。"
24774
25126
  },
24775
25127
  {
24776
25128
  "title": "可选:应用级全局配置",
@@ -24792,7 +25144,7 @@
24792
25144
  "en-US": {
24793
25145
  "title": "Quick start",
24794
25146
  "description": "Install the package, import styles, and render the first component.",
24795
- "markdown": "---\ntitle: Quick start\norder: 2\ndescription: Install the package, import styles, and render the first component.\n---\n\n# Quick start\n\n> Live docs: [morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/) · Source: [GitHub](https://github.com/morya-space/morya-ui) · npm: [`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## Install\n\n**In an application (npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\nOr:\n\n```bash\nnpx @morya-ui/setup app\n```\n\nThis installs the dependency and tries to inject styles at the app entry. More commands and options: [One-shot setup](/docs/setup). Requires Vue 3 (3.5+ recommended). Theme tokens, color-mode switching, and motion APIs are all included in `morya-ui`. For Agent skill / MCP, see [AI setup](/docs/ai-setup).\n\nAfter cloning this repository, run `pnpm install`. The docs playground resolves source via Vite aliases (see `playground/vite.config.ts`).\n\nTo debug from another app, use `link:` / `pnpm link` plus Vite aliases. A plain npm install always resolves `dist/`.\n\n## Choose an import mode\n\nThe library supports **full** and **on-demand** usage. Pick one per app (stay consistent within a project).\n\n| | Full | On-demand |\n| --- | --- | --- |\n| Best for | Many components, fastest setup | Bundle size, few components |\n| Components | `app.use(MoryaUI)` or named imports from `morya-ui` | `morya-ui/button` subpaths, or Vite auto-resolver |\n| Styles | Import `morya-ui/styles.css` at entry | Bundled with subpath imports (theme + deps) |\n| JS size | Full plugin bundles all components; named imports tree-shake | Only used components and their deps |\n\n## Full usage\n\n### 1. Plugin registration (recommended full mode)\n\nImport the **full stylesheet** and register all components once:\n\n```ts\nimport MoryaUI from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).use(MoryaUI).mount('#app')\n```\n\nTemplates can use `<MButton>`, `<MInput>`, etc. without per-file imports.\n\n### 2. Named imports + full CSS\n\nSkip the plugin; import components in SFCs. JS can tree-shake, but styles still need the full CSS file:\n\n```ts\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).mount('#app')\n```\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton, MInput } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst name = ref('')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 1rem; max-width: 20rem\">\n <MInput v-model=\"name\" label=\"Name\" placeholder=\"Enter a name\" />\n <MButton label=\"Submit\" @click=\"() => undefined\" />\n </div>\n</template>\n```\n\n## On-demand usage\n\n### 1. Subpath imports\n\nImport from kebab-case subpaths (e.g. `button`, `input-password`, `tree-select`). Each entry bundles component JS, internal dependencies, and styles — **no** `morya-ui/styles.css` required:\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\nStyles only:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. Auto on-demand (Vite)\n\nWith `unplugin-vue-components`, add the resolver so templates can use `<MButton>` without manual imports:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({ resolvers: [MoryaUIResolver()] }),\n ],\n})\n```\n\nIn on-demand mode, `createMoryaUI({ components: false })` still applies global config without registering components.\n\n## Optional: app-level defaults\n\n`createMoryaUI` applies global defaults and registers all components by default:\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 1100,\n }),\n )\n .mount('#app')\n```\n\nUse `components: false` for config-only install.\n\nSee [Configuration](/docs/config) for details.\n\n## Theme API\n\nColor-mode helpers come from the same package:\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { toggleTheme } = useTheme()\n```\n\nSee [Theme](/docs/theme).\n\n## Run this docs site\n\n```bash\npnpm --filter morya-ui dev\n# http://localhost:5182\n\n# Build the static docs site\npnpm --filter morya-ui build:docs\n```\n",
25147
+ "markdown": "---\ntitle: Quick start\norder: 2\ndescription: Install the package, import styles, and render the first component.\n---\n\n# Quick start\n\n> Live docs: [morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/) · Source: [GitHub](https://github.com/morya-space/morya-ui) · npm: [`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## Install\n\n**In an application (npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\nOr:\n\n```bash\nnpx @morya-ui/setup app\n```\n\nThis installs the dependency and tries to inject styles at the app entry. More commands and options: [One-shot setup](/docs/setup). Requires Vue 3 (3.5+ recommended). Theme tokens, color-mode switching, and motion APIs are all included in `morya-ui`. For Agent skill / MCP, see [AI setup](/docs/ai-setup).\n\nAfter cloning this repository, run `pnpm install`. The docs playground resolves source via Vite aliases (see `playground/vite.config.ts`).\n\nTo debug from another app, use `link:` / `pnpm link` plus Vite aliases. A plain npm install always resolves `dist/`.\n\n## Choose an import mode\n\nThe library supports **full** and **on-demand** usage. Pick one per app (stay consistent within a project).\n\n| | Full | On-demand |\n| --- | --- | --- |\n| Best for | Many components, fastest setup | Bundle size, few components |\n| Components | `app.use(MoryaUI)` or named imports from `morya-ui` | `morya-ui/button` subpaths, or Vite auto-resolver |\n| Styles | Import `morya-ui/styles.css` at entry | Bundled with subpath imports (theme + deps) |\n| JS size | Full plugin bundles all components; named imports tree-shake | Only used components and their deps |\n\n## Full usage\n\n### 1. Plugin registration (recommended full mode)\n\nImport the **full stylesheet** and register all components once:\n\n```ts\nimport MoryaUI from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).use(MoryaUI).mount('#app')\n```\n\nTemplates can use `<MButton>`, `<MInput>`, etc. without per-file imports.\n\n### 2. Named imports + full CSS\n\nSkip the plugin; import components in SFCs. JS can tree-shake, but styles still need the full CSS file:\n\n```ts\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).mount('#app')\n```\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton, MInput } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst name = ref('')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 1rem; max-width: 20rem\">\n <MInput v-model=\"name\" label=\"Name\" placeholder=\"Enter a name\" />\n <MButton label=\"Submit\" @click=\"() => undefined\" />\n </div>\n</template>\n```\n\n## On-demand usage\n\n### 1. Subpath imports\n\nImport from kebab-case subpaths (e.g. `button`, `input-password`, `tree-select`). Each entry bundles component JS, type declarations, internal dependencies, and styles — **no** `morya-ui/styles.css` required. Prop types come from the same path, for example `import type { ButtonProps } from 'morya-ui/button'`.\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\nStyles only:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. Auto on-demand (Vite)\n\nWith `unplugin-vue-components`, add the resolver so templates can use `<MButton>` without manual imports:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({\n dts: 'src/components.d.ts',\n resolvers: [MoryaUIResolver()],\n }),\n ],\n})\n```\n\n`dts` writes component declarations so the editor and `vue-tsc` can resolve components used in templates. That file must be covered by `include` in `tsconfig.json`. In on-demand mode, `createMoryaUI({ components: false })` still applies global config without registering components.\n\n## Optional: app-level defaults\n\n`createMoryaUI` applies global defaults and registers all components by default:\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 1100,\n }),\n )\n .mount('#app')\n```\n\nUse `components: false` for config-only install.\n\nSee [Configuration](/docs/config) for details.\n\n## Theme API\n\nColor-mode helpers come from the same package:\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { toggleTheme } = useTheme()\n```\n\nSee [Theme](/docs/theme).\n\n## Run this docs site\n\n```bash\npnpm --filter morya-ui dev\n# http://localhost:5182\n\n# Build the static docs site\npnpm --filter morya-ui build:docs\n```\n",
24796
25148
  "sections": [
24797
25149
  {
24798
25150
  "title": "",
@@ -24817,7 +25169,7 @@
24817
25169
  {
24818
25170
  "title": "On-demand usage",
24819
25171
  "id": "on-demand-usage",
24820
- "body": "### 1. Subpath imports\n\nImport from kebab-case subpaths (e.g. `button`, `input-password`, `tree-select`). Each entry bundles component JS, internal dependencies, and styles — **no** `morya-ui/styles.css` required:\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\nStyles only:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. Auto on-demand (Vite)\n\nWith `unplugin-vue-components`, add the resolver so templates can use `<MButton>` without manual imports:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({ resolvers: [MoryaUIResolver()] }),\n ],\n})\n```\n\nIn on-demand mode, `createMoryaUI({ components: false })` still applies global config without registering components."
25172
+ "body": "### 1. Subpath imports\n\nImport from kebab-case subpaths (e.g. `button`, `input-password`, `tree-select`). Each entry bundles component JS, type declarations, internal dependencies, and styles — **no** `morya-ui/styles.css` required. Prop types come from the same path, for example `import type { ButtonProps } from 'morya-ui/button'`.\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\nStyles only:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. Auto on-demand (Vite)\n\nWith `unplugin-vue-components`, add the resolver so templates can use `<MButton>` without manual imports:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({\n dts: 'src/components.d.ts',\n resolvers: [MoryaUIResolver()],\n }),\n ],\n})\n```\n\n`dts` writes component declarations so the editor and `vue-tsc` can resolve components used in templates. That file must be covered by `include` in `tsconfig.json`. In on-demand mode, `createMoryaUI({ components: false })` still applies global config without registering components."
24821
25173
  },
24822
25174
  {
24823
25175
  "title": "Optional: app-level defaults",
@@ -24849,7 +25201,7 @@
24849
25201
  "zh-CN": {
24850
25202
  "title": "一键接入",
24851
25203
  "description": "用 @morya-ui/setup 安装组件库,并按需写入样式、Agent 配置与 MCP。",
24852
- "markdown": "---\ntitle: 一键接入\norder: 3\ndescription: 用 @morya-ui/setup 安装组件库,并按需写入样式、Agent 配置与 MCP。\n---\n\n# 一键接入\n\n[`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) 用于在业务 Vue 项目中接入 `morya-ui`:安装依赖、注入样式,并可一并写入 Agent Skill、Cursor 规则与 MCP。手写安装见 [快速上手](/docs/quick-start);AI 生成页面的约定见 [AI 接入](/docs/ai-setup)。\n\n## 命令\n\n在业务项目根目录执行:\n\n```bash\nnpx @morya-ui/setup\n```\n\n默认会:\n\n1. 安装 `morya-ui`(按锁文件选用 pnpm / yarn / npm)\n2. 复制 `DESIGN.md`、Agent Skill、Cursor rules、黄金样例与检查脚本\n3. 合并 `.cursor/mcp.json`,接入 [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. 尝试在入口注入 `import 'morya-ui/styles.css'`,并写入 `morya-app-shell.css`\n5. 若缺失则追加 `check:colors` 脚本\n\n也可以按场景选用:\n\n```bash\n# 只安装组件库并注入样式\nnpx @morya-ui/setup app\n\n# 已装库时,只写入 AI 配置与 MCP\nnpx @morya-ui/setup ai\n```\n\n完成后若写入了 MCP,请 **重启 Cursor**(或重载 MCP)。生成页面前让 Agent 先读 `DESIGN.md`。\n\n## 选项\n\n| Flag | 说明 |\n| --- | --- |\n| `--cwd <dir>` | 目标项目根(默认当前目录) |\n| `--pm pnpm\\|yarn\\|npm` | 指定包管理器 |\n| `--force` | 覆盖已有模板文件与 `morya-ui` MCP 条目 |\n| `--dry-run` | 只打印将要执行的操作 |\n| `--skip-install` | 不安装依赖 |\n| `--skip-template` | 不复制 skill / rules / docs |\n| `--skip-mcp` | 不写 MCP 配置 |\n| `--skip-styles` | 不注入样式 import |\n| `--skip-scripts` | 不改 `package.json` scripts |\n\n默认 **不覆盖** 已有文件;只有 `--force` 才会覆盖模板与 MCP 条目。\n\n示例:只补 MCP:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```\n\n## 会落到项目里的内容\n\n| 路径 | 作用 |\n| --- | --- |\n| `DESIGN.md` | AI 设计第一信源 |\n| `.agents/skills/morya-ui-pages/` | 页面生成 Agent Skill(见 [Agent Skill](/docs/agent-skill)) |\n| `.cursor/rules/` | Cursor 常驻规则 |\n| `docs/`、`design-tokens/`、`src/examples/` | 组件索引、黄金样例、令牌 |\n| `scripts/check-raw-colors.mjs` | 裸色值扫描 |\n| `.cursor/mcp.json` | Cursor MCP(`npx -y @morya-ui/mcp`) |\n| `src/styles/morya-app-shell.css` | 页面高度链(默认命令或 `app` 写入) |\n\n模板源在仓库 [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit)。CLI 不调用 `app.use(MoryaUI)`,也不改 `App.vue`。\n\n## 冲突策略\n\n- 模板文件与 `.cursor/rules/*`:目标已存在则跳过(除非 `--force`)\n- `.cursor/mcp.json`:合并其它 server;已有 `morya-ui` 条目则跳过(除非 `--force`)\n- `check:colors`:仅在缺失时追加(除非 `--force`)\n- 样式:找到入口且尚未引入时才注入\n\n## 下一步\n\n- [快速上手](/docs/quick-start):组件用法与最小示例 \n- [AI 接入](/docs/ai-setup):用 AI 生成业务页面时如何配合 Skill / MCP \n- [Agent Skill](/docs/agent-skill) · [Agent MCP](/docs/mcp) \n- [组件](/components):浏览 API 与预览\n",
25204
+ "markdown": "---\ntitle: 一键接入\norder: 3\ndescription: 用 @morya-ui/setup 安装组件库,并按需写入样式、Agent 配置与 MCP。\n---\n\n# 一键接入\n\n[`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) 用于在业务 Vue 项目中接入 `morya-ui`:安装依赖、注入样式,并可一并写入 Agent Skill、Cursor 规则与 MCP。手写安装见 [快速上手](/docs/quick-start);AI 生成页面的约定见 [AI 接入](/docs/ai-setup)。\n\n## 命令\n\n在业务项目根目录执行:\n\n```bash\nnpx @morya-ui/setup\n```\n\n默认会:\n\n1. 安装 `morya-ui`(按锁文件选用 pnpm / yarn / npm)\n2. 复制 `DESIGN.md`、Agent Skill、Cursor rules 与检查脚本\n3. 合并 `.cursor/mcp.json`,接入 [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. 尝试在入口注入 `import 'morya-ui/styles.css'`\n5. 若缺失则追加 `check:colors` 脚本\n\n也可以按场景选用:\n\n```bash\n# 只安装组件库并注入样式\nnpx @morya-ui/setup app\n\n# 已装库时,只写入 AI 配置与 MCP\nnpx @morya-ui/setup ai\n```\n\n完成后若写入了 MCP,请 **重启 Cursor**(或重载 MCP)。生成页面前让 Agent 先读 `DESIGN.md`。\n\n## 选项\n\n| Flag | 说明 |\n| --- | --- |\n| `--cwd <dir>` | 目标项目根(默认当前目录) |\n| `--pm pnpm\\|yarn\\|npm` | 指定包管理器 |\n| `--force` | 覆盖已有模板文件与 `morya-ui` MCP 条目 |\n| `--dry-run` | 只打印将要执行的操作 |\n| `--skip-install` | 不安装依赖 |\n| `--skip-template` | 不复制 skill / rules / docs |\n| `--skip-mcp` | 不写 MCP 配置 |\n| `--skip-styles` | 不注入样式 import |\n| `--skip-scripts` | 不改 `package.json` scripts |\n\n默认 **不覆盖** 已有文件;只有 `--force` 才会覆盖模板与 MCP 条目。\n\n示例:只补 MCP:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```\n\n## 会落到项目里的内容\n\n| 路径 | 作用 |\n| --- | --- |\n| `DESIGN.md` | AI 设计第一信源 |\n| `.agents/skills/morya-ui-pages/` | 页面生成 Agent Skill(见 [Agent Skill](/docs/agent-skill)) |\n| `.cursor/rules/` | Cursor 常驻规则 |\n| `scripts/check-raw-colors.mjs` | 裸色值扫描 |\n| `.cursor/mcp.json` | Cursor MCP(`npx -y @morya-ui/mcp`) |\n\n模板源在仓库 [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit)。CLI 不调用 `app.use(MoryaUI)`,也不改 `App.vue`。\n\n## 冲突策略\n\n- 模板文件与 `.cursor/rules/*`:目标已存在则跳过(除非 `--force`)\n- `.cursor/mcp.json`:合并其它 server;已有 `morya-ui` 条目则跳过(除非 `--force`)\n- `check:colors`:仅在缺失时追加(除非 `--force`)\n- 样式:找到入口且尚未引入时才注入\n\n## 下一步\n\n- [快速上手](/docs/quick-start):组件用法与最小示例 \n- [AI 接入](/docs/ai-setup):用 AI 生成业务页面时如何配合 Skill / MCP \n- [Agent Skill](/docs/agent-skill) · [Agent MCP](/docs/mcp) \n- [组件](/components):浏览 API 与预览\n",
24853
25205
  "sections": [
24854
25206
  {
24855
25207
  "title": "",
@@ -24859,7 +25211,7 @@
24859
25211
  {
24860
25212
  "title": "命令",
24861
25213
  "id": "命令",
24862
- "body": "在业务项目根目录执行:\n\n```bash\nnpx @morya-ui/setup\n```\n\n默认会:\n\n1. 安装 `morya-ui`(按锁文件选用 pnpm / yarn / npm)\n2. 复制 `DESIGN.md`、Agent Skill、Cursor rules、黄金样例与检查脚本\n3. 合并 `.cursor/mcp.json`,接入 [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. 尝试在入口注入 `import 'morya-ui/styles.css'`,并写入 `morya-app-shell.css`\n5. 若缺失则追加 `check:colors` 脚本\n\n也可以按场景选用:\n\n```bash\n# 只安装组件库并注入样式\nnpx @morya-ui/setup app\n\n# 已装库时,只写入 AI 配置与 MCP\nnpx @morya-ui/setup ai\n```\n\n完成后若写入了 MCP,请 **重启 Cursor**(或重载 MCP)。生成页面前让 Agent 先读 `DESIGN.md`。"
25214
+ "body": "在业务项目根目录执行:\n\n```bash\nnpx @morya-ui/setup\n```\n\n默认会:\n\n1. 安装 `morya-ui`(按锁文件选用 pnpm / yarn / npm)\n2. 复制 `DESIGN.md`、Agent Skill、Cursor rules 与检查脚本\n3. 合并 `.cursor/mcp.json`,接入 [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. 尝试在入口注入 `import 'morya-ui/styles.css'`\n5. 若缺失则追加 `check:colors` 脚本\n\n也可以按场景选用:\n\n```bash\n# 只安装组件库并注入样式\nnpx @morya-ui/setup app\n\n# 已装库时,只写入 AI 配置与 MCP\nnpx @morya-ui/setup ai\n```\n\n完成后若写入了 MCP,请 **重启 Cursor**(或重载 MCP)。生成页面前让 Agent 先读 `DESIGN.md`。"
24863
25215
  },
24864
25216
  {
24865
25217
  "title": "选项",
@@ -24869,7 +25221,7 @@
24869
25221
  {
24870
25222
  "title": "会落到项目里的内容",
24871
25223
  "id": "会落到项目里的内容",
24872
- "body": "| 路径 | 作用 |\n| --- | --- |\n| `DESIGN.md` | AI 设计第一信源 |\n| `.agents/skills/morya-ui-pages/` | 页面生成 Agent Skill(见 [Agent Skill](/docs/agent-skill)) |\n| `.cursor/rules/` | Cursor 常驻规则 |\n| `docs/`、`design-tokens/`、`src/examples/` | 组件索引、黄金样例、令牌 |\n| `scripts/check-raw-colors.mjs` | 裸色值扫描 |\n| `.cursor/mcp.json` | Cursor MCP(`npx -y @morya-ui/mcp`) |\n| `src/styles/morya-app-shell.css` | 页面高度链(默认命令或 `app` 写入) |\n\n模板源在仓库 [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit)。CLI 不调用 `app.use(MoryaUI)`,也不改 `App.vue`。"
25224
+ "body": "| 路径 | 作用 |\n| --- | --- |\n| `DESIGN.md` | AI 设计第一信源 |\n| `.agents/skills/morya-ui-pages/` | 页面生成 Agent Skill(见 [Agent Skill](/docs/agent-skill)) |\n| `.cursor/rules/` | Cursor 常驻规则 |\n| `scripts/check-raw-colors.mjs` | 裸色值扫描 |\n| `.cursor/mcp.json` | Cursor MCP(`npx -y @morya-ui/mcp`) |\n\n模板源在仓库 [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit)。CLI 不调用 `app.use(MoryaUI)`,也不改 `App.vue`。"
24873
25225
  },
24874
25226
  {
24875
25227
  "title": "冲突策略",
@@ -24886,7 +25238,7 @@
24886
25238
  "en-US": {
24887
25239
  "title": "One-shot setup",
24888
25240
  "description": "Use @morya-ui/setup to install the library and optionally write styles, Agent config, and MCP.",
24889
- "markdown": "---\ntitle: One-shot setup\norder: 3\ndescription: Use @morya-ui/setup to install the library and optionally write styles, Agent config, and MCP.\n---\n\n# One-shot setup\n\n[`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) onboards a consumer Vue app to `morya-ui`: install the dependency, inject styles, and optionally write the Agent skill, Cursor rules, and MCP. For manual install see [Quick start](/docs/quick-start). For AI page-generation workflow see [AI setup](/docs/ai-setup).\n\n## Commands\n\nFrom the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\nBy default this will:\n\n1. Install `morya-ui` (pnpm / yarn / npm from the lockfile)\n2. Copy `DESIGN.md`, Agent skill, Cursor rules, golden pages, and check scripts\n3. Merge `.cursor/mcp.json` for [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. Try to inject `import 'morya-ui/styles.css'` and write `morya-app-shell.css`\n5. Add a `check:colors` script when missing\n\nOther common commands:\n\n```bash\n# Library + styles only\nnpx @morya-ui/setup app\n\n# AI config + MCP only (library already installed)\nnpx @morya-ui/setup ai\n```\n\nIf MCP was written, **restart Cursor** (or reload MCP). Have the agent read `DESIGN.md` before generating pages.\n\n## Options\n\n| Flag | Meaning |\n| --- | --- |\n| `--cwd <dir>` | Target project root (default: cwd) |\n| `--pm pnpm\\|yarn\\|npm` | Package manager |\n| `--force` | Overwrite existing template files and the `morya-ui` MCP entry |\n| `--dry-run` | Print actions only |\n| `--skip-install` | Skip dependency install |\n| `--skip-template` | Skip copying skill / rules / docs |\n| `--skip-mcp` | Skip writing MCP config |\n| `--skip-styles` | Skip styles import injection |\n| `--skip-scripts` | Skip `package.json` scripts |\n\nBy default **existing files are not overwritten**; use `--force` to overwrite templates and the MCP entry.\n\nExample: MCP only:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```\n\n## What lands in the project\n\n| Path | Role |\n| --- | --- |\n| `DESIGN.md` | Primary design brief for AI |\n| `.agents/skills/morya-ui-pages/` | Page-generation Agent skill (see [Agent Skill](/docs/agent-skill)) |\n| `.cursor/rules/` | Cursor always-on rules |\n| `docs/`, `design-tokens/`, `src/examples/` | Index, golden pages, tokens |\n| `scripts/check-raw-colors.mjs` | Raw color scan |\n| `.cursor/mcp.json` | Cursor MCP (`npx -y @morya-ui/mcp`) |\n| `src/styles/morya-app-shell.css` | Height chain (default command or `app`) |\n\nTemplate source: [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit). The CLI does not call `app.use(MoryaUI)` or edit `App.vue`.\n\n## Conflict policy\n\n- Template files and `.cursor/rules/*`: skip if the destination exists (unless `--force`)\n- `.cursor/mcp.json`: merge other servers; skip an existing `morya-ui` entry unless `--force`\n- `check:colors`: add only if missing (unless `--force`)\n- Styles: inject only when an entry is found and the import is not already present\n\n## Next steps\n\n- [Quick start](/docs/quick-start): component usage and a minimal example \n- [AI setup](/docs/ai-setup): how setup relates to Skill / MCP for AI page generation \n- [Agent Skill](/docs/agent-skill) · [Agent MCP](/docs/mcp) \n- [Components](/components): browse APIs and previews\n",
25241
+ "markdown": "---\ntitle: One-shot setup\norder: 3\ndescription: Use @morya-ui/setup to install the library and optionally write styles, Agent config, and MCP.\n---\n\n# One-shot setup\n\n[`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) onboards a consumer Vue app to `morya-ui`: install the dependency, inject styles, and optionally write the Agent skill, Cursor rules, and MCP. For manual install see [Quick start](/docs/quick-start). For AI page-generation workflow see [AI setup](/docs/ai-setup).\n\n## Commands\n\nFrom the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\nBy default this will:\n\n1. Install `morya-ui` (pnpm / yarn / npm from the lockfile)\n2. Copy `DESIGN.md`, Agent skill, Cursor rules, and check scripts\n3. Merge `.cursor/mcp.json` for [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. Try to inject `import 'morya-ui/styles.css'`\n5. Add a `check:colors` script when missing\n\nOther common commands:\n\n```bash\n# Library + styles only\nnpx @morya-ui/setup app\n\n# AI config + MCP only (library already installed)\nnpx @morya-ui/setup ai\n```\n\nIf MCP was written, **restart Cursor** (or reload MCP). Have the agent read `DESIGN.md` before generating pages.\n\n## Options\n\n| Flag | Meaning |\n| --- | --- |\n| `--cwd <dir>` | Target project root (default: cwd) |\n| `--pm pnpm\\|yarn\\|npm` | Package manager |\n| `--force` | Overwrite existing template files and the `morya-ui` MCP entry |\n| `--dry-run` | Print actions only |\n| `--skip-install` | Skip dependency install |\n| `--skip-template` | Skip copying skill / rules / docs |\n| `--skip-mcp` | Skip writing MCP config |\n| `--skip-styles` | Skip styles import injection |\n| `--skip-scripts` | Skip `package.json` scripts |\n\nBy default **existing files are not overwritten**; use `--force` to overwrite templates and the MCP entry.\n\nExample: MCP only:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```\n\n## What lands in the project\n\n| Path | Role |\n| --- | --- |\n| `DESIGN.md` | Primary design brief for AI |\n| `.agents/skills/morya-ui-pages/` | Page-generation Agent skill (see [Agent Skill](/docs/agent-skill)) |\n| `.cursor/rules/` | Cursor always-on rules |\n| `scripts/check-raw-colors.mjs` | Raw color scan |\n| `.cursor/mcp.json` | Cursor MCP (`npx -y @morya-ui/mcp`) |\n\nTemplate source: [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit). The CLI does not call `app.use(MoryaUI)` or edit `App.vue`.\n\n## Conflict policy\n\n- Template files and `.cursor/rules/*`: skip if the destination exists (unless `--force`)\n- `.cursor/mcp.json`: merge other servers; skip an existing `morya-ui` entry unless `--force`\n- `check:colors`: add only if missing (unless `--force`)\n- Styles: inject only when an entry is found and the import is not already present\n\n## Next steps\n\n- [Quick start](/docs/quick-start): component usage and a minimal example \n- [AI setup](/docs/ai-setup): how setup relates to Skill / MCP for AI page generation \n- [Agent Skill](/docs/agent-skill) · [Agent MCP](/docs/mcp) \n- [Components](/components): browse APIs and previews\n",
24890
25242
  "sections": [
24891
25243
  {
24892
25244
  "title": "",
@@ -24896,7 +25248,7 @@
24896
25248
  {
24897
25249
  "title": "Commands",
24898
25250
  "id": "commands",
24899
- "body": "From the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\nBy default this will:\n\n1. Install `morya-ui` (pnpm / yarn / npm from the lockfile)\n2. Copy `DESIGN.md`, Agent skill, Cursor rules, golden pages, and check scripts\n3. Merge `.cursor/mcp.json` for [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. Try to inject `import 'morya-ui/styles.css'` and write `morya-app-shell.css`\n5. Add a `check:colors` script when missing\n\nOther common commands:\n\n```bash\n# Library + styles only\nnpx @morya-ui/setup app\n\n# AI config + MCP only (library already installed)\nnpx @morya-ui/setup ai\n```\n\nIf MCP was written, **restart Cursor** (or reload MCP). Have the agent read `DESIGN.md` before generating pages."
25251
+ "body": "From the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\nBy default this will:\n\n1. Install `morya-ui` (pnpm / yarn / npm from the lockfile)\n2. Copy `DESIGN.md`, Agent skill, Cursor rules, and check scripts\n3. Merge `.cursor/mcp.json` for [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. Try to inject `import 'morya-ui/styles.css'`\n5. Add a `check:colors` script when missing\n\nOther common commands:\n\n```bash\n# Library + styles only\nnpx @morya-ui/setup app\n\n# AI config + MCP only (library already installed)\nnpx @morya-ui/setup ai\n```\n\nIf MCP was written, **restart Cursor** (or reload MCP). Have the agent read `DESIGN.md` before generating pages."
24900
25252
  },
24901
25253
  {
24902
25254
  "title": "Options",
@@ -24906,7 +25258,7 @@
24906
25258
  {
24907
25259
  "title": "What lands in the project",
24908
25260
  "id": "what-lands-in-the-project",
24909
- "body": "| Path | Role |\n| --- | --- |\n| `DESIGN.md` | Primary design brief for AI |\n| `.agents/skills/morya-ui-pages/` | Page-generation Agent skill (see [Agent Skill](/docs/agent-skill)) |\n| `.cursor/rules/` | Cursor always-on rules |\n| `docs/`, `design-tokens/`, `src/examples/` | Index, golden pages, tokens |\n| `scripts/check-raw-colors.mjs` | Raw color scan |\n| `.cursor/mcp.json` | Cursor MCP (`npx -y @morya-ui/mcp`) |\n| `src/styles/morya-app-shell.css` | Height chain (default command or `app`) |\n\nTemplate source: [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit). The CLI does not call `app.use(MoryaUI)` or edit `App.vue`."
25261
+ "body": "| Path | Role |\n| --- | --- |\n| `DESIGN.md` | Primary design brief for AI |\n| `.agents/skills/morya-ui-pages/` | Page-generation Agent skill (see [Agent Skill](/docs/agent-skill)) |\n| `.cursor/rules/` | Cursor always-on rules |\n| `scripts/check-raw-colors.mjs` | Raw color scan |\n| `.cursor/mcp.json` | Cursor MCP (`npx -y @morya-ui/mcp`) |\n\nTemplate source: [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit). The CLI does not call `app.use(MoryaUI)` or edit `App.vue`."
24910
25262
  },
24911
25263
  {
24912
25264
  "title": "Conflict policy",
@@ -25645,7 +25997,7 @@
25645
25997
  "zh-CN": {
25646
25998
  "title": "Agent Skill",
25647
25999
  "description": "消费方 morya-ui-pages skill:何时触发、与 rules/MCP 分工、页面类型地图。",
25648
- "markdown": "---\ntitle: Agent Skill\norder: 12\ndescription: 消费方 morya-ui-pages skill:何时触发、与 rules/MCP 分工、页面类型地图。\n---\n\n# Agent Skill\n\n消费方用 AI 生成 **基于 `morya-ui` 的业务页面** 时,应加载 **`morya-ui-pages`** skill。它规定组件契约、页面类型与工作流;**不是**组件库源码里写新组件用的 skill。\n\n安装方式见 [一键接入](/docs/setup)(`npx @morya-ui/setup` 会复制到项目);AI 侧流程见 [AI 接入](/docs/ai-setup)。本文说明 skill **是什么、何时用、和其它配置怎么分工**。\n\n## 装到哪里\n\n```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # 布局、表面、令牌、反馈、检查清单等\n```\n\n支持 Agent Skills 自动发现的客户端(如 Cursor)会从 `.agents/skills` 读取。生成列表 / 表单 / 登录 / 落地等页面前,应优先匹配本 skill。\n\n源文件在仓库 [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages),随 `@morya-ui/setup` 的 template 同步。\n\n## 何时触发\n\n典型话术或主题:\n\n- `morya-ui`、`M*` 组件、`--m-*` 令牌、黄金样例\n- 后台 / 列表 / 表单 / 仪表盘 / 详情 / 设置\n- 登录 / 注册 / 空状态 / 向导 / 落地页 / 官网\n\n**优先于**通用 `frontend-design`、Impeccable、UI-UX-Pro-Max 等:那些只能当审美参考;栈是 morya-ui 时以本 skill 为准。\n\n**不要**用于:纯后端、或在本仓库 `src/components` 里新增组件库组件。\n\n## 与其它配置的分工\n\n| 层 | 角色 |\n| --- | --- |\n| [一键接入](/docs/setup) / `@morya-ui/setup` | 一次性把库 + skill + rules + MCP 装进项目 |\n| [AI 接入](/docs/ai-setup) | 装好后如何配合 Agent 生成页面 |\n| **`morya-ui-pages` skill** | 按需工作流:选表面、读黄金样例、组 `M*`、自检 |\n| `.cursor/rules/` | 编辑器常驻短规则(设计系统、组件用法、布局) |\n| `DESIGN.md` | 项目设计第一信源;与 skill 冲突时以项目 `DESIGN.md` 为准 |\n| [Agent MCP](/docs/mcp) | 运行时查真实 Props / Events / 示例,禁止臆造 API |\n\n两层始终生效:\n\n1. **契约** — 只用 `M*` 与 `--m-*`,API 以 MCP / 文档为准 \n2. **工艺** — 先定表面类型,再做视觉;后台偏克制,落地 / 品牌向可有意表达,但仍上令牌、上组件\n\n## 页面类型(Surface)地图\n\n| 车道 | 典型表面 | 优先参考 |\n| --- | --- | --- |\n| **Ops** | 列表、表单、仪表盘、详情、设置、筛选抽屉 | 黄金样例 + skill `page-layouts` |\n| **Account** | 登录、注册、邀请、重置密码、个人资料 | skill `surfaces` § Account |\n| **Flow** | 引导、空状态、向导、成功页 | skill `surfaces` § Flow |\n| **System** | 404、无权限、维护中 | skill `surfaces` § System |\n| **Express** | 营销落地、定价、功能展示 | skill `surfaces` + `visual-craft` |\n| **Overlay** | 以 Dialog / Drawer / CommandMenu 为主界面 | skill `surfaces` § Overlay |\n\n不确定时:后台默认 Ops → 最近黄金样例;对外营销 → Express。\n\n## Agent 推荐工作流(摘要)\n\n1. 钉死主体、受众、表面、第一屏单一任务 \n2. 优先 MCP:`recommend_page` → `get_golden_page` → `get_component` / `get_example` \n3. 无 MCP 时读项目内 `docs/golden-pages/` 与 skill `references/` \n4. 反馈默认 `message`;`toast` 仅 summary+detail / 异步感(见项目 `docs/feedback-message-vs-toast.md`) \n5. 交付前对照 skill 检查清单;有 MCP 时跑 `validate_page`\n\n细节与硬边界以项目内 `SKILL.md` 为准,本文不重复全文。\n\n## 下一步\n\n- [一键接入](/docs/setup):安装 skill 与其它配置 \n- [AI 接入](/docs/ai-setup):用 AI 生成页面时的流程 \n- [Agent MCP](/docs/mcp):工具与客户端配置 \n- [快速上手](/docs/quick-start):手写安装组件库 \n- [组件](/components):浏览 API\n",
26000
+ "markdown": "---\ntitle: Agent Skill\norder: 12\ndescription: 消费方 morya-ui-pages skill:何时触发、与 rules/MCP 分工、页面类型地图。\n---\n\n# Agent Skill\n\n消费方用 AI 生成 **基于 `morya-ui` 的业务页面** 时,应加载 **`morya-ui-pages`** skill。它规定组件契约、页面类型与工作流;**不是**组件库源码里写新组件用的 skill。\n\n安装方式见 [一键接入](/docs/setup)(`npx @morya-ui/setup` 会复制到项目);AI 侧流程见 [AI 接入](/docs/ai-setup)。本文说明 skill **是什么、何时用、和其它配置怎么分工**。\n\n## 装到哪里\n\n```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # 布局、表面、令牌、反馈、检查清单等\n```\n\n支持 Agent Skills 自动发现的客户端(如 Cursor)会从 `.agents/skills` 读取。生成列表 / 表单 / 登录 / 落地等页面前,应优先匹配本 skill。\n\n源文件在仓库 [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages),随 `@morya-ui/setup` 的 template 同步。\n\n## 何时触发\n\n典型话术或主题:\n\n- `morya-ui`、`M*` 组件、`--m-*` 令牌、黄金样例\n- 后台 / 列表 / 表单 / 仪表盘 / 详情 / 设置\n- 登录 / 注册 / 空状态 / 向导 / 落地页 / 官网\n\n**优先于**通用 `frontend-design`、Impeccable、UI-UX-Pro-Max 等:那些只能当审美参考;栈是 morya-ui 时以本 skill 为准。\n\n**不要**用于:纯后端、或在本仓库 `src/components` 里新增组件库组件。\n\n## 与其它配置的分工\n\n| 层 | 角色 |\n| --- | --- |\n| [一键接入](/docs/setup) / `@morya-ui/setup` | 一次性把库 + skill + rules + MCP 装进项目 |\n| [AI 接入](/docs/ai-setup) | 装好后如何配合 Agent 生成页面 |\n| **`morya-ui-pages` skill** | 按需工作流:选表面、读黄金样例、组 `M*`、自检 |\n| `.cursor/rules/` | 编辑器常驻短规则(设计系统、组件用法、布局) |\n| `DESIGN.md` | 项目设计第一信源;与 skill 冲突时以项目 `DESIGN.md` 为准 |\n| [Agent MCP](/docs/mcp) | 运行时查真实 Props / Events / 示例,禁止臆造 API |\n\n两层始终生效:\n\n1. **契约** — 只用 `M*` 与 `--m-*`,API 以 MCP / 文档为准 \n2. **工艺** — 先定表面类型,再做视觉;后台偏克制,落地 / 品牌向可有意表达,但仍上令牌、上组件\n\n## 页面类型(Surface)地图\n\n| 车道 | 典型表面 | 优先参考 |\n| --- | --- | --- |\n| **Ops** | 列表、表单、仪表盘、详情、设置、筛选抽屉 | 黄金样例 + skill `page-layouts` |\n| **Account** | 登录、注册、邀请、重置密码、个人资料 | skill `surfaces` § Account |\n| **Flow** | 引导、空状态、向导、成功页 | skill `surfaces` § Flow |\n| **System** | 404、无权限、维护中 | skill `surfaces` § System |\n| **Express** | 营销落地、定价、功能展示 | skill `surfaces` + `visual-craft` |\n| **Overlay** | 以 Dialog / Drawer / CommandMenu 为主界面 | skill `surfaces` § Overlay |\n\n不确定时:后台默认 Ops → 最近黄金样例;对外营销 → Express。\n\n## Agent 推荐工作流(摘要)\n\n1. 钉死主体、受众、表面、第一屏单一任务 \n2. 优先 MCP:`recommend_page` → `get_golden_page` → `get_component` / `get_example` \n3. 无 MCP 时读 skill `references/`(布局、表面、反馈) \n4. 反馈默认 `message`;`toast` 仅 summary+detail / 异步感(见 skill `references/feedback.md`) \n5. 交付前对照 skill 检查清单;有 MCP 时跑 `validate_page`\n\n细节与硬边界以项目内 `SKILL.md` 为准,本文不重复全文。\n\n## 下一步\n\n- [一键接入](/docs/setup):安装 skill 与其它配置 \n- [AI 接入](/docs/ai-setup):用 AI 生成页面时的流程 \n- [Agent MCP](/docs/mcp):工具与客户端配置 \n- [快速上手](/docs/quick-start):手写安装组件库 \n- [组件](/components):浏览 API\n",
25649
26001
  "sections": [
25650
26002
  {
25651
26003
  "title": "",
@@ -25675,7 +26027,7 @@
25675
26027
  {
25676
26028
  "title": "Agent 推荐工作流(摘要)",
25677
26029
  "id": "agent-推荐工作流-摘要",
25678
- "body": "1. 钉死主体、受众、表面、第一屏单一任务 \n2. 优先 MCP:`recommend_page` → `get_golden_page` → `get_component` / `get_example` \n3. 无 MCP 时读项目内 `docs/golden-pages/` 与 skill `references/` \n4. 反馈默认 `message`;`toast` 仅 summary+detail / 异步感(见项目 `docs/feedback-message-vs-toast.md`) \n5. 交付前对照 skill 检查清单;有 MCP 时跑 `validate_page`\n\n细节与硬边界以项目内 `SKILL.md` 为准,本文不重复全文。"
26030
+ "body": "1. 钉死主体、受众、表面、第一屏单一任务 \n2. 优先 MCP:`recommend_page` → `get_golden_page` → `get_component` / `get_example` \n3. 无 MCP 时读 skill `references/`(布局、表面、反馈) \n4. 反馈默认 `message`;`toast` 仅 summary+detail / 异步感(见 skill `references/feedback.md`) \n5. 交付前对照 skill 检查清单;有 MCP 时跑 `validate_page`\n\n细节与硬边界以项目内 `SKILL.md` 为准,本文不重复全文。"
25679
26031
  },
25680
26032
  {
25681
26033
  "title": "下一步",
@@ -25687,7 +26039,7 @@
25687
26039
  "en-US": {
25688
26040
  "title": "Agent Skill",
25689
26041
  "description": "Consumer morya-ui-pages skill — when it triggers, vs rules/MCP, and the surface map.",
25690
- "markdown": "---\ntitle: Agent Skill\norder: 12\ndescription: Consumer morya-ui-pages skill — when it triggers, vs rules/MCP, and the surface map.\n---\n\n# Agent Skill\n\nWhen AI generates **morya-ui consumer pages**, load the **`morya-ui-pages`** skill. It defines the component contract, surface types, and workflow. It is **not** for authoring new components inside the library source.\n\nInstall via [One-shot setup](/docs/setup) (`npx @morya-ui/setup` copies it into the project); AI workflow: [AI setup](/docs/ai-setup). This page explains **what it is, when to use it, and how it relates to other config**.\n\n## Where it lives\n\n```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # layouts, surfaces, tokens, feedback, checklist, …\n```\n\nClients that auto-discover Agent Skills (e.g. Cursor) read `.agents/skills`. Prefer this skill before generating list / form / login / landing pages.\n\nSource: [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages), synced into the `@morya-ui/setup` template.\n\n## When it triggers\n\nTypical topics:\n\n- `morya-ui`, `M*` components, `--m-*` tokens, golden pages\n- Admin list / form / dashboard / detail / settings\n- Login / register / empty state / wizard / landing / marketing site\n\n**Prefer over** generic `frontend-design`, Impeccable, or UI-UX-Pro-Max when the stack is morya-ui — those may inform taste only.\n\n**Do not** use for backend-only work or for adding components under this repo’s `src/components`.\n\n## How it relates to other config\n\n| Layer | Role |\n| --- | --- |\n| [One-shot setup](/docs/setup) / `@morya-ui/setup` | One-shot install of library + skill + rules + MCP |\n| [AI setup](/docs/ai-setup) | How to use the Agent after install |\n| **`morya-ui-pages` skill** | On-demand workflow: pick surface, golden pages, compose `M*`, review |\n| `.cursor/rules/` | Always-on short editor rules |\n| `DESIGN.md` | Project design source of truth; wins over skill on conflict |\n| [Agent MCP](/docs/mcp) | Runtime lookup of real props / events / examples |\n\nTwo layers always apply:\n\n1. **Contract** — only `M*` and `--m-*`; APIs from MCP / docs \n2. **Craft** — pick the surface first; Ops stays restrained; Express may take intentional aesthetic risk on-token and on-component\n\n## Surface map\n\n| Lane | Surfaces | Prefer |\n| --- | --- | --- |\n| **Ops** | list, form, dashboard, detail, settings, filter drawer | Golden pages + skill `page-layouts` |\n| **Account** | login, register, invite, reset password, profile | skill `surfaces` § Account |\n| **Flow** | onboarding, empty, wizard, success | skill `surfaces` § Flow |\n| **System** | 404, permission denied, maintenance | skill `surfaces` § System |\n| **Express** | marketing landing, pricing, feature showcase | skill `surfaces` + `visual-craft` |\n| **Overlay** | Dialog / Drawer / CommandMenu as the main UI | skill `surfaces` § Overlay |\n\nUnclear brief → Ops → nearest golden page; public marketing → Express.\n\n## Recommended agent workflow (summary)\n\n1. Pin subject, audience, surface, and the first viewport’s single job \n2. Prefer MCP: `recommend_page` → `get_golden_page` → `get_component` / `get_example` \n3. Without MCP, read project `docs/golden-pages/` and skill `references/` \n4. Feedback defaults to `message`; `toast` only for summary+detail / async feel \n5. Review with the skill checklist; run MCP `validate_page` when available \n\nFull rules and hard boundaries live in the project’s `SKILL.md` — this page does not duplicate it.\n\n## Next steps\n\n- [One-shot setup](/docs/setup): install the skill and related config \n- [AI setup](/docs/ai-setup): AI page-generation workflow \n- [Agent MCP](/docs/mcp): tools and client config \n- [Quick start](/docs/quick-start): manual library install \n- [Components](/components): browse APIs\n",
26042
+ "markdown": "---\ntitle: Agent Skill\norder: 12\ndescription: Consumer morya-ui-pages skill — when it triggers, vs rules/MCP, and the surface map.\n---\n\n# Agent Skill\n\nWhen AI generates **morya-ui consumer pages**, load the **`morya-ui-pages`** skill. It defines the component contract, surface types, and workflow. It is **not** for authoring new components inside the library source.\n\nInstall via [One-shot setup](/docs/setup) (`npx @morya-ui/setup` copies it into the project); AI workflow: [AI setup](/docs/ai-setup). This page explains **what it is, when to use it, and how it relates to other config**.\n\n## Where it lives\n\n```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # layouts, surfaces, tokens, feedback, checklist, …\n```\n\nClients that auto-discover Agent Skills (e.g. Cursor) read `.agents/skills`. Prefer this skill before generating list / form / login / landing pages.\n\nSource: [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages), synced into the `@morya-ui/setup` template.\n\n## When it triggers\n\nTypical topics:\n\n- `morya-ui`, `M*` components, `--m-*` tokens, golden pages\n- Admin list / form / dashboard / detail / settings\n- Login / register / empty state / wizard / landing / marketing site\n\n**Prefer over** generic `frontend-design`, Impeccable, or UI-UX-Pro-Max when the stack is morya-ui — those may inform taste only.\n\n**Do not** use for backend-only work or for adding components under this repo’s `src/components`.\n\n## How it relates to other config\n\n| Layer | Role |\n| --- | --- |\n| [One-shot setup](/docs/setup) / `@morya-ui/setup` | One-shot install of library + skill + rules + MCP |\n| [AI setup](/docs/ai-setup) | How to use the Agent after install |\n| **`morya-ui-pages` skill** | On-demand workflow: pick surface, golden pages, compose `M*`, review |\n| `.cursor/rules/` | Always-on short editor rules |\n| `DESIGN.md` | Project design source of truth; wins over skill on conflict |\n| [Agent MCP](/docs/mcp) | Runtime lookup of real props / events / examples |\n\nTwo layers always apply:\n\n1. **Contract** — only `M*` and `--m-*`; APIs from MCP / docs \n2. **Craft** — pick the surface first; Ops stays restrained; Express may take intentional aesthetic risk on-token and on-component\n\n## Surface map\n\n| Lane | Surfaces | Prefer |\n| --- | --- | --- |\n| **Ops** | list, form, dashboard, detail, settings, filter drawer | Golden pages + skill `page-layouts` |\n| **Account** | login, register, invite, reset password, profile | skill `surfaces` § Account |\n| **Flow** | onboarding, empty, wizard, success | skill `surfaces` § Flow |\n| **System** | 404, permission denied, maintenance | skill `surfaces` § System |\n| **Express** | marketing landing, pricing, feature showcase | skill `surfaces` + `visual-craft` |\n| **Overlay** | Dialog / Drawer / CommandMenu as the main UI | skill `surfaces` § Overlay |\n\nUnclear brief → Ops → nearest golden page; public marketing → Express.\n\n## Recommended agent workflow (summary)\n\n1. Pin subject, audience, surface, and the first viewport’s single job \n2. Prefer MCP: `recommend_page` → `get_golden_page` → `get_component` / `get_example` \n3. Without MCP, read skill `references/` (layouts, surfaces, feedback) \n4. Feedback defaults to `message`; `toast` only for summary+detail / async feel \n5. Review with the skill checklist; run MCP `validate_page` when available \n\nFull rules and hard boundaries live in the project’s `SKILL.md` — this page does not duplicate it.\n\n## Next steps\n\n- [One-shot setup](/docs/setup): install the skill and related config \n- [AI setup](/docs/ai-setup): AI page-generation workflow \n- [Agent MCP](/docs/mcp): tools and client config \n- [Quick start](/docs/quick-start): manual library install \n- [Components](/components): browse APIs\n",
25691
26043
  "sections": [
25692
26044
  {
25693
26045
  "title": "",
@@ -25717,7 +26069,7 @@
25717
26069
  {
25718
26070
  "title": "Recommended agent workflow (summary)",
25719
26071
  "id": "recommended-agent-workflow-summary",
25720
- "body": "1. Pin subject, audience, surface, and the first viewport’s single job \n2. Prefer MCP: `recommend_page` → `get_golden_page` → `get_component` / `get_example` \n3. Without MCP, read project `docs/golden-pages/` and skill `references/` \n4. Feedback defaults to `message`; `toast` only for summary+detail / async feel \n5. Review with the skill checklist; run MCP `validate_page` when available \n\nFull rules and hard boundaries live in the project’s `SKILL.md` — this page does not duplicate it."
26072
+ "body": "1. Pin subject, audience, surface, and the first viewport’s single job \n2. Prefer MCP: `recommend_page` → `get_golden_page` → `get_component` / `get_example` \n3. Without MCP, read skill `references/` (layouts, surfaces, feedback) \n4. Feedback defaults to `message`; `toast` only for summary+detail / async feel \n5. Review with the skill checklist; run MCP `validate_page` when available \n\nFull rules and hard boundaries live in the project’s `SKILL.md` — this page does not duplicate it."
25721
26073
  },
25722
26074
  {
25723
26075
  "title": "Next steps",