@morya-ui/mcp 0.2.6 → 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-16T08:53:15.402Z",
2
+ "generatedAt": "2026-09-21T01:38:25.787Z",
3
3
  "library": {
4
4
  "name": "morya-ui",
5
- "version": "0.2.6"
5
+ "version": "0.2.8"
6
6
  },
7
7
  "mcp": {
8
8
  "name": "@morya-ui/mcp",
9
- "version": "0.2.6"
9
+ "version": "0.2.8"
10
10
  },
11
11
  "components": [
12
12
  {
@@ -6690,33 +6690,63 @@
6690
6690
  "name": "Empty",
6691
6691
  "exportName": "MEmpty",
6692
6692
  "category": "05 / FEEDBACK",
6693
- "description": "空状态:图标 / 插图 + 标题 + 说明 + 操作。",
6694
- "descriptionEn": "Empty state with icon/image, title, description, and actions.",
6693
+ "description": "空状态:插图 / 图标 + 标题 + 说明 + 操作。",
6694
+ "descriptionEn": "Empty states with illustration / icon, title, description, and actions.",
6695
6695
  "import": "import { MEmpty } from 'morya-ui'",
6696
6696
  "props": [
6697
6697
  {
6698
6698
  "name": "title",
6699
6699
  "type": "string",
6700
- "default": "locale `emptyMessage",
6701
- "description": "标题。"
6700
+ "default": "",
6701
+ "description": "可选标题;传空字符串可隐藏。"
6702
6702
  },
6703
6703
  {
6704
6704
  "name": "description",
6705
6705
  "type": "string",
6706
+ "default": "locale `emptyMessage",
6707
+ "description": "说明文案;默认插槽可覆盖。"
6708
+ },
6709
+ {
6710
+ "name": "showDescription",
6711
+ "type": "boolean",
6712
+ "default": "true",
6713
+ "description": "是否显示说明。"
6714
+ },
6715
+ {
6716
+ "name": "showIcon",
6717
+ "type": "boolean",
6718
+ "default": "true",
6719
+ "description": "是否显示插图 / 图标。"
6720
+ },
6721
+ {
6722
+ "name": "illustration",
6723
+ "type": "EmptyIllustration",
6706
6724
  "default": "—",
6707
- "description": "说明文案。"
6725
+ "description": "内置插图名;按需加载,优先于默认轻量图标 / `icon=\"search\"` 映射。"
6708
6726
  },
6709
6727
  {
6710
6728
  "name": "icon",
6711
6729
  "type": "[IconName](/docs/types#IconName)",
6712
- "default": "'database'",
6713
- "description": "视觉锚点图标;有 `image` 时忽略。"
6730
+ "default": "",
6731
+ "description": "可选图标;未传且无 `image` / 插槽时显示轻量默认图标;`search` 映射 `no-result`。"
6714
6732
  },
6715
6733
  {
6716
6734
  "name": "image",
6717
6735
  "type": "string",
6718
6736
  "default": "—",
6719
- "description": "插图 URL,优先于 `icon`。"
6737
+ "description": "插图 URL,优先于 `illustration` / `icon`。"
6738
+ },
6739
+ {
6740
+ "name": "size",
6741
+ "type": "'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'",
6742
+ "default": "'medium'",
6743
+ "description": "尺寸。"
6744
+ },
6745
+ {
6746
+ "name": "simple",
6747
+ "type": "boolean",
6748
+ "default": "false",
6749
+ "description": "紧凑横向布局。"
6720
6750
  },
6721
6751
  {
6722
6752
  "name": "pt",
@@ -6740,16 +6770,12 @@
6740
6770
  "description": "自定义标题。"
6741
6771
  },
6742
6772
  {
6743
- "name": "description",
6744
- "description": "自定义说明。"
6773
+ "name": "default",
6774
+ "description": "覆盖说明文案。"
6745
6775
  },
6746
6776
  {
6747
6777
  "name": "extra",
6748
6778
  "description": "操作区。"
6749
- },
6750
- {
6751
- "name": "default",
6752
- "description": "同 `extra`,追加在操作区。"
6753
6779
  }
6754
6780
  ],
6755
6781
  "examples": [
@@ -6759,7 +6785,7 @@
6759
6785
  "sectionId": "引入",
6760
6786
  "lang": "ts",
6761
6787
  "preview": false,
6762
- "code": "import { MEmpty } from 'morya-ui'",
6788
+ "code": "import { MEmpty } from \"morya-ui\";",
6763
6789
  "locale": "zh-CN"
6764
6790
  },
6765
6791
  {
@@ -6789,13 +6815,31 @@
6789
6815
  "code": "<script setup lang=\"ts\">\nimport { MEmpty } from 'morya-ui'\n</script>\n\n<template>\n <MEmpty\n title=\"没有匹配结果\"\n description=\"试试调整筛选条件,或清除搜索关键词。\"\n icon=\"search\"\n />\n</template>",
6790
6816
  "locale": "zh-CN"
6791
6817
  },
6818
+ {
6819
+ "id": "内置插图-1",
6820
+ "section": "内置插图",
6821
+ "sectionId": "内置插图",
6822
+ "lang": "vue",
6823
+ "preview": true,
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
+ "locale": "zh-CN"
6826
+ },
6827
+ {
6828
+ "id": "紧凑模式-1",
6829
+ "section": "紧凑模式",
6830
+ "sectionId": "紧凑模式",
6831
+ "lang": "vue",
6832
+ "preview": true,
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
+ "locale": "zh-CN"
6835
+ },
6792
6836
  {
6793
6837
  "id": "import-1",
6794
6838
  "section": "Import",
6795
6839
  "sectionId": "import",
6796
6840
  "lang": "ts",
6797
6841
  "preview": false,
6798
- "code": "import { MEmpty } from 'morya-ui'",
6842
+ "code": "import { MEmpty } from \"morya-ui\";",
6799
6843
  "locale": "en-US"
6800
6844
  },
6801
6845
  {
@@ -6824,47 +6868,75 @@
6824
6868
  "preview": true,
6825
6869
  "code": "<script setup lang=\"ts\">\nimport { MEmpty } from 'morya-ui'\n</script>\n\n<template>\n <MEmpty\n title=\"No matching results\"\n description=\"Try adjusting filters or clearing the search query.\"\n icon=\"search\"\n />\n</template>",
6826
6870
  "locale": "en-US"
6871
+ },
6872
+ {
6873
+ "id": "built-in-illustrations-1",
6874
+ "section": "Built-in illustrations",
6875
+ "sectionId": "built-in-illustrations",
6876
+ "lang": "vue",
6877
+ "preview": true,
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
+ "locale": "en-US"
6880
+ },
6881
+ {
6882
+ "id": "compact-1",
6883
+ "section": "Compact",
6884
+ "sectionId": "compact",
6885
+ "lang": "vue",
6886
+ "preview": true,
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
+ "locale": "en-US"
6827
6889
  }
6828
6890
  ],
6829
6891
  "locales": {
6830
6892
  "zh-CN": {
6831
6893
  "title": "Empty",
6832
- "description": "空状态:图标 / 插图 + 标题 + 说明 + 操作。",
6894
+ "description": "空状态:插图 / 图标 + 标题 + 说明 + 操作。",
6833
6895
  "sections": [
6834
6896
  {
6835
6897
  "id": "overview",
6836
6898
  "title": "",
6837
- "body": "# Empty\n\n用于列表无数据、筛选无结果、首次使用等场景。不要用错误色表达正常的无数据状态;接口失败请用 [Result](/components/Result) 或 Message"
6899
+ "body": "# Empty\n\n用于列表无数据、筛选无结果、首次使用等场景。不要用错误色表达正常的无数据状态;接口失败请用 [Result](/components/Result) 或 Message。\n\n默认展示轻量空态图标与 locale `emptyMessage`。内置彩色插图按需加载,通过 `illustration` 显式选用;也可用 `icon`、`image` 或插槽替换视觉。"
6838
6900
  },
6839
6901
  {
6840
6902
  "id": "引入",
6841
6903
  "title": "引入",
6842
- "body": "```ts\nimport { MEmpty } from 'morya-ui'\n```"
6904
+ "body": "```ts\nimport { MEmpty } from \"morya-ui\";\n```"
6843
6905
  },
6844
6906
  {
6845
6907
  "id": "基础用法",
6846
6908
  "title": "基础用法",
6847
- "body": "未传 `title` 时使用 locale 的 `emptyMessage`。\n\n```vue preview src=\"./demos/Basic.vue\"\n```"
6909
+ "body": "未传 `description` 时使用 locale 的 `emptyMessage`。未传 `icon` / `image` / `illustration` 时使用轻量默认图标(不打包插画 catalog)。\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```"
6848
6910
  },
6849
6911
  {
6850
6912
  "id": "操作区",
6851
6913
  "title": "操作区",
6852
- "body": "通过 `#extra`(或默认插槽)放置恢复动作。\n\n```vue preview src=\"./demos/WithActions.zh.vue\"\n```"
6914
+ "body": "通过 `#extra` 放置恢复动作;默认插槽覆盖说明文案。\n\n```vue preview src=\"./demos/WithActions.zh.vue\"\n\n```"
6853
6915
  },
6854
6916
  {
6855
6917
  "id": "无结果",
6856
6918
  "title": "无结果",
6857
- "body": "```vue preview src=\"./demos/NoResult.zh.vue\"\n```"
6919
+ "body": "`icon=\"search\"` 或 `illustration=\"no-result\"` 使用搜索空结果插图(按需加载)。\n\n```vue preview src=\"./demos/NoResult.zh.vue\"\n\n```"
6920
+ },
6921
+ {
6922
+ "id": "内置插图",
6923
+ "title": "内置插图",
6924
+ "body": "空态推荐:`no-content` / `no-result` / `no-message` / `no-schedule` / `no-issue`。仅在传入 `illustration` 时加载对应 SVG。\n\n```vue preview src=\"./demos/Illustrations.zh.vue\"\n\n```"
6925
+ },
6926
+ {
6927
+ "id": "紧凑模式",
6928
+ "title": "紧凑模式",
6929
+ "body": "`simple` 为横向紧凑布局,适合表格分组、侧栏等窄区域。\n\n```vue preview src=\"./demos/Simple.zh.vue\"\n\n```"
6858
6930
  },
6859
6931
  {
6860
6932
  "id": "props",
6861
6933
  "title": "Props",
6862
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | locale `emptyMessage` | 标题。 |\n| `description` | `string` | | 说明文案。 |\n| `icon` | [IconName](/docs/types#IconName) | `'database'` | 视觉锚点图标;有 `image` 时忽略。 |\n| `image` | `string` | — | 插图 URL,优先于 `icon`。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
6934
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| ------------------ | ---------------------------------------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------- |\n| `title` | `string` | | 可选标题;传空字符串可隐藏。 |\n| `description` | `string` | locale `emptyMessage` | 说明文案;默认插槽可覆盖。 |\n| `showDescription` | `boolean` | `true` | 是否显示说明。 |\n| `showIcon` | `boolean` | `true` | 是否显示插图 / 图标。 |\n| `illustration` | `EmptyIllustration` | — | 内置插图名;按需加载,优先于默认轻量图标 / `icon=\"search\"` 映射。 |\n| `icon` | [IconName](/docs/types#IconName) | | 可选图标;未传且无 `image` / 插槽时显示轻量默认图标;`search` 映射 `no-result`。 |\n| `image` | `string` | — | 插图 URL,优先于 `illustration` / `icon`。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | `'medium'` | 尺寸。 |\n| `simple` | `boolean` | `false` | 紧凑横向布局。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
6863
6935
  },
6864
6936
  {
6865
6937
  "id": "slots",
6866
6938
  "title": "Slots",
6867
- "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `icon` | 自定义图标区。 |\n| `image` | 自定义插图区。 |\n| `title` | 自定义标题。 |\n| `description` | 自定义说明。 |\n| `extra` | 操作区。 |\n| `default` | 同 `extra`,追加在操作区。 |"
6939
+ "body": "| 插槽名 | 说明 |\n| --------- | -------------------------- |\n| `icon` | 自定义图标区。 |\n| `image` | 自定义插图区。 |\n| `title` | 自定义标题。 |\n| `default` | 覆盖说明文案。 |\n| `extra` | 操作区。 |"
6868
6940
  },
6869
6941
  {
6870
6942
  "id": "无障碍",
@@ -6877,51 +6949,61 @@
6877
6949
  "body": "无自定义事件。"
6878
6950
  }
6879
6951
  ],
6880
- "markdown": "---\ntitle: Empty\ncategory: 05 / FEEDBACK\ndescription: 空状态:图标 / 插图 + 标题 + 说明 + 操作。\n---\n\n# Empty\n\n用于列表无数据、筛选无结果、首次使用等场景。不要用错误色表达正常的无数据状态;接口失败请用 [Result](/components/Result) 或 Message。\n\n## 引入\n\n```ts\nimport { MEmpty } from 'morya-ui'\n```\n\n## 基础用法\n\n未传 `title` 时使用 locale 的 `emptyMessage`。\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## 操作区\n\n通过 `#extra`(或默认插槽)放置恢复动作。\n\n```vue preview src=\"./demos/WithActions.zh.vue\"\n```\n\n## 无结果\n\n```vue preview src=\"./demos/NoResult.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | locale `emptyMessage` | 标题。 |\n| `description` | `string` | | 说明文案。 |\n| `icon` | [IconName](/docs/types#IconName) | `'database'` | 视觉锚点图标;有 `image` 时忽略。 |\n| `image` | `string` | — | 插图 URL,优先于 `icon`。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `icon` | 自定义图标区。 |\n| `image` | 自定义插图区。 |\n| `title` | 自定义标题。 |\n| `description` | 自定义说明。 |\n| `extra` | 操作区。 |\n| `default` | 同 `extra`,追加在操作区。 |\n\n## 无障碍\n\n- 根节点使用 `role=\"status\"`。\n- 装饰性图标 / 插图使用 `aria-hidden`;操作按钮需有可见文案。\n\n## Events\n\n无自定义事件。\n"
6952
+ "markdown": "---\ntitle: Empty\ncategory: 05 / FEEDBACK\ndescription: 空状态:插图 / 图标 + 标题 + 说明 + 操作。\n---\n\n# Empty\n\n用于列表无数据、筛选无结果、首次使用等场景。不要用错误色表达正常的无数据状态;接口失败请用 [Result](/components/Result) 或 Message。\n\n默认展示轻量空态图标与 locale `emptyMessage`。内置彩色插图按需加载,通过 `illustration` 显式选用;也可用 `icon`、`image` 或插槽替换视觉。\n\n## 引入\n\n```ts\nimport { MEmpty } from \"morya-ui\";\n```\n\n## 基础用法\n\n未传 `description` 时使用 locale 的 `emptyMessage`。未传 `icon` / `image` / `illustration` 时使用轻量默认图标(不打包插画 catalog)。\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n## 操作区\n\n通过 `#extra` 放置恢复动作;默认插槽覆盖说明文案。\n\n```vue preview src=\"./demos/WithActions.zh.vue\"\n\n```\n\n## 无结果\n\n`icon=\"search\"` 或 `illustration=\"no-result\"` 使用搜索空结果插图(按需加载)。\n\n```vue preview src=\"./demos/NoResult.zh.vue\"\n\n```\n\n## 内置插图\n\n空态推荐:`no-content` / `no-result` / `no-message` / `no-schedule` / `no-issue`。仅在传入 `illustration` 时加载对应 SVG。\n\n```vue preview src=\"./demos/Illustrations.zh.vue\"\n\n```\n\n## 紧凑模式\n\n`simple` 为横向紧凑布局,适合表格分组、侧栏等窄区域。\n\n```vue preview src=\"./demos/Simple.zh.vue\"\n\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| ------------------ | ---------------------------------------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------- |\n| `title` | `string` | | 可选标题;传空字符串可隐藏。 |\n| `description` | `string` | locale `emptyMessage` | 说明文案;默认插槽可覆盖。 |\n| `showDescription` | `boolean` | `true` | 是否显示说明。 |\n| `showIcon` | `boolean` | `true` | 是否显示插图 / 图标。 |\n| `illustration` | `EmptyIllustration` | — | 内置插图名;按需加载,优先于默认轻量图标 / `icon=\"search\"` 映射。 |\n| `icon` | [IconName](/docs/types#IconName) | | 可选图标;未传且无 `image` / 插槽时显示轻量默认图标;`search` 映射 `no-result`。 |\n| `image` | `string` | — | 插图 URL,优先于 `illustration` / `icon`。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | `'medium'` | 尺寸。 |\n| `simple` | `boolean` | `false` | 紧凑横向布局。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --------- | -------------------------- |\n| `icon` | 自定义图标区。 |\n| `image` | 自定义插图区。 |\n| `title` | 自定义标题。 |\n| `default` | 覆盖说明文案。 |\n| `extra` | 操作区。 |\n\n## 无障碍\n\n- 根节点使用 `role=\"status\"`。\n- 装饰性图标 / 插图使用 `aria-hidden`;操作按钮需有可见文案。\n\n## Events\n\n无自定义事件。\n"
6881
6953
  },
6882
6954
  "en-US": {
6883
6955
  "title": "Empty",
6884
- "description": "Empty state with icon/image, title, description, and actions.",
6956
+ "description": "Empty states with illustration / icon, title, description, and actions.",
6885
6957
  "sections": [
6886
6958
  {
6887
6959
  "id": "overview",
6888
6960
  "title": "",
6889
- "body": "# Empty\n\nFor no-data lists, filtered results, and first-use screens. Do not style normal emptiness as an error; use [Result](/components/Result) or Message for failures."
6961
+ "body": "# Empty\n\nFor list no-data, filtered no-results, and first-use prompts. Do not use error colors for normal empty states; use [Result](/components/Result) or Message for failures.\n\n`MEmpty` is a standalone component (no longer a Result wrapper). Rich catalog illustrations load on demand when you pass `illustration`.\n\nBy default it shows a lightweight empty glyph and locale `emptyMessage`. Override with `illustration`, `icon`, `image`, or slots."
6890
6962
  },
6891
6963
  {
6892
6964
  "id": "import",
6893
6965
  "title": "Import",
6894
- "body": "```ts\nimport { MEmpty } from 'morya-ui'\n```"
6966
+ "body": "```ts\nimport { MEmpty } from \"morya-ui\";\n```"
6895
6967
  },
6896
6968
  {
6897
6969
  "id": "basic",
6898
6970
  "title": "Basic",
6899
- "body": "When `title` is omitted, locale `emptyMessage` is used.\n\n```vue preview src=\"./demos/Basic.vue\"\n```"
6971
+ "body": "Without `description`, uses locale `emptyMessage`. Without `icon` / `image` / `illustration`, shows the lightweight default icon (catalog SVGs are not bundled into the Empty entry).\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```"
6900
6972
  },
6901
6973
  {
6902
6974
  "id": "actions",
6903
6975
  "title": "Actions",
6904
- "body": "Put recovery actions in `#extra` (or the default slot).\n\n```vue preview src=\"./demos/WithActions.en.vue\"\n```"
6976
+ "body": "Put recovery actions in `#extra`. The default slot replaces the description text.\n\n```vue preview src=\"./demos/WithActions.en.vue\"\n\n```"
6905
6977
  },
6906
6978
  {
6907
6979
  "id": "no-results",
6908
6980
  "title": "No results",
6909
- "body": "```vue preview src=\"./demos/NoResult.en.vue\"\n```"
6981
+ "body": "`icon=\"search\"` or `illustration=\"no-result\"` uses the search-empty illustration (loaded on demand).\n\n```vue preview src=\"./demos/NoResult.en.vue\"\n\n```"
6982
+ },
6983
+ {
6984
+ "id": "built-in-illustrations",
6985
+ "title": "Built-in illustrations",
6986
+ "body": "Empty-oriented presets: `no-content` / `no-result` / `no-message` / `no-schedule` / `no-issue`. Each SVG loads only when that `illustration` is used.\n\n```vue preview src=\"./demos/Illustrations.zh.vue\"\n\n```"
6987
+ },
6988
+ {
6989
+ "id": "compact",
6990
+ "title": "Compact",
6991
+ "body": "`simple` is a horizontal compact layout for narrow regions such as table groups or sidebars.\n\n```vue preview src=\"./demos/Simple.en.vue\"\n\n```"
6910
6992
  },
6911
6993
  {
6912
6994
  "id": "props",
6913
6995
  "title": "Props",
6914
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `title` | `string` | locale `emptyMessage` | Title. |\n| `description` | `string` | | Supporting copy. |\n| `icon` | [IconName](/docs/types#IconName) | `'database'` | Visual mark; ignored when `image` is set. |\n| `image` | `string` | — | Image URL; takes precedence over `icon`. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
6996
+ "body": "| Prop | Type | Default | Description |\n| ----------------- | ---------------------------------------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------- |\n| `title` | `string` | | Optional title; pass `\"\"` to hide. |\n| `description` | `string` | locale `emptyMessage` | Description; default slot overrides. |\n| `showDescription` | `boolean` | `true` | Whether to show the description. |\n| `showIcon` | `boolean` | `true` | Whether to show the illustration / icon. |\n| `illustration` | `EmptyIllustration` | — | Built-in illustration; loaded on demand; overrides default glyph / `icon=\"search\"` mapping. |\n| `icon` | [IconName](/docs/types#IconName) | | Optional icon; omitted + no image/slot → light default glyph; `search` maps to `no-result`. |\n| `image` | `string` | — | Image URL; wins over `illustration` / `icon`. |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | `'medium'` | Size. |\n| `simple` | `boolean` | `false` | Compact horizontal layout. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |"
6915
6997
  },
6916
6998
  {
6917
6999
  "id": "slots",
6918
7000
  "title": "Slots",
6919
- "body": "| Slot | Description |\n| --- | --- |\n| `icon` | Custom icon area. |\n| `image` | Custom image area. |\n| `title` | Custom title. |\n| `description` | Custom description. |\n| `extra` | Action area. |\n| `default` | Same as `extra`, appended in the action area. |"
7001
+ "body": "| Slot | Description |\n| --------- | -------------------------- |\n| `icon` | Custom icon area. |\n| `image` | Custom image area. |\n| `title` | Custom title. |\n| `default` | Overrides description. |\n| `extra` | Action area. |"
6920
7002
  },
6921
7003
  {
6922
7004
  "id": "accessibility",
6923
7005
  "title": "Accessibility",
6924
- "body": "- Root uses `role=\"status\"`.\n- Decorative icon/image is `aria-hidden`; action buttons need visible labels."
7006
+ "body": "- Root uses `role=\"status\"`.\n- Decorative icons / illustrations use `aria-hidden`; action buttons need visible labels."
6925
7007
  },
6926
7008
  {
6927
7009
  "id": "events",
@@ -6929,7 +7011,7 @@
6929
7011
  "body": "No custom events."
6930
7012
  }
6931
7013
  ],
6932
- "markdown": "---\ntitle: Empty\ncategory: 05 / FEEDBACK\ndescription: Empty state with icon/image, title, description, and actions.\n---\n\n# Empty\n\nFor no-data lists, filtered results, and first-use screens. Do not style normal emptiness as an error; use [Result](/components/Result) or Message for failures.\n\n## Import\n\n```ts\nimport { MEmpty } from 'morya-ui'\n```\n\n## Basic\n\nWhen `title` is omitted, locale `emptyMessage` is used.\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Actions\n\nPut recovery actions in `#extra` (or the default slot).\n\n```vue preview src=\"./demos/WithActions.en.vue\"\n```\n\n## No results\n\n```vue preview src=\"./demos/NoResult.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `title` | `string` | locale `emptyMessage` | Title. |\n| `description` | `string` | | Supporting copy. |\n| `icon` | [IconName](/docs/types#IconName) | `'database'` | Visual mark; ignored when `image` is set. |\n| `image` | `string` | — | Image URL; takes precedence over `icon`. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `icon` | Custom icon area. |\n| `image` | Custom image area. |\n| `title` | Custom title. |\n| `description` | Custom description. |\n| `extra` | Action area. |\n| `default` | Same as `extra`, appended in the action area. |\n\n## Accessibility\n\n- Root uses `role=\"status\"`.\n- Decorative icon/image is `aria-hidden`; action buttons need visible labels.\n\n## Events\n\nNo custom events.\n"
7014
+ "markdown": "---\ntitle: Empty\ncategory: 05 / FEEDBACK\ndescription: Empty states with illustration / icon, title, description, and actions.\n---\n\n# Empty\n\nFor list no-data, filtered no-results, and first-use prompts. Do not use error colors for normal empty states; use [Result](/components/Result) or Message for failures.\n\n`MEmpty` is a standalone component (no longer a Result wrapper). Rich catalog illustrations load on demand when you pass `illustration`.\n\nBy default it shows a lightweight empty glyph and locale `emptyMessage`. Override with `illustration`, `icon`, `image`, or slots.\n\n## Import\n\n```ts\nimport { MEmpty } from \"morya-ui\";\n```\n\n## Basic\n\nWithout `description`, uses locale `emptyMessage`. Without `icon` / `image` / `illustration`, shows the lightweight default icon (catalog SVGs are not bundled into the Empty entry).\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n## Actions\n\nPut recovery actions in `#extra`. The default slot replaces the description text.\n\n```vue preview src=\"./demos/WithActions.en.vue\"\n\n```\n\n## No results\n\n`icon=\"search\"` or `illustration=\"no-result\"` uses the search-empty illustration (loaded on demand).\n\n```vue preview src=\"./demos/NoResult.en.vue\"\n\n```\n\n## Built-in illustrations\n\nEmpty-oriented presets: `no-content` / `no-result` / `no-message` / `no-schedule` / `no-issue`. Each SVG loads only when that `illustration` is used.\n\n```vue preview src=\"./demos/Illustrations.zh.vue\"\n\n```\n\n## Compact\n\n`simple` is a horizontal compact layout for narrow regions such as table groups or sidebars.\n\n```vue preview src=\"./demos/Simple.en.vue\"\n\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| ----------------- | ---------------------------------------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------- |\n| `title` | `string` | | Optional title; pass `\"\"` to hide. |\n| `description` | `string` | locale `emptyMessage` | Description; default slot overrides. |\n| `showDescription` | `boolean` | `true` | Whether to show the description. |\n| `showIcon` | `boolean` | `true` | Whether to show the illustration / icon. |\n| `illustration` | `EmptyIllustration` | — | Built-in illustration; loaded on demand; overrides default glyph / `icon=\"search\"` mapping. |\n| `icon` | [IconName](/docs/types#IconName) | | Optional icon; omitted + no image/slot → light default glyph; `search` maps to `no-result`. |\n| `image` | `string` | — | Image URL; wins over `illustration` / `icon`. |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | `'medium'` | Size. |\n| `simple` | `boolean` | `false` | Compact horizontal layout. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |\n\n## Slots\n\n| Slot | Description |\n| --------- | -------------------------- |\n| `icon` | Custom icon area. |\n| `image` | Custom image area. |\n| `title` | Custom title. |\n| `default` | Overrides description. |\n| `extra` | Action area. |\n\n## Accessibility\n\n- Root uses `role=\"status\"`.\n- Decorative icons / illustrations use `aria-hidden`; action buttons need visible labels.\n\n## Events\n\nNo custom events.\n"
6933
7015
  }
6934
7016
  }
6935
7017
  },
@@ -7500,7 +7582,7 @@
7500
7582
  {
7501
7583
  "id": "overview",
7502
7584
  "title": "",
7503
- "body": "# FileUpload\n\n选择本地文件。支持点击选择、拖拽上传、文本 / 图片列表、卡片墙,以及通过 `action` 或 `httpRequest` 实际上传。`select` 仍会返回本次选中的 `File[]`,完整状态用 `v-model:file-list`。默认展示文件列表;提供上传地址或自定义请求后会自动上传。\n\n**与 Naive `n-upload` 命名对照:**\n\n| Naive | Wi |\n| --- | --- |\n| `action` | `action` |\n| `file-list` | `fileList`(`v-model:file-list`) |\n| `list-type` | `listType` |\n| `directory` | `directory`(`webkitdirectory`,浏览器支持文件夹选择) |\n| `custom-request` | `httpRequest` |\n| `name` | `name` |\n\n队列 UI 细控(如自定义队列按钮布局)本期不做。"
7585
+ "body": "# FileUpload\n\n选择本地文件。支持点击选择、拖拽上传、文本 / 图片列表、卡片墙,以及通过 `action` 或 `httpRequest` 实际上传。`select` 仍会返回本次选中的 `File[]`,完整状态用 `v-model:file-list`。默认展示文件列表;提供上传地址或自定义请求后会自动上传。\n\n常用能力:`action` / `httpRequest` 实际上传,`v-model:file-list` 管理队列,`listType` 控制列表样式,`directory` 支持文件夹选择(浏览器能力允许时)。\n\n队列 UI 细控(如自定义队列按钮布局)本期不做。"
7504
7586
  },
7505
7587
  {
7506
7588
  "id": "引入",
@@ -7568,7 +7650,7 @@
7568
7650
  "body": "<h4 id=\"FileUploadFile\">FileUploadFile</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface FileUploadFile {\n uid: string\n name: string\n size?: number\n type?: string\n status: FileUploadStatus\n percentage?: number\n url?: string\n raw?: File\n response?: unknown\n error?: string\n}\n```"
7569
7651
  }
7570
7652
  ],
7571
- "markdown": "---\ntitle: FileUpload\ncategory: 02 / FORM\ndescription: 选择、拖拽、列表、预览与上传。\n---\n\n# FileUpload\n\n选择本地文件。支持点击选择、拖拽上传、文本 / 图片列表、卡片墙,以及通过 `action` 或 `httpRequest` 实际上传。`select` 仍会返回本次选中的 `File[]`,完整状态用 `v-model:file-list`。默认展示文件列表;提供上传地址或自定义请求后会自动上传。\n\n**与 Naive `n-upload` 命名对照:**\n\n| Naive | Wi |\n| --- | --- |\n| `action` | `action` |\n| `file-list` | `fileList`(`v-model:file-list`) |\n| `list-type` | `listType` |\n| `directory` | `directory`(`webkitdirectory`,浏览器支持文件夹选择) |\n| `custom-request` | `httpRequest` |\n| `name` | `name` |\n\n队列 UI 细控(如自定义队列按钮布局)本期不做。\n\n## 引入\n\n```ts\nimport { MFileUpload } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Drag to upload\n\n设置 `drag` 后出现虚线拖放区:可拖入文件,也可点击区域选择。\n\n```vue preview src=\"./demos/DragToUpload.zh.vue\"\n```\n\n## Picture list\n\n`list-type=\"picture\"` 在列表中显示缩略图,可预览或删除。\n\n```vue preview src=\"./demos/PictureList.vue\"\n```\n\n## Picture card\n\n照片墙:加号卡片选择文件,悬停可预览 / 删除。也可直接把图片拖到卡片区域。\n\n```vue preview src=\"./demos/PictureCard.vue\"\n```\n\n## Auto upload\n\n提供 `httpRequest`(或 `action`)后默认自动上传。下面用本地模拟请求,不依赖真实接口。\n\n```vue preview src=\"./demos/AutoUpload.zh.vue\"\n```\n\n## Manual upload\n\n`auto-upload=\"false\"` 时先加入列表,再点「上传」。`before-upload` 可拦截不合格文件。\n\n```vue preview src=\"./demos/ManualUpload.zh.vue\"\n```\n\n## Instance methods\n\n通过模板 ref 可以控制选择器、提交队列、取消上传和清空列表。\n\n```vue preview src=\"./demos/InstanceMethods.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `mode` | `'basic' \\| 'advanced'` | `'basic'` | 视觉变体。文件列表由 `showFileList` 控制。 |\n| `multiple` | `boolean` | `false` | 多选。关闭时新选择会替换当前列表。 |\n| `directory` | `boolean` | `false` | 选择文件夹(`webkitdirectory`),同时开启多选。 |\n| `accept` | `string` | — | 接受的文件类型,拖入时同样过滤。 |\n| `drag` | `boolean` | `false` | 启用拖拽上传区域。 |\n| `limit` | `number` | — | 最多文件数;本次选择会使总数超出时触发 `exceed`,整批不加入。 |\n| `maxSize` | `number` | — | 单文件最大字节数,超出则跳过。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `chooseLabel` | `string` | `'选择文件'` | 按钮 / 拖放区无障碍名称。 |\n| `showFileList` | `boolean` | `true` | 是否显示列表。 |\n| `listType` | `'text' \\| 'picture' \\| 'picture-card'` | `'text'` | 列表样式。`picture-card` 用加号卡片作为触发器。 |\n| `fileList` | `FileUploadFile[]` | — | 文件列表,配合 `v-model:file-list`。 |\n| `action` | `string` | — | 上传地址。设置后默认自动上传。 |\n| `method` | `string` | `'post'` | 请求方法。 |\n| `name` | `string` | `'file'` | 表单字段名。 |\n| `headers` | `Record<string, string>` | — | 额外请求头。 |\n| `data` | `object \\| (() => object)` | — | 随文件一起提交的字段。 |\n| `withCredentials` | `boolean` | `false` | 跨域携带 cookie。 |\n| `autoUpload` | `boolean` | `true` | 是否选完即传。需要同时提供 `action` 或 `httpRequest`。 |\n| `httpRequest` | `(options) => void \\| Promise \\| XMLHttpRequest` | — | 自定义上传。返回 Promise 时以 resolve 值为成功响应。 |\n| `beforeUpload` | `(file, uploadFile) => boolean \\| Promise` | — | 上传前钩子,返回 `false` 则跳过该文件。 |\n| `beforeRemove` | `(uploadFile, fileList) => boolean \\| Promise` | — | 删除前钩子,返回 `false` 则取消删除。 |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `select` | `File[]` | 选择或拖入完成(已通过类型 / 大小 / `beforeUpload` 过滤)。 |\n| `exceed` | `File[]` | 超过 `limit`。 |\n| `update:fileList` | `FileUploadFile[]` | 列表变化。 |\n| `change` | `file, fileList` | 单个文件状态变化。 |\n| `remove` | `file` | 从列表移除。 |\n| `preview` | `file` | 点击预览。 |\n| `progress` | `file, percent` | 上传进度。 |\n| `success` | `file, response` | 上传成功。 |\n| `error` | `file, error` | 上传失败。 |\n| `abort` | — | — |\n| `exceed-size` | — | — |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 自定义拖放区内容(仅 `drag`)。 |\n| `trigger` | 自定义选择按钮内容(非 `picture-card`)。 |\n| `tip` | 触发区下方的提示。 |\n| `file` | 自定义列表项,作用域 `{ file }`。 |\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `openPicker()` | 打开系统文件选择框。 |\n| `submit()` | 上传列表中 `ready` / `fail` 的文件。 |\n| `abort(file?)` | 取消进行中的请求;不传则全部取消。 |\n| `clear()` / `clearFiles()` | 清空列表并中止上传。 |\n\n## 类型\n\n<h4 id=\"FileUploadFile\">FileUploadFile</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface FileUploadFile {\n uid: string\n name: string\n size?: number\n type?: string\n status: FileUploadStatus\n percentage?: number\n url?: string\n raw?: File\n response?: unknown\n error?: string\n}\n```\n"
7653
+ "markdown": "---\ntitle: FileUpload\ncategory: 02 / FORM\ndescription: 选择、拖拽、列表、预览与上传。\n---\n\n# FileUpload\n\n选择本地文件。支持点击选择、拖拽上传、文本 / 图片列表、卡片墙,以及通过 `action` 或 `httpRequest` 实际上传。`select` 仍会返回本次选中的 `File[]`,完整状态用 `v-model:file-list`。默认展示文件列表;提供上传地址或自定义请求后会自动上传。\n\n常用能力:`action` / `httpRequest` 实际上传,`v-model:file-list` 管理队列,`listType` 控制列表样式,`directory` 支持文件夹选择(浏览器能力允许时)。\n\n队列 UI 细控(如自定义队列按钮布局)本期不做。\n\n## 引入\n\n```ts\nimport { MFileUpload } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Drag to upload\n\n设置 `drag` 后出现虚线拖放区:可拖入文件,也可点击区域选择。\n\n```vue preview src=\"./demos/DragToUpload.zh.vue\"\n```\n\n## Picture list\n\n`list-type=\"picture\"` 在列表中显示缩略图,可预览或删除。\n\n```vue preview src=\"./demos/PictureList.vue\"\n```\n\n## Picture card\n\n照片墙:加号卡片选择文件,悬停可预览 / 删除。也可直接把图片拖到卡片区域。\n\n```vue preview src=\"./demos/PictureCard.vue\"\n```\n\n## Auto upload\n\n提供 `httpRequest`(或 `action`)后默认自动上传。下面用本地模拟请求,不依赖真实接口。\n\n```vue preview src=\"./demos/AutoUpload.zh.vue\"\n```\n\n## Manual upload\n\n`auto-upload=\"false\"` 时先加入列表,再点「上传」。`before-upload` 可拦截不合格文件。\n\n```vue preview src=\"./demos/ManualUpload.zh.vue\"\n```\n\n## Instance methods\n\n通过模板 ref 可以控制选择器、提交队列、取消上传和清空列表。\n\n```vue preview src=\"./demos/InstanceMethods.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `mode` | `'basic' \\| 'advanced'` | `'basic'` | 视觉变体。文件列表由 `showFileList` 控制。 |\n| `multiple` | `boolean` | `false` | 多选。关闭时新选择会替换当前列表。 |\n| `directory` | `boolean` | `false` | 选择文件夹(`webkitdirectory`),同时开启多选。 |\n| `accept` | `string` | — | 接受的文件类型,拖入时同样过滤。 |\n| `drag` | `boolean` | `false` | 启用拖拽上传区域。 |\n| `limit` | `number` | — | 最多文件数;本次选择会使总数超出时触发 `exceed`,整批不加入。 |\n| `maxSize` | `number` | — | 单文件最大字节数,超出则跳过。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `chooseLabel` | `string` | `'选择文件'` | 按钮 / 拖放区无障碍名称。 |\n| `showFileList` | `boolean` | `true` | 是否显示列表。 |\n| `listType` | `'text' \\| 'picture' \\| 'picture-card'` | `'text'` | 列表样式。`picture-card` 用加号卡片作为触发器。 |\n| `fileList` | `FileUploadFile[]` | — | 文件列表,配合 `v-model:file-list`。 |\n| `action` | `string` | — | 上传地址。设置后默认自动上传。 |\n| `method` | `string` | `'post'` | 请求方法。 |\n| `name` | `string` | `'file'` | 表单字段名。 |\n| `headers` | `Record<string, string>` | — | 额外请求头。 |\n| `data` | `object \\| (() => object)` | — | 随文件一起提交的字段。 |\n| `withCredentials` | `boolean` | `false` | 跨域携带 cookie。 |\n| `autoUpload` | `boolean` | `true` | 是否选完即传。需要同时提供 `action` 或 `httpRequest`。 |\n| `httpRequest` | `(options) => void \\| Promise \\| XMLHttpRequest` | — | 自定义上传。返回 Promise 时以 resolve 值为成功响应。 |\n| `beforeUpload` | `(file, uploadFile) => boolean \\| Promise` | — | 上传前钩子,返回 `false` 则跳过该文件。 |\n| `beforeRemove` | `(uploadFile, fileList) => boolean \\| Promise` | — | 删除前钩子,返回 `false` 则取消删除。 |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `select` | `File[]` | 选择或拖入完成(已通过类型 / 大小 / `beforeUpload` 过滤)。 |\n| `exceed` | `File[]` | 超过 `limit`。 |\n| `update:fileList` | `FileUploadFile[]` | 列表变化。 |\n| `change` | `file, fileList` | 单个文件状态变化。 |\n| `remove` | `file` | 从列表移除。 |\n| `preview` | `file` | 点击预览。 |\n| `progress` | `file, percent` | 上传进度。 |\n| `success` | `file, response` | 上传成功。 |\n| `error` | `file, error` | 上传失败。 |\n| `abort` | — | — |\n| `exceed-size` | — | — |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 自定义拖放区内容(仅 `drag`)。 |\n| `trigger` | 自定义选择按钮内容(非 `picture-card`)。 |\n| `tip` | 触发区下方的提示。 |\n| `file` | 自定义列表项,作用域 `{ file }`。 |\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `openPicker()` | 打开系统文件选择框。 |\n| `submit()` | 上传列表中 `ready` / `fail` 的文件。 |\n| `abort(file?)` | 取消进行中的请求;不传则全部取消。 |\n| `clear()` / `clearFiles()` | 清空列表并中止上传。 |\n\n## 类型\n\n<h4 id=\"FileUploadFile\">FileUploadFile</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface FileUploadFile {\n uid: string\n name: string\n size?: number\n type?: string\n status: FileUploadStatus\n percentage?: number\n url?: string\n raw?: File\n response?: unknown\n error?: string\n}\n```\n"
7572
7654
  },
7573
7655
  "en-US": {
7574
7656
  "title": "FileUpload",
@@ -7577,7 +7659,7 @@
7577
7659
  {
7578
7660
  "id": "overview",
7579
7661
  "title": "",
7580
- "body": "# FileUpload\n\nPick local files. Supports click-to-choose, drag-and-drop, text / picture lists, a picture-card wall, and real uploads via `action` or `httpRequest`. `select` still emits the chosen `File[]`; the full list is `v-model:file-list`. The file list is shown by default; files upload automatically when `action` or `httpRequest` is set.\n\n**Naive `n-upload` name map:**\n\n| Naive | Wi |\n| --- | --- |\n| `action` | `action` |\n| `file-list` | `fileList` (`v-model:file-list`) |\n| `list-type` | `listType` |\n| `directory` | `directory` (`webkitdirectory`; folder pick where the browser supports it) |\n| `custom-request` | `httpRequest` |\n| `name` | `name` |\n\nQueue UI extras are out of scope this batch."
7662
+ "body": "# FileUpload\n\nPick local files. Supports click-to-choose, drag-and-drop, text / picture lists, a picture-card wall, and real uploads via `action` or `httpRequest`. `select` still emits the chosen `File[]`; the full list is `v-model:file-list`. The file list is shown by default; files upload automatically when `action` or `httpRequest` is set.\n\nCommon options: `action` / `httpRequest` for real uploads, `v-model:file-list` for the queue, `listType` for list chrome, and `directory` for folder pick when the browser supports it.\n\nQueue UI extras are out of scope this batch."
7581
7663
  },
7582
7664
  {
7583
7665
  "id": "import",
@@ -7645,7 +7727,7 @@
7645
7727
  "body": "<h4 id=\"FileUploadFile\">FileUploadFile</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface FileUploadFile {\n uid: string\n name: string\n size?: number\n type?: string\n status: FileUploadStatus\n percentage?: number\n url?: string\n raw?: File\n response?: unknown\n error?: string\n}\n```"
7646
7728
  }
7647
7729
  ],
7648
- "markdown": "---\ntitle: FileUpload\ncategory: 02 / FORM\ndescription: Select, drag, list, preview, and upload.\n---\n\n# FileUpload\n\nPick local files. Supports click-to-choose, drag-and-drop, text / picture lists, a picture-card wall, and real uploads via `action` or `httpRequest`. `select` still emits the chosen `File[]`; the full list is `v-model:file-list`. The file list is shown by default; files upload automatically when `action` or `httpRequest` is set.\n\n**Naive `n-upload` name map:**\n\n| Naive | Wi |\n| --- | --- |\n| `action` | `action` |\n| `file-list` | `fileList` (`v-model:file-list`) |\n| `list-type` | `listType` |\n| `directory` | `directory` (`webkitdirectory`; folder pick where the browser supports it) |\n| `custom-request` | `httpRequest` |\n| `name` | `name` |\n\nQueue UI extras are out of scope this batch.\n\n## Import\n\n```ts\nimport { MFileUpload } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Drag to upload\n\nSet `drag` to show a dashed drop zone. Drop files or click the area to choose.\n\n```vue preview src=\"./demos/DragToUpload.en.vue\"\n```\n\n## Picture list\n\n`list-type=\"picture\"` shows thumbnails in the list, with preview and remove.\n\n```vue preview src=\"./demos/PictureList.vue\"\n```\n\n## Picture card\n\nA photo wall: the plus tile opens the picker; hover to preview or remove. Images can also be dropped onto the card area.\n\n```vue preview src=\"./demos/PictureCard.vue\"\n```\n\n## Auto upload\n\nWith `httpRequest` (or `action`), files upload automatically. The demo mocks the request locally.\n\n```vue preview src=\"./demos/AutoUpload.en.vue\"\n```\n\n## Manual upload\n\nWith `auto-upload=\"false\"`, files join the list first; click Upload to send them. `before-upload` can reject a file.\n\n```vue preview src=\"./demos/ManualUpload.en.vue\"\n```\n\n## Instance methods\n\nUse a template ref to control the picker, upload queue, cancellation, and clearing.\n\n```vue preview src=\"./demos/InstanceMethods.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `mode` | `'basic' \\| 'advanced'` | `'basic'` | Visual variant. Use `showFileList` to toggle the list. |\n| `multiple` | `boolean` | `false` | Multiple selection. When off, a new pick replaces the list. |\n| `directory` | `boolean` | `false` | Pick a folder (`webkitdirectory`); implies multiple. |\n| `accept` | `string` | — | Accepted types; also applied to dropped files. |\n| `drag` | `boolean` | `false` | Enable the drag-and-drop zone. |\n| `limit` | `number` | — | Max files. If this pick would exceed it, `exceed` fires and nothing is added. |\n| `maxSize` | `number` | — | Max bytes per file; larger files are skipped. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `chooseLabel` | `string` | `'Choose file'` | Accessible name for the button / drop zone. |\n| `showFileList` | `boolean` | `true` | Show the list. |\n| `listType` | `'text' \\| 'picture' \\| 'picture-card'` | `'text'` | List layout. `picture-card` uses a plus tile as the trigger. |\n| `fileList` | `FileUploadFile[]` | — | Bound list (`v-model:file-list`). |\n| `action` | `string` | — | Upload URL. When set, files upload automatically by default. |\n| `method` | `string` | `'post'` | Request method. |\n| `name` | `string` | `'file'` | Form field name. |\n| `headers` | `Record<string, string>` | — | Extra headers. |\n| `data` | `object \\| (() => object)` | — | Extra fields sent with the file. |\n| `withCredentials` | `boolean` | `false` | Send cookies on cross-origin requests. |\n| `autoUpload` | `boolean` | `true` | Upload on select. Requires `action` or `httpRequest`. |\n| `httpRequest` | `(options) => void \\| Promise \\| XMLHttpRequest` | — | Custom uploader. A returned Promise is treated as the success response. |\n| `beforeUpload` | `(file, uploadFile) => boolean \\| Promise` | — | Return `false` to skip the file. |\n| `beforeRemove` | `(uploadFile, fileList) => boolean \\| Promise` | — | Return `false` to cancel removal. |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `select` | `File[]` | Selection or drop complete (after type / size / `beforeUpload` filters). |\n| `exceed` | `File[]` | More files than `limit`. |\n| `update:fileList` | `FileUploadFile[]` | List changed. |\n| `change` | `file, fileList` | A file's status changed. |\n| `remove` | `file` | Removed from the list. |\n| `preview` | `file` | Preview clicked. |\n| `progress` | `file, percent` | Upload progress. |\n| `success` | `file, response` | Upload succeeded. |\n| `error` | `file, error` | Upload failed. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Custom drop-zone content (`drag` only). |\n| `trigger` | Custom choose-button content (not `picture-card`). |\n| `tip` | Hint below the trigger. |\n| `file` | Custom list item; scope `{ file }`. |\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `openPicker()` | Open the system file picker. |\n| `submit()` | Upload `ready` / `fail` files in the list. |\n| `abort(file?)` | Abort in-flight request(s); omit `file` to abort all. |\n| `clear()` / `clearFiles()` | Clear the list and abort uploads. |\n\n## Types\n\n<h4 id=\"FileUploadFile\">FileUploadFile</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface FileUploadFile {\n uid: string\n name: string\n size?: number\n type?: string\n status: FileUploadStatus\n percentage?: number\n url?: string\n raw?: File\n response?: unknown\n error?: string\n}\n```\n"
7730
+ "markdown": "---\ntitle: FileUpload\ncategory: 02 / FORM\ndescription: Select, drag, list, preview, and upload.\n---\n\n# FileUpload\n\nPick local files. Supports click-to-choose, drag-and-drop, text / picture lists, a picture-card wall, and real uploads via `action` or `httpRequest`. `select` still emits the chosen `File[]`; the full list is `v-model:file-list`. The file list is shown by default; files upload automatically when `action` or `httpRequest` is set.\n\nCommon options: `action` / `httpRequest` for real uploads, `v-model:file-list` for the queue, `listType` for list chrome, and `directory` for folder pick when the browser supports it.\n\nQueue UI extras are out of scope this batch.\n\n## Import\n\n```ts\nimport { MFileUpload } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Drag to upload\n\nSet `drag` to show a dashed drop zone. Drop files or click the area to choose.\n\n```vue preview src=\"./demos/DragToUpload.en.vue\"\n```\n\n## Picture list\n\n`list-type=\"picture\"` shows thumbnails in the list, with preview and remove.\n\n```vue preview src=\"./demos/PictureList.vue\"\n```\n\n## Picture card\n\nA photo wall: the plus tile opens the picker; hover to preview or remove. Images can also be dropped onto the card area.\n\n```vue preview src=\"./demos/PictureCard.vue\"\n```\n\n## Auto upload\n\nWith `httpRequest` (or `action`), files upload automatically. The demo mocks the request locally.\n\n```vue preview src=\"./demos/AutoUpload.en.vue\"\n```\n\n## Manual upload\n\nWith `auto-upload=\"false\"`, files join the list first; click Upload to send them. `before-upload` can reject a file.\n\n```vue preview src=\"./demos/ManualUpload.en.vue\"\n```\n\n## Instance methods\n\nUse a template ref to control the picker, upload queue, cancellation, and clearing.\n\n```vue preview src=\"./demos/InstanceMethods.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `mode` | `'basic' \\| 'advanced'` | `'basic'` | Visual variant. Use `showFileList` to toggle the list. |\n| `multiple` | `boolean` | `false` | Multiple selection. When off, a new pick replaces the list. |\n| `directory` | `boolean` | `false` | Pick a folder (`webkitdirectory`); implies multiple. |\n| `accept` | `string` | — | Accepted types; also applied to dropped files. |\n| `drag` | `boolean` | `false` | Enable the drag-and-drop zone. |\n| `limit` | `number` | — | Max files. If this pick would exceed it, `exceed` fires and nothing is added. |\n| `maxSize` | `number` | — | Max bytes per file; larger files are skipped. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `chooseLabel` | `string` | `'Choose file'` | Accessible name for the button / drop zone. |\n| `showFileList` | `boolean` | `true` | Show the list. |\n| `listType` | `'text' \\| 'picture' \\| 'picture-card'` | `'text'` | List layout. `picture-card` uses a plus tile as the trigger. |\n| `fileList` | `FileUploadFile[]` | — | Bound list (`v-model:file-list`). |\n| `action` | `string` | — | Upload URL. When set, files upload automatically by default. |\n| `method` | `string` | `'post'` | Request method. |\n| `name` | `string` | `'file'` | Form field name. |\n| `headers` | `Record<string, string>` | — | Extra headers. |\n| `data` | `object \\| (() => object)` | — | Extra fields sent with the file. |\n| `withCredentials` | `boolean` | `false` | Send cookies on cross-origin requests. |\n| `autoUpload` | `boolean` | `true` | Upload on select. Requires `action` or `httpRequest`. |\n| `httpRequest` | `(options) => void \\| Promise \\| XMLHttpRequest` | — | Custom uploader. A returned Promise is treated as the success response. |\n| `beforeUpload` | `(file, uploadFile) => boolean \\| Promise` | — | Return `false` to skip the file. |\n| `beforeRemove` | `(uploadFile, fileList) => boolean \\| Promise` | — | Return `false` to cancel removal. |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `select` | `File[]` | Selection or drop complete (after type / size / `beforeUpload` filters). |\n| `exceed` | `File[]` | More files than `limit`. |\n| `update:fileList` | `FileUploadFile[]` | List changed. |\n| `change` | `file, fileList` | A file's status changed. |\n| `remove` | `file` | Removed from the list. |\n| `preview` | `file` | Preview clicked. |\n| `progress` | `file, percent` | Upload progress. |\n| `success` | `file, response` | Upload succeeded. |\n| `error` | `file, error` | Upload failed. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Custom drop-zone content (`drag` only). |\n| `trigger` | Custom choose-button content (not `picture-card`). |\n| `tip` | Hint below the trigger. |\n| `file` | Custom list item; scope `{ file }`. |\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `openPicker()` | Open the system file picker. |\n| `submit()` | Upload `ready` / `fail` files in the list. |\n| `abort(file?)` | Abort in-flight request(s); omit `file` to abort all. |\n| `clear()` / `clearFiles()` | Clear the list and abort uploads. |\n\n## Types\n\n<h4 id=\"FileUploadFile\">FileUploadFile</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface FileUploadFile {\n uid: string\n name: string\n size?: number\n type?: string\n status: FileUploadStatus\n percentage?: number\n url?: string\n raw?: File\n response?: unknown\n error?: string\n}\n```\n"
7649
7731
  }
7650
7732
  }
7651
7733
  },
@@ -8294,7 +8376,7 @@
8294
8376
  {
8295
8377
  "id": "overview",
8296
8378
  "title": "",
8297
- "body": "# Form\n\n`MForm` / `MFormItem` 负责布局、必填标记与错误展示。校验有两条路,可同时使用:\n\n1. **声明式 `rules`(推荐)**:按字段名配置 `required` / `min` / `max` / `pattern` / `validator`。\n2. **回调 `validate`**:FormItem 上传入函数,返回错误文案。仍可用于复杂跨字段逻辑。\n\n未指定 `trigger` 的规则继承 Form 的 `validateOn`。程序化 `validate()` 与 `validateOn` 含 `submit` 的原生提交会跑完该字段全部规则。\n\n**与 Naive UI 的差异:** 不引入 `async-validator`;`validate()` **始终 resolve** `{ valid, errors }`,校验失败不会 `reject`。Nested path(如 `user.name`)暂不支持,请用扁平字段名。"
8379
+ "body": "# Form\n\n`MForm` / `MFormItem` 负责布局、必填标记与错误展示。校验有两条路,可同时使用:\n\n1. **声明式 `rules`(推荐)**:按字段名配置 `required` / `min` / `max` / `pattern` / `validator`。\n2. **回调 `validate`**:FormItem 上传入函数,返回错误文案。仍可用于复杂跨字段逻辑。\n\n未指定 `trigger` 的规则继承 Form 的 `validateOn`。程序化 `validate()` 与 `validateOn` 含 `submit` 的原生提交会跑完该字段全部规则。\n\n**校验约定:** 不依赖外部校验库;`validate()` **始终 resolve** `{ valid, errors }`,校验失败不会 `reject`。Nested path(如 `user.name`)暂不支持,请用扁平字段名。"
8298
8380
  },
8299
8381
  {
8300
8382
  "id": "引入",
@@ -8319,7 +8401,7 @@
8319
8401
  {
8320
8402
  "id": "props-form",
8321
8403
  "title": "Props — Form",
8322
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `model` | `Record<string, unknown>` | — | 供 `rules` 读取的字段值 |\n| `rules` | `FormRules` | — | 按 `name` 声明的规则 |\n| `labelPosition` | `'top' \\| 'left'` | `'top'` | 标签位置 |\n| `labelPlacement` | `'top' \\| 'left'` | — | `labelPosition` 别名(Naive) |\n| `labelAlign` | `'left' \\| 'center' \\| 'right'` | `'left'` | 标签文本对齐 |\n| `labelWidth` | `string \\| number` | — | 左侧标签宽度;数字视为 px |\n| `inline` | `boolean` | `false` | 表单项横向排列 |\n| `requireMark` | `boolean` | `true` | 必填星号(`required` 或 `rules.required`) |\n| `disabled` | `boolean` | `false` | 禁用态 |\n| `validateOn` | `'submit' \\| 'blur' \\| 'change' \\| 'input' \\| 数组` | `['submit']` | 默认触发时机;无 `trigger` 的规则继承此项 |\n| `for` | `string` | — | — |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | — |"
8404
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `model` | `Record<string, unknown>` | — | 供 `rules` 读取的字段值 |\n| `rules` | `FormRules` | — | 按 `name` 声明的规则 |\n| `labelPosition` | `'top' \\| 'left'` | `'top'` | 标签位置 |\n| `labelPlacement` | `'top' \\| 'left'` | — | `labelPosition` 的别名 |\n| `labelAlign` | `'left' \\| 'center' \\| 'right'` | `'left'` | 标签文本对齐 |\n| `labelWidth` | `string \\| number` | — | 左侧标签宽度;数字视为 px |\n| `inline` | `boolean` | `false` | 表单项横向排列 |\n| `requireMark` | `boolean` | `true` | 必填星号(`required` 或 `rules.required`) |\n| `disabled` | `boolean` | `false` | 禁用态 |\n| `validateOn` | `'submit' \\| 'blur' \\| 'change' \\| 'input' \\| 数组` | `['submit']` | 默认触发时机;无 `trigger` 的规则继承此项 |\n| `for` | `string` | — | — |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | — |"
8323
8405
  },
8324
8406
  {
8325
8407
  "id": "props-formitem",
@@ -8347,7 +8429,7 @@
8347
8429
  "body": "<h4 id=\"FormRules\">FormRules</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ntype FormRules = Record<string, FormItemRule | FormItemRule[]>\n```"
8348
8430
  }
8349
8431
  ],
8350
- "markdown": "---\ntitle: Form\ncategory: 02 / FORM\ndescription: 表单布局与字段校验。声明式 rules、label 对齐/行内布局;validate() 始终 resolve,不 reject。\n---\n\n# Form\n\n`MForm` / `MFormItem` 负责布局、必填标记与错误展示。校验有两条路,可同时使用:\n\n1. **声明式 `rules`(推荐)**:按字段名配置 `required` / `min` / `max` / `pattern` / `validator`。\n2. **回调 `validate`**:FormItem 上传入函数,返回错误文案。仍可用于复杂跨字段逻辑。\n\n未指定 `trigger` 的规则继承 Form 的 `validateOn`。程序化 `validate()` 与 `validateOn` 含 `submit` 的原生提交会跑完该字段全部规则。\n\n**与 Naive UI 的差异:** 不引入 `async-validator`;`validate()` **始终 resolve** `{ valid, errors }`,校验失败不会 `reject`。Nested path(如 `user.name`)暂不支持,请用扁平字段名。\n\n## 引入\n\n```ts\nimport type { FormInstance, FormRules } from 'morya-ui'\nimport { MForm, MFormItem } from 'morya-ui'\n```\n\n## 声明式 rules\n\n```vue preview src=\"./demos/DeclarativeRules.zh.vue\"\n```\n\n## 回调校验(兼容)\n\n```vue preview src=\"./demos/CallbackValidationCompatible.zh.vue\"\n```\n\n## inline 与 label 对齐\n\n```vue preview src=\"./demos/InlineLayoutAndLabelAlignment.zh.vue\"\n```\n\n## Props — Form\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `model` | `Record<string, unknown>` | — | 供 `rules` 读取的字段值 |\n| `rules` | `FormRules` | — | 按 `name` 声明的规则 |\n| `labelPosition` | `'top' \\| 'left'` | `'top'` | 标签位置 |\n| `labelPlacement` | `'top' \\| 'left'` | — | `labelPosition` 别名(Naive) |\n| `labelAlign` | `'left' \\| 'center' \\| 'right'` | `'left'` | 标签文本对齐 |\n| `labelWidth` | `string \\| number` | — | 左侧标签宽度;数字视为 px |\n| `inline` | `boolean` | `false` | 表单项横向排列 |\n| `requireMark` | `boolean` | `true` | 必填星号(`required` 或 `rules.required`) |\n| `disabled` | `boolean` | `false` | 禁用态 |\n| `validateOn` | `'submit' \\| 'blur' \\| 'change' \\| 'input' \\| 数组` | `['submit']` | 默认触发时机;无 `trigger` 的规则继承此项 |\n| `for` | `string` | — | — |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | — |\n\n## Props — FormItem\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `name` | `string` | — | 字段名(注册到 Form,对应 `model` / `rules`) |\n| `rules` | `FormItemRule \\| FormItemRule[]` | — | 字段级规则,排在 Form `rules[name]` 之后 |\n| `validate` | `(trigger?) => string \\| boolean \\| void \\| Promise<…>` | — | 回调校验;返回错误文案或 `false` |\n| `error` | `string` | — | 受控错误(优先于内部结果) |\n| `invalid` / `help` / `required` / `label` | — | — | 布局与展示 |\n\n## FormItemRule\n\n| 字段 | 说明 |\n| --- | --- |\n| `required` | 空值(`null` / 空白字符串 / 空数组)时报错 |\n| `min` / `max` | 字符串/数组长度,或有限数字本身 |\n| `pattern` | 非空字符串才检测 |\n| `message` | 错误文案;缺省回退到 locale `required` |\n| `trigger` | `'blur' \\| 'change' \\| 'input' \\| 'submit'`;省略则继承 Form `validateOn` |\n| `validator` | `(value) => string \\| false \\| Promise<…>`;`true` / `undefined` 视为通过 |\n\n## Events / Expose — Form\n\n| 名称 | 说明 |\n| --- | --- |\n| `submit` | `{ valid }`。仅当 `validateOn` 含 `submit` 时自动跑校验 |\n| `validate` | `{ valid, errors }` |\n| `validate(name?)` | **始终 resolve** `{ valid, errors }`,不会因失败 reject |\n| `clearValidate(name?)` | 清除内部错误 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 表单项。 |\n\n## 类型\n\n<h4 id=\"FormRules\">FormRules</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ntype FormRules = Record<string, FormItemRule | FormItemRule[]>\n```\n"
8432
+ "markdown": "---\ntitle: Form\ncategory: 02 / FORM\ndescription: 表单布局与字段校验。声明式 rules、label 对齐/行内布局;validate() 始终 resolve,不 reject。\n---\n\n# Form\n\n`MForm` / `MFormItem` 负责布局、必填标记与错误展示。校验有两条路,可同时使用:\n\n1. **声明式 `rules`(推荐)**:按字段名配置 `required` / `min` / `max` / `pattern` / `validator`。\n2. **回调 `validate`**:FormItem 上传入函数,返回错误文案。仍可用于复杂跨字段逻辑。\n\n未指定 `trigger` 的规则继承 Form 的 `validateOn`。程序化 `validate()` 与 `validateOn` 含 `submit` 的原生提交会跑完该字段全部规则。\n\n**校验约定:** 不依赖外部校验库;`validate()` **始终 resolve** `{ valid, errors }`,校验失败不会 `reject`。Nested path(如 `user.name`)暂不支持,请用扁平字段名。\n\n## 引入\n\n```ts\nimport type { FormInstance, FormRules } from 'morya-ui'\nimport { MForm, MFormItem } from 'morya-ui'\n```\n\n## 声明式 rules\n\n```vue preview src=\"./demos/DeclarativeRules.zh.vue\"\n```\n\n## 回调校验(兼容)\n\n```vue preview src=\"./demos/CallbackValidationCompatible.zh.vue\"\n```\n\n## inline 与 label 对齐\n\n```vue preview src=\"./demos/InlineLayoutAndLabelAlignment.zh.vue\"\n```\n\n## Props — Form\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `model` | `Record<string, unknown>` | — | 供 `rules` 读取的字段值 |\n| `rules` | `FormRules` | — | 按 `name` 声明的规则 |\n| `labelPosition` | `'top' \\| 'left'` | `'top'` | 标签位置 |\n| `labelPlacement` | `'top' \\| 'left'` | — | `labelPosition` 的别名 |\n| `labelAlign` | `'left' \\| 'center' \\| 'right'` | `'left'` | 标签文本对齐 |\n| `labelWidth` | `string \\| number` | — | 左侧标签宽度;数字视为 px |\n| `inline` | `boolean` | `false` | 表单项横向排列 |\n| `requireMark` | `boolean` | `true` | 必填星号(`required` 或 `rules.required`) |\n| `disabled` | `boolean` | `false` | 禁用态 |\n| `validateOn` | `'submit' \\| 'blur' \\| 'change' \\| 'input' \\| 数组` | `['submit']` | 默认触发时机;无 `trigger` 的规则继承此项 |\n| `for` | `string` | — | — |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | — |\n\n## Props — FormItem\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `name` | `string` | — | 字段名(注册到 Form,对应 `model` / `rules`) |\n| `rules` | `FormItemRule \\| FormItemRule[]` | — | 字段级规则,排在 Form `rules[name]` 之后 |\n| `validate` | `(trigger?) => string \\| boolean \\| void \\| Promise<…>` | — | 回调校验;返回错误文案或 `false` |\n| `error` | `string` | — | 受控错误(优先于内部结果) |\n| `invalid` / `help` / `required` / `label` | — | — | 布局与展示 |\n\n## FormItemRule\n\n| 字段 | 说明 |\n| --- | --- |\n| `required` | 空值(`null` / 空白字符串 / 空数组)时报错 |\n| `min` / `max` | 字符串/数组长度,或有限数字本身 |\n| `pattern` | 非空字符串才检测 |\n| `message` | 错误文案;缺省回退到 locale `required` |\n| `trigger` | `'blur' \\| 'change' \\| 'input' \\| 'submit'`;省略则继承 Form `validateOn` |\n| `validator` | `(value) => string \\| false \\| Promise<…>`;`true` / `undefined` 视为通过 |\n\n## Events / Expose — Form\n\n| 名称 | 说明 |\n| --- | --- |\n| `submit` | `{ valid }`。仅当 `validateOn` 含 `submit` 时自动跑校验 |\n| `validate` | `{ valid, errors }` |\n| `validate(name?)` | **始终 resolve** `{ valid, errors }`,不会因失败 reject |\n| `clearValidate(name?)` | 清除内部错误 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 表单项。 |\n\n## 类型\n\n<h4 id=\"FormRules\">FormRules</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ntype FormRules = Record<string, FormItemRule | FormItemRule[]>\n```\n"
8351
8433
  },
8352
8434
  "en-US": {
8353
8435
  "title": "Form",
@@ -8356,7 +8438,7 @@
8356
8438
  {
8357
8439
  "id": "overview",
8358
8440
  "title": "",
8359
- "body": "# Form\n\n`MForm` / `MFormItem` handle layout, required marks, and error display. Validation can use both of these, together:\n\n1. **Declarative `rules` (preferred):** `required` / `min` / `max` / `pattern` / `validator` keyed by field name.\n2. **`validate` callback:** return an error string from FormItem. Still useful for cross-field logic.\n\nRules without `trigger` inherit Form `validateOn`. Programmatic `validate()` and native submit (when `validateOn` includes `submit`) run every rule on the field.\n\n**Difference from Naive UI:** there is no `async-validator` dependency. `validate()` **always resolves** `{ valid, errors }` and does not `reject` on failure. Nested paths such as `user.name` are not supported; use flat field names."
8441
+ "body": "# Form\n\n`MForm` / `MFormItem` handle layout, required marks, and error display. Validation can use both of these, together:\n\n1. **Declarative `rules` (preferred):** `required` / `min` / `max` / `pattern` / `validator` keyed by field name.\n2. **`validate` callback:** return an error string from FormItem. Still useful for cross-field logic.\n\nRules without `trigger` inherit Form `validateOn`. Programmatic `validate()` and native submit (when `validateOn` includes `submit`) run every rule on the field.\n\n**Validation contract:** no external schema validator dependency. `validate()` **always resolves** `{ valid, errors }` and does not `reject` on failure. Nested paths such as `user.name` are not supported; use flat field names."
8360
8442
  },
8361
8443
  {
8362
8444
  "id": "import",
@@ -8381,7 +8463,7 @@
8381
8463
  {
8382
8464
  "id": "props-form",
8383
8465
  "title": "Props — Form",
8384
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `model` | `Record<string, unknown>` | — | Values read by `rules` |\n| `rules` | `FormRules` | — | Rules keyed by field `name` |\n| `labelPosition` | `'top' \\| 'left'` | `'top'` | Label placement |\n| `labelPlacement` | `'top' \\| 'left'` | — | Alias of `labelPosition` (Naive) |\n| `labelAlign` | `'left' \\| 'center' \\| 'right'` | `'left'` | Label text alignment |\n| `labelWidth` | `string \\| number` | — | Left label width; numbers are px |\n| `inline` | `boolean` | `false` | Place items in a wrapping row |\n| `requireMark` | `boolean` | `true` | Required asterisk (`required` or `rules.required`) |\n| `disabled` | `boolean` | `false` | Disabled state |\n| `validateOn` | `'submit' \\| 'blur' \\| 'change' \\| 'input' \\| array` | `['submit']` | Default timing; rules without `trigger` inherit this |"
8466
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `model` | `Record<string, unknown>` | — | Values read by `rules` |\n| `rules` | `FormRules` | — | Rules keyed by field `name` |\n| `labelPosition` | `'top' \\| 'left'` | `'top'` | Label placement |\n| `labelPlacement` | `'top' \\| 'left'` | — | Alias of `labelPosition` |\n| `labelAlign` | `'left' \\| 'center' \\| 'right'` | `'left'` | Label text alignment |\n| `labelWidth` | `string \\| number` | — | Left label width; numbers are px |\n| `inline` | `boolean` | `false` | Place items in a wrapping row |\n| `requireMark` | `boolean` | `true` | Required asterisk (`required` or `rules.required`) |\n| `disabled` | `boolean` | `false` | Disabled state |\n| `validateOn` | `'submit' \\| 'blur' \\| 'change' \\| 'input' \\| array` | `['submit']` | Default timing; rules without `trigger` inherit this |"
8385
8467
  },
8386
8468
  {
8387
8469
  "id": "props-formitem",
@@ -8409,7 +8491,7 @@
8409
8491
  "body": "<h4 id=\"FormRules\">FormRules</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ntype FormRules = Record<string, FormItemRule | FormItemRule[]>\n```"
8410
8492
  }
8411
8493
  ],
8412
- "markdown": "---\ntitle: Form\ncategory: 02 / FORM\ndescription: Form layout and field validation. Declarative rules, label alignment, and inline layout. validate() always resolves and never rejects.\n---\n\n# Form\n\n`MForm` / `MFormItem` handle layout, required marks, and error display. Validation can use both of these, together:\n\n1. **Declarative `rules` (preferred):** `required` / `min` / `max` / `pattern` / `validator` keyed by field name.\n2. **`validate` callback:** return an error string from FormItem. Still useful for cross-field logic.\n\nRules without `trigger` inherit Form `validateOn`. Programmatic `validate()` and native submit (when `validateOn` includes `submit`) run every rule on the field.\n\n**Difference from Naive UI:** there is no `async-validator` dependency. `validate()` **always resolves** `{ valid, errors }` and does not `reject` on failure. Nested paths such as `user.name` are not supported; use flat field names.\n\n## Import\n\n```ts\nimport type { FormInstance, FormRules } from 'morya-ui'\nimport { MForm, MFormItem } from 'morya-ui'\n```\n\n## Declarative rules\n\n```vue preview src=\"./demos/DeclarativeRules.en.vue\"\n```\n\n## Callback validation (compatible)\n\n```vue preview src=\"./demos/CallbackValidationCompatible.en.vue\"\n```\n\n## Inline layout and label alignment\n\n```vue preview src=\"./demos/InlineLayoutAndLabelAlignment.en.vue\"\n```\n\n## Props — Form\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `model` | `Record<string, unknown>` | — | Values read by `rules` |\n| `rules` | `FormRules` | — | Rules keyed by field `name` |\n| `labelPosition` | `'top' \\| 'left'` | `'top'` | Label placement |\n| `labelPlacement` | `'top' \\| 'left'` | — | Alias of `labelPosition` (Naive) |\n| `labelAlign` | `'left' \\| 'center' \\| 'right'` | `'left'` | Label text alignment |\n| `labelWidth` | `string \\| number` | — | Left label width; numbers are px |\n| `inline` | `boolean` | `false` | Place items in a wrapping row |\n| `requireMark` | `boolean` | `true` | Required asterisk (`required` or `rules.required`) |\n| `disabled` | `boolean` | `false` | Disabled state |\n| `validateOn` | `'submit' \\| 'blur' \\| 'change' \\| 'input' \\| array` | `['submit']` | Default timing; rules without `trigger` inherit this |\n\n## Props — FormItem\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `name` | `string` | — | Field name (registered on Form; matches `model` / `rules`) |\n| `rules` | `FormItemRule \\| FormItemRule[]` | — | Item rules, merged after Form `rules[name]` |\n| `validate` | `(trigger?) => string \\| boolean \\| void \\| Promise<…>` | — | Callback validator; return error text or `false` |\n| `error` | `string` | — | Controlled error (wins over internal result) |\n| `invalid` / `help` / `required` / `label` | — | — | Layout and display |\n\n## FormItemRule\n\n| Field | Description |\n| --- | --- |\n| `required` | Fails on `null`, blank strings, and empty arrays |\n| `min` / `max` | String/array length, or a finite number value |\n| `pattern` | Checked only for non-empty strings |\n| `message` | Error copy; falls back to locale `required` |\n| `trigger` | `'blur' \\| 'change' \\| 'input' \\| 'submit'`; omit to inherit Form `validateOn` |\n| `validator` | `(value) => string \\| false \\| Promise<…>`; `true` / `undefined` pass |\n\n## Events / Expose — Form\n\n| Name | Description |\n| --- | --- |\n| `submit` | `{ valid }`. Auto-validates only when `validateOn` includes `submit` |\n| `validate` | `{ valid, errors }` |\n| `validate(name?)` | **Always resolves** `{ valid, errors }`; never rejects on failure |\n| `clearValidate(name?)` | Clears internal errors |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Form items. |\n\n## Types\n\n<h4 id=\"FormRules\">FormRules</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ntype FormRules = Record<string, FormItemRule | FormItemRule[]>\n```\n"
8494
+ "markdown": "---\ntitle: Form\ncategory: 02 / FORM\ndescription: Form layout and field validation. Declarative rules, label alignment, and inline layout. validate() always resolves and never rejects.\n---\n\n# Form\n\n`MForm` / `MFormItem` handle layout, required marks, and error display. Validation can use both of these, together:\n\n1. **Declarative `rules` (preferred):** `required` / `min` / `max` / `pattern` / `validator` keyed by field name.\n2. **`validate` callback:** return an error string from FormItem. Still useful for cross-field logic.\n\nRules without `trigger` inherit Form `validateOn`. Programmatic `validate()` and native submit (when `validateOn` includes `submit`) run every rule on the field.\n\n**Validation contract:** no external schema validator dependency. `validate()` **always resolves** `{ valid, errors }` and does not `reject` on failure. Nested paths such as `user.name` are not supported; use flat field names.\n\n## Import\n\n```ts\nimport type { FormInstance, FormRules } from 'morya-ui'\nimport { MForm, MFormItem } from 'morya-ui'\n```\n\n## Declarative rules\n\n```vue preview src=\"./demos/DeclarativeRules.en.vue\"\n```\n\n## Callback validation (compatible)\n\n```vue preview src=\"./demos/CallbackValidationCompatible.en.vue\"\n```\n\n## Inline layout and label alignment\n\n```vue preview src=\"./demos/InlineLayoutAndLabelAlignment.en.vue\"\n```\n\n## Props — Form\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `model` | `Record<string, unknown>` | — | Values read by `rules` |\n| `rules` | `FormRules` | — | Rules keyed by field `name` |\n| `labelPosition` | `'top' \\| 'left'` | `'top'` | Label placement |\n| `labelPlacement` | `'top' \\| 'left'` | — | Alias of `labelPosition` |\n| `labelAlign` | `'left' \\| 'center' \\| 'right'` | `'left'` | Label text alignment |\n| `labelWidth` | `string \\| number` | — | Left label width; numbers are px |\n| `inline` | `boolean` | `false` | Place items in a wrapping row |\n| `requireMark` | `boolean` | `true` | Required asterisk (`required` or `rules.required`) |\n| `disabled` | `boolean` | `false` | Disabled state |\n| `validateOn` | `'submit' \\| 'blur' \\| 'change' \\| 'input' \\| array` | `['submit']` | Default timing; rules without `trigger` inherit this |\n\n## Props — FormItem\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `name` | `string` | — | Field name (registered on Form; matches `model` / `rules`) |\n| `rules` | `FormItemRule \\| FormItemRule[]` | — | Item rules, merged after Form `rules[name]` |\n| `validate` | `(trigger?) => string \\| boolean \\| void \\| Promise<…>` | — | Callback validator; return error text or `false` |\n| `error` | `string` | — | Controlled error (wins over internal result) |\n| `invalid` / `help` / `required` / `label` | — | — | Layout and display |\n\n## FormItemRule\n\n| Field | Description |\n| --- | --- |\n| `required` | Fails on `null`, blank strings, and empty arrays |\n| `min` / `max` | String/array length, or a finite number value |\n| `pattern` | Checked only for non-empty strings |\n| `message` | Error copy; falls back to locale `required` |\n| `trigger` | `'blur' \\| 'change' \\| 'input' \\| 'submit'`; omit to inherit Form `validateOn` |\n| `validator` | `(value) => string \\| false \\| Promise<…>`; `true` / `undefined` pass |\n\n## Events / Expose — Form\n\n| Name | Description |\n| --- | --- |\n| `submit` | `{ valid }`. Auto-validates only when `validateOn` includes `submit` |\n| `validate` | `{ valid, errors }` |\n| `validate(name?)` | **Always resolves** `{ valid, errors }`; never rejects on failure |\n| `clearValidate(name?)` | Clears internal errors |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Form items. |\n\n## Types\n\n<h4 id=\"FormRules\">FormRules</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ntype FormRules = Record<string, FormItemRule | FormItemRule[]>\n```\n"
8413
8495
  }
8414
8496
  }
8415
8497
  },
@@ -12318,6 +12400,358 @@
12318
12400
  }
12319
12401
  }
12320
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
+ },
12321
12755
  {
12322
12756
  "id": "MegaMenu",
12323
12757
  "name": "MegaMenu",
@@ -13365,7 +13799,7 @@
13365
13799
  {
13366
13800
  "id": "overview",
13367
13801
  "title": "",
13368
- "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`](../../../../ai-design-config/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 })`。"
13369
13803
  },
13370
13804
  {
13371
13805
  "id": "引入",
@@ -13385,7 +13819,7 @@
13385
13819
  {
13386
13820
  "id": "methods",
13387
13821
  "title": "Methods",
13388
- "body": "| 方法 | 说明 |\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()` | 关闭全部(`destroyAll` 对齐 Naive) |\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` | 自动生成 | 唯一键 |"
13822
+ "body": "| 方法 | 说明 |\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` | 自动生成 | 唯一键 |"
13389
13823
  },
13390
13824
  {
13391
13825
  "id": "可选宿主",
@@ -13413,7 +13847,7 @@
13413
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```"
13414
13848
  }
13415
13849
  ],
13416
- "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`](../../../../ai-design-config/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()` | 关闭全部(`destroyAll` 对齐 Naive) |\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"
13417
13851
  },
13418
13852
  "en-US": {
13419
13853
  "title": "Message",
@@ -13422,7 +13856,7 @@
13422
13856
  {
13423
13857
  "id": "overview",
13424
13858
  "title": "",
13425
- "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`](../../../../ai-design-config/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 })`."
13426
13860
  },
13427
13861
  {
13428
13862
  "id": "import",
@@ -13442,7 +13876,7 @@
13442
13876
  {
13443
13877
  "id": "methods",
13444
13878
  "title": "Methods",
13445
- "body": "| 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 (`destroyAll` matches Naive) |\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 |"
13879
+ "body": "| 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 |"
13446
13880
  },
13447
13881
  {
13448
13882
  "id": "optional-host",
@@ -13465,7 +13899,7 @@
13465
13899
  "body": "No slots; content is injected through the `message.*` API."
13466
13900
  }
13467
13901
  ],
13468
- "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`](../../../../ai-design-config/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 (`destroyAll` matches Naive) |\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"
13469
13903
  }
13470
13904
  }
13471
13905
  },
@@ -13921,7 +14355,7 @@
13921
14355
  {
13922
14356
  "id": "组合规则",
13923
14357
  "title": "组合规则",
13924
- "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`)。"
13925
14359
  },
13926
14360
  {
13927
14361
  "id": "api",
@@ -13929,7 +14363,7 @@
13929
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'` | 最小高度。 |"
13930
14364
  }
13931
14365
  ],
13932
- "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"
13933
14367
  },
13934
14368
  "en-US": {
13935
14369
  "title": "Page",
@@ -13958,10 +14392,10 @@
13958
14392
  {
13959
14393
  "id": "composition-rules",
13960
14394
  "title": "Composition rules",
13961
- "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`."
13962
14396
  }
13963
14397
  ],
13964
- "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"
13965
14399
  }
13966
14400
  }
13967
14401
  },
@@ -13996,7 +14430,7 @@
13996
14430
  "name": "pageSize",
13997
14431
  "type": "number",
13998
14432
  "default": "—",
13999
- "description": "`rows` 的别名(Naive `page-size`);两者同时传入时以 `pageSize` 为准。"
14433
+ "description": "`rows` 的别名;两者同时传入时以 `pageSize` 为准。"
14000
14434
  },
14001
14435
  {
14002
14436
  "name": "pageLinkSize",
@@ -14128,7 +14562,7 @@
14128
14562
  {
14129
14563
  "id": "overview",
14130
14564
  "title": "",
14131
- "body": "# Pagination\n\n分页导航,`v-model` 使用 **1-based 页码**;实例属性 `first` 对应零基首条记录索引 `(page - 1) * rows`。\n\n对照 Naive:`pageSize` 是 `rows` 的别名(同时传入时 `pageSize` 优先);`showSizePicker` / `showQuickJumper` / `simple` 对应 `n-pagination` 的常用能力。"
14565
+ "body": "# Pagination\n\n分页导航,`v-model` 使用 **1-based 页码**;实例属性 `first` 对应零基首条记录索引 `(page - 1) * rows`。\n\n`pageSize` 是 `rows` 的别名(同时传入时 `pageSize` 优先);另支持 `showSizePicker`、`showQuickJumper`、`simple`。"
14132
14566
  },
14133
14567
  {
14134
14568
  "id": "引入",
@@ -14148,7 +14582,7 @@
14148
14582
  {
14149
14583
  "id": "props",
14150
14584
  "title": "Props",
14151
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | 当前页(从 1 开始)。 |\n| `totalRecords` | `number` | — | 总记录数。 |\n| `rows` | `number` | `10` | 每页条数。 |\n| `pageSize` | `number` | — | `rows` 的别名(Naive `page-size`);两者同时传入时以 `pageSize` 为准。 |\n| `pageLinkSize` | `number` | `5` | 页码按钮数量。 |\n| `showSizePicker` | `boolean` | `false` | 显示每页条数选择器。 |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | `showSizePicker` 的选项。 |\n| `showQuickJumper` | `boolean` | `false` | 显示跳转到指定页。 |\n| `simple` | `boolean` | `false` | 精简为上一页 / 当前页 / 下一页。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
14585
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | 当前页(从 1 开始)。 |\n| `totalRecords` | `number` | — | 总记录数。 |\n| `rows` | `number` | `10` | 每页条数。 |\n| `pageSize` | `number` | — | `rows` 的别名;两者同时传入时以 `pageSize` 为准。 |\n| `pageLinkSize` | `number` | `5` | 页码按钮数量。 |\n| `showSizePicker` | `boolean` | `false` | 显示每页条数选择器。 |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | `showSizePicker` 的选项。 |\n| `showQuickJumper` | `boolean` | `false` | 显示跳转到指定页。 |\n| `simple` | `boolean` | `false` | 精简为上一页 / 当前页 / 下一页。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
14152
14586
  },
14153
14587
  {
14154
14588
  "id": "events",
@@ -14166,7 +14600,7 @@
14166
14600
  "body": "无插槽。"
14167
14601
  }
14168
14602
  ],
14169
- "markdown": "---\ntitle: Pagination\ncategory: 03 / DATA\ndescription: 分页器,v-model 为页码;实例暴露 first(零基首条索引)。\n---\n\n# Pagination\n\n分页导航,`v-model` 使用 **1-based 页码**;实例属性 `first` 对应零基首条记录索引 `(page - 1) * rows`。\n\n对照 Naive:`pageSize` 是 `rows` 的别名(同时传入时 `pageSize` 优先);`showSizePicker` / `showQuickJumper` / `simple` 对应 `n-pagination` 的常用能力。\n\n## 引入\n\n```ts\nimport { MPagination } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Size picker / jumper / simple\n\n```vue preview src=\"./demos/SizePickerJumperSimple.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | 当前页(从 1 开始)。 |\n| `totalRecords` | `number` | — | 总记录数。 |\n| `rows` | `number` | `10` | 每页条数。 |\n| `pageSize` | `number` | — | `rows` 的别名(Naive `page-size`);两者同时传入时以 `pageSize` 为准。 |\n| `pageLinkSize` | `number` | `5` | 页码按钮数量。 |\n| `showSizePicker` | `boolean` | `false` | 显示每页条数选择器。 |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | `showSizePicker` 的选项。 |\n| `showQuickJumper` | `boolean` | `false` | 显示跳转到指定页。 |\n| `simple` | `boolean` | `false` | 精简为上一页 / 当前页 / 下一页。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `number` | 页码变化。 |\n| `page` | `number` | 页码变化(同值)。 |\n| `update:rows` / `update:pageSize` | `number` | 每页条数变化(同值)。 |\n\n## Instance\n\n| 方法 / 属性 | 说明 |\n| --- | --- |\n| `first` | 当前页首条记录的零基索引:`(page - 1) * rows`。 |\n| `pageCount` | 总页数。 |\n\n## Slots\n\n无插槽。\n"
14603
+ "markdown": "---\ntitle: Pagination\ncategory: 03 / DATA\ndescription: 分页器,v-model 为页码;实例暴露 first(零基首条索引)。\n---\n\n# Pagination\n\n分页导航,`v-model` 使用 **1-based 页码**;实例属性 `first` 对应零基首条记录索引 `(page - 1) * rows`。\n\n`pageSize` 是 `rows` 的别名(同时传入时 `pageSize` 优先);另支持 `showSizePicker`、`showQuickJumper`、`simple`。\n\n## 引入\n\n```ts\nimport { MPagination } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Size picker / jumper / simple\n\n```vue preview src=\"./demos/SizePickerJumperSimple.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | 当前页(从 1 开始)。 |\n| `totalRecords` | `number` | — | 总记录数。 |\n| `rows` | `number` | `10` | 每页条数。 |\n| `pageSize` | `number` | — | `rows` 的别名;两者同时传入时以 `pageSize` 为准。 |\n| `pageLinkSize` | `number` | `5` | 页码按钮数量。 |\n| `showSizePicker` | `boolean` | `false` | 显示每页条数选择器。 |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | `showSizePicker` 的选项。 |\n| `showQuickJumper` | `boolean` | `false` | 显示跳转到指定页。 |\n| `simple` | `boolean` | `false` | 精简为上一页 / 当前页 / 下一页。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `number` | 页码变化。 |\n| `page` | `number` | 页码变化(同值)。 |\n| `update:rows` / `update:pageSize` | `number` | 每页条数变化(同值)。 |\n\n## Instance\n\n| 方法 / 属性 | 说明 |\n| --- | --- |\n| `first` | 当前页首条记录的零基索引:`(page - 1) * rows`。 |\n| `pageCount` | 总页数。 |\n\n## Slots\n\n无插槽。\n"
14170
14604
  },
14171
14605
  "en-US": {
14172
14606
  "title": "Pagination",
@@ -14175,7 +14609,7 @@
14175
14609
  {
14176
14610
  "id": "overview",
14177
14611
  "title": "",
14178
- "body": "# Pagination\n\nPagination. `v-model` uses a **1-based page number**. The instance property `first` is the zero-based index of the first record on the page: `(page - 1) * rows`.\n\nNaive mapping: `pageSize` is an alias of `rows` (`pageSize` wins when both are set). `showSizePicker` / `showQuickJumper` / `simple` cover the common `n-pagination` subset."
14612
+ "body": "# Pagination\n\nPagination. `v-model` uses a **1-based page number**. The instance property `first` is the zero-based index of the first record on the page: `(page - 1) * rows`.\n\n`pageSize` is an alias of `rows` (`pageSize` wins when both are set). Also supports `showSizePicker`, `showQuickJumper`, and `simple`."
14179
14613
  },
14180
14614
  {
14181
14615
  "id": "import",
@@ -14195,7 +14629,7 @@
14195
14629
  {
14196
14630
  "id": "props",
14197
14631
  "title": "Props",
14198
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | Current page (1-based). |\n| `totalRecords` | `number` | — | Total number of records. |\n| `rows` | `number` | `10` | Rows per page. |\n| `pageSize` | `number` | — | Alias of `rows` (Naive `page-size`); `pageSize` wins when both are set. |\n| `pageLinkSize` | `number` | `5` | Number of page link buttons. |\n| `showSizePicker` | `boolean` | `false` | Show the page-size select. |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | Options for `showSizePicker`. |\n| `showQuickJumper` | `boolean` | `false` | Jump-to-page input. |\n| `simple` | `boolean` | `false` | Compact prev / current / next. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
14632
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | Current page (1-based). |\n| `totalRecords` | `number` | — | Total number of records. |\n| `rows` | `number` | `10` | Rows per page. |\n| `pageSize` | `number` | — | Alias of `rows`; `pageSize` wins when both are set. |\n| `pageLinkSize` | `number` | `5` | Number of page link buttons. |\n| `showSizePicker` | `boolean` | `false` | Show the page-size select. |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | Options for `showSizePicker`. |\n| `showQuickJumper` | `boolean` | `false` | Jump-to-page input. |\n| `simple` | `boolean` | `false` | Compact prev / current / next. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
14199
14633
  },
14200
14634
  {
14201
14635
  "id": "events",
@@ -14213,7 +14647,7 @@
14213
14647
  "body": "No slots."
14214
14648
  }
14215
14649
  ],
14216
- "markdown": "---\ntitle: Pagination\ncategory: 03 / DATA\ndescription: Pagination. v-model is the page number. The instance exposes first (zero-based index of the first record).\n---\n\n# Pagination\n\nPagination. `v-model` uses a **1-based page number**. The instance property `first` is the zero-based index of the first record on the page: `(page - 1) * rows`.\n\nNaive mapping: `pageSize` is an alias of `rows` (`pageSize` wins when both are set). `showSizePicker` / `showQuickJumper` / `simple` cover the common `n-pagination` subset.\n\n## Import\n\n```ts\nimport { MPagination } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Size picker / jumper / simple\n\n```vue preview src=\"./demos/SizePickerJumperSimple.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | Current page (1-based). |\n| `totalRecords` | `number` | — | Total number of records. |\n| `rows` | `number` | `10` | Rows per page. |\n| `pageSize` | `number` | — | Alias of `rows` (Naive `page-size`); `pageSize` wins when both are set. |\n| `pageLinkSize` | `number` | `5` | Number of page link buttons. |\n| `showSizePicker` | `boolean` | `false` | Show the page-size select. |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | Options for `showSizePicker`. |\n| `showQuickJumper` | `boolean` | `false` | Jump-to-page input. |\n| `simple` | `boolean` | `false` | Compact prev / current / next. |\n| `disabled` | `boolean` | `false` | Disabled. |\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` | `number` | Emitted when the page changes. |\n| `page` | `number` | Emitted when the page changes (same value). |\n| `update:rows` / `update:pageSize` | `number` | Emitted when page size changes (same value). |\n\n## Instance\n\n| Method / Property | Description |\n| --- | --- |\n| `first` | Zero-based index of the first record on the current page: `(page - 1) * rows`. |\n| `pageCount` | Total number of pages. |\n\n## Slots\n\nNo slots.\n"
14650
+ "markdown": "---\ntitle: Pagination\ncategory: 03 / DATA\ndescription: Pagination. v-model is the page number. The instance exposes first (zero-based index of the first record).\n---\n\n# Pagination\n\nPagination. `v-model` uses a **1-based page number**. The instance property `first` is the zero-based index of the first record on the page: `(page - 1) * rows`.\n\n`pageSize` is an alias of `rows` (`pageSize` wins when both are set). Also supports `showSizePicker`, `showQuickJumper`, and `simple`.\n\n## Import\n\n```ts\nimport { MPagination } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Size picker / jumper / simple\n\n```vue preview src=\"./demos/SizePickerJumperSimple.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | Current page (1-based). |\n| `totalRecords` | `number` | — | Total number of records. |\n| `rows` | `number` | `10` | Rows per page. |\n| `pageSize` | `number` | — | Alias of `rows`; `pageSize` wins when both are set. |\n| `pageLinkSize` | `number` | `5` | Number of page link buttons. |\n| `showSizePicker` | `boolean` | `false` | Show the page-size select. |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | Options for `showSizePicker`. |\n| `showQuickJumper` | `boolean` | `false` | Jump-to-page input. |\n| `simple` | `boolean` | `false` | Compact prev / current / next. |\n| `disabled` | `boolean` | `false` | Disabled. |\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` | `number` | Emitted when the page changes. |\n| `page` | `number` | Emitted when the page changes (same value). |\n| `update:rows` / `update:pageSize` | `number` | Emitted when page size changes (same value). |\n\n## Instance\n\n| Method / Property | Description |\n| --- | --- |\n| `first` | Zero-based index of the first record on the current page: `(page - 1) * rows`. |\n| `pageCount` | Total number of pages. |\n\n## Slots\n\nNo slots.\n"
14217
14651
  }
14218
14652
  }
14219
14653
  },
@@ -15884,9 +16318,9 @@
15884
16318
  "props": [
15885
16319
  {
15886
16320
  "name": "status",
15887
- "type": "'success' | 'info' | 'warning' | 'warn' | 'error' | 'danger' | '403' | '404' | '500'",
16321
+ "type": "'info' | 'success' | 'warning' | 'error' | '403' | '404' | '500' | '418'",
15888
16322
  "default": "'info'",
15889
- "description": "结果状态。`warn`→警告,`danger`→错误。"
16323
+ "description": "结果状态。HTTP 类默认显示内置插图。"
15890
16324
  },
15891
16325
  {
15892
16326
  "name": "title",
@@ -15904,7 +16338,13 @@
15904
16338
  "name": "icon",
15905
16339
  "type": "[IconName](/docs/types#IconName)",
15906
16340
  "default": "按 `status",
15907
- "description": "覆盖默认图标。"
16341
+ "description": "覆盖默认图标;对 HTTP 状态会切换到图标模式。"
16342
+ },
16343
+ {
16344
+ "name": "size",
16345
+ "type": "'small' | 'medium' | 'large' | 'huge' | 'sm' | 'md' | 'lg'",
16346
+ "default": "'medium'",
16347
+ "description": "尺寸。"
15908
16348
  },
15909
16349
  {
15910
16350
  "name": "pt",
@@ -15928,12 +16368,12 @@
15928
16368
  "description": "自定义说明。"
15929
16369
  },
15930
16370
  {
15931
- "name": "extra",
15932
- "description": "操作区。"
16371
+ "name": "default",
16372
+ "description": "标题/说明下方的补充内容。"
15933
16373
  },
15934
16374
  {
15935
- "name": "default",
15936
- "description": "同 `extra`,追加在操作区。"
16375
+ "name": "footer",
16376
+ "description": "操作区。"
15937
16377
  }
15938
16378
  ],
15939
16379
  "examples": [
@@ -15943,7 +16383,7 @@
15943
16383
  "sectionId": "引入",
15944
16384
  "lang": "ts",
15945
16385
  "preview": false,
15946
- "code": "import { MResult } from 'morya-ui'",
16386
+ "code": "import { MResult } from \"morya-ui\";",
15947
16387
  "locale": "zh-CN"
15948
16388
  },
15949
16389
  {
@@ -15961,7 +16401,7 @@
15961
16401
  "sectionId": "操作区",
15962
16402
  "lang": "vue",
15963
16403
  "preview": true,
15964
- "code": "<script setup lang=\"ts\">\nimport { MButton, MResult } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-8\">\n <MResult status=\"success\" description=\"订单已创建,可在列表中查看详情。\">\n <template #extra>\n <MButton label=\"查看订单\" />\n <MButton label=\"返回首页\" severity=\"secondary\" text />\n </template>\n </MResult>\n <MResult status=\"error\" description=\"请检查网络后重试,或联系管理员。\">\n <template #extra>\n <MButton label=\"重试\" />\n </template>\n </MResult>\n </div>\n</template>",
16404
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MResult } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-8\">\n <MResult status=\"success\" description=\"订单已创建,可在列表中查看详情。\">\n <template #footer>\n <MButton label=\"查看订单\" />\n <MButton label=\"返回首页\" severity=\"secondary\" text />\n </template>\n </MResult>\n <MResult status=\"error\" description=\"请检查网络后重试,或联系管理员。\">\n <template #footer>\n <MButton label=\"重试\" />\n </template>\n </MResult>\n </div>\n</template>",
15965
16405
  "locale": "zh-CN"
15966
16406
  },
15967
16407
  {
@@ -15970,7 +16410,16 @@
15970
16410
  "sectionId": "http-类状态",
15971
16411
  "lang": "vue",
15972
16412
  "preview": true,
15973
- "code": "<script setup lang=\"ts\">\nimport { MButton, MResult } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-8\">\n <MResult status=\"403\" description=\"你没有访问该资源的权限。\">\n <template #extra>\n <MButton label=\"返回\" severity=\"secondary\" />\n </template>\n </MResult>\n <MResult status=\"404\" description=\"页面不存在或已被移除。\" />\n <MResult status=\"500\" description=\"服务暂时不可用,请稍后再试。\" />\n </div>\n</template>",
16413
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MResult } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-8\">\n <MResult status=\"403\" description=\"你没有访问该资源的权限。\">\n <template #footer>\n <MButton label=\"返回\" severity=\"secondary\" />\n </template>\n </MResult>\n <MResult status=\"404\" description=\"页面不存在或已被移除。\" />\n <MResult status=\"500\" description=\"服务暂时不可用,请稍后再试。\" />\n <MResult :status=\"('418' as any)\" description=\"服务器拒绝泡茶请求。\" />\n </div>\n</template>",
16414
+ "locale": "zh-CN"
16415
+ },
16416
+ {
16417
+ "id": "尺寸-1",
16418
+ "section": "尺寸",
16419
+ "sectionId": "尺寸",
16420
+ "lang": "vue",
16421
+ "preview": true,
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>",
15974
16423
  "locale": "zh-CN"
15975
16424
  },
15976
16425
  {
@@ -15979,7 +16428,7 @@
15979
16428
  "sectionId": "import",
15980
16429
  "lang": "ts",
15981
16430
  "preview": false,
15982
- "code": "import { MResult } from 'morya-ui'",
16431
+ "code": "import { MResult } from \"morya-ui\";",
15983
16432
  "locale": "en-US"
15984
16433
  },
15985
16434
  {
@@ -15997,16 +16446,25 @@
15997
16446
  "sectionId": "actions",
15998
16447
  "lang": "vue",
15999
16448
  "preview": true,
16000
- "code": "<script setup lang=\"ts\">\nimport { MButton, MResult } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-8\">\n <MResult status=\"success\" description=\"Your order was created. You can review it in the list.\">\n <template #extra>\n <MButton label=\"View order\" />\n <MButton label=\"Back home\" severity=\"secondary\" text />\n </template>\n </MResult>\n <MResult status=\"error\" description=\"Check your network and try again, or contact an admin.\">\n <template #extra>\n <MButton label=\"Retry\" />\n </template>\n </MResult>\n </div>\n</template>",
16449
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MResult } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-8\">\n <MResult status=\"success\" description=\"Your order was created. You can review it in the list.\">\n <template #footer>\n <MButton label=\"View order\" />\n <MButton label=\"Back home\" severity=\"secondary\" text />\n </template>\n </MResult>\n <MResult status=\"error\" description=\"Check your network and try again, or contact an admin.\">\n <template #footer>\n <MButton label=\"Retry\" />\n </template>\n </MResult>\n </div>\n</template>",
16450
+ "locale": "en-US"
16451
+ },
16452
+ {
16453
+ "id": "http-statuses-1",
16454
+ "section": "HTTP statuses",
16455
+ "sectionId": "http-statuses",
16456
+ "lang": "vue",
16457
+ "preview": true,
16458
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MResult } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-8\">\n <MResult status=\"403\" description=\"You do not have permission to access this resource.\">\n <template #footer>\n <MButton label=\"Go back\" severity=\"secondary\" />\n </template>\n </MResult>\n <MResult status=\"404\" description=\"This page does not exist or was removed.\" />\n <MResult status=\"500\" description=\"The service is temporarily unavailable. Try again later.\" />\n <MResult :status=\"('418' as any)\" description=\"The server refuses to brew coffee.\" />\n </div>\n</template>",
16001
16459
  "locale": "en-US"
16002
16460
  },
16003
16461
  {
16004
- "id": "http-style-statuses-1",
16005
- "section": "HTTP-style statuses",
16006
- "sectionId": "http-style-statuses",
16462
+ "id": "size-1",
16463
+ "section": "Size",
16464
+ "sectionId": "size",
16007
16465
  "lang": "vue",
16008
16466
  "preview": true,
16009
- "code": "<script setup lang=\"ts\">\nimport { MButton, MResult } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-8\">\n <MResult status=\"403\" description=\"You do not have permission to access this resource.\">\n <template #extra>\n <MButton label=\"Go back\" severity=\"secondary\" />\n </template>\n </MResult>\n <MResult status=\"404\" description=\"This page does not exist or was removed.\" />\n <MResult status=\"500\" description=\"The service is temporarily unavailable. Try again later.\" />\n </div>\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>",
16010
16468
  "locale": "en-US"
16011
16469
  }
16012
16470
  ],
@@ -16018,37 +16476,42 @@
16018
16476
  {
16019
16477
  "id": "overview",
16020
16478
  "title": "",
16021
- "body": "# Result\n\n用于提交成功、失败回执、权限不足或页面不存在等**流程终点**场景。无数据空态请用 [Empty](/components/Empty)"
16479
+ "body": "# Result\n\n用于提交成功、失败回执、权限不足或页面不存在等**流程终点**场景。无数据空态请用 [Empty](/components/Empty)。\n\n核心 API:`status` + `size` + `title` / `description`,插槽 `icon` / `default` / `footer`。"
16022
16480
  },
16023
16481
  {
16024
16482
  "id": "引入",
16025
16483
  "title": "引入",
16026
- "body": "```ts\nimport { MResult } from 'morya-ui'\n```"
16484
+ "body": "```ts\nimport { MResult } from \"morya-ui\";\n```"
16027
16485
  },
16028
16486
  {
16029
16487
  "id": "基础用法",
16030
16488
  "title": "基础用法",
16031
- "body": "`status` 决定默认图标、语义色与 locale 标题。\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```"
16489
+ "body": "`status` 决定默认图标、语义色与 locale 标题。\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n\n```"
16032
16490
  },
16033
16491
  {
16034
16492
  "id": "操作区",
16035
16493
  "title": "操作区",
16036
- "body": "```vue preview src=\"./demos/Actions.zh.vue\"\n```"
16494
+ "body": "使用 `#footer` 放置操作按钮;`#default` 可放额外说明内容。\n\n```vue preview src=\"./demos/Actions.zh.vue\"\n\n```"
16037
16495
  },
16038
16496
  {
16039
16497
  "id": "http-类状态",
16040
16498
  "title": "HTTP 类状态",
16041
- "body": "```vue preview src=\"./demos/Http.zh.vue\"\n```"
16499
+ "body": "`403` / `404` / `500` / `418` 默认展示内置插图;传入 `icon` 或 `#icon` 时可改回图标模式。\n\n```vue preview src=\"./demos/Http.zh.vue\"\n\n```"
16500
+ },
16501
+ {
16502
+ "id": "尺寸",
16503
+ "title": "尺寸",
16504
+ "body": "`size`:`small` / `medium` / `large` / `huge`。\n\n```vue preview src=\"./demos/Compact.zh.vue\"\n\n```"
16042
16505
  },
16043
16506
  {
16044
16507
  "id": "props",
16045
16508
  "title": "Props",
16046
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'warn' \\| 'error' \\| 'danger' \\| '403' \\| '404' \\| '500'` | `'info'` | 结果状态。`warn`→警告,`danger`→错误。 |\n| `title` | `string` | 按 `status` 的 locale | 标题。 |\n| `description` | `string` | — | 说明文案。 |\n| `icon` | [IconName](/docs/types#IconName) | 按 `status` | 覆盖默认图标。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
16509
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| ------------- | ----------------------------------------------------------------------------------------- | --------------------- | ----------------------------------------- |\n| `status` | `'info' \\| 'success' \\| 'warning' \\| 'error' \\| '403' \\| '404' \\| '500' \\| '418'` | `'info'` | 结果状态。HTTP 类默认显示内置插图。 |\n| `title` | `string` | 按 `status` 的 locale | 标题。 |\n| `description` | `string` | — | 说明文案。 |\n| `icon` | [IconName](/docs/types#IconName) | 按 `status` | 覆盖默认图标;对 HTTP 状态会切换到图标模式。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'huge' \\| 'sm' \\| 'md' \\| 'lg'` | `'medium'` | 尺寸。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
16047
16510
  },
16048
16511
  {
16049
16512
  "id": "slots",
16050
16513
  "title": "Slots",
16051
- "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `icon` | 自定义图标区。 |\n| `title` | 自定义标题。 |\n| `description` | 自定义说明。 |\n| `extra` | 操作区。 |\n| `default` | 同 `extra`,追加在操作区。 |"
16514
+ "body": "| 插槽名 | 说明 |\n| ------------- | ---------------------------- |\n| `icon` | 自定义图标区。 |\n| `title` | 自定义标题。 |\n| `description` | 自定义说明。 |\n| `default` | 标题/说明下方的补充内容。 |\n| `footer` | 操作区。 |"
16052
16515
  },
16053
16516
  {
16054
16517
  "id": "无障碍",
@@ -16059,9 +16522,14 @@
16059
16522
  "id": "events",
16060
16523
  "title": "Events",
16061
16524
  "body": "无自定义事件。"
16525
+ },
16526
+ {
16527
+ "id": "破坏性变更",
16528
+ "title": "破坏性变更",
16529
+ "body": "- 移除 `presentation` / `illustration` / `image` / `simple`,以及 `warn` / `danger` 别名。\n- `#extra` 更名为 `#footer`。\n- HTTP 默认视觉改为内置 SVG 插图(不再是巨大状态码数字)。\n- 内置插图目录迁至 [Empty](/components/Empty)。"
16062
16530
  }
16063
16531
  ],
16064
- "markdown": "---\ntitle: Result\ncategory: 05 / FEEDBACK\ndescription: 操作结果 / 阻断页:成功、失败、403、404 等。\n---\n\n# Result\n\n用于提交成功、失败回执、权限不足或页面不存在等**流程终点**场景。无数据空态请用 [Empty](/components/Empty)。\n\n## 引入\n\n```ts\nimport { MResult } from 'morya-ui'\n```\n\n## 基础用法\n\n`status` 决定默认图标、语义色与 locale 标题。\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## 操作区\n\n```vue preview src=\"./demos/Actions.zh.vue\"\n```\n\n## HTTP 类状态\n\n```vue preview src=\"./demos/Http.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'warn' \\| 'error' \\| 'danger' \\| '403' \\| '404' \\| '500'` | `'info'` | 结果状态。`warn`→警告,`danger`→错误。 |\n| `title` | `string` | 按 `status` 的 locale | 标题。 |\n| `description` | `string` | — | 说明文案。 |\n| `icon` | [IconName](/docs/types#IconName) | 按 `status` | 覆盖默认图标。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `icon` | 自定义图标区。 |\n| `title` | 自定义标题。 |\n| `description` | 自定义说明。 |\n| `extra` | 操作区。 |\n| `default` | 同 `extra`,追加在操作区。 |\n\n## 无障碍\n\n- 根节点使用 `role=\"status\"`。\n- 不要仅靠颜色表达结果;保持标题文案。\n\n## Events\n\n无自定义事件。\n"
16532
+ "markdown": "---\ntitle: Result\ncategory: 05 / FEEDBACK\ndescription: 操作结果 / 阻断页:成功、失败、403、404 等。\n---\n\n# Result\n\n用于提交成功、失败回执、权限不足或页面不存在等**流程终点**场景。无数据空态请用 [Empty](/components/Empty)。\n\n核心 API:`status` + `size` + `title` / `description`,插槽 `icon` / `default` / `footer`。\n\n## 引入\n\n```ts\nimport { MResult } from \"morya-ui\";\n```\n\n## 基础用法\n\n`status` 决定默认图标、语义色与 locale 标题。\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n\n```\n\n## 操作区\n\n使用 `#footer` 放置操作按钮;`#default` 可放额外说明内容。\n\n```vue preview src=\"./demos/Actions.zh.vue\"\n\n```\n\n## HTTP 类状态\n\n`403` / `404` / `500` / `418` 默认展示内置插图;传入 `icon` 或 `#icon` 时可改回图标模式。\n\n```vue preview src=\"./demos/Http.zh.vue\"\n\n```\n\n## 尺寸\n\n`size`:`small` / `medium` / `large` / `huge`。\n\n```vue preview src=\"./demos/Compact.zh.vue\"\n\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| ------------- | ----------------------------------------------------------------------------------------- | --------------------- | ----------------------------------------- |\n| `status` | `'info' \\| 'success' \\| 'warning' \\| 'error' \\| '403' \\| '404' \\| '500' \\| '418'` | `'info'` | 结果状态。HTTP 类默认显示内置插图。 |\n| `title` | `string` | 按 `status` 的 locale | 标题。 |\n| `description` | `string` | — | 说明文案。 |\n| `icon` | [IconName](/docs/types#IconName) | 按 `status` | 覆盖默认图标;对 HTTP 状态会切换到图标模式。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'huge' \\| 'sm' \\| 'md' \\| 'lg'` | `'medium'` | 尺寸。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n## Slots\n\n| 插槽名 | 说明 |\n| ------------- | ---------------------------- |\n| `icon` | 自定义图标区。 |\n| `title` | 自定义标题。 |\n| `description` | 自定义说明。 |\n| `default` | 标题/说明下方的补充内容。 |\n| `footer` | 操作区。 |\n\n## 无障碍\n\n- 根节点使用 `role=\"status\"`。\n- 不要仅靠颜色表达结果;保持标题文案。\n\n## Events\n\n无自定义事件。\n\n## 破坏性变更\n\n- 移除 `presentation` / `illustration` / `image` / `simple`,以及 `warn` / `danger` 别名。\n- `#extra` 更名为 `#footer`。\n- HTTP 默认视觉改为内置 SVG 插图(不再是巨大状态码数字)。\n- 内置插图目录迁至 [Empty](/components/Empty)。\n"
16065
16533
  },
16066
16534
  "en-US": {
16067
16535
  "title": "Result",
@@ -16070,50 +16538,60 @@
16070
16538
  {
16071
16539
  "id": "overview",
16072
16540
  "title": "",
16073
- "body": "# Result\n\nFor submit outcomes, failures, forbidden access, and missing pages. Use [Empty](/components/Empty) for no-data states."
16541
+ "body": "# Result\n\nFor submit outcomes, failures, forbidden access, and missing pages. Use [Empty](/components/Empty) for no-data states.\n\nCore API: `status` + `size` + `title` / `description`, slots `icon` / `default` / `footer`."
16074
16542
  },
16075
16543
  {
16076
16544
  "id": "import",
16077
16545
  "title": "Import",
16078
- "body": "```ts\nimport { MResult } from 'morya-ui'\n```"
16546
+ "body": "```ts\nimport { MResult } from \"morya-ui\";\n```"
16079
16547
  },
16080
16548
  {
16081
16549
  "id": "basic",
16082
16550
  "title": "Basic",
16083
- "body": "`status` drives the default icon, tone, and locale title.\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```"
16551
+ "body": "`status` drives the default icon, tone, and locale title.\n\n```vue preview src=\"./demos/Basic.en.vue\"\n\n```"
16084
16552
  },
16085
16553
  {
16086
16554
  "id": "actions",
16087
16555
  "title": "Actions",
16088
- "body": "```vue preview src=\"./demos/Actions.en.vue\"\n```"
16556
+ "body": "Put buttons in `#footer`. Use `#default` for extra content under the description.\n\n```vue preview src=\"./demos/Actions.en.vue\"\n\n```"
16089
16557
  },
16090
16558
  {
16091
- "id": "http-style-statuses",
16092
- "title": "HTTP-style statuses",
16093
- "body": "```vue preview src=\"./demos/Http.en.vue\"\n```"
16559
+ "id": "http-statuses",
16560
+ "title": "HTTP statuses",
16561
+ "body": "`403` / `404` / `500` / `418` show a built-in illustration by default. Pass `icon` or `#icon` to switch back to icon mode.\n\n```vue preview src=\"./demos/Http.en.vue\"\n\n```"
16562
+ },
16563
+ {
16564
+ "id": "size",
16565
+ "title": "Size",
16566
+ "body": "`size`: `small` / `medium` / `large` / `huge`.\n\n```vue preview src=\"./demos/Compact.en.vue\"\n\n```"
16094
16567
  },
16095
16568
  {
16096
16569
  "id": "props",
16097
16570
  "title": "Props",
16098
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'warn' \\| 'error' \\| 'danger' \\| '403' \\| '404' \\| '500'` | `'info'` | Outcome status. `warn` warning; `danger` error. |\n| `title` | `string` | locale for `status` | Title. |\n| `description` | `string` | — | Supporting copy. |\n| `icon` | [IconName](/docs/types#IconName) | from `status` | Override default icon. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
16571
+ "body": "| Prop | Type | Default | Description |\n| ------------- | --------------------------------------------------------------------------------- | ----------------------- | --------------------------------------------------------------------- |\n| `status` | `'info' \\| 'success' \\| 'warning' \\| 'error' \\| '403' \\| '404' \\| '500' \\| '418'` | `'info'` | Outcome status. HTTP statuses use a built-in illustration by default. |\n| `title` | `string` | locale for `status` | Title. |\n| `description` | `string` | — | Supporting text. |\n| `icon` | [IconName](/docs/types#IconName) | by `status` | Overrides the default icon; forces icon mode for HTTP statuses. |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'huge' \\| 'sm' \\| 'md' \\| 'lg'` | `'medium'` | Size. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |"
16099
16572
  },
16100
16573
  {
16101
16574
  "id": "slots",
16102
16575
  "title": "Slots",
16103
- "body": "| Slot | Description |\n| --- | --- |\n| `icon` | Custom icon area. |\n| `title` | Custom title. |\n| `description` | Custom description. |\n| `extra` | Action area. |\n| `default` | Same as `extra`, appended in the action area. |"
16576
+ "body": "| Slot | Description |\n| ------------- | ------------------------------------ |\n| `icon` | Custom icon area. |\n| `title` | Custom title. |\n| `description` | Custom description. |\n| `default` | Extra content below title/description. |\n| `footer` | Action area. |"
16104
16577
  },
16105
16578
  {
16106
16579
  "id": "accessibility",
16107
16580
  "title": "Accessibility",
16108
- "body": "- Root uses `role=\"status\"`.\n- Do not rely on color alone; keep a title."
16581
+ "body": "- Root uses `role=\"status\"`.\n- Do not rely on color alone; keep a visible title."
16109
16582
  },
16110
16583
  {
16111
16584
  "id": "events",
16112
16585
  "title": "Events",
16113
16586
  "body": "No custom events."
16587
+ },
16588
+ {
16589
+ "id": "breaking-changes",
16590
+ "title": "Breaking changes",
16591
+ "body": "- Removed `presentation` / `illustration` / `image` / `simple`, and `warn` / `danger` aliases.\n- `#extra` renamed to `#footer`.\n- HTTP defaults to built-in SVG illustrations (no giant numeric code).\n- Illustration catalog moved to [Empty](/components/Empty)."
16114
16592
  }
16115
16593
  ],
16116
- "markdown": "---\ntitle: Result\ncategory: 05 / FEEDBACK\ndescription: Outcome / terminal pages for success, failure, 403, 404, and more.\n---\n\n# Result\n\nFor submit outcomes, failures, forbidden access, and missing pages. Use [Empty](/components/Empty) for no-data states.\n\n## Import\n\n```ts\nimport { MResult } from 'morya-ui'\n```\n\n## Basic\n\n`status` drives the default icon, tone, and locale title.\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Actions\n\n```vue preview src=\"./demos/Actions.en.vue\"\n```\n\n## HTTP-style statuses\n\n```vue preview src=\"./demos/Http.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'warn' \\| 'error' \\| 'danger' \\| '403' \\| '404' \\| '500'` | `'info'` | Outcome status. `warn` warning; `danger` error. |\n| `title` | `string` | locale for `status` | Title. |\n| `description` | `string` | — | Supporting copy. |\n| `icon` | [IconName](/docs/types#IconName) | from `status` | Override default icon. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `icon` | Custom icon area. |\n| `title` | Custom title. |\n| `description` | Custom description. |\n| `extra` | Action area. |\n| `default` | Same as `extra`, appended in the action area. |\n\n## Accessibility\n\n- Root uses `role=\"status\"`.\n- Do not rely on color alone; keep a title.\n\n## Events\n\nNo custom events.\n"
16594
+ "markdown": "---\ntitle: Result\ncategory: 05 / FEEDBACK\ndescription: Outcome / terminal pages for success, failure, 403, 404, and more.\n---\n\n# Result\n\nFor submit outcomes, failures, forbidden access, and missing pages. Use [Empty](/components/Empty) for no-data states.\n\nCore API: `status` + `size` + `title` / `description`, slots `icon` / `default` / `footer`.\n\n## Import\n\n```ts\nimport { MResult } from \"morya-ui\";\n```\n\n## Basic\n\n`status` drives the default icon, tone, and locale title.\n\n```vue preview src=\"./demos/Basic.en.vue\"\n\n```\n\n## Actions\n\nPut buttons in `#footer`. Use `#default` for extra content under the description.\n\n```vue preview src=\"./demos/Actions.en.vue\"\n\n```\n\n## HTTP statuses\n\n`403` / `404` / `500` / `418` show a built-in illustration by default. Pass `icon` or `#icon` to switch back to icon mode.\n\n```vue preview src=\"./demos/Http.en.vue\"\n\n```\n\n## Size\n\n`size`: `small` / `medium` / `large` / `huge`.\n\n```vue preview src=\"./demos/Compact.en.vue\"\n\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| ------------- | --------------------------------------------------------------------------------- | ----------------------- | --------------------------------------------------------------------- |\n| `status` | `'info' \\| 'success' \\| 'warning' \\| 'error' \\| '403' \\| '404' \\| '500' \\| '418'` | `'info'` | Outcome status. HTTP statuses use a built-in illustration by default. |\n| `title` | `string` | locale for `status` | Title. |\n| `description` | `string` | — | Supporting text. |\n| `icon` | [IconName](/docs/types#IconName) | by `status` | Overrides the default icon; forces icon mode for HTTP statuses. |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'huge' \\| 'sm' \\| 'md' \\| 'lg'` | `'medium'` | Size. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |\n\n## Slots\n\n| Slot | Description |\n| ------------- | ------------------------------------ |\n| `icon` | Custom icon area. |\n| `title` | Custom title. |\n| `description` | Custom description. |\n| `default` | Extra content below title/description. |\n| `footer` | Action area. |\n\n## Accessibility\n\n- Root uses `role=\"status\"`.\n- Do not rely on color alone; keep a visible title.\n\n## Events\n\nNo custom events.\n\n## Breaking changes\n\n- Removed `presentation` / `illustration` / `image` / `simple`, and `warn` / `danger` aliases.\n- `#extra` renamed to `#footer`.\n- HTTP defaults to built-in SVG illustrations (no giant numeric code).\n- Illustration catalog moved to [Empty](/components/Empty).\n"
16117
16595
  }
16118
16596
  }
16119
16597
  },
@@ -18914,7 +19392,7 @@
18914
19392
  "name": "direction",
18915
19393
  "type": "同上",
18916
19394
  "default": "—",
18917
- "description": "`layout` 别名(Naive)。"
19395
+ "description": "`layout` 的别名。"
18918
19396
  },
18919
19397
  {
18920
19398
  "name": "size",
@@ -19136,7 +19614,7 @@
19136
19614
  {
19137
19615
  "id": "overview",
19138
19616
  "title": "",
19139
- "body": "# Splitter\n\n将内容拆成两个可并排或上下排列的区域,拖动分隔条即可调整比例。对齐 Naive `n-split` 的常用能力,同时保留 Wi 百分比用法。"
19617
+ "body": "# Splitter\n\n将内容拆成两个可并排或上下排列的区域,拖动分隔条即可调整比例。"
19140
19618
  },
19141
19619
  {
19142
19620
  "id": "引入",
@@ -19151,12 +19629,12 @@
19151
19629
  {
19152
19630
  "id": "vertical-direction",
19153
19631
  "title": "Vertical / direction",
19154
- "body": "`layout` 与 Naive 风格的 `direction` 等价。\n\n```vue preview src=\"./demos/VerticalDirection.vue\"\n```"
19632
+ "body": "`layout` 与 `direction` 等价(`direction` 为别名)。\n\n```vue preview src=\"./demos/VerticalDirection.vue\"\n```"
19155
19633
  },
19156
19634
  {
19157
19635
  "id": "size-modes",
19158
19636
  "title": "Size modes",
19159
- "body": "- `number > 1`:百分比(Wi 默认,如 `35` → 35%)\n- `number ≤ 1`:比例(Naive,如 `0.35` → 35%)\n- `string`:像素(如 `'120px'`)\n\n```vue preview src=\"./demos/SizeModes.vue\"\n```"
19637
+ "body": "- `number > 1`:百分比(如 `35` → 35%)\n- `number ≤ 1`:比例(如 `0.35` → 35%)\n- `string`:像素(如 `'120px'`)\n\n```vue preview src=\"./demos/SizeModes.vue\"\n```"
19160
19638
  },
19161
19639
  {
19162
19640
  "id": "disabled",
@@ -19166,7 +19644,7 @@
19166
19644
  {
19167
19645
  "id": "props",
19168
19646
  "title": "Props",
19169
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 分割方向。 |\n| `direction` | 同上 | — | `layout` 别名(Naive)。 |\n| `size` | `number \\| string` | — | 受控尺寸;`>1` 为 `%`,`≤1` 为比例,`'Npx'` 为像素。 |\n| `defaultSize` | `number \\| string` | `50` | 非受控初始尺寸。 |\n| `min` / `max` | `number \\| string` | 随模式 | 下限 / 上限(单位与 `size` 一致)。 |\n| `disabled` | `boolean` | `false` | 禁用拖拽与键盘调整。 |\n| `resizeTriggerSize` | `number` | `6` | 分隔条厚度(px)。 |\n| `pane1Class` / `pane1Style` | — | — | 主面板 class / style。 |\n| `pane2Class` / `pane2Style` | — | — | 次面板 class / style。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
19647
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 分割方向。 |\n| `direction` | 同上 | — | `layout` 的别名。 |\n| `size` | `number \\| string` | — | 受控尺寸;`>1` 为 `%`,`≤1` 为比例,`'Npx'` 为像素。 |\n| `defaultSize` | `number \\| string` | `50` | 非受控初始尺寸。 |\n| `min` / `max` | `number \\| string` | 随模式 | 下限 / 上限(单位与 `size` 一致)。 |\n| `disabled` | `boolean` | `false` | 禁用拖拽与键盘调整。 |\n| `resizeTriggerSize` | `number` | `6` | 分隔条厚度(px)。 |\n| `pane1Class` / `pane1Style` | — | — | 主面板 class / style。 |\n| `pane2Class` / `pane2Style` | — | — | 次面板 class / style。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
19170
19648
  },
19171
19649
  {
19172
19650
  "id": "slots",
@@ -19179,7 +19657,7 @@
19179
19657
  "body": "| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:size` | `number \\| string` | 尺寸变化。 |\n| `resize` | 同上 | 便于单独监听。 |\n| `drag-start` / `drag-move` / `drag-end` | `Event` | 拖拽生命周期。 |"
19180
19658
  }
19181
19659
  ],
19182
- "markdown": "---\ntitle: Splitter\ncategory: 06 / LAYOUT\ndescription: 双栏分割布局,支持水平 / 垂直与拖拽调整比例。\n---\n\n# Splitter\n\n将内容拆成两个可并排或上下排列的区域,拖动分隔条即可调整比例。对齐 Naive `n-split` 的常用能力,同时保留 Wi 百分比用法。\n\n## 引入\n\n```ts\nimport { MSplitter } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Vertical / direction\n\n`layout` 与 Naive 风格的 `direction` 等价。\n\n```vue preview src=\"./demos/VerticalDirection.vue\"\n```\n\n## Size modes\n\n- `number > 1`:百分比(Wi 默认,如 `35` → 35%)\n- `number ≤ 1`:比例(Naive,如 `0.35` → 35%)\n- `string`:像素(如 `'120px'`)\n\n```vue preview src=\"./demos/SizeModes.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 分割方向。 |\n| `direction` | 同上 | — | `layout` 别名(Naive)。 |\n| `size` | `number \\| string` | — | 受控尺寸;`>1` 为 `%`,`≤1` 为比例,`'Npx'` 为像素。 |\n| `defaultSize` | `number \\| string` | `50` | 非受控初始尺寸。 |\n| `min` / `max` | `number \\| string` | 随模式 | 下限 / 上限(单位与 `size` 一致)。 |\n| `disabled` | `boolean` | `false` | 禁用拖拽与键盘调整。 |\n| `resizeTriggerSize` | `number` | `6` | 分隔条厚度(px)。 |\n| `pane1Class` / `pane1Style` | — | — | 主面板 class / style。 |\n| `pane2Class` / `pane2Style` | — | — | 次面板 class / style。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `panel1` / `1` | 左侧 / 上方面板。 |\n| `panel2` / `2` | 右侧 / 下方面板。 |\n| `resize-trigger` | 自定义分隔条内容。 |\n| `default` | 未使用命名插槽时取前两个子节点。 |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:size` | `number \\| string` | 尺寸变化。 |\n| `resize` | 同上 | 便于单独监听。 |\n| `drag-start` / `drag-move` / `drag-end` | `Event` | 拖拽生命周期。 |\n"
19660
+ "markdown": "---\ntitle: Splitter\ncategory: 06 / LAYOUT\ndescription: 双栏分割布局,支持水平 / 垂直与拖拽调整比例。\n---\n\n# Splitter\n\n将内容拆成两个可并排或上下排列的区域,拖动分隔条即可调整比例。\n\n## 引入\n\n```ts\nimport { MSplitter } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Vertical / direction\n\n`layout` 与 `direction` 等价(`direction` 为别名)。\n\n```vue preview src=\"./demos/VerticalDirection.vue\"\n```\n\n## Size modes\n\n- `number > 1`:百分比(如 `35` → 35%)\n- `number ≤ 1`:比例(如 `0.35` → 35%)\n- `string`:像素(如 `'120px'`)\n\n```vue preview src=\"./demos/SizeModes.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 分割方向。 |\n| `direction` | 同上 | — | `layout` 的别名。 |\n| `size` | `number \\| string` | — | 受控尺寸;`>1` 为 `%`,`≤1` 为比例,`'Npx'` 为像素。 |\n| `defaultSize` | `number \\| string` | `50` | 非受控初始尺寸。 |\n| `min` / `max` | `number \\| string` | 随模式 | 下限 / 上限(单位与 `size` 一致)。 |\n| `disabled` | `boolean` | `false` | 禁用拖拽与键盘调整。 |\n| `resizeTriggerSize` | `number` | `6` | 分隔条厚度(px)。 |\n| `pane1Class` / `pane1Style` | — | — | 主面板 class / style。 |\n| `pane2Class` / `pane2Style` | — | — | 次面板 class / style。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `panel1` / `1` | 左侧 / 上方面板。 |\n| `panel2` / `2` | 右侧 / 下方面板。 |\n| `resize-trigger` | 自定义分隔条内容。 |\n| `default` | 未使用命名插槽时取前两个子节点。 |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:size` | `number \\| string` | 尺寸变化。 |\n| `resize` | 同上 | 便于单独监听。 |\n| `drag-start` / `drag-move` / `drag-end` | `Event` | 拖拽生命周期。 |\n"
19183
19661
  },
19184
19662
  "en-US": {
19185
19663
  "title": "Splitter",
@@ -19188,7 +19666,7 @@
19188
19666
  {
19189
19667
  "id": "overview",
19190
19668
  "title": "",
19191
- "body": "# Splitter\n\nSplit content into two panes with a draggable gutter. Covers common Naive `n-split` capabilities while keeping Wi percent sizing."
19669
+ "body": "# Splitter\n\nSplit content into two panes with a draggable gutter."
19192
19670
  },
19193
19671
  {
19194
19672
  "id": "import",
@@ -19203,12 +19681,12 @@
19203
19681
  {
19204
19682
  "id": "vertical-direction",
19205
19683
  "title": "Vertical / direction",
19206
- "body": "`layout` and Naive-style `direction` are equivalent.\n\n```vue preview src=\"./demos/VerticalDirection.vue\"\n```"
19684
+ "body": "`layout` and `direction` are equivalent (`direction` is an alias).\n\n```vue preview src=\"./demos/VerticalDirection.vue\"\n```"
19207
19685
  },
19208
19686
  {
19209
19687
  "id": "size-modes",
19210
19688
  "title": "Size modes",
19211
- "body": "- `number > 1`: percent (Wi default, e.g. `35` → 35%)\n- `number ≤ 1`: ratio (Naive, e.g. `0.35` → 35%)\n- `string`: pixels (e.g. `'120px'`)\n\n```vue preview src=\"./demos/SizeModes.vue\"\n```"
19689
+ "body": "- `number > 1`: percent (e.g. `35` → 35%)\n- `number ≤ 1`: ratio (e.g. `0.35` → 35%)\n- `string`: pixels (e.g. `'120px'`)\n\n```vue preview src=\"./demos/SizeModes.vue\"\n```"
19212
19690
  },
19213
19691
  {
19214
19692
  "id": "disabled",
@@ -19218,7 +19696,7 @@
19218
19696
  {
19219
19697
  "id": "props",
19220
19698
  "title": "Props",
19221
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | Split direction. |\n| `direction` | same | — | Alias of `layout` (Naive). |\n| `size` | `number \\| string` | — | Controlled size; `>1` = `%`, `≤1` = ratio, `'Npx'` = pixels. |\n| `defaultSize` | `number \\| string` | `50` | Uncontrolled initial size. |\n| `min` / `max` | `number \\| string` | mode-based | Bounds (same unit family as `size`). |\n| `disabled` | `boolean` | `false` | Disable drag and keyboard resize. |\n| `resizeTriggerSize` | `number` | `6` | Gutter thickness in px. |\n| `pane1Class` / `pane1Style` | — | — | Primary pane class / style. |\n| `pane2Class` / `pane2Style` | — | — | Secondary pane class / style. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
19699
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | Split direction. |\n| `direction` | same | — | Alias of `layout`. |\n| `size` | `number \\| string` | — | Controlled size; `>1` = `%`, `≤1` = ratio, `'Npx'` = pixels. |\n| `defaultSize` | `number \\| string` | `50` | Uncontrolled initial size. |\n| `min` / `max` | `number \\| string` | mode-based | Bounds (same unit family as `size`). |\n| `disabled` | `boolean` | `false` | Disable drag and keyboard resize. |\n| `resizeTriggerSize` | `number` | `6` | Gutter thickness in px. |\n| `pane1Class` / `pane1Style` | — | — | Primary pane class / style. |\n| `pane2Class` / `pane2Style` | — | — | Secondary pane class / style. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
19222
19700
  },
19223
19701
  {
19224
19702
  "id": "slots",
@@ -19231,7 +19709,7 @@
19231
19709
  "body": "| Event | Payload | Description |\n| --- | --- | --- |\n| `update:size` | `number \\| string` | Size changed. |\n| `resize` | same | Convenience listener. |\n| `drag-start` / `drag-move` / `drag-end` | `Event` | Drag lifecycle. |"
19232
19710
  }
19233
19711
  ],
19234
- "markdown": "---\ntitle: Splitter\ncategory: 06 / LAYOUT\ndescription: Two-pane resizable split layout (horizontal / vertical).\n---\n\n# Splitter\n\nSplit content into two panes with a draggable gutter. Covers common Naive `n-split` capabilities while keeping Wi percent sizing.\n\n## Import\n\n```ts\nimport { MSplitter } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Vertical / direction\n\n`layout` and Naive-style `direction` are equivalent.\n\n```vue preview src=\"./demos/VerticalDirection.vue\"\n```\n\n## Size modes\n\n- `number > 1`: percent (Wi default, e.g. `35` → 35%)\n- `number ≤ 1`: ratio (Naive, e.g. `0.35` → 35%)\n- `string`: pixels (e.g. `'120px'`)\n\n```vue preview src=\"./demos/SizeModes.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | Split direction. |\n| `direction` | same | — | Alias of `layout` (Naive). |\n| `size` | `number \\| string` | — | Controlled size; `>1` = `%`, `≤1` = ratio, `'Npx'` = pixels. |\n| `defaultSize` | `number \\| string` | `50` | Uncontrolled initial size. |\n| `min` / `max` | `number \\| string` | mode-based | Bounds (same unit family as `size`). |\n| `disabled` | `boolean` | `false` | Disable drag and keyboard resize. |\n| `resizeTriggerSize` | `number` | `6` | Gutter thickness in px. |\n| `pane1Class` / `pane1Style` | — | — | Primary pane class / style. |\n| `pane2Class` / `pane2Style` | — | — | Secondary pane class / style. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `panel1` / `1` | Left / top pane. |\n| `panel2` / `2` | Right / bottom pane. |\n| `resize-trigger` | Custom gutter content. |\n| `default` | First two children when named slots are unused. |\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `update:size` | `number \\| string` | Size changed. |\n| `resize` | same | Convenience listener. |\n| `drag-start` / `drag-move` / `drag-end` | `Event` | Drag lifecycle. |\n"
19712
+ "markdown": "---\ntitle: Splitter\ncategory: 06 / LAYOUT\ndescription: Two-pane resizable split layout (horizontal / vertical).\n---\n\n# Splitter\n\nSplit content into two panes with a draggable gutter.\n\n## Import\n\n```ts\nimport { MSplitter } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Vertical / direction\n\n`layout` and `direction` are equivalent (`direction` is an alias).\n\n```vue preview src=\"./demos/VerticalDirection.vue\"\n```\n\n## Size modes\n\n- `number > 1`: percent (e.g. `35` → 35%)\n- `number ≤ 1`: ratio (e.g. `0.35` → 35%)\n- `string`: pixels (e.g. `'120px'`)\n\n```vue preview src=\"./demos/SizeModes.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | Split direction. |\n| `direction` | same | — | Alias of `layout`. |\n| `size` | `number \\| string` | — | Controlled size; `>1` = `%`, `≤1` = ratio, `'Npx'` = pixels. |\n| `defaultSize` | `number \\| string` | `50` | Uncontrolled initial size. |\n| `min` / `max` | `number \\| string` | mode-based | Bounds (same unit family as `size`). |\n| `disabled` | `boolean` | `false` | Disable drag and keyboard resize. |\n| `resizeTriggerSize` | `number` | `6` | Gutter thickness in px. |\n| `pane1Class` / `pane1Style` | — | — | Primary pane class / style. |\n| `pane2Class` / `pane2Style` | — | — | Secondary pane class / style. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `panel1` / `1` | Left / top pane. |\n| `panel2` / `2` | Right / bottom pane. |\n| `resize-trigger` | Custom gutter content. |\n| `default` | First two children when named slots are unused. |\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `update:size` | `number \\| string` | Size changed. |\n| `resize` | same | Convenience listener. |\n| `drag-start` / `drag-move` / `drag-end` | `Event` | Drag lifecycle. |\n"
19235
19713
  }
19236
19714
  }
19237
19715
  },
@@ -19239,9 +19717,9 @@
19239
19717
  "id": "Status",
19240
19718
  "name": "Status",
19241
19719
  "exportName": "MStatus",
19242
- "category": "01 / BASIC",
19243
- "description": "行内状态指示,圆点加文案。",
19244
- "descriptionEn": "Inline status with a colored dot and label.",
19720
+ "category": "01 / DATA",
19721
+ "description": "行内状态标识:圆点 / 语义图标 + 文案。",
19722
+ "descriptionEn": "Inline status marker with a colored dot or semantic icon plus label.",
19245
19723
  "import": "import { MStatus } from 'morya-ui'",
19246
19724
  "props": [
19247
19725
  {
@@ -19254,13 +19732,13 @@
19254
19732
  "name": "severity",
19255
19733
  "type": "'primary' | 'secondary' | 'success' | 'info' | 'warn' | 'help' | 'danger' | 'contrast' | 'warning'",
19256
19734
  "default": "'secondary'",
19257
- "description": "语义色。`warning` 为兼容别名,映射为 `warn`。"
19735
+ "description": "语义色。非中性态默认带图标。"
19258
19736
  },
19259
19737
  {
19260
19738
  "name": "processing",
19261
19739
  "type": "boolean",
19262
19740
  "default": "false",
19263
- "description": "圆点脉冲动画。"
19741
+ "description": "标识脉冲动画。"
19264
19742
  },
19265
19743
  {
19266
19744
  "name": "size",
@@ -19273,6 +19751,24 @@
19273
19751
  "type": "string",
19274
19752
  "default": "—",
19275
19753
  "description": "自定义颜色,覆盖 `severity`。"
19754
+ },
19755
+ {
19756
+ "name": "variant",
19757
+ "type": "'dot' | 'tag' | 'text'",
19758
+ "default": "'dot'",
19759
+ "description": "展示形态:圆点/图标 / 胶囊 / 纯文字。"
19760
+ },
19761
+ {
19762
+ "name": "icon",
19763
+ "type": "[IconName](/docs/types#IconName)",
19764
+ "default": "—",
19765
+ "description": "前导图标;覆盖自动图标。"
19766
+ },
19767
+ {
19768
+ "name": "disabled",
19769
+ "type": "boolean",
19770
+ "default": "false",
19771
+ "description": "禁用弱化样式。"
19276
19772
  }
19277
19773
  ],
19278
19774
  "events": [],
@@ -19280,6 +19776,10 @@
19280
19776
  {
19281
19777
  "name": "default",
19282
19778
  "description": "状态文案。"
19779
+ },
19780
+ {
19781
+ "name": "icon",
19782
+ "description": "自定义前导图标。"
19283
19783
  }
19284
19784
  ],
19285
19785
  "examples": [
@@ -19289,7 +19789,7 @@
19289
19789
  "sectionId": "引入",
19290
19790
  "lang": "ts",
19291
19791
  "preview": false,
19292
- "code": "import { MStatus } from 'morya-ui'",
19792
+ "code": "import { MStatus } from \"morya-ui\";",
19293
19793
  "locale": "zh-CN"
19294
19794
  },
19295
19795
  {
@@ -19307,7 +19807,7 @@
19307
19807
  "sectionId": "severity",
19308
19808
  "lang": "vue",
19309
19809
  "preview": true,
19310
- "code": "<script setup lang=\"ts\">\nimport { MStatus } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MStatus label=\"Primary\" severity=\"primary\" />\n <MStatus label=\"Secondary\" severity=\"secondary\" />\n <MStatus label=\"Success\" severity=\"success\" />\n <MStatus label=\"Info\" severity=\"info\" />\n <MStatus label=\"Warn\" severity=\"warn\" />\n <MStatus label=\"Danger\" severity=\"danger\" />\n <MStatus label=\"Contrast\" severity=\"contrast\" />\n </div>\n</template>",
19810
+ "code": "<script setup lang=\"ts\">\nimport { MStatus } from \"morya-ui\";\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MStatus label=\"Primary\" severity=\"primary\" />\n <MStatus label=\"Secondary\" severity=\"secondary\" />\n <MStatus label=\"Success\" severity=\"success\" />\n <MStatus label=\"Info\" severity=\"info\" />\n <MStatus label=\"Warn\" severity=\"warn\" />\n <MStatus label=\"Danger\" severity=\"danger\" />\n <MStatus label=\"Contrast\" severity=\"contrast\" />\n <MStatus label=\"Disabled\" disabled />\n </div>\n</template>",
19311
19811
  "locale": "zh-CN"
19312
19812
  },
19313
19813
  {
@@ -19319,13 +19819,22 @@
19319
19819
  "code": "<script setup lang=\"ts\">\nimport { MStatus } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MStatus label=\"Small\" size=\"small\" severity=\"success\" />\n <MStatus label=\"Medium\" severity=\"info\" />\n <MStatus label=\"Large\" size=\"large\" severity=\"warn\" />\n <MStatus label=\"Processing\" severity=\"primary\" processing />\n </div>\n</template>",
19320
19820
  "locale": "zh-CN"
19321
19821
  },
19822
+ {
19823
+ "id": "标签-纯文字-自定义图标-1",
19824
+ "section": "标签 · 纯文字 · 自定义图标",
19825
+ "sectionId": "标签-纯文字-自定义图标",
19826
+ "lang": "vue",
19827
+ "preview": true,
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>",
19829
+ "locale": "zh-CN"
19830
+ },
19322
19831
  {
19323
19832
  "id": "import-1",
19324
19833
  "section": "Import",
19325
19834
  "sectionId": "import",
19326
19835
  "lang": "ts",
19327
19836
  "preview": false,
19328
- "code": "import { MStatus } from 'morya-ui'",
19837
+ "code": "import { MStatus } from \"morya-ui\";",
19329
19838
  "locale": "en-US"
19330
19839
  },
19331
19840
  {
@@ -19343,7 +19852,7 @@
19343
19852
  "sectionId": "severity",
19344
19853
  "lang": "vue",
19345
19854
  "preview": true,
19346
- "code": "<script setup lang=\"ts\">\nimport { MStatus } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MStatus label=\"Primary\" severity=\"primary\" />\n <MStatus label=\"Secondary\" severity=\"secondary\" />\n <MStatus label=\"Success\" severity=\"success\" />\n <MStatus label=\"Info\" severity=\"info\" />\n <MStatus label=\"Warn\" severity=\"warn\" />\n <MStatus label=\"Danger\" severity=\"danger\" />\n <MStatus label=\"Contrast\" severity=\"contrast\" />\n </div>\n</template>",
19855
+ "code": "<script setup lang=\"ts\">\nimport { MStatus } from \"morya-ui\";\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MStatus label=\"Primary\" severity=\"primary\" />\n <MStatus label=\"Secondary\" severity=\"secondary\" />\n <MStatus label=\"Success\" severity=\"success\" />\n <MStatus label=\"Info\" severity=\"info\" />\n <MStatus label=\"Warn\" severity=\"warn\" />\n <MStatus label=\"Danger\" severity=\"danger\" />\n <MStatus label=\"Contrast\" severity=\"contrast\" />\n <MStatus label=\"Disabled\" disabled />\n </div>\n</template>",
19347
19856
  "locale": "en-US"
19348
19857
  },
19349
19858
  {
@@ -19354,47 +19863,61 @@
19354
19863
  "preview": true,
19355
19864
  "code": "<script setup lang=\"ts\">\nimport { MStatus } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MStatus label=\"Small\" size=\"small\" severity=\"success\" />\n <MStatus label=\"Medium\" severity=\"info\" />\n <MStatus label=\"Large\" size=\"large\" severity=\"warn\" />\n <MStatus label=\"Processing\" severity=\"primary\" processing />\n </div>\n</template>",
19356
19865
  "locale": "en-US"
19866
+ },
19867
+ {
19868
+ "id": "tag-text-custom-icon-1",
19869
+ "section": "Tag · Text · Custom icon",
19870
+ "sectionId": "tag-text-custom-icon",
19871
+ "lang": "vue",
19872
+ "preview": true,
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>",
19874
+ "locale": "en-US"
19357
19875
  }
19358
19876
  ],
19359
19877
  "locales": {
19360
19878
  "zh-CN": {
19361
19879
  "title": "Status",
19362
- "description": "行内状态指示,圆点加文案。",
19880
+ "description": "行内状态标识:圆点 / 语义图标 + 文案。",
19363
19881
  "sections": [
19364
19882
  {
19365
19883
  "id": "overview",
19366
19884
  "title": "",
19367
- "body": "# Status\n\n用于表格、详情标题旁等场景,以圆点 + 文案展示业务状态。比 [Tag](/components/Tag) 更轻;需要分类标签或可关闭时用 Tag"
19885
+ "body": "# Status\n\n用于表格、详情标题旁等场景,以彩色标识 + 文案展示业务状态。比 [Tag](/components/Tag) 更轻;需要分类标签或可关闭时用 Tag。\n\n语义色(非 `secondary` / `contrast`)默认带对应图标,避免「纯色文字」难以扫读。"
19368
19886
  },
19369
19887
  {
19370
19888
  "id": "引入",
19371
19889
  "title": "引入",
19372
- "body": "```ts\nimport { MStatus } from 'morya-ui'\n```"
19890
+ "body": "```ts\nimport { MStatus } from \"morya-ui\";\n```"
19373
19891
  },
19374
19892
  {
19375
19893
  "id": "基础用法",
19376
19894
  "title": "基础用法",
19377
- "body": "通过 `label` 或默认插槽展示文案。\n\n```vue preview src=\"./demos/Basic.vue\"\n```"
19895
+ "body": "通过 `label` 或默认插槽展示文案。中性态用圆点;成功 / 失败等自动显示图标。\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```"
19378
19896
  },
19379
19897
  {
19380
19898
  "id": "severity",
19381
19899
  "title": "Severity",
19382
- "body": "使用 `severity` 定义语义色;默认 `secondary`(中性)。兼容旧值 `warning`(映射为 `warn`)。\n\n```vue preview src=\"./demos/Severity.vue\"\n```"
19900
+ "body": "使用 `severity` 定义语义色;默认 `secondary`(圆点、中性)。\n\n```vue preview src=\"./demos/Severity.vue\"\n\n```"
19383
19901
  },
19384
19902
  {
19385
19903
  "id": "size-processing",
19386
19904
  "title": "Size & Processing",
19387
- "body": "`size` 支持 `small` / `large`;`processing` 为圆点脉冲动画。\n\n```vue preview src=\"./demos/Processing.vue\"\n```"
19905
+ "body": "`size` 支持 `small` / `large`;`processing` 为标识脉冲动画。\n\n```vue preview src=\"./demos/Processing.vue\"\n\n```"
19906
+ },
19907
+ {
19908
+ "id": "标签-纯文字-自定义图标",
19909
+ "title": "标签 · 纯文字 · 自定义图标",
19910
+ "body": "- `variant=\"tag\"`:柔和胶囊底 + 圆点 / 自动图标。\n- `variant=\"text\"`:仅文案,无标识、无自动图标。\n- `icon` / `#icon`:覆盖自动图标。\n- `disabled`:弱化禁用态。\n\n```vue preview src=\"./demos/Variants.vue\"\n\n```"
19388
19911
  },
19389
19912
  {
19390
19913
  "id": "props",
19391
19914
  "title": "Props",
19392
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 状态文案。存在默认插槽内容时以插槽为准。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'secondary'` | 语义色。`warning` 为兼容别名,映射为 `warn`。 |\n| `processing` | `boolean` | `false` | 圆点脉冲动画。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n| `color` | `string` | — | 自定义颜色,覆盖 `severity`。 |"
19915
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| ------------ | ------------------------------------------------------------------------------------------------------------ | ------------- | ------------------------------------------------------------ |\n| `label` | `string` | — | 状态文案。存在默认插槽内容时以插槽为准。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'secondary'` | 语义色。非中性态默认带图标。 |\n| `processing` | `boolean` | `false` | 标识脉冲动画。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n| `color` | `string` | — | 自定义颜色,覆盖 `severity`。 |\n| `variant` | `'dot' \\| 'tag' \\| 'text'` | `'dot'` | 展示形态:圆点/图标 / 胶囊 / 纯文字。 |\n| `icon` | [IconName](/docs/types#IconName) | — | 前导图标;覆盖自动图标。 |\n| `disabled` | `boolean` | `false` | 禁用弱化样式。 |"
19393
19916
  },
19394
19917
  {
19395
19918
  "id": "slots",
19396
19919
  "title": "Slots",
19397
- "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 状态文案。 |"
19920
+ "body": "| 插槽名 | 说明 |\n| --------- | ---------------- |\n| `default` | 状态文案。 |\n| `icon` | 自定义前导图标。 |"
19398
19921
  },
19399
19922
  {
19400
19923
  "id": "无障碍",
@@ -19407,46 +19930,51 @@
19407
19930
  "body": "无自定义事件。"
19408
19931
  }
19409
19932
  ],
19410
- "markdown": "---\ntitle: Status\ncategory: 01 / BASIC\ndescription: 行内状态指示,圆点加文案。\n---\n\n# Status\n\n用于表格、详情标题旁等场景,以圆点 + 文案展示业务状态。比 [Tag](/components/Tag) 更轻;需要分类标签或可关闭时用 Tag。\n\n## 引入\n\n```ts\nimport { MStatus } from 'morya-ui'\n```\n\n## 基础用法\n\n通过 `label` 或默认插槽展示文案。\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\n使用 `severity` 定义语义色;默认 `secondary`(中性)。兼容旧值 `warning`(映射为 `warn`)。\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Size & Processing\n\n`size` 支持 `small` / `large`;`processing` 为圆点脉冲动画。\n\n```vue preview src=\"./demos/Processing.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 状态文案。存在默认插槽内容时以插槽为准。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'secondary'` | 语义色。`warning` 为兼容别名,映射为 `warn`。 |\n| `processing` | `boolean` | `false` | 圆点脉冲动画。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n| `color` | `string` | — | 自定义颜色,覆盖 `severity`。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 状态文案。 |\n\n## 无障碍\n\n- 根节点使用 `role=\"status\"`。\n- 不要仅靠颜色区分状态;保持可见文案。\n\n## Events\n\n无自定义事件。\n"
19933
+ "markdown": "---\ntitle: Status\ncategory: 01 / DATA\ndescription: 行内状态标识:圆点 / 语义图标 + 文案。\n---\n\n# Status\n\n用于表格、详情标题旁等场景,以彩色标识 + 文案展示业务状态。比 [Tag](/components/Tag) 更轻;需要分类标签或可关闭时用 Tag。\n\n语义色(非 `secondary` / `contrast`)默认带对应图标,避免「纯色文字」难以扫读。\n\n## 引入\n\n```ts\nimport { MStatus } from \"morya-ui\";\n```\n\n## 基础用法\n\n通过 `label` 或默认插槽展示文案。中性态用圆点;成功 / 失败等自动显示图标。\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n## Severity\n\n使用 `severity` 定义语义色;默认 `secondary`(圆点、中性)。\n\n```vue preview src=\"./demos/Severity.vue\"\n\n```\n\n## Size & Processing\n\n`size` 支持 `small` / `large`;`processing` 为标识脉冲动画。\n\n```vue preview src=\"./demos/Processing.vue\"\n\n```\n\n## 标签 · 纯文字 · 自定义图标\n\n- `variant=\"tag\"`:柔和胶囊底 + 圆点 / 自动图标。\n- `variant=\"text\"`:仅文案,无标识、无自动图标。\n- `icon` / `#icon`:覆盖自动图标。\n- `disabled`:弱化禁用态。\n\n```vue preview src=\"./demos/Variants.vue\"\n\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| ------------ | ------------------------------------------------------------------------------------------------------------ | ------------- | ------------------------------------------------------------ |\n| `label` | `string` | — | 状态文案。存在默认插槽内容时以插槽为准。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'secondary'` | 语义色。非中性态默认带图标。 |\n| `processing` | `boolean` | `false` | 标识脉冲动画。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n| `color` | `string` | — | 自定义颜色,覆盖 `severity`。 |\n| `variant` | `'dot' \\| 'tag' \\| 'text'` | `'dot'` | 展示形态:圆点/图标 / 胶囊 / 纯文字。 |\n| `icon` | [IconName](/docs/types#IconName) | — | 前导图标;覆盖自动图标。 |\n| `disabled` | `boolean` | `false` | 禁用弱化样式。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --------- | ---------------- |\n| `default` | 状态文案。 |\n| `icon` | 自定义前导图标。 |\n\n## 无障碍\n\n- 根节点使用 `role=\"status\"`。\n- 不要仅靠颜色区分状态;保持可见文案。\n\n## Events\n\n无自定义事件。\n"
19411
19934
  },
19412
19935
  "en-US": {
19413
19936
  "title": "Status",
19414
- "description": "Inline status with a colored dot and label.",
19937
+ "description": "Inline status marker with a colored dot or semantic icon plus label.",
19415
19938
  "sections": [
19416
19939
  {
19417
19940
  "id": "overview",
19418
19941
  "title": "",
19419
- "body": "# Status\n\nLightweight status for tables and detail headers: a colored dot plus label. Prefer [Tag](/components/Tag) when you need a chip-like label or closable control."
19942
+ "body": "# Status\n\nLightweight status for tables and detail headers. Prefer [Tag](/components/Tag) when you need a chip-like label or closable control.\n\nNon-neutral severities show a semantic icon by default so the status reads as a marker, not plain tinted text."
19420
19943
  },
19421
19944
  {
19422
19945
  "id": "import",
19423
19946
  "title": "Import",
19424
- "body": "```ts\nimport { MStatus } from 'morya-ui'\n```"
19947
+ "body": "```ts\nimport { MStatus } from \"morya-ui\";\n```"
19425
19948
  },
19426
19949
  {
19427
19950
  "id": "basic",
19428
19951
  "title": "Basic",
19429
- "body": "Pass `label` or use the default slot.\n\n```vue preview src=\"./demos/Basic.vue\"\n```"
19952
+ "body": "Pass `label` or use the default slot. Neutral status uses a dot; success / danger / etc. get an icon automatically.\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```"
19430
19953
  },
19431
19954
  {
19432
19955
  "id": "severity",
19433
19956
  "title": "Severity",
19434
- "body": "Use `severity` for semantic color; defaults to `secondary`. Legacy `warning` maps to `warn`.\n\n```vue preview src=\"./demos/Severity.vue\"\n```"
19957
+ "body": "Use `severity` for semantic color; defaults to `secondary` (dot, neutral).\n\n```vue preview src=\"./demos/Severity.vue\"\n\n```"
19435
19958
  },
19436
19959
  {
19437
19960
  "id": "size-processing",
19438
19961
  "title": "Size & Processing",
19439
- "body": "`size` supports `small` / `large`. `processing` pulses the dot.\n\n```vue preview src=\"./demos/Processing.vue\"\n```"
19962
+ "body": "`size` supports `small` / `large`. `processing` pulses the indicator.\n\n```vue preview src=\"./demos/Processing.vue\"\n\n```"
19963
+ },
19964
+ {
19965
+ "id": "tag-text-custom-icon",
19966
+ "title": "Tag · Text · Custom icon",
19967
+ "body": "- `variant=\"tag\"`: soft pill with dot or auto icon.\n- `variant=\"text\"`: label only — no indicator, no auto icon.\n- `icon` / `#icon`: overrides the auto icon.\n- `disabled`: muted inactive look.\n\n```vue preview src=\"./demos/Variants.vue\"\n\n```"
19440
19968
  },
19441
19969
  {
19442
19970
  "id": "props",
19443
19971
  "title": "Props",
19444
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `label` | `string` | — | Status text. Slot content wins when present. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'secondary'` | Semantic color. `warning` maps to `warn`. |\n| `processing` | `boolean` | `false` | Pulse animation on the dot. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Size. |\n| `color` | `string` | — | Custom color; overrides `severity`. |"
19972
+ "body": "| Prop | Type | Default | Description |\n| ------------ | ------------------------------------------------------------------------------------------------------------ | ------------- | -------------------------------------------------------- |\n| `label` | `string` | — | Status text. Slot content wins when present. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'secondary'` | Semantic color. Non-neutral tones get a default icon. |\n| `processing` | `boolean` | `false` | Pulse animation on the indicator. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Size. |\n| `color` | `string` | — | Custom color; overrides `severity`. |\n| `variant` | `'dot' \\| 'tag' \\| 'text'` | `'dot'` | Presentation: marker / soft pill / text only. |\n| `icon` | [IconName](/docs/types#IconName) | — | Leading icon; overrides auto icon. |\n| `disabled` | `boolean` | `false` | Muted disabled appearance. |"
19445
19973
  },
19446
19974
  {
19447
19975
  "id": "slots",
19448
19976
  "title": "Slots",
19449
- "body": "| Slot | Description |\n| --- | --- |\n| `default` | Status text. |"
19977
+ "body": "| Slot | Description |\n| --------- | -------------------- |\n| `default` | Status text. |\n| `icon` | Custom leading icon. |"
19450
19978
  },
19451
19979
  {
19452
19980
  "id": "accessibility",
@@ -19459,7 +19987,7 @@
19459
19987
  "body": "No custom events."
19460
19988
  }
19461
19989
  ],
19462
- "markdown": "---\ntitle: Status\ncategory: 01 / BASIC\ndescription: Inline status with a colored dot and label.\n---\n\n# Status\n\nLightweight status for tables and detail headers: a colored dot plus label. Prefer [Tag](/components/Tag) when you need a chip-like label or closable control.\n\n## Import\n\n```ts\nimport { MStatus } from 'morya-ui'\n```\n\n## Basic\n\nPass `label` or use the default slot.\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\nUse `severity` for semantic color; defaults to `secondary`. Legacy `warning` maps to `warn`.\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Size & Processing\n\n`size` supports `small` / `large`. `processing` pulses the dot.\n\n```vue preview src=\"./demos/Processing.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `label` | `string` | — | Status text. Slot content wins when present. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'secondary'` | Semantic color. `warning` maps to `warn`. |\n| `processing` | `boolean` | `false` | Pulse animation on the dot. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Size. |\n| `color` | `string` | — | Custom color; overrides `severity`. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Status text. |\n\n## Accessibility\n\n- Root uses `role=\"status\"`.\n- Do not rely on color alone; keep visible text.\n\n## Events\n\nNo custom events.\n"
19990
+ "markdown": "---\ntitle: Status\ncategory: 01 / DATA\ndescription: Inline status marker with a colored dot or semantic icon plus label.\n---\n\n# Status\n\nLightweight status for tables and detail headers. Prefer [Tag](/components/Tag) when you need a chip-like label or closable control.\n\nNon-neutral severities show a semantic icon by default so the status reads as a marker, not plain tinted text.\n\n## Import\n\n```ts\nimport { MStatus } from \"morya-ui\";\n```\n\n## Basic\n\nPass `label` or use the default slot. Neutral status uses a dot; success / danger / etc. get an icon automatically.\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n## Severity\n\nUse `severity` for semantic color; defaults to `secondary` (dot, neutral).\n\n```vue preview src=\"./demos/Severity.vue\"\n\n```\n\n## Size & Processing\n\n`size` supports `small` / `large`. `processing` pulses the indicator.\n\n```vue preview src=\"./demos/Processing.vue\"\n\n```\n\n## Tag · Text · Custom icon\n\n- `variant=\"tag\"`: soft pill with dot or auto icon.\n- `variant=\"text\"`: label only — no indicator, no auto icon.\n- `icon` / `#icon`: overrides the auto icon.\n- `disabled`: muted inactive look.\n\n```vue preview src=\"./demos/Variants.vue\"\n\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| ------------ | ------------------------------------------------------------------------------------------------------------ | ------------- | -------------------------------------------------------- |\n| `label` | `string` | — | Status text. Slot content wins when present. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'secondary'` | Semantic color. Non-neutral tones get a default icon. |\n| `processing` | `boolean` | `false` | Pulse animation on the indicator. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Size. |\n| `color` | `string` | — | Custom color; overrides `severity`. |\n| `variant` | `'dot' \\| 'tag' \\| 'text'` | `'dot'` | Presentation: marker / soft pill / text only. |\n| `icon` | [IconName](/docs/types#IconName) | — | Leading icon; overrides auto icon. |\n| `disabled` | `boolean` | `false` | Muted disabled appearance. |\n\n## Slots\n\n| Slot | Description |\n| --------- | -------------------- |\n| `default` | Status text. |\n| `icon` | Custom leading icon. |\n\n## Accessibility\n\n- Root uses `role=\"status\"`.\n- Do not rely on color alone; keep visible text.\n\n## Events\n\nNo custom events.\n"
19463
19991
  }
19464
19992
  }
19465
19993
  },
@@ -21064,7 +21592,7 @@
21064
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```"
21065
21593
  }
21066
21594
  ],
21067
- "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"
21068
21596
  },
21069
21597
  "en-US": {
21070
21598
  "title": "Tabs",
@@ -21111,7 +21639,7 @@
21111
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```"
21112
21640
  }
21113
21641
  ],
21114
- "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"
21115
21643
  }
21116
21644
  }
21117
21645
  },
@@ -22639,7 +23167,7 @@
22639
23167
  {
22640
23168
  "id": "overview",
22641
23169
  "title": "",
22642
- "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`](../../../../ai-design-config/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('已保存')`。"
22643
23171
  },
22644
23172
  {
22645
23173
  "id": "引入",
@@ -22687,7 +23215,7 @@
22687
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```"
22688
23216
  }
22689
23217
  ],
22690
- "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`](../../../../ai-design-config/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"
22691
23219
  },
22692
23220
  "en-US": {
22693
23221
  "title": "Toast",
@@ -22696,7 +23224,7 @@
22696
23224
  {
22697
23225
  "id": "overview",
22698
23226
  "title": "",
22699
- "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`](../../../../ai-design-config/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."
22700
23228
  },
22701
23229
  {
22702
23230
  "id": "import",
@@ -22744,7 +23272,7 @@
22744
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```"
22745
23273
  }
22746
23274
  ],
22747
- "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`](../../../../ai-design-config/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"
22748
23276
  }
22749
23277
  }
22750
23278
  },
@@ -23584,7 +24112,7 @@
23584
24112
  {
23585
24113
  "id": "overview",
23586
24114
  "title": "",
23587
- "body": "# Tree\n\n层级节点树,支持展开、勾选、过滤与拖拽等常用能力。\n\n**与 Naive 的差异:** 默认插槽 `{ node, data }` 自定义节点内容。`checkStrategy` 为 `'all' | 'parent' | 'child'`(`checkStrictly` 时忽略)。内部仍按级联计算半选;`v-model:checked-keys` 按策略投影。虚拟滚动不做。"
24115
+ "body": "# Tree\n\n层级节点树,支持展开、勾选、过滤与拖拽等常用能力。\n\n默认插槽 `{ node, data }` 可自定义节点内容。`checkStrategy` 为 `'all' | 'parent' | 'child'`(`checkStrictly` 时忽略)。内部仍按级联计算半选;`v-model:checked-keys` 按策略投影。虚拟滚动本期不做。"
23588
24116
  },
23589
24117
  {
23590
24118
  "id": "引入",
@@ -23604,7 +24132,7 @@
23604
24132
  {
23605
24133
  "id": "check-strategy",
23606
24134
  "title": "Check strategy",
23607
- "body": "勾选父节点时,`check-strategy=\"child\"` 只绑定叶子 key(对照 Naive `n-tree`)。\n\n```vue preview src=\"./demos/CheckStrategy.vue\"\n```"
24135
+ "body": "勾选父节点时,`check-strategy=\"child\"` 只绑定叶子 key。\n\n```vue preview src=\"./demos/CheckStrategy.vue\"\n```"
23608
24136
  },
23609
24137
  {
23610
24138
  "id": "filter",
@@ -23637,7 +24165,7 @@
23637
24165
  "body": "<h4 id=\"TreeNode\">TreeNode</h4>\n\n`value` 数组项:\n\n```ts\ninterface TreeNode {\n key: string\n label: string\n children?: TreeNode[]\n icon?: string\n disabled?: boolean\n isLeaf?: boolean\n}\n```\n\n选中/勾选/展开分别用 `selectionKeys`、`checkedKeys`、`expandedKeys`(`Record<string, boolean>`)。`checkStrategy` 为 `'all' | 'parent' | 'child'`。更多见 [API 类型](/docs/types)。"
23638
24166
  }
23639
24167
  ],
23640
- "markdown": "---\ntitle: Tree\ncategory: 03 / DATA\ndescription: 树形结构。支持勾选半选、过滤、受控展开、懒加载与拖拽。\n---\n\n# Tree\n\n层级节点树,支持展开、勾选、过滤与拖拽等常用能力。\n\n**与 Naive 的差异:** 默认插槽 `{ node, data }` 自定义节点内容。`checkStrategy` 为 `'all' | 'parent' | 'child'`(`checkStrictly` 时忽略)。内部仍按级联计算半选;`v-model:checked-keys` 按策略投影。虚拟滚动不做。\n\n## 引入\n\n```ts\nimport { MTree } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Checkbox\n\n```vue preview src=\"./demos/Checkbox.zh.vue\"\n```\n\n## Check strategy\n\n勾选父节点时,`check-strategy=\"child\"` 只绑定叶子 key(对照 Naive `n-tree`)。\n\n```vue preview src=\"./demos/CheckStrategy.vue\"\n```\n\n## Filter\n\n```vue preview src=\"./demos/Filter.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `TreeNode[]` | — | 节点树。 |\n| `modelValue` / `selectionKeys` / `selectionMode` | — | — | 高亮选择。 |\n| `showCheckbox` / `checkedKeys` / `checkStrictly` / `checkStrategy` | — | `'all'` | `checkStrategy` 默认 `'all'`;`'parent'` / `'child'` 只改变绑定的 keys。 |\n| `expandedKeys` / `defaultExpandAll` / `accordion` | — | — | 展开控制。 |\n| `filter` / `filterNode` | — | — | 过滤。 |\n| `lazy` / `load` | — | — | 懒加载子节点。 |\n| `draggable` | `boolean` | `false` | 拖拽;落点通过 `node-drop` 由业务改树。 |\n| `emptyMessage` | `string` | — | 无数据时的提示文案。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Slots / Events\n\n| 插槽 | 说明 |\n| --- | --- |\n| `default` | `{ node, data }` 自定义节点内容。 |\n\n| 事件 | 说明 |\n| --- | --- |\n| `update:checkedKeys` / `update:expandedKeys` / `check` / `node-expand` / `node-collapse` / `node-drop` | 交互回调。 |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `node-select` | `TreeNode` | 节点选中。 |\n| `node-expand` | `TreeNode` | 节点展开。 |\n| `node-collapse` | `TreeNode` | 节点收起。 |\n| `node-load-error` | `{ node, error }` | 懒加载子节点失败。 |\n| `node-unselect` | `TreeNode` | 取消选中节点。 |\n| `update:modelValue` | `TreeNodeKey \\| TreeNodeKey[]` | 选中键 v-model。 |\n| `update:selectionKeys` | `Record<string, boolean>` | 选中键集合 v-model。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `empty` | 自定义 `empty` 内容。 |\n\n## 类型\n\n<h4 id=\"TreeNode\">TreeNode</h4>\n\n`value` 数组项:\n\n```ts\ninterface TreeNode {\n key: string\n label: string\n children?: TreeNode[]\n icon?: string\n disabled?: boolean\n isLeaf?: boolean\n}\n```\n\n选中/勾选/展开分别用 `selectionKeys`、`checkedKeys`、`expandedKeys`(`Record<string, boolean>`)。`checkStrategy` 为 `'all' | 'parent' | 'child'`。更多见 [API 类型](/docs/types)。\n"
24168
+ "markdown": "---\ntitle: Tree\ncategory: 03 / DATA\ndescription: 树形结构。支持勾选半选、过滤、受控展开、懒加载与拖拽。\n---\n\n# Tree\n\n层级节点树,支持展开、勾选、过滤与拖拽等常用能力。\n\n默认插槽 `{ node, data }` 可自定义节点内容。`checkStrategy` 为 `'all' | 'parent' | 'child'`(`checkStrictly` 时忽略)。内部仍按级联计算半选;`v-model:checked-keys` 按策略投影。虚拟滚动本期不做。\n\n## 引入\n\n```ts\nimport { MTree } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Checkbox\n\n```vue preview src=\"./demos/Checkbox.zh.vue\"\n```\n\n## Check strategy\n\n勾选父节点时,`check-strategy=\"child\"` 只绑定叶子 key。\n\n```vue preview src=\"./demos/CheckStrategy.vue\"\n```\n\n## Filter\n\n```vue preview src=\"./demos/Filter.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `TreeNode[]` | — | 节点树。 |\n| `modelValue` / `selectionKeys` / `selectionMode` | — | — | 高亮选择。 |\n| `showCheckbox` / `checkedKeys` / `checkStrictly` / `checkStrategy` | — | `'all'` | `checkStrategy` 默认 `'all'`;`'parent'` / `'child'` 只改变绑定的 keys。 |\n| `expandedKeys` / `defaultExpandAll` / `accordion` | — | — | 展开控制。 |\n| `filter` / `filterNode` | — | — | 过滤。 |\n| `lazy` / `load` | — | — | 懒加载子节点。 |\n| `draggable` | `boolean` | `false` | 拖拽;落点通过 `node-drop` 由业务改树。 |\n| `emptyMessage` | `string` | — | 无数据时的提示文案。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Slots / Events\n\n| 插槽 | 说明 |\n| --- | --- |\n| `default` | `{ node, data }` 自定义节点内容。 |\n\n| 事件 | 说明 |\n| --- | --- |\n| `update:checkedKeys` / `update:expandedKeys` / `check` / `node-expand` / `node-collapse` / `node-drop` | 交互回调。 |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `node-select` | `TreeNode` | 节点选中。 |\n| `node-expand` | `TreeNode` | 节点展开。 |\n| `node-collapse` | `TreeNode` | 节点收起。 |\n| `node-load-error` | `{ node, error }` | 懒加载子节点失败。 |\n| `node-unselect` | `TreeNode` | 取消选中节点。 |\n| `update:modelValue` | `TreeNodeKey \\| TreeNodeKey[]` | 选中键 v-model。 |\n| `update:selectionKeys` | `Record<string, boolean>` | 选中键集合 v-model。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `empty` | 自定义 `empty` 内容。 |\n\n## 类型\n\n<h4 id=\"TreeNode\">TreeNode</h4>\n\n`value` 数组项:\n\n```ts\ninterface TreeNode {\n key: string\n label: string\n children?: TreeNode[]\n icon?: string\n disabled?: boolean\n isLeaf?: boolean\n}\n```\n\n选中/勾选/展开分别用 `selectionKeys`、`checkedKeys`、`expandedKeys`(`Record<string, boolean>`)。`checkStrategy` 为 `'all' | 'parent' | 'child'`。更多见 [API 类型](/docs/types)。\n"
23641
24169
  },
23642
24170
  "en-US": {
23643
24171
  "title": "Tree",
@@ -23646,7 +24174,7 @@
23646
24174
  {
23647
24175
  "id": "overview",
23648
24176
  "title": "",
23649
- "body": "# Tree\n\nHierarchical node tree with expand, check, filter, and drag-and-drop.\n\n**Naive differences:** the default slot `{ node, data }` customizes node content. `checkStrategy` is `'all' | 'parent' | 'child'` (ignored when `checkStrictly`). Cascade still drives the UI; `v-model:checked-keys` is projected by strategy. Virtual scroll is out of scope."
24177
+ "body": "# Tree\n\nHierarchical node tree with expand, check, filter, and drag-and-drop.\n\nThe default slot `{ node, data }` customizes node content. `checkStrategy` is `'all' | 'parent' | 'child'` (ignored when `checkStrictly`). Cascade still drives the UI; `v-model:checked-keys` is projected by strategy. Virtual scroll is out of scope."
23650
24178
  },
23651
24179
  {
23652
24180
  "id": "import",
@@ -23666,7 +24194,7 @@
23666
24194
  {
23667
24195
  "id": "check-strategy",
23668
24196
  "title": "Check strategy",
23669
- "body": "With `check-strategy=\"child\"`, checking a parent binds leaf keys only (Naive `n-tree`).\n\n```vue preview src=\"./demos/CheckStrategy.vue\"\n```"
24197
+ "body": "With `check-strategy=\"child\"`, checking a parent binds leaf keys only.\n\n```vue preview src=\"./demos/CheckStrategy.vue\"\n```"
23670
24198
  },
23671
24199
  {
23672
24200
  "id": "filter",
@@ -23694,7 +24222,7 @@
23694
24222
  "body": "<h4 id=\"TreeNode\">TreeNode</h4>\n\nEach node in `value`:\n\n```ts\ninterface TreeNode {\n key: string\n label: string\n children?: TreeNode[]\n icon?: string\n disabled?: boolean\n isLeaf?: boolean\n}\n```\n\nSelection, check, and expand state use `selectionKeys`, `checkedKeys`, and `expandedKeys` (`Record<string, boolean>`). `checkStrategy` is `'all' | 'parent' | 'child'`. See also [API types](/docs/types)."
23695
24223
  }
23696
24224
  ],
23697
- "markdown": "---\ntitle: Tree\ncategory: 03 / DATA\ndescription: Tree structure. Supports check with indeterminate state, filter, controlled expand, lazy load, and drag-and-drop.\n---\n\n# Tree\n\nHierarchical node tree with expand, check, filter, and drag-and-drop.\n\n**Naive differences:** the default slot `{ node, data }` customizes node content. `checkStrategy` is `'all' | 'parent' | 'child'` (ignored when `checkStrictly`). Cascade still drives the UI; `v-model:checked-keys` is projected by strategy. Virtual scroll is out of scope.\n\n## Import\n\n```ts\nimport { MTree } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Checkbox\n\n```vue preview src=\"./demos/Checkbox.en.vue\"\n```\n\n## Check strategy\n\nWith `check-strategy=\"child\"`, checking a parent binds leaf keys only (Naive `n-tree`).\n\n```vue preview src=\"./demos/CheckStrategy.vue\"\n```\n\n## Filter\n\n```vue preview src=\"./demos/Filter.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `TreeNode[]` | — | Node tree. |\n| `modelValue` / `selectionKeys` / `selectionMode` | — | — | Highlight selection. |\n| `showCheckbox` / `checkedKeys` / `checkStrictly` / `checkStrategy` | — | `'all'` | `checkStrategy` defaults to `'all'`; `'parent'` / `'child'` only change which keys are bound. |\n| `expandedKeys` / `defaultExpandAll` / `accordion` | — | — | Expand control. |\n| `filter` / `filterNode` | — | — | Filter. |\n| `lazy` / `load` | — | — | Lazy-load child nodes. |\n| `draggable` | `boolean` | `false` | Drag and drop; the drop target is applied by the consumer via `node-drop`. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Slots / Events\n\n| Slot | Description |\n| --- | --- |\n| `default` | `{ node, data }` custom node content. |\n\n| Event | Description |\n| --- | --- |\n| `update:checkedKeys` / `update:expandedKeys` / `check` / `node-expand` / `node-collapse` / `node-drop` | Interaction callbacks. |\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `node-select` | `TreeNode` | Node selected. |\n| `node-expand` | `TreeNode` | Node expanded. |\n| `node-collapse` | `TreeNode` | Node collapsed. |\n\n## Types\n\n<h4 id=\"TreeNode\">TreeNode</h4>\n\nEach node in `value`:\n\n```ts\ninterface TreeNode {\n key: string\n label: string\n children?: TreeNode[]\n icon?: string\n disabled?: boolean\n isLeaf?: boolean\n}\n```\n\nSelection, check, and expand state use `selectionKeys`, `checkedKeys`, and `expandedKeys` (`Record<string, boolean>`). `checkStrategy` is `'all' | 'parent' | 'child'`. See also [API types](/docs/types).\n"
24225
+ "markdown": "---\ntitle: Tree\ncategory: 03 / DATA\ndescription: Tree structure. Supports check with indeterminate state, filter, controlled expand, lazy load, and drag-and-drop.\n---\n\n# Tree\n\nHierarchical node tree with expand, check, filter, and drag-and-drop.\n\nThe default slot `{ node, data }` customizes node content. `checkStrategy` is `'all' | 'parent' | 'child'` (ignored when `checkStrictly`). Cascade still drives the UI; `v-model:checked-keys` is projected by strategy. Virtual scroll is out of scope.\n\n## Import\n\n```ts\nimport { MTree } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Checkbox\n\n```vue preview src=\"./demos/Checkbox.en.vue\"\n```\n\n## Check strategy\n\nWith `check-strategy=\"child\"`, checking a parent binds leaf keys only.\n\n```vue preview src=\"./demos/CheckStrategy.vue\"\n```\n\n## Filter\n\n```vue preview src=\"./demos/Filter.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `TreeNode[]` | — | Node tree. |\n| `modelValue` / `selectionKeys` / `selectionMode` | — | — | Highlight selection. |\n| `showCheckbox` / `checkedKeys` / `checkStrictly` / `checkStrategy` | — | `'all'` | `checkStrategy` defaults to `'all'`; `'parent'` / `'child'` only change which keys are bound. |\n| `expandedKeys` / `defaultExpandAll` / `accordion` | — | — | Expand control. |\n| `filter` / `filterNode` | — | — | Filter. |\n| `lazy` / `load` | — | — | Lazy-load child nodes. |\n| `draggable` | `boolean` | `false` | Drag and drop; the drop target is applied by the consumer via `node-drop`. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Slots / Events\n\n| Slot | Description |\n| --- | --- |\n| `default` | `{ node, data }` custom node content. |\n\n| Event | Description |\n| --- | --- |\n| `update:checkedKeys` / `update:expandedKeys` / `check` / `node-expand` / `node-collapse` / `node-drop` | Interaction callbacks. |\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `node-select` | `TreeNode` | Node selected. |\n| `node-expand` | `TreeNode` | Node expanded. |\n| `node-collapse` | `TreeNode` | Node collapsed. |\n\n## Types\n\n<h4 id=\"TreeNode\">TreeNode</h4>\n\nEach node in `value`:\n\n```ts\ninterface TreeNode {\n key: string\n label: string\n children?: TreeNode[]\n icon?: string\n disabled?: boolean\n isLeaf?: boolean\n}\n```\n\nSelection, check, and expand state use `selectionKeys`, `checkedKeys`, and `expandedKeys` (`Record<string, boolean>`). `checkStrategy` is `'all' | 'parent' | 'child'`. See also [API types](/docs/types).\n"
23698
24226
  }
23699
24227
  }
23700
24228
  },
@@ -23968,7 +24496,7 @@
23968
24496
  {
23969
24497
  "id": "overview",
23970
24498
  "title": "",
23971
- "body": "# TreeSelect\n\n在下拉中展示可展开树。`multiple` / `checkable` 打开多选;`filterable`、`clearable`、`showPath` 对照 Naive `n-tree-select` 常用能力。"
24499
+ "body": "# TreeSelect\n\n在下拉中展示可展开树。`multiple` / `checkable` 打开多选;另支持 `filterable`、`clearable`、`showPath`。"
23972
24500
  },
23973
24501
  {
23974
24502
  "id": "引入",
@@ -24011,7 +24539,7 @@
24011
24539
  "body": "<h4 id=\"TreeSelectNode\">TreeSelectNode</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface TreeSelectNode {\n key: string\n label: string\n children?: TreeSelectNode[]\n disabled?: boolean\n}\n```"
24012
24540
  }
24013
24541
  ],
24014
- "markdown": "---\ntitle: TreeSelect\ncategory: 02 / FORM\ndescription: 下拉树选择。支持单选/多选、勾选级联、过滤、清空与路径展示。\n---\n\n# TreeSelect\n\n在下拉中展示可展开树。`multiple` / `checkable` 打开多选;`filterable`、`clearable`、`showPath` 对照 Naive `n-tree-select` 常用能力。\n\n## 引入\n\n```ts\nimport { MTreeSelect } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Multiple / filter / path\n\n```vue preview src=\"./demos/MultipleFilterPath.zh.vue\"\n```\n\n## Size\n\n```vue preview src=\"./demos/Size.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `options` | `TreeSelectNode[]` | — | 树节点。 |\n| `modelValue` | `string \\| string[] \\| null` | `null` | 选中节点 key;多选为数组。 |\n| `placeholder` | `string` | locale | 占位文案。 |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | `small` / `large`;可继承 ConfigProvider。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `multiple` | `boolean` | `false` | 多选。 |\n| `checkable` | `boolean` | `false` | 显示勾选框(级联语义同 Tree)。 |\n| `checkStrictly` | `boolean` | `false` | 父子不关联。 |\n| `checkStrategy` | `'all' \\| 'parent' \\| 'child'` | `'all'` | 级联时绑定哪些 keys。 |\n| `clearable` | `boolean` | `false` | 显示清空。 |\n| `filterable` | `boolean` | `false` | 面板内过滤。 |\n| `showPath` | `boolean` | `false` | 展示祖先路径。 |\n| `separator` | `string` | `' / '` | 路径分隔符。 |\n| `maxTagCount` | `number` | — | 多选最多展示的 tag 数。 |\n| `selectionMode` | `'single' \\| 'multiple'` | `'single'` | 兼容字段;请优先用 `multiple`。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `errorMessage` | `string` | — | — |\n| `helpText` | `string` | — | — |\n| `id` | `string` | — | — |\n| `invalid` | `boolean` | — | — |\n| `label` | `string` | — | — |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `string \\| string[] \\| null` | 选中变化。 |\n| `clear` | — | 点击清空。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `value` | 触发器展示。 |\n| `option` | 树节点 `{ node }`。 |\n\n## 类型\n\n<h4 id=\"TreeSelectNode\">TreeSelectNode</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface TreeSelectNode {\n key: string\n label: string\n children?: TreeSelectNode[]\n disabled?: boolean\n}\n```\n"
24542
+ "markdown": "---\ntitle: TreeSelect\ncategory: 02 / FORM\ndescription: 下拉树选择。支持单选/多选、勾选级联、过滤、清空与路径展示。\n---\n\n# TreeSelect\n\n在下拉中展示可展开树。`multiple` / `checkable` 打开多选;另支持 `filterable`、`clearable`、`showPath`。\n\n## 引入\n\n```ts\nimport { MTreeSelect } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Multiple / filter / path\n\n```vue preview src=\"./demos/MultipleFilterPath.zh.vue\"\n```\n\n## Size\n\n```vue preview src=\"./demos/Size.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `options` | `TreeSelectNode[]` | — | 树节点。 |\n| `modelValue` | `string \\| string[] \\| null` | `null` | 选中节点 key;多选为数组。 |\n| `placeholder` | `string` | locale | 占位文案。 |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | `small` / `large`;可继承 ConfigProvider。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `multiple` | `boolean` | `false` | 多选。 |\n| `checkable` | `boolean` | `false` | 显示勾选框(级联语义同 Tree)。 |\n| `checkStrictly` | `boolean` | `false` | 父子不关联。 |\n| `checkStrategy` | `'all' \\| 'parent' \\| 'child'` | `'all'` | 级联时绑定哪些 keys。 |\n| `clearable` | `boolean` | `false` | 显示清空。 |\n| `filterable` | `boolean` | `false` | 面板内过滤。 |\n| `showPath` | `boolean` | `false` | 展示祖先路径。 |\n| `separator` | `string` | `' / '` | 路径分隔符。 |\n| `maxTagCount` | `number` | — | 多选最多展示的 tag 数。 |\n| `selectionMode` | `'single' \\| 'multiple'` | `'single'` | 兼容字段;请优先用 `multiple`。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `errorMessage` | `string` | — | — |\n| `helpText` | `string` | — | — |\n| `id` | `string` | — | — |\n| `invalid` | `boolean` | — | — |\n| `label` | `string` | — | — |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `string \\| string[] \\| null` | 选中变化。 |\n| `clear` | — | 点击清空。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `value` | 触发器展示。 |\n| `option` | 树节点 `{ node }`。 |\n\n## 类型\n\n<h4 id=\"TreeSelectNode\">TreeSelectNode</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface TreeSelectNode {\n key: string\n label: string\n children?: TreeSelectNode[]\n disabled?: boolean\n}\n```\n"
24015
24543
  },
24016
24544
  "en-US": {
24017
24545
  "title": "TreeSelect",
@@ -24020,7 +24548,7 @@
24020
24548
  {
24021
24549
  "id": "overview",
24022
24550
  "title": "",
24023
- "body": "# TreeSelect\n\nShow an expandable tree in a dropdown. `multiple` / `checkable` enable multi-select. `filterable`, `clearable`, and `showPath` cover the common `n-tree-select` subset."
24551
+ "body": "# TreeSelect\n\nShow an expandable tree in a dropdown. `multiple` / `checkable` enable multi-select; `filterable`, `clearable`, and `showPath` are also available."
24024
24552
  },
24025
24553
  {
24026
24554
  "id": "import",
@@ -24063,7 +24591,7 @@
24063
24591
  "body": "<h4 id=\"TreeSelectNode\">TreeSelectNode</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface TreeSelectNode {\n key: string\n label: string\n children?: TreeSelectNode[]\n disabled?: boolean\n}\n```"
24064
24592
  }
24065
24593
  ],
24066
- "markdown": "---\ntitle: TreeSelect\ncategory: 02 / FORM\ndescription: Tree select in a dropdown. Supports single/multiple, cascade checks, filter, clear, and path labels.\n---\n\n# TreeSelect\n\nShow an expandable tree in a dropdown. `multiple` / `checkable` enable multi-select. `filterable`, `clearable`, and `showPath` cover the common `n-tree-select` subset.\n\n## Import\n\n```ts\nimport { MTreeSelect } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Multiple / filter / path\n\n```vue preview src=\"./demos/MultipleFilterPath.en.vue\"\n```\n\n## Size\n\n```vue preview src=\"./demos/Size.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `options` | `TreeSelectNode[]` | — | Tree nodes. |\n| `modelValue` | `string \\| string[] \\| null` | `null` | Selected key(s); array when multiple. |\n| `placeholder` | `string` | locale `selectPlaceholder` | Placeholder text. |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | `small` / `large`; can inherit from ConfigProvider. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `multiple` | `boolean` | `false` | Multiple selection. |\n| `checkable` | `boolean` | `false` | Show checkboxes (cascade like Tree). |\n| `checkStrictly` | `boolean` | `false` | Independent parent/child checks. |\n| `checkStrategy` | `'all' \\| 'parent' \\| 'child'` | `'all'` | Which keys to bind when cascading. |\n| `clearable` | `boolean` | `false` | Show a clear button. |\n| `filterable` | `boolean` | `false` | Filter inside the panel. |\n| `showPath` | `boolean` | `false` | Show ancestor labels. |\n| `separator` | `string` | `' / '` | Path separator. |\n| `maxTagCount` | `number` | — | Max visible tags when multiple. |\n| `selectionMode` | `'single' \\| 'multiple'` | `'single'` | Compatibility; prefer `multiple`. |\n| `teleport` | `boolean` | `true` | Overlay Teleport; defaults to `body`. |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target; `'self'` / `false` renders in place. |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `update:modelValue` | `string \\| string[] \\| null` | Emitted when the selection changes. |\n| `clear` | — | Emitted when cleared. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `value` | Trigger display. |\n| `option` | Tree node `{ node }`. |\n\n## Types\n\n<h4 id=\"TreeSelectNode\">TreeSelectNode</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface TreeSelectNode {\n key: string\n label: string\n children?: TreeSelectNode[]\n disabled?: boolean\n}\n```\n"
24594
+ "markdown": "---\ntitle: TreeSelect\ncategory: 02 / FORM\ndescription: Tree select in a dropdown. Supports single/multiple, cascade checks, filter, clear, and path labels.\n---\n\n# TreeSelect\n\nShow an expandable tree in a dropdown. `multiple` / `checkable` enable multi-select; `filterable`, `clearable`, and `showPath` are also available.\n\n## Import\n\n```ts\nimport { MTreeSelect } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Multiple / filter / path\n\n```vue preview src=\"./demos/MultipleFilterPath.en.vue\"\n```\n\n## Size\n\n```vue preview src=\"./demos/Size.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `options` | `TreeSelectNode[]` | — | Tree nodes. |\n| `modelValue` | `string \\| string[] \\| null` | `null` | Selected key(s); array when multiple. |\n| `placeholder` | `string` | locale `selectPlaceholder` | Placeholder text. |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | `small` / `large`; can inherit from ConfigProvider. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `multiple` | `boolean` | `false` | Multiple selection. |\n| `checkable` | `boolean` | `false` | Show checkboxes (cascade like Tree). |\n| `checkStrictly` | `boolean` | `false` | Independent parent/child checks. |\n| `checkStrategy` | `'all' \\| 'parent' \\| 'child'` | `'all'` | Which keys to bind when cascading. |\n| `clearable` | `boolean` | `false` | Show a clear button. |\n| `filterable` | `boolean` | `false` | Filter inside the panel. |\n| `showPath` | `boolean` | `false` | Show ancestor labels. |\n| `separator` | `string` | `' / '` | Path separator. |\n| `maxTagCount` | `number` | — | Max visible tags when multiple. |\n| `selectionMode` | `'single' \\| 'multiple'` | `'single'` | Compatibility; prefer `multiple`. |\n| `teleport` | `boolean` | `true` | Overlay Teleport; defaults to `body`. |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target; `'self'` / `false` renders in place. |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `update:modelValue` | `string \\| string[] \\| null` | Emitted when the selection changes. |\n| `clear` | — | Emitted when cleared. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `value` | Trigger display. |\n| `option` | Tree node `{ node }`. |\n\n## Types\n\n<h4 id=\"TreeSelectNode\">TreeSelectNode</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface TreeSelectNode {\n key: string\n label: string\n children?: TreeSelectNode[]\n disabled?: boolean\n}\n```\n"
24067
24595
  }
24068
24596
  }
24069
24597
  },
@@ -24485,7 +25013,7 @@
24485
25013
  "zh-CN": {
24486
25014
  "title": "介绍",
24487
25015
  "description": "Morya UI 是什么、适合谁用、如何开始。",
24488
- "markdown": "---\ntitle: 介绍\norder: 1\ndescription: Morya UI 是什么、适合谁用、如何开始。\n---\n\n# 介绍\n\n**Morya UI**(`morya-ui`)是一套**开源**的 Vue 3 组件库,内置设计令牌、亮暗主题、国际化与交互式文档。\n\n- **文档站**:[morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/)\n- **源码**:[GitHub](https://github.com/morya-space/morya-ui)\n- **npm**:[`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## 为什么选择 Morya UI\n\n| | |\n| --- | --- |\n| **90+ 个组件** | 基础、表单、导航、数据展示、布局、反馈一应俱全 |\n| **主题系统** | `--m-*` 设计令牌,亮/暗色、`useTheme` / `useDensity` / `useMotion` 同包导出 |\n| **TypeScript** | Composition API 编写,Props / Emits / locale 完整类型 |\n| **按需加载** | ESM 子路径 + `MoryaUIResolver`,支持 tree-shaking |\n| **文档即预览** | 每个组件自带 Markdown + 可交互 `vue preview` |\n\n## 适用场景\n\n- 管理后台、运营平台、SaaS 控制台\n- 需要统一视觉语言的中大型 Vue 3 应用\n- 希望开箱即用主题、浮层与表单能力的团队\n\n## 包结构\n\n| 包 | 说明 |\n| --- | --- |\n| `morya-ui` | 组件、样式、主题 API、文档站源码 |\n| `@morya-ui/setup` | (可选)业务项目一键接入:库 + AI Skill / rules + MCP |\n| `@morya-ui/mcp` | (可选)MCP 服务,供支持该协议的 AI 客户端检索文档 |\n\n## 安装\n\n```bash\npnpm add morya-ui\n```\n\n需要 Vue 3(推荐 3.5 及以上)。支持 [Nuxt / Astro / Vite SSR 等](/docs/ssr)。详见 [快速上手](/docs/quick-start)。\n\n## 下一步\n\n- [快速上手](/docs/quick-start):安装与最小示例\n- [设计令牌](/docs/design-tokens):全部 `--m-*` 变量与用途\n- [主题](/docs/theme):亮暗色与动效\n- [样式与 attrs](/docs/attrs):fallthrough、`pt`、事件在各组件上的落点\n- [API 类型](/docs/types):Props 里 `FieldPassThrough`、`SelectOption` 等类型的结构\n- [全局配置](/docs/config):`ConfigProvider` / `createMoryaUI`\n- [SSR](/docs/ssr):Nuxt / Astro 等集成\n- [无障碍](/docs/accessibility):键盘、表单与浮层约定\n- [AI 接入](/docs/ai-setup):`npx @morya-ui/setup` 与 Agent 配置\n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 页面生成约定\n- [Agent MCP](/docs/mcp):AI 客户端文档检索\n- [组件](/components):浏览全部组件与 API\n- [参与贡献](https://github.com/morya-space/morya-ui/blob/main/CONTRIBUTING.zh-CN.md)\n",
25016
+ "markdown": "---\ntitle: 介绍\norder: 1\ndescription: Morya UI 是什么、适合谁用、如何开始。\n---\n\n# 介绍\n\n**Morya UI**(`morya-ui`)是一套**开源**的 Vue 3 组件库,内置设计令牌、亮暗主题、国际化与交互式文档。\n\n- **文档站**:[morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/)\n- **源码**:[GitHub](https://github.com/morya-space/morya-ui)\n- **npm**:[`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## 为什么选择 Morya UI\n\n| | |\n| --- | --- |\n| **90+ 个组件** | 基础、表单、导航、数据展示、布局、反馈一应俱全 |\n| **主题系统** | `--m-*` 设计令牌,亮/暗色、`useTheme` / `useDensity` / `useMotion` 同包导出 |\n| **TypeScript** | Composition API 编写,Props / Emits / locale 完整类型 |\n| **按需加载** | ESM 子路径 + `MoryaUIResolver`,支持 tree-shaking |\n| **文档即预览** | 每个组件自带 Markdown + 可交互 `vue preview` |\n\n## 适用场景\n\n- 管理后台、运营平台、SaaS 控制台\n- 需要统一视觉语言的中大型 Vue 3 应用\n- 希望开箱即用主题、浮层与表单能力的团队\n\n## 包结构\n\n| 包 | 说明 |\n| --- | --- |\n| `morya-ui` | 组件、样式、主题 API、文档站源码 |\n| `@morya-ui/setup` | (可选)业务项目一键接入:库 + AI Skill / rules + MCP |\n| `@morya-ui/mcp` | (可选)MCP 服务,供支持该协议的 AI 客户端检索文档 |\n\n## 安装\n\n```bash\npnpm add morya-ui\n```\n\n需要 Vue 3(推荐 3.5 及以上)。支持 [Nuxt / Astro / Vite SSR 等](/docs/ssr)。详见 [快速上手](/docs/quick-start)。\n\n## 下一步\n\n- [快速上手](/docs/quick-start):安装与最小示例\n- [一键接入](/docs/setup):`@morya-ui/setup` 安装库与 AI 配置\n- [设计令牌](/docs/design-tokens):全部 `--m-*` 变量与用途\n- [主题](/docs/theme):亮暗色与动效\n- [样式与 attrs](/docs/attrs):fallthrough、`pt`、事件在各组件上的落点\n- [API 类型](/docs/types):Props 里 `FieldPassThrough`、`SelectOption` 等类型的结构\n- [全局配置](/docs/config):`ConfigProvider` / `createMoryaUI`\n- [SSR](/docs/ssr):Nuxt / Astro 等集成\n- [无障碍](/docs/accessibility):键盘、表单与浮层约定\n- [AI 接入](/docs/ai-setup):配合 Agent 生成业务页面\n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 页面生成约定\n- [Agent MCP](/docs/mcp):AI 客户端文档检索\n- [组件](/components):浏览全部组件与 API\n- [参与贡献](https://github.com/morya-space/morya-ui/blob/main/CONTRIBUTING.zh-CN.md)\n",
24489
25017
  "sections": [
24490
25018
  {
24491
25019
  "title": "",
@@ -24515,14 +25043,14 @@
24515
25043
  {
24516
25044
  "title": "下一步",
24517
25045
  "id": "下一步",
24518
- "body": "- [快速上手](/docs/quick-start):安装与最小示例\n- [设计令牌](/docs/design-tokens):全部 `--m-*` 变量与用途\n- [主题](/docs/theme):亮暗色与动效\n- [样式与 attrs](/docs/attrs):fallthrough、`pt`、事件在各组件上的落点\n- [API 类型](/docs/types):Props 里 `FieldPassThrough`、`SelectOption` 等类型的结构\n- [全局配置](/docs/config):`ConfigProvider` / `createMoryaUI`\n- [SSR](/docs/ssr):Nuxt / Astro 等集成\n- [无障碍](/docs/accessibility):键盘、表单与浮层约定\n- [AI 接入](/docs/ai-setup):`npx @morya-ui/setup` 与 Agent 配置\n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 页面生成约定\n- [Agent MCP](/docs/mcp):AI 客户端文档检索\n- [组件](/components):浏览全部组件与 API\n- [参与贡献](https://github.com/morya-space/morya-ui/blob/main/CONTRIBUTING.zh-CN.md)"
25046
+ "body": "- [快速上手](/docs/quick-start):安装与最小示例\n- [一键接入](/docs/setup):`@morya-ui/setup` 安装库与 AI 配置\n- [设计令牌](/docs/design-tokens):全部 `--m-*` 变量与用途\n- [主题](/docs/theme):亮暗色与动效\n- [样式与 attrs](/docs/attrs):fallthrough、`pt`、事件在各组件上的落点\n- [API 类型](/docs/types):Props 里 `FieldPassThrough`、`SelectOption` 等类型的结构\n- [全局配置](/docs/config):`ConfigProvider` / `createMoryaUI`\n- [SSR](/docs/ssr):Nuxt / Astro 等集成\n- [无障碍](/docs/accessibility):键盘、表单与浮层约定\n- [AI 接入](/docs/ai-setup):配合 Agent 生成业务页面\n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 页面生成约定\n- [Agent MCP](/docs/mcp):AI 客户端文档检索\n- [组件](/components):浏览全部组件与 API\n- [参与贡献](https://github.com/morya-space/morya-ui/blob/main/CONTRIBUTING.zh-CN.md)"
24519
25047
  }
24520
25048
  ]
24521
25049
  },
24522
25050
  "en-US": {
24523
25051
  "title": "Introduction",
24524
25052
  "description": "What Morya UI is, who it is for, and how to get started.",
24525
- "markdown": "---\ntitle: Introduction\norder: 1\ndescription: What Morya UI is, who it is for, and how to get started.\n---\n\n# Introduction\n\n**Morya UI** (`morya-ui`) is an **open-source** Vue 3 component library with design tokens, light/dark themes, i18n, and interactive documentation.\n\n- **Docs**: [morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/)\n- **Source**: [GitHub](https://github.com/morya-space/morya-ui)\n- **npm**: [`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## Why Morya UI\n\n| | |\n| --- | --- |\n| **90+ components** | Basics, forms, navigation, data display, layout, and feedback |\n| **Theme system** | `--m-*` design tokens; `useTheme` / `useDensity` / `useMotion` in the same package |\n| **TypeScript** | Built with Composition API; fully typed props, emits, and locale |\n| **On-demand** | ESM subpaths + `MoryaUIResolver` with tree-shaking |\n| **Docs as preview** | Markdown + interactive `vue preview` for every component |\n\n## Use cases\n\n- Admin dashboards, ops consoles, SaaS back offices\n- Medium-to-large Vue 3 apps that need a shared visual language\n- Teams that want themes, overlays, and forms without reinventing primitives\n\n## Packages\n\n| Package | Role |\n| --- | --- |\n| `morya-ui` | Components, styles, theme APIs, docs site source |\n| `@morya-ui/setup` | (Optional) One-shot app onboarding: library + AI skill / rules + MCP |\n| `@morya-ui/mcp` | (Optional) MCP server for AI clients that support the protocol |\n\n## Install\n\n```bash\npnpm add morya-ui\n```\n\nRequires Vue 3 (3.5+ recommended). Works with [Nuxt, Astro, Vite SSR, and more](/docs/ssr). See [Quick start](/docs/quick-start).\n\n## Next steps\n\n- [Quick start](/docs/quick-start): install and a minimal example\n- [Design tokens](/docs/design-tokens): full `--m-*` reference\n- [Theme](/docs/theme): light/dark and motion\n- [Styling & attrs](/docs/attrs): fallthrough, `pt`, and event placement\n- [API types](/docs/types): shapes behind names like `FieldPassThrough`, `SelectOption`\n- [Configuration](/docs/config): `ConfigProvider` / `createMoryaUI`\n- [SSR](/docs/ssr): Nuxt, Astro, and similar setups\n- [Accessibility](/docs/accessibility): forms, keyboard, overlays\n- [AI setup](/docs/ai-setup): `npx @morya-ui/setup` and Agent config\n- [Agent Skill](/docs/agent-skill): `morya-ui-pages` page-generation contract\n- [Agent MCP](/docs/mcp): doc lookup for AI clients\n- [Components](/components): browse all components and APIs\n- [Contributing](https://github.com/morya-space/morya-ui/blob/main/CONTRIBUTING.md)\n",
25053
+ "markdown": "---\ntitle: Introduction\norder: 1\ndescription: What Morya UI is, who it is for, and how to get started.\n---\n\n# Introduction\n\n**Morya UI** (`morya-ui`) is an **open-source** Vue 3 component library with design tokens, light/dark themes, i18n, and interactive documentation.\n\n- **Docs**: [morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/)\n- **Source**: [GitHub](https://github.com/morya-space/morya-ui)\n- **npm**: [`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## Why Morya UI\n\n| | |\n| --- | --- |\n| **90+ components** | Basics, forms, navigation, data display, layout, and feedback |\n| **Theme system** | `--m-*` design tokens; `useTheme` / `useDensity` / `useMotion` in the same package |\n| **TypeScript** | Built with Composition API; fully typed props, emits, and locale |\n| **On-demand** | ESM subpaths + `MoryaUIResolver` with tree-shaking |\n| **Docs as preview** | Markdown + interactive `vue preview` for every component |\n\n## Use cases\n\n- Admin dashboards, ops consoles, SaaS back offices\n- Medium-to-large Vue 3 apps that need a shared visual language\n- Teams that want themes, overlays, and forms without reinventing primitives\n\n## Packages\n\n| Package | Role |\n| --- | --- |\n| `morya-ui` | Components, styles, theme APIs, docs site source |\n| `@morya-ui/setup` | (Optional) One-shot app onboarding: library + AI skill / rules + MCP |\n| `@morya-ui/mcp` | (Optional) MCP server for AI clients that support the protocol |\n\n## Install\n\n```bash\npnpm add morya-ui\n```\n\nRequires Vue 3 (3.5+ recommended). Works with [Nuxt, Astro, Vite SSR, and more](/docs/ssr). See [Quick start](/docs/quick-start).\n\n## Next steps\n\n- [Quick start](/docs/quick-start): install and a minimal example\n- [One-shot setup](/docs/setup): `@morya-ui/setup` for library and AI config\n- [Design tokens](/docs/design-tokens): full `--m-*` reference\n- [Theme](/docs/theme): light/dark and motion\n- [Styling & attrs](/docs/attrs): fallthrough, `pt`, and event placement\n- [API types](/docs/types): shapes behind names like `FieldPassThrough`, `SelectOption`\n- [Configuration](/docs/config): `ConfigProvider` / `createMoryaUI`\n- [SSR](/docs/ssr): Nuxt, Astro, and similar setups\n- [Accessibility](/docs/accessibility): forms, keyboard, overlays\n- [AI setup](/docs/ai-setup): Agent-assisted page generation\n- [Agent Skill](/docs/agent-skill): `morya-ui-pages` page-generation contract\n- [Agent MCP](/docs/mcp): doc lookup for AI clients\n- [Components](/components): browse all components and APIs\n- [Contributing](https://github.com/morya-space/morya-ui/blob/main/CONTRIBUTING.md)\n",
24526
25054
  "sections": [
24527
25055
  {
24528
25056
  "title": "",
@@ -24552,7 +25080,7 @@
24552
25080
  {
24553
25081
  "title": "Next steps",
24554
25082
  "id": "next-steps",
24555
- "body": "- [Quick start](/docs/quick-start): install and a minimal example\n- [Design tokens](/docs/design-tokens): full `--m-*` reference\n- [Theme](/docs/theme): light/dark and motion\n- [Styling & attrs](/docs/attrs): fallthrough, `pt`, and event placement\n- [API types](/docs/types): shapes behind names like `FieldPassThrough`, `SelectOption`\n- [Configuration](/docs/config): `ConfigProvider` / `createMoryaUI`\n- [SSR](/docs/ssr): Nuxt, Astro, and similar setups\n- [Accessibility](/docs/accessibility): forms, keyboard, overlays\n- [AI setup](/docs/ai-setup): `npx @morya-ui/setup` and Agent config\n- [Agent Skill](/docs/agent-skill): `morya-ui-pages` page-generation contract\n- [Agent MCP](/docs/mcp): doc lookup for AI clients\n- [Components](/components): browse all components and APIs\n- [Contributing](https://github.com/morya-space/morya-ui/blob/main/CONTRIBUTING.md)"
25083
+ "body": "- [Quick start](/docs/quick-start): install and a minimal example\n- [One-shot setup](/docs/setup): `@morya-ui/setup` for library and AI config\n- [Design tokens](/docs/design-tokens): full `--m-*` reference\n- [Theme](/docs/theme): light/dark and motion\n- [Styling & attrs](/docs/attrs): fallthrough, `pt`, and event placement\n- [API types](/docs/types): shapes behind names like `FieldPassThrough`, `SelectOption`\n- [Configuration](/docs/config): `ConfigProvider` / `createMoryaUI`\n- [SSR](/docs/ssr): Nuxt, Astro, and similar setups\n- [Accessibility](/docs/accessibility): forms, keyboard, overlays\n- [AI setup](/docs/ai-setup): Agent-assisted page generation\n- [Agent Skill](/docs/agent-skill): `morya-ui-pages` page-generation contract\n- [Agent MCP](/docs/mcp): doc lookup for AI clients\n- [Components](/components): browse all components and APIs\n- [Contributing](https://github.com/morya-space/morya-ui/blob/main/CONTRIBUTING.md)"
24556
25084
  }
24557
25085
  ]
24558
25086
  }
@@ -24569,7 +25097,7 @@
24569
25097
  "zh-CN": {
24570
25098
  "title": "快速上手",
24571
25099
  "description": "安装依赖、引入样式,并渲染第一个组件。",
24572
- "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需要 Vue 3(推荐 3.5 及以上)。主题 token、亮暗切换与动效 API 均包含在 `morya-ui` 中。\n\n克隆本仓库后执行 `pnpm install`。文档站通过 Vite alias 直连 `src/` 源码(见 `playground/vite.config.ts`)。\n\n在其他业务项目中联调本库时,使用 `link:` / `pnpm link` 并配置 Vite alias;从 npm 安装则始终解析 `dist/`。\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",
24573
25101
  "sections": [
24574
25102
  {
24575
25103
  "title": "",
@@ -24579,7 +25107,7 @@
24579
25107
  {
24580
25108
  "title": "安装",
24581
25109
  "id": "安装",
24582
- "body": "**在应用项目中(npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\n需要 Vue 3(推荐 3.5 及以上)。主题 token、亮暗切换与动效 API 均包含在 `morya-ui` 中。\n\n克隆本仓库后执行 `pnpm install`。文档站通过 Vite alias 直连 `src/` 源码(见 `playground/vite.config.ts`)。\n\n在其他业务项目中联调本库时,使用 `link:` / `pnpm link` 并配置 Vite alias;从 npm 安装则始终解析 `dist/`。"
25110
+ "body": "**在应用项目中(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)。"
24583
25111
  },
24584
25112
  {
24585
25113
  "title": "选择使用方式",
@@ -24594,7 +25122,7 @@
24594
25122
  {
24595
25123
  "title": "按需用法",
24596
25124
  "id": "按需用法",
24597
- "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 })` 仍可注入全局配置而不注册组件。"
24598
25126
  },
24599
25127
  {
24600
25128
  "title": "可选:应用级全局配置",
@@ -24616,7 +25144,7 @@
24616
25144
  "en-US": {
24617
25145
  "title": "Quick start",
24618
25146
  "description": "Install the package, import styles, and render the first component.",
24619
- "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\nRequires Vue 3 (3.5+ recommended). Theme tokens, color-mode switching, and motion APIs are all included in `morya-ui`.\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",
24620
25148
  "sections": [
24621
25149
  {
24622
25150
  "title": "",
@@ -24626,7 +25154,7 @@
24626
25154
  {
24627
25155
  "title": "Install",
24628
25156
  "id": "install",
24629
- "body": "**In an application (npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\nRequires Vue 3 (3.5+ recommended). Theme tokens, color-mode switching, and motion APIs are all included in `morya-ui`.\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/`."
25157
+ "body": "**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/`."
24630
25158
  },
24631
25159
  {
24632
25160
  "title": "Choose an import mode",
@@ -24641,7 +25169,7 @@
24641
25169
  {
24642
25170
  "title": "On-demand usage",
24643
25171
  "id": "on-demand-usage",
24644
- "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."
24645
25173
  },
24646
25174
  {
24647
25175
  "title": "Optional: app-level defaults",
@@ -24662,18 +25190,102 @@
24662
25190
  }
24663
25191
  }
24664
25192
  },
25193
+ {
25194
+ "id": "setup",
25195
+ "title": "一键接入",
25196
+ "titleEn": "One-shot setup",
25197
+ "description": "用 @morya-ui/setup 安装组件库,并按需写入样式、Agent 配置与 MCP。",
25198
+ "descriptionEn": "Use @morya-ui/setup to install the library and optionally write styles, Agent config, and MCP.",
25199
+ "order": 3,
25200
+ "locales": {
25201
+ "zh-CN": {
25202
+ "title": "一键接入",
25203
+ "description": "用 @morya-ui/setup 安装组件库,并按需写入样式、Agent 配置与 MCP。",
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",
25205
+ "sections": [
25206
+ {
25207
+ "title": "",
25208
+ "id": "overview",
25209
+ "body": "# 一键接入\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)。"
25210
+ },
25211
+ {
25212
+ "title": "命令",
25213
+ "id": "命令",
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`。"
25215
+ },
25216
+ {
25217
+ "title": "选项",
25218
+ "id": "选项",
25219
+ "body": "| 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```"
25220
+ },
25221
+ {
25222
+ "title": "会落到项目里的内容",
25223
+ "id": "会落到项目里的内容",
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`。"
25225
+ },
25226
+ {
25227
+ "title": "冲突策略",
25228
+ "id": "冲突策略",
25229
+ "body": "- 模板文件与 `.cursor/rules/*`:目标已存在则跳过(除非 `--force`)\n- `.cursor/mcp.json`:合并其它 server;已有 `morya-ui` 条目则跳过(除非 `--force`)\n- `check:colors`:仅在缺失时追加(除非 `--force`)\n- 样式:找到入口且尚未引入时才注入"
25230
+ },
25231
+ {
25232
+ "title": "下一步",
25233
+ "id": "下一步",
25234
+ "body": "- [快速上手](/docs/quick-start):组件用法与最小示例 \n- [AI 接入](/docs/ai-setup):用 AI 生成业务页面时如何配合 Skill / MCP \n- [Agent Skill](/docs/agent-skill) · [Agent MCP](/docs/mcp) \n- [组件](/components):浏览 API 与预览"
25235
+ }
25236
+ ]
25237
+ },
25238
+ "en-US": {
25239
+ "title": "One-shot setup",
25240
+ "description": "Use @morya-ui/setup to install the library and optionally write styles, Agent config, and MCP.",
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",
25242
+ "sections": [
25243
+ {
25244
+ "title": "",
25245
+ "id": "overview",
25246
+ "body": "# 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)."
25247
+ },
25248
+ {
25249
+ "title": "Commands",
25250
+ "id": "commands",
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."
25252
+ },
25253
+ {
25254
+ "title": "Options",
25255
+ "id": "options",
25256
+ "body": "| 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```"
25257
+ },
25258
+ {
25259
+ "title": "What lands in the project",
25260
+ "id": "what-lands-in-the-project",
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`."
25262
+ },
25263
+ {
25264
+ "title": "Conflict policy",
25265
+ "id": "conflict-policy",
25266
+ "body": "- 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"
25267
+ },
25268
+ {
25269
+ "title": "Next steps",
25270
+ "id": "next-steps",
25271
+ "body": "- [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"
25272
+ }
25273
+ ]
25274
+ }
25275
+ }
25276
+ },
24665
25277
  {
24666
25278
  "id": "design-tokens",
24667
25279
  "title": "设计令牌",
24668
25280
  "titleEn": "Design tokens",
24669
25281
  "description": "全部 --m-* CSS 变量、默认值与用途说明。",
24670
25282
  "descriptionEn": "Full --m-* CSS variable reference with defaults and usage notes.",
24671
- "order": 3,
25283
+ "order": 4,
24672
25284
  "locales": {
24673
25285
  "zh-CN": {
24674
25286
  "title": "设计令牌",
24675
25287
  "description": "全部 --m-* CSS 变量、默认值与用途说明。",
24676
- "markdown": "---\ntitle: 设计令牌\norder: 3\ndescription: 全部 --m-* CSS 变量、默认值与用途说明。\n---\n\n# 设计令牌\n\nMorya UI 组件只消费语义化 CSS 变量(`--m-*`),不维护第二套色板。下面列表从 `src/**/*.css` **自动提取**,运行 `pnpm tokens:generate` 可与源码保持同步。\n\n## 覆盖方式\n\n| 机制 | 作用 |\n| --- | --- |\n| `[data-theme=\"dark\"]` | 亮 / 暗色主题 |\n| `[data-m-density]` | 间距与控件高度密度 |\n| `[data-m-motion]` | 动效时长 |\n| `createMoryaUI({ zIndex })` / `MConfigProvider` | 写入 `--m-z-base` 等全局配置 |\n\n主题 API 与密度说明见 [主题](/docs/theme)。\n\n## 完整列表\n\n```vue preview src=\"./demos/design-tokens/FullCatalog.vue\"\n```\n\n## 自定义\n\n在应用入口覆盖变量即可,无需 fork 组件:\n\n```css\n:root {\n --m-color-primary: #0f766e;\n --m-radius-control: 6px;\n}\n```\n\n组件局部变量(如 `--m-button-padding-x-medium`)定义在对应 `styles.css`,同样可通过更高优先级选择器覆盖。\n",
25288
+ "markdown": "---\ntitle: 设计令牌\norder: 4\ndescription: 全部 --m-* CSS 变量、默认值与用途说明。\n---\n\n# 设计令牌\n\nMorya UI 组件只消费语义化 CSS 变量(`--m-*`),不维护第二套色板。下面列表从 `src/**/*.css` **自动提取**,运行 `pnpm tokens:generate` 可与源码保持同步。\n\n## 覆盖方式\n\n| 机制 | 作用 |\n| --- | --- |\n| `[data-theme=\"dark\"]` | 亮 / 暗色主题 |\n| `[data-m-density]` | 间距与控件高度密度 |\n| `[data-m-motion]` | 动效时长 |\n| `createMoryaUI({ zIndex })` / `MConfigProvider` | 写入 `--m-z-base` 等全局配置 |\n\n主题 API 与密度说明见 [主题](/docs/theme)。\n\n## 完整列表\n\n```vue preview src=\"./demos/design-tokens/FullCatalog.vue\"\n```\n\n## 自定义\n\n在应用入口覆盖变量即可,无需 fork 组件:\n\n```css\n:root {\n --m-color-primary: #0f766e;\n --m-radius-control: 6px;\n}\n```\n\n组件局部变量(如 `--m-button-padding-x-medium`)定义在对应 `styles.css`,同样可通过更高优先级选择器覆盖。\n",
24677
25289
  "sections": [
24678
25290
  {
24679
25291
  "title": "",
@@ -24700,7 +25312,7 @@
24700
25312
  "en-US": {
24701
25313
  "title": "Design tokens",
24702
25314
  "description": "Full --m-* CSS variable reference with defaults and usage notes.",
24703
- "markdown": "---\ntitle: Design tokens\norder: 3\ndescription: Full --m-* CSS variable reference with defaults and usage notes.\n---\n\n# Design tokens\n\nMorya UI components consume semantic CSS variables (`--m-*`) only. The catalog below is **auto-extracted** from `src/**/*.css`. Run `pnpm tokens:generate` to keep it in sync with source.\n\n## Override mechanisms\n\n| Mechanism | Purpose |\n| --- | --- |\n| `[data-theme=\"dark\"]` | Light / dark theme |\n| `[data-m-density]` | Spacing and control height density |\n| `[data-m-motion]` | Motion duration preferences |\n| `createMoryaUI({ zIndex })` / `MConfigProvider` | Writes globals such as `--m-z-base` |\n\nSee [Theme](/docs/theme) for theme APIs and density behavior.\n\n## Full catalog\n\n```vue preview src=\"./demos/design-tokens/FullCatalog.vue\"\n```\n\n## Customization\n\nOverride variables at the app entry without forking components:\n\n```css\n:root {\n --m-color-primary: #0f766e;\n --m-radius-control: 6px;\n}\n```\n\nComponent-local tokens (for example `--m-button-padding-x-medium`) live in each `styles.css` and can be overridden with higher-specificity selectors.\n",
25315
+ "markdown": "---\ntitle: Design tokens\norder: 4\ndescription: Full --m-* CSS variable reference with defaults and usage notes.\n---\n\n# Design tokens\n\nMorya UI components consume semantic CSS variables (`--m-*`) only. The catalog below is **auto-extracted** from `src/**/*.css`. Run `pnpm tokens:generate` to keep it in sync with source.\n\n## Override mechanisms\n\n| Mechanism | Purpose |\n| --- | --- |\n| `[data-theme=\"dark\"]` | Light / dark theme |\n| `[data-m-density]` | Spacing and control height density |\n| `[data-m-motion]` | Motion duration preferences |\n| `createMoryaUI({ zIndex })` / `MConfigProvider` | Writes globals such as `--m-z-base` |\n\nSee [Theme](/docs/theme) for theme APIs and density behavior.\n\n## Full catalog\n\n```vue preview src=\"./demos/design-tokens/FullCatalog.vue\"\n```\n\n## Customization\n\nOverride variables at the app entry without forking components:\n\n```css\n:root {\n --m-color-primary: #0f766e;\n --m-radius-control: 6px;\n}\n```\n\nComponent-local tokens (for example `--m-button-padding-x-medium`) live in each `styles.css` and can be overridden with higher-specificity selectors.\n",
24704
25316
  "sections": [
24705
25317
  {
24706
25318
  "title": "",
@@ -24732,12 +25344,12 @@
24732
25344
  "titleEn": "Theme",
24733
25345
  "description": "亮暗主题、设计令牌与动效偏好。",
24734
25346
  "descriptionEn": "Light and dark themes, design tokens, and motion preferences.",
24735
- "order": 4,
25347
+ "order": 5,
24736
25348
  "locales": {
24737
25349
  "zh-CN": {
24738
25350
  "title": "主题",
24739
25351
  "description": "亮暗主题、设计令牌与动效偏好。",
24740
- "markdown": "---\ntitle: 主题\norder: 4\ndescription: 亮暗主题、设计令牌与动效偏好。\n---\n\n# 主题\n\n主题能力内置于 `morya-ui`。组件只消费语义化 CSS 变量(`--m-*`),不自行维护第二套色板。\n\n引入 `morya-ui/styles.css` 时已包含这些变量;主题 JS API(`useTheme` 等)从同一包导入。\n\n## 亮 / 暗色\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { isDark, setTheme, toggleTheme } = useTheme()\n\nsetTheme('light') // 或 'dark'\ntoggleTheme()\n```\n\n文档站右上角的按钮调用的就是同一套 API。主题偏好会写到 `document.documentElement` 的 `data-theme`。\n\n## 设计令牌\n\n常用变量示例见 [设计令牌](/docs/design-tokens) 完整列表(支持搜索与分类)。\n\n| Token | 用途 |\n| --- | --- |\n| `--m-color-primary` | 品牌主色 |\n| `--m-color-surface` | 页面底色 |\n| `--m-color-text` | 正文 |\n| `--m-color-border` | 分割线 / 描边 |\n| `--m-radius-sm/md/lg` | 圆角阶梯 |\n| `--m-space-*` | 间距阶梯 |\n| `--m-font-size-xs/sm/md/lg` | 组件正文字号阶梯 |\n| `--m-opacity-disabled` | 禁用态透明度 |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | 浮层层叠(Config `zIndex` 会写 `--m-z-base`) |\n| `--m-menu-min-width` / `--m-control-affix-*` | 菜单最小宽、输入清除区尺寸 |\n| `--m-motion-fast/normal` | 过渡时长 |\n\n## 内容密度\n\n```ts\nimport { useDensity } from 'morya-ui'\n\nconst { preference, setDensity } = useDensity()\nsetDensity('compact') // 'compact' | 'comfortable' | 'spacious'\n```\n\n也会写到 `document.documentElement` 的 `data-m-density`,并缩放 `--m-space-*` 与 `--m-control-height-*`。 \n应用级可用 `createMoryaUI({ density: 'compact' })` 或 `<MConfigProvider density=\"compact\">`。\n\n在组件页侧栏「主题」可临时改主色、圆角与密度,用于本地预览。\n\n## 动效偏好\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`:标准过渡与浮层动画 \n- `reduced`:缩短时长、弱化位移 \n- `none`:立即切换 \n\n## 控件尺寸与聚焦\n\n默认控件高度采用 compact 节奏:\n\n| Size | 高度 | 字号 |\n| --- | --- | --- |\n| `small` | `28px`(`--m-control-height-small`) | `14px` |\n| 默认 / `medium` | `34px` | `14px` |\n| `large` | `40px` | `15px` |\n\n聚焦样式为 **主色描边 + 2px 淡色光晕**(非外扩 outline ring):\n\n```css\nborder-color: var(--m-color-primary-hover);\nbox-shadow: var(--m-focus-shadow); /* 0 0 0 2px primary@20% */\n```\n\n相关 token:`--m-radius-control`、`--m-control-padding-x-*`、`--m-button-padding-x-*`、`--m-focus-shadow` / `--m-focus-shadow-danger`。\n\n## 与 ConfigProvider\n\n主题切换是「视觉层」;`MConfigProvider` / `createMoryaUI` 负责尺寸、文案、浮层挂载等「行为默认值」。二者可同时使用,详见 [全局配置](/docs/config)。\n",
25352
+ "markdown": "---\ntitle: 主题\norder: 5\ndescription: 亮暗主题、设计令牌与动效偏好。\n---\n\n# 主题\n\n主题能力内置于 `morya-ui`。组件只消费语义化 CSS 变量(`--m-*`),不自行维护第二套色板。\n\n引入 `morya-ui/styles.css` 时已包含这些变量;主题 JS API(`useTheme` 等)从同一包导入。\n\n## 亮 / 暗色\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { isDark, setTheme, toggleTheme } = useTheme()\n\nsetTheme('light') // 或 'dark'\ntoggleTheme()\n```\n\n文档站右上角的按钮调用的就是同一套 API。主题偏好会写到 `document.documentElement` 的 `data-theme`。\n\n## 设计令牌\n\n常用变量示例见 [设计令牌](/docs/design-tokens) 完整列表(支持搜索与分类)。\n\n| Token | 用途 |\n| --- | --- |\n| `--m-color-primary` | 品牌主色 |\n| `--m-color-surface` | 页面底色 |\n| `--m-color-text` | 正文 |\n| `--m-color-border` | 分割线 / 描边 |\n| `--m-radius-sm/md/lg` | 圆角阶梯 |\n| `--m-space-*` | 间距阶梯 |\n| `--m-font-size-xs/sm/md/lg` | 组件正文字号阶梯 |\n| `--m-opacity-disabled` | 禁用态透明度 |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | 浮层层叠(Config `zIndex` 会写 `--m-z-base`) |\n| `--m-menu-min-width` / `--m-control-affix-*` | 菜单最小宽、输入清除区尺寸 |\n| `--m-motion-fast/normal` | 过渡时长 |\n\n## 内容密度\n\n```ts\nimport { useDensity } from 'morya-ui'\n\nconst { preference, setDensity } = useDensity()\nsetDensity('compact') // 'compact' | 'comfortable' | 'spacious'\n```\n\n也会写到 `document.documentElement` 的 `data-m-density`,并缩放 `--m-space-*` 与 `--m-control-height-*`。 \n应用级可用 `createMoryaUI({ density: 'compact' })` 或 `<MConfigProvider density=\"compact\">`。\n\n在组件页侧栏「主题」可临时改主色、圆角与密度,用于本地预览。\n\n## 动效偏好\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`:标准过渡与浮层动画 \n- `reduced`:缩短时长、弱化位移 \n- `none`:立即切换 \n\n## 控件尺寸与聚焦\n\n默认控件高度采用 compact 节奏:\n\n| Size | 高度 | 字号 |\n| --- | --- | --- |\n| `small` | `28px`(`--m-control-height-small`) | `14px` |\n| 默认 / `medium` | `34px` | `14px` |\n| `large` | `40px` | `15px` |\n\n聚焦样式为 **主色描边 + 2px 淡色光晕**(非外扩 outline ring):\n\n```css\nborder-color: var(--m-color-primary-hover);\nbox-shadow: var(--m-focus-shadow); /* 0 0 0 2px primary@20% */\n```\n\n相关 token:`--m-radius-control`、`--m-control-padding-x-*`、`--m-button-padding-x-*`、`--m-focus-shadow` / `--m-focus-shadow-danger`。\n\n## 与 ConfigProvider\n\n主题切换是「视觉层」;`MConfigProvider` / `createMoryaUI` 负责尺寸、文案、浮层挂载等「行为默认值」。二者可同时使用,详见 [全局配置](/docs/config)。\n",
24741
25353
  "sections": [
24742
25354
  {
24743
25355
  "title": "",
@@ -24779,7 +25391,7 @@
24779
25391
  "en-US": {
24780
25392
  "title": "Theme",
24781
25393
  "description": "Light and dark themes, design tokens, and motion preferences.",
24782
- "markdown": "---\ntitle: Theme\norder: 4\ndescription: Light and dark themes, design tokens, and motion preferences.\n---\n\n# Theme\n\nTheme support is built into `morya-ui`. Components consume semantic CSS variables (`--m-*`) and do not keep a second palette.\n\nImporting `morya-ui/styles.css` already includes these variables. Theme JS APIs (`useTheme` and friends) come from the same package.\n\n## Light / dark\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { isDark, setTheme, toggleTheme } = useTheme()\n\nsetTheme('light') // or 'dark'\ntoggleTheme()\n```\n\nThe button at the top-right of the docs site uses the same API. The preference is written to `data-theme` on `document.documentElement`.\n\n## Design tokens\n\nSee the full [Design tokens](/docs/design-tokens) catalog (searchable, grouped by category).\n\n| Token | Use |\n| --- | --- |\n| `--m-color-primary` | Brand color |\n| `--m-color-surface` | Page background |\n| `--m-color-text` | Body text |\n| `--m-color-border` | Dividers / strokes |\n| `--m-radius-sm/md/lg` | Radius scale |\n| `--m-space-*` | Spacing scale |\n| `--m-font-size-xs/sm/md/lg` | Component type scale |\n| `--m-opacity-disabled` | Disabled opacity |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | Overlay stacking (`zIndex` writes `--m-z-base`) |\n| `--m-menu-min-width` / `--m-control-affix-*` | Menu min width, input clear-button size |\n| `--m-motion-fast/normal` | Transition duration |\n\n## Density\n\n```ts\nimport { useDensity } from 'morya-ui'\n\nconst { preference, setDensity } = useDensity()\nsetDensity('compact') // 'compact' | 'comfortable' | 'spacious'\n```\n\nThis writes `data-m-density` on `document.documentElement` and scales `--m-space-*` plus `--m-control-height-*`. \nAt the app level use `createMoryaUI({ density: 'compact' })` or `<MConfigProvider density=\"compact\">`.\n\nThe Components page sidebar Theme panel can temporarily change accent, radius, and density for local preview.\n\n## Motion preference\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`: standard transitions and overlay motion \n- `reduced`: shorter duration, less travel \n- `none`: instant switches \n\n## Control size and focus\n\nDefault control heights follow a compact rhythm:\n\n| Size | Height | Font size |\n| --- | --- | --- |\n| `small` | `28px` (`--m-control-height-small`) | `14px` |\n| Default / `medium` | `34px` | `14px` |\n| `large` | `40px` | `15px` |\n\nFocus uses a **brand border + 2px tinted glow** (not an outset outline ring):\n\n```css\nborder-color: var(--m-color-primary-hover);\nbox-shadow: var(--m-focus-shadow); /* 0 0 0 2px primary@20% */\n```\n\nRelated tokens: `--m-radius-control`, `--m-control-padding-x-*`, `--m-button-padding-x-*`, `--m-focus-shadow` / `--m-focus-shadow-danger`.\n\n## With ConfigProvider\n\nTheme switching is the visual layer. `MConfigProvider` / `createMoryaUI` own size, copy, overlay mount, and other behavioral defaults. Use both together; see [Configuration](/docs/config).\n",
25394
+ "markdown": "---\ntitle: Theme\norder: 5\ndescription: Light and dark themes, design tokens, and motion preferences.\n---\n\n# Theme\n\nTheme support is built into `morya-ui`. Components consume semantic CSS variables (`--m-*`) and do not keep a second palette.\n\nImporting `morya-ui/styles.css` already includes these variables. Theme JS APIs (`useTheme` and friends) come from the same package.\n\n## Light / dark\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { isDark, setTheme, toggleTheme } = useTheme()\n\nsetTheme('light') // or 'dark'\ntoggleTheme()\n```\n\nThe button at the top-right of the docs site uses the same API. The preference is written to `data-theme` on `document.documentElement`.\n\n## Design tokens\n\nSee the full [Design tokens](/docs/design-tokens) catalog (searchable, grouped by category).\n\n| Token | Use |\n| --- | --- |\n| `--m-color-primary` | Brand color |\n| `--m-color-surface` | Page background |\n| `--m-color-text` | Body text |\n| `--m-color-border` | Dividers / strokes |\n| `--m-radius-sm/md/lg` | Radius scale |\n| `--m-space-*` | Spacing scale |\n| `--m-font-size-xs/sm/md/lg` | Component type scale |\n| `--m-opacity-disabled` | Disabled opacity |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | Overlay stacking (`zIndex` writes `--m-z-base`) |\n| `--m-menu-min-width` / `--m-control-affix-*` | Menu min width, input clear-button size |\n| `--m-motion-fast/normal` | Transition duration |\n\n## Density\n\n```ts\nimport { useDensity } from 'morya-ui'\n\nconst { preference, setDensity } = useDensity()\nsetDensity('compact') // 'compact' | 'comfortable' | 'spacious'\n```\n\nThis writes `data-m-density` on `document.documentElement` and scales `--m-space-*` plus `--m-control-height-*`. \nAt the app level use `createMoryaUI({ density: 'compact' })` or `<MConfigProvider density=\"compact\">`.\n\nThe Components page sidebar Theme panel can temporarily change accent, radius, and density for local preview.\n\n## Motion preference\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`: standard transitions and overlay motion \n- `reduced`: shorter duration, less travel \n- `none`: instant switches \n\n## Control size and focus\n\nDefault control heights follow a compact rhythm:\n\n| Size | Height | Font size |\n| --- | --- | --- |\n| `small` | `28px` (`--m-control-height-small`) | `14px` |\n| Default / `medium` | `34px` | `14px` |\n| `large` | `40px` | `15px` |\n\nFocus uses a **brand border + 2px tinted glow** (not an outset outline ring):\n\n```css\nborder-color: var(--m-color-primary-hover);\nbox-shadow: var(--m-focus-shadow); /* 0 0 0 2px primary@20% */\n```\n\nRelated tokens: `--m-radius-control`, `--m-control-padding-x-*`, `--m-button-padding-x-*`, `--m-focus-shadow` / `--m-focus-shadow-danger`.\n\n## With ConfigProvider\n\nTheme switching is the visual layer. `MConfigProvider` / `createMoryaUI` own size, copy, overlay mount, and other behavioral defaults. Use both together; see [Configuration](/docs/config).\n",
24783
25395
  "sections": [
24784
25396
  {
24785
25397
  "title": "",
@@ -24826,12 +25438,12 @@
24826
25438
  "titleEn": "Styling & attrs",
24827
25439
  "description": "class、style、事件与 pt 在各组件上的落点约定。",
24828
25440
  "descriptionEn": "Where class, style, events, and pt land on each component.",
24829
- "order": 5,
25441
+ "order": 6,
24830
25442
  "locales": {
24831
25443
  "zh-CN": {
24832
25444
  "title": "样式与 attrs",
24833
25445
  "description": "class、style、事件与 pt 在各组件上的落点约定。",
24834
- "markdown": "---\ntitle: 样式与 attrs\norder: 5\ndescription: class、style、事件与 pt 在各组件上的落点约定。\n---\n\n# 样式与 attrs\n\n给组件传 `class`、`style` 或 `@keydown` 时,先搞清楚它们会绑到哪一层 DOM。Morya UI 的复合组件(尤其表单字段)不是「根元素就是 input」,外层还有 label、help、前后缀等结构。\n\n完整规则见下文;各组件 Props 里的 `pt` 字段用来改内部某一块 DOM,细节查对应组件文档。\n\n## 三类落点\n\n| 类型 | 例子 | 透传 attrs(除控件事件外) | 事件 `@xxx` | 常见原生属性 |\n| --- | --- | --- | --- | --- |\n| **字段** | Input、Select、DatePicker | 外层 field 根(`.m-input-field` 等) | 原生 input / textarea / 控件 | 用 props:`placeholder`、`name`… |\n| **Label 控件** | Checkbox、Radio、Switch | 可见的 `<label>` 根 | hidden 的 `<input>` | `name`、`value` 用 props |\n| **容器** | Card、Dialog、Tabs、Table | 组件对外那一层根 DOM | 同一层根 DOM | 内部节点用 `pt` |\n| **叶子** | Button、Icon、Tag | 就是交互元素本身 | 同一元素 | 与原生 Vue 组件一致 |\n\n**字段 / Label 控件的规则**:除了明确绑在子控件上的**事件监听**(`@keydown`、`@paste` 等),其余 fallthrough attrs(`class`、`style`、`data-*`、`title`、`tabindex`、未声明的 `aria-*` 等)一律落到**根节点**。常见语义仍优先走 props;要精确改内层 DOM 用 `pt`。\n\n叶子组件没有额外包裹层,写起来最省心;字段类只需记住「事件绑控件,其它 attrs 绑外层根」。\n\n## 字段组件\n\n以 Input 为例,结构大致是:\n\n```text\ndiv.m-input-field ← class / style / data-* / title / tabindex … 落在这里\n label\n div.m-input-field__control\n input ← @keydown、@focus 等事件落在这里\n span.m-input-field__help\n```\n\n因此:\n\n```vue preview src=\"./demos/attrs/FieldComponents.zh.vue\"\n```\n\n`placeholder`、`name`、`autocomplete`、`autofocus` 等请走 **props**(有类型与文档);若作为未声明 attrs 传入,会落到 field 根而非 input——需要绑到 input 时用 `pt.input`。\n\nSelect、DatePicker、InputNumber 等同理:`class` 撑满栅格时加在 field 根上,别指望它直接写到内层 input。\n\n## Label 控件\n\nCheckbox / Radio / Switch 的可点击区域是 `<label>`,`class` 加在 label 上;`@change` 等由内部 input 接收。\n\n```vue preview src=\"./demos/attrs/LabelControls.vue\"\n```\n\n## 容器组件\n\nCard、Panel、Tabs、Table 等:`class` 加在整个组件根节点,和直觉一致。\n\nDialog、Drawer 会 Teleport,`class` / `style` 加在**遮罩层**(backdrop)上,不是内层 `.m-dialog` 面板——这样你才能控制蒙层全屏布局或 z-index 相关样式。\n\n```vue preview src=\"./demos/attrs/Containers.vue\"\n```\n\n## pt 透传\n\n需要精确改内部某块 DOM(class、style、`data-*`、原生属性)时用 `pt`,键名对应组件 DOM 分段。Input 示例:\n\n```vue\n<MInput\n label=\"API Key\"\n pt={{\n root: { class: 'col-span-2' },\n input: { class: 'font-mono', autocomplete: 'off' },\n prefix: { class: 'text-muted' },\n }}\n/>\n```\n\n常见键名:\n\n| 组件形态 | `pt` 键 |\n| --- | --- |\n| 字段(Input、Textarea、Select…) | `root`、`input` 或 `control`、`label`,部分还有 `prefix` / `suffix` / `help` |\n| Checkbox / Radio / Switch | `root`、`input` |\n| 单根容器 | `root` |\n\n`pt` 里同名的 `class`、`style` 会与对应 DOM 上已有绑定合并,不是整段覆盖。\n\n`FieldPassThrough`、`RootPassThrough` 等在 Props 表里的具体结构,见 [API 类型](/docs/types)。\n\n## PrimeVue / 其它库的差异\n\n若你习惯 PrimeVue 的 `pt` 或把 `class` 直接写到 input 上:Morya 字段组件故意把布局类留在外层,避免 label/help 和输入框宽度对不齐。迁移时把布局 `class` 留在组件标签上即可,一般不用改模板结构。\n\n## 相关文档\n\n- [Input](/components/Input):字段类完整示例\n- [Checkbox](/components/Checkbox):Label 控件\n- [Card](/components/Card)、[Dialog](/components/Dialog):容器\n",
25446
+ "markdown": "---\ntitle: 样式与 attrs\norder: 6\ndescription: class、style、事件与 pt 在各组件上的落点约定。\n---\n\n# 样式与 attrs\n\n给组件传 `class`、`style` 或 `@keydown` 时,先搞清楚它们会绑到哪一层 DOM。Morya UI 的复合组件(尤其表单字段)不是「根元素就是 input」,外层还有 label、help、前后缀等结构。\n\n完整规则见下文;各组件 Props 里的 `pt` 字段用来改内部某一块 DOM,细节查对应组件文档。\n\n## 三类落点\n\n| 类型 | 例子 | 透传 attrs(除控件事件外) | 事件 `@xxx` | 常见原生属性 |\n| --- | --- | --- | --- | --- |\n| **字段** | Input、Select、DatePicker | 外层 field 根(`.m-input-field` 等) | 原生 input / textarea / 控件 | 用 props:`placeholder`、`name`… |\n| **Label 控件** | Checkbox、Radio、Switch | 可见的 `<label>` 根 | hidden 的 `<input>` | `name`、`value` 用 props |\n| **容器** | Card、Dialog、Tabs、Table | 组件对外那一层根 DOM | 同一层根 DOM | 内部节点用 `pt` |\n| **叶子** | Button、Icon、Tag | 就是交互元素本身 | 同一元素 | 与原生 Vue 组件一致 |\n\n**字段 / Label 控件的规则**:除了明确绑在子控件上的**事件监听**(`@keydown`、`@paste` 等),其余 fallthrough attrs(`class`、`style`、`data-*`、`title`、`tabindex`、未声明的 `aria-*` 等)一律落到**根节点**。常见语义仍优先走 props;要精确改内层 DOM 用 `pt`。\n\n叶子组件没有额外包裹层,写起来最省心;字段类只需记住「事件绑控件,其它 attrs 绑外层根」。\n\n## 字段组件\n\n以 Input 为例,结构大致是:\n\n```text\ndiv.m-input-field ← class / style / data-* / title / tabindex … 落在这里\n label\n div.m-input-field__control\n input ← @keydown、@focus 等事件落在这里\n span.m-input-field__help\n```\n\n因此:\n\n```vue preview src=\"./demos/attrs/FieldComponents.zh.vue\"\n```\n\n`placeholder`、`name`、`autocomplete`、`autofocus` 等请走 **props**(有类型与文档);若作为未声明 attrs 传入,会落到 field 根而非 input——需要绑到 input 时用 `pt.input`。\n\nSelect、DatePicker、InputNumber 等同理:`class` 撑满栅格时加在 field 根上,别指望它直接写到内层 input。\n\n## Label 控件\n\nCheckbox / Radio / Switch 的可点击区域是 `<label>`,`class` 加在 label 上;`@change` 等由内部 input 接收。\n\n```vue preview src=\"./demos/attrs/LabelControls.vue\"\n```\n\n## 容器组件\n\nCard、Panel、Tabs、Table 等:`class` 加在整个组件根节点,和直觉一致。\n\nDialog、Drawer 会 Teleport,`class` / `style` 加在**遮罩层**(backdrop)上,不是内层 `.m-dialog` 面板——这样你才能控制蒙层全屏布局或 z-index 相关样式。\n\n```vue preview src=\"./demos/attrs/Containers.vue\"\n```\n\n## pt 透传\n\n需要精确改内部某块 DOM(class、style、`data-*`、原生属性)时用 `pt`,键名对应组件 DOM 分段。Input 示例:\n\n```vue\n<MInput\n label=\"API Key\"\n pt={{\n root: { class: 'col-span-2' },\n input: { class: 'font-mono', autocomplete: 'off' },\n prefix: { class: 'text-muted' },\n }}\n/>\n```\n\n常见键名:\n\n| 组件形态 | `pt` 键 |\n| --- | --- |\n| 字段(Input、Textarea、Select…) | `root`、`input` 或 `control`、`label`,部分还有 `prefix` / `suffix` / `help` |\n| Checkbox / Radio / Switch | `root`、`input` |\n| 单根容器 | `root` |\n\n`pt` 里同名的 `class`、`style` 会与对应 DOM 上已有绑定合并,不是整段覆盖。\n\n`FieldPassThrough`、`RootPassThrough` 等在 Props 表里的具体结构,见 [API 类型](/docs/types)。\n\n## 布局 class 落在哪里\n\n字段组件把布局相关的 `class` / `style` 留在外层根节点,避免 labelhelp 与输入框宽度对不齐。把布局 `class` 写在组件标签上即可,一般不必改模板结构或改绑到内部 input。\n\n## 相关文档\n\n- [Input](/components/Input):字段类完整示例\n- [Checkbox](/components/Checkbox):Label 控件\n- [Card](/components/Card)、[Dialog](/components/Dialog):容器\n",
24835
25447
  "sections": [
24836
25448
  {
24837
25449
  "title": "",
@@ -24864,9 +25476,9 @@
24864
25476
  "body": "需要精确改内部某块 DOM(class、style、`data-*`、原生属性)时用 `pt`,键名对应组件 DOM 分段。Input 示例:\n\n```vue\n<MInput\n label=\"API Key\"\n pt={{\n root: { class: 'col-span-2' },\n input: { class: 'font-mono', autocomplete: 'off' },\n prefix: { class: 'text-muted' },\n }}\n/>\n```\n\n常见键名:\n\n| 组件形态 | `pt` 键 |\n| --- | --- |\n| 字段(Input、Textarea、Select…) | `root`、`input` 或 `control`、`label`,部分还有 `prefix` / `suffix` / `help` |\n| Checkbox / Radio / Switch | `root`、`input` |\n| 单根容器 | `root` |\n\n`pt` 里同名的 `class`、`style` 会与对应 DOM 上已有绑定合并,不是整段覆盖。\n\n`FieldPassThrough`、`RootPassThrough` 等在 Props 表里的具体结构,见 [API 类型](/docs/types)。"
24865
25477
  },
24866
25478
  {
24867
- "title": " PrimeVue / 其它库的差异",
24868
- "id": "与-primevue-其它库的差异",
24869
- "body": "若你习惯 PrimeVue 的 `pt` 或把 `class` 直接写到 input 上:Morya 字段组件故意把布局类留在外层,避免 label/help 和输入框宽度对不齐。迁移时把布局 `class` 留在组件标签上即可,一般不用改模板结构。"
25479
+ "title": "布局 class 落在哪里",
25480
+ "id": "布局-class-落在哪里",
25481
+ "body": "字段组件把布局相关的 `class` / `style` 留在外层根节点,避免 labelhelp 与输入框宽度对不齐。把布局 `class` 写在组件标签上即可,一般不必改模板结构或改绑到内部 input。"
24870
25482
  },
24871
25483
  {
24872
25484
  "title": "相关文档",
@@ -24878,7 +25490,7 @@
24878
25490
  "en-US": {
24879
25491
  "title": "Styling & attrs",
24880
25492
  "description": "Where class, style, events, and pt land on each component.",
24881
- "markdown": "---\ntitle: Styling & attrs\norder: 5\ndescription: Where class, style, events, and pt land on each component.\n---\n\n# Styling & attrs\n\nBefore you pass `class`, `style`, or `@keydown` to a component, know which DOM node receives it. Compound fields (especially form controls) are not a single native element—they wrap labels, help text, affixes, and more.\n\nThe rules below are the library-wide contract. Each component’s `pt` prop targets inner parts; see that component’s API for allowed keys.\n\n## Three fallthrough patterns\n\n| Pattern | Examples | Fallthrough attrs (except control events) | `@xxx` events | Common native attrs |\n| --- | --- | --- | --- | --- |\n| **Field** | Input, Select, DatePicker | Outer field root (`.m-input-field`, etc.) | Native input / textarea / control | Use props: `placeholder`, `name`, … |\n| **Label control** | Checkbox, Radio, Switch | Visible `<label>` root | Hidden `<input>` | `name`, `value` as props |\n| **Container** | Card, Dialog, Tabs, Table | Component root element | Same root | Inner nodes via `pt` |\n| **Leaf** | Button, Icon, Tag | The interactive element itself | Same element | Same as a plain Vue component |\n\n**Field / label controls:** every fallthrough attr except **event listeners** bound to the native control (`@keydown`, `@paste`, …) goes on the **root** (`class`, `style`, `data-*`, `title`, `tabindex`, undeclared `aria-*`, etc.). Prefer props for common semantics; use `pt` to target inner DOM.\n\nLeaf components behave like you expect. For fields: events on the control, everything else on the wrapper root.\n\n## Field components\n\nInput is roughly:\n\n```text\ndiv.m-input-field ← class / style / data-* / title / tabindex … go here\n label\n div.m-input-field__control\n input ← @keydown, @focus, etc. go here\n span.m-input-field__help\n```\n\nExample:\n\n```vue preview src=\"./demos/attrs/FieldComponents.en.vue\"\n```\n\nUse **props** for `placeholder`, `name`, `autocomplete`, and `autofocus` (typed and documented). Undeclared attrs of the same names fall through to the field root, not the input—use `pt.input` when you need them on the control.\n\nThe same split applies to Select, DatePicker, InputNumber, and similar fields.\n\n## Label controls\n\nFor Checkbox / Radio / Switch, `class` lands on the `<label>`; change/input events are wired on the inner input.\n\n```vue preview src=\"./demos/attrs/LabelControls.vue\"\n```\n\n## Containers\n\nCard, Panel, Tabs, Table: `class` on the outer root, as you would expect.\n\nDialog and Drawer Teleport to `body`. `class` / `style` apply to the **backdrop** layer, not the inner `.m-dialog` panel—so you can style the full-screen overlay without fighting panel layout.\n\n```vue preview src=\"./demos/attrs/Containers.vue\"\n```\n\n## Pass-through (`pt`)\n\nUse `pt` when you need a specific inner node—extra classes, styles, `data-*`, or native attributes:\n\n```vue\n<MInput\n label=\"API Key\"\n pt={{\n root: { class: 'col-span-2' },\n input: { class: 'font-mono', autocomplete: 'off' },\n prefix: { class: 'text-muted' },\n }}\n/>\n```\n\nTypical keys:\n\n| Shape | `pt` keys |\n| --- | --- |\n| Fields (Input, Textarea, Select, …) | `root`, `input` or `control`, `label`; some add `prefix` / `suffix` / `help` |\n| Checkbox / Radio / Switch | `root`, `input` |\n| Single-root containers | `root` |\n\n`class` and `style` in `pt` merge with existing bindings on that node; they do not replace the whole attribute object.\n\nFor full shapes of `FieldPassThrough`, `RootPassThrough`, and similar names in Props tables, see [API types](/docs/types).\n\n## Coming from PrimeVue\n\nIf you are used to PrimeVue `pt` or putting `class` directly on the input: Morya field components keep layout classes on the outer wrapper so labels and help text stay aligned. In most migrations you can leave `class` on the component tag and call it done.\n\n## See also\n\n- [Input](/components/Input): full field example\n- [Checkbox](/components/Checkbox): label control\n- [Card](/components/Card), [Dialog](/components/Dialog): containers\n",
25493
+ "markdown": "---\ntitle: Styling & attrs\norder: 6\ndescription: Where class, style, events, and pt land on each component.\n---\n\n# Styling & attrs\n\nBefore you pass `class`, `style`, or `@keydown` to a component, know which DOM node receives it. Compound fields (especially form controls) are not a single native element—they wrap labels, help text, affixes, and more.\n\nThe rules below are the library-wide contract. Each component’s `pt` prop targets inner parts; see that component’s API for allowed keys.\n\n## Three fallthrough patterns\n\n| Pattern | Examples | Fallthrough attrs (except control events) | `@xxx` events | Common native attrs |\n| --- | --- | --- | --- | --- |\n| **Field** | Input, Select, DatePicker | Outer field root (`.m-input-field`, etc.) | Native input / textarea / control | Use props: `placeholder`, `name`, … |\n| **Label control** | Checkbox, Radio, Switch | Visible `<label>` root | Hidden `<input>` | `name`, `value` as props |\n| **Container** | Card, Dialog, Tabs, Table | Component root element | Same root | Inner nodes via `pt` |\n| **Leaf** | Button, Icon, Tag | The interactive element itself | Same element | Same as a plain Vue component |\n\n**Field / label controls:** every fallthrough attr except **event listeners** bound to the native control (`@keydown`, `@paste`, …) goes on the **root** (`class`, `style`, `data-*`, `title`, `tabindex`, undeclared `aria-*`, etc.). Prefer props for common semantics; use `pt` to target inner DOM.\n\nLeaf components behave like you expect. For fields: events on the control, everything else on the wrapper root.\n\n## Field components\n\nInput is roughly:\n\n```text\ndiv.m-input-field ← class / style / data-* / title / tabindex … go here\n label\n div.m-input-field__control\n input ← @keydown, @focus, etc. go here\n span.m-input-field__help\n```\n\nExample:\n\n```vue preview src=\"./demos/attrs/FieldComponents.en.vue\"\n```\n\nUse **props** for `placeholder`, `name`, `autocomplete`, and `autofocus` (typed and documented). Undeclared attrs of the same names fall through to the field root, not the input—use `pt.input` when you need them on the control.\n\nThe same split applies to Select, DatePicker, InputNumber, and similar fields.\n\n## Label controls\n\nFor Checkbox / Radio / Switch, `class` lands on the `<label>`; change/input events are wired on the inner input.\n\n```vue preview src=\"./demos/attrs/LabelControls.vue\"\n```\n\n## Containers\n\nCard, Panel, Tabs, Table: `class` on the outer root, as you would expect.\n\nDialog and Drawer Teleport to `body`. `class` / `style` apply to the **backdrop** layer, not the inner `.m-dialog` panel—so you can style the full-screen overlay without fighting panel layout.\n\n```vue preview src=\"./demos/attrs/Containers.vue\"\n```\n\n## Pass-through (`pt`)\n\nUse `pt` when you need a specific inner node—extra classes, styles, `data-*`, or native attributes:\n\n```vue\n<MInput\n label=\"API Key\"\n pt={{\n root: { class: 'col-span-2' },\n input: { class: 'font-mono', autocomplete: 'off' },\n prefix: { class: 'text-muted' },\n }}\n/>\n```\n\nTypical keys:\n\n| Shape | `pt` keys |\n| --- | --- |\n| Fields (Input, Textarea, Select, …) | `root`, `input` or `control`, `label`; some add `prefix` / `suffix` / `help` |\n| Checkbox / Radio / Switch | `root`, `input` |\n| Single-root containers | `root` |\n\n`class` and `style` in `pt` merge with existing bindings on that node; they do not replace the whole attribute object.\n\nFor full shapes of `FieldPassThrough`, `RootPassThrough`, and similar names in Props tables, see [API types](/docs/types).\n\n## Where layout classes land\n\nField components keep layout `class` / `style` on the outer root so labels and help text stay aligned with the control width. Put layout classes on the component tag; you usually do not need to rebind them onto the inner input.\n\n## See also\n\n- [Input](/components/Input): full field example\n- [Checkbox](/components/Checkbox): label control\n- [Card](/components/Card), [Dialog](/components/Dialog): containers\n",
24882
25494
  "sections": [
24883
25495
  {
24884
25496
  "title": "",
@@ -24911,9 +25523,9 @@
24911
25523
  "body": "Use `pt` when you need a specific inner node—extra classes, styles, `data-*`, or native attributes:\n\n```vue\n<MInput\n label=\"API Key\"\n pt={{\n root: { class: 'col-span-2' },\n input: { class: 'font-mono', autocomplete: 'off' },\n prefix: { class: 'text-muted' },\n }}\n/>\n```\n\nTypical keys:\n\n| Shape | `pt` keys |\n| --- | --- |\n| Fields (Input, Textarea, Select, …) | `root`, `input` or `control`, `label`; some add `prefix` / `suffix` / `help` |\n| Checkbox / Radio / Switch | `root`, `input` |\n| Single-root containers | `root` |\n\n`class` and `style` in `pt` merge with existing bindings on that node; they do not replace the whole attribute object.\n\nFor full shapes of `FieldPassThrough`, `RootPassThrough`, and similar names in Props tables, see [API types](/docs/types)."
24912
25524
  },
24913
25525
  {
24914
- "title": "Coming from PrimeVue",
24915
- "id": "coming-from-primevue",
24916
- "body": "If you are used to PrimeVue `pt` or putting `class` directly on the input: Morya field components keep layout classes on the outer wrapper so labels and help text stay aligned. In most migrations you can leave `class` on the component tag and call it done."
25526
+ "title": "Where layout classes land",
25527
+ "id": "where-layout-classes-land",
25528
+ "body": "Field components keep layout `class` / `style` on the outer root so labels and help text stay aligned with the control width. Put layout classes on the component tag; you usually do not need to rebind them onto the inner input."
24917
25529
  },
24918
25530
  {
24919
25531
  "title": "See also",
@@ -24930,12 +25542,12 @@
24930
25542
  "titleEn": "API types",
24931
25543
  "description": "文档 Props 里常见类型名的结构与含义。",
24932
25544
  "descriptionEn": "Shapes behind type names in component Props tables.",
24933
- "order": 6,
25545
+ "order": 7,
24934
25546
  "locales": {
24935
25547
  "zh-CN": {
24936
25548
  "title": "API 类型",
24937
25549
  "description": "文档 Props 里常见类型名的结构与含义。",
24938
- "markdown": "---\ntitle: API 类型\norder: 6\ndescription: 文档 Props 里常见类型名的结构与含义。\n---\n\n# API 类型\n\n组件文档 Props 表里出现的类型名,在这里查具体结构。包入口也导出同名类型,可在业务代码里 `import type { … } from 'morya-ui'`(以各组件 `types.ts` 为准)。\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\n单个 DOM 节点上要合并的属性 bag。`pt.<part>` 的值就是这个类型。\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\n常用键:`class`、`style`、`data-*`、`onClick` / `onKeydown`(Vue 事件监听写法)、以及该节点合法的原生 HTML 属性。\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\n单根容器(Card、Dialog 遮罩、Tabs 等):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch(可见根是 `<label>`,hidden input 单独一段):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // 一般是 label\n input?: PassThroughPart // 原生 input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\n表单字段(Input、Select、DatePicker 等):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // 外层 .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // 触发器 / 组合控件(Select 等)\n input?: PassThroughPart // 原生 input / textarea\n}\n```\n\n具体组件支持哪些键,见该组件文档的 **类型** 或 **pt** 小节。\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) 在 `FieldPassThrough` 基础上多了前后缀等:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\n控件尺寸,多数表单 / 按钮组件的 `size` prop:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` 为兼容别名;未传时通常继承 [ConfigProvider](/docs/config) 的 `size`。\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n输入框视觉变体:\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonSeverity\">ButtonSeverity</h3>\n\n按钮语义色([`Button`](/components/Button)、Dialog 页脚等):\n\n```ts\ntype ButtonSeverity =\n | 'primary'\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning' // 'warn' 为别名\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\n浮层 Teleport 挂载目标(Dialog、Select 菜单、Toast 等):\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'`(默认):挂到 document.body \n- `'self'`:不 Teleport,就地渲染 \n- 也常见 `appendTo: false`(运行时兼容,同 `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\n关闭 / 确认前的拦截函数。返回 `false`(含 Promise 解析为 `false`)则**不继续**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\n用于 Dialog `beforeClose`、`onPositiveClick`,ConfirmDialog / ConfirmPopup 的 `beforeAccept` 等。\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) 选项项:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\n单选为标量;`multiple` 时为数组。\n\n<h3 id=\"IconName\">IconName</h3>\n\n[`MIcon`](/components/Icon) / [`Button`](/components/Button) 的 `icon` / `name` 使用的注册名,例如 `'search'`、`'chevron-down'`。完整列表见 Icon 文档注册表。\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nMenu / Dropdown / ContextMenu 等导航项的公共字段:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MSeverity\">MSeverity</h3>\n\nMessage、Tag 等的状态色:\n\n```ts\ntype MSeverity =\n | 'primary'\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'contrast'\n```\n\n---\n\n更细的组件专属类型(如 `TableServerOptions`、`MenuItem`)写在对应组件页 **类型** 小节;这里只列跨组件复用的名字。\n",
25550
+ "markdown": "---\ntitle: API 类型\norder: 7\ndescription: 文档 Props 里常见类型名的结构与含义。\n---\n\n# API 类型\n\n组件文档 Props 表里出现的类型名,在这里查具体结构。包入口也导出同名类型,可在业务代码里 `import type { … } from 'morya-ui'`(以各组件 `types.ts` 为准)。\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\n单个 DOM 节点上要合并的属性 bag。`pt.<part>` 的值就是这个类型。\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\n常用键:`class`、`style`、`data-*`、`onClick` / `onKeydown`(Vue 事件监听写法)、以及该节点合法的原生 HTML 属性。\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\n单根容器(Card、Dialog 遮罩、Tabs 等):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch(可见根是 `<label>`,hidden input 单独一段):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // 一般是 label\n input?: PassThroughPart // 原生 input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\n表单字段(Input、Select、DatePicker 等):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // 外层 .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // 触发器 / 组合控件(Select 等)\n input?: PassThroughPart // 原生 input / textarea\n}\n```\n\n具体组件支持哪些键,见该组件文档的 **类型** 或 **pt** 小节。\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) 在 `FieldPassThrough` 基础上多了前后缀等:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\n控件尺寸,多数表单 / 按钮组件的 `size` prop:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` 为兼容别名;未传时通常继承 [ConfigProvider](/docs/config) 的 `size`。\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n输入框视觉变体:\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonSeverity\">ButtonSeverity</h3>\n\n按钮语义色([`Button`](/components/Button)、Dialog 页脚等):\n\n```ts\ntype ButtonSeverity =\n | 'primary'\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning' // 'warn' 为别名\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\n浮层 Teleport 挂载目标(Dialog、Select 菜单、Toast 等):\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'`(默认):挂到 document.body \n- `'self'`:不 Teleport,就地渲染 \n- 也常见 `appendTo: false`(运行时兼容,同 `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\n关闭 / 确认前的拦截函数。返回 `false`(含 Promise 解析为 `false`)则**不继续**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\n用于 Dialog `beforeClose`、`onPositiveClick`,ConfirmDialog / ConfirmPopup 的 `beforeAccept` 等。\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) 选项项:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\n单选为标量;`multiple` 时为数组。\n\n<h3 id=\"IconName\">IconName</h3>\n\n[`MIcon`](/components/Icon) / [`Button`](/components/Button) 的 `icon` / `name` 使用的注册名,例如 `'search'`、`'chevron-down'`。完整列表见 Icon 文档注册表。\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nMenu / Dropdown / ContextMenu 等导航项的公共字段:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MSeverity\">MSeverity</h3>\n\nMessage、Tag 等的状态色:\n\n```ts\ntype MSeverity =\n | 'primary'\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'contrast'\n```\n\n---\n\n更细的组件专属类型(如 `TableServerOptions`、`MenuItem`)写在对应组件页 **类型** 小节;这里只列跨组件复用的名字。\n",
24939
25551
  "sections": [
24940
25552
  {
24941
25553
  "title": "",
@@ -24947,7 +25559,7 @@
24947
25559
  "en-US": {
24948
25560
  "title": "API types",
24949
25561
  "description": "Shapes behind type names in component Props tables.",
24950
- "markdown": "---\ntitle: API types\norder: 6\ndescription: Shapes behind type names in component Props tables.\n---\n\n# API types\n\nLook up structures for names that appear in Props tables. The package re-exports the same names as TypeScript types (`import type { … } from 'morya-ui'`), per component `types.ts`.\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\nAttribute bag merged onto one DOM node—the value of `pt.<part>`.\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\nCommon keys: `class`, `style`, `data-*`, `onClick` / `onKeydown`, and valid native attributes for that element.\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\nSingle-root containers (Card, Dialog backdrop, Tabs, …):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch (visible `<label>` root + hidden input):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // usually the label\n input?: PassThroughPart // native input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\nForm fields (Input, Select, DatePicker, …):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // outer .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // trigger / composite control\n input?: PassThroughPart // native input / textarea\n}\n```\n\nWhich keys a component accepts is listed on that component’s **Types** or **pt** section.\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) extends `FieldPassThrough` with affixes:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\nControl size for many form / button props:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` are legacy aliases. Omitted `size` usually inherits [ConfigProvider](/docs/config).\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonSeverity\">ButtonSeverity</h3>\n\nButton / dialog footer tones:\n\n```ts\ntype ButtonSeverity =\n | 'primary'\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning' // alias: 'warn'\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\nOverlay Teleport target:\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'` (default) \n- `'self'` — render in place (no Teleport) \n- `false` is accepted at runtime (same idea as `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\nGuard before close / confirm. Return `false` (including from a Promise) to **abort**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\nUsed by Dialog `beforeClose`, ConfirmDialog `beforeAccept`, and similar.\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) option row:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\nScalar when single-select; array when `multiple`.\n\n<h3 id=\"IconName\">IconName</h3>\n\nRegistered icon id for [`MIcon`](/components/Icon) / [`Button`](/components/Button), e.g. `'search'`. See the Icon registry.\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nShared fields for Menu / Dropdown / ContextMenu items:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MSeverity\">MSeverity</h3>\n\nStatus tone for Message, Tag, etc.:\n\n```ts\ntype MSeverity =\n | 'primary'\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'contrast'\n```\n\n---\n\nComponent-only types (`TableServerOptions`, `MenuItem`, …) live under each component’s **Types** section; this page is for shared names only.\n",
25562
+ "markdown": "---\ntitle: API types\norder: 7\ndescription: Shapes behind type names in component Props tables.\n---\n\n# API types\n\nLook up structures for names that appear in Props tables. The package re-exports the same names as TypeScript types (`import type { … } from 'morya-ui'`), per component `types.ts`.\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\nAttribute bag merged onto one DOM node—the value of `pt.<part>`.\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\nCommon keys: `class`, `style`, `data-*`, `onClick` / `onKeydown`, and valid native attributes for that element.\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\nSingle-root containers (Card, Dialog backdrop, Tabs, …):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch (visible `<label>` root + hidden input):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // usually the label\n input?: PassThroughPart // native input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\nForm fields (Input, Select, DatePicker, …):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // outer .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // trigger / composite control\n input?: PassThroughPart // native input / textarea\n}\n```\n\nWhich keys a component accepts is listed on that component’s **Types** or **pt** section.\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) extends `FieldPassThrough` with affixes:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\nControl size for many form / button props:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` are legacy aliases. Omitted `size` usually inherits [ConfigProvider](/docs/config).\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonSeverity\">ButtonSeverity</h3>\n\nButton / dialog footer tones:\n\n```ts\ntype ButtonSeverity =\n | 'primary'\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning' // alias: 'warn'\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\nOverlay Teleport target:\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'` (default) \n- `'self'` — render in place (no Teleport) \n- `false` is accepted at runtime (same idea as `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\nGuard before close / confirm. Return `false` (including from a Promise) to **abort**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\nUsed by Dialog `beforeClose`, ConfirmDialog `beforeAccept`, and similar.\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) option row:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\nScalar when single-select; array when `multiple`.\n\n<h3 id=\"IconName\">IconName</h3>\n\nRegistered icon id for [`MIcon`](/components/Icon) / [`Button`](/components/Button), e.g. `'search'`. See the Icon registry.\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nShared fields for Menu / Dropdown / ContextMenu items:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MSeverity\">MSeverity</h3>\n\nStatus tone for Message, Tag, etc.:\n\n```ts\ntype MSeverity =\n | 'primary'\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'contrast'\n```\n\n---\n\nComponent-only types (`TableServerOptions`, `MenuItem`, …) live under each component’s **Types** section; this page is for shared names only.\n",
24951
25563
  "sections": [
24952
25564
  {
24953
25565
  "title": "",
@@ -24964,12 +25576,12 @@
24964
25576
  "titleEn": "Configuration",
24965
25577
  "description": "ConfigProvider、createMoryaUI 与 useMConfig。",
24966
25578
  "descriptionEn": "ConfigProvider, createMoryaUI, and useMConfig.",
24967
- "order": 7,
25579
+ "order": 8,
24968
25580
  "locales": {
24969
25581
  "zh-CN": {
24970
25582
  "title": "全局配置",
24971
25583
  "description": "ConfigProvider、createMoryaUI 与 useMConfig。",
24972
- "markdown": "---\ntitle: 全局配置\norder: 7\ndescription: ConfigProvider、createMoryaUI 与 useMConfig。\n---\n\n# 全局配置\n\nMorya UI 提供应用级 / 页面级默认值,用于统一浮层挂载、尺寸、密度与文案。\n\n## 能力一览\n\n| 字段 | 说明 |\n| --- | --- |\n| `appendTo` | 浮层默认 Teleport 目标,默认 `body` |\n| `size` | 表单 / 按钮等默认尺寸 |\n| `density` | `compact` / `comfortable` / `spacious`,缩放间距与控件高度 |\n| `inputVariant` | 输入框 `outlined` / `filled` |\n| `zIndex` | 浮层基准层级 |\n| `locale` | 确认、空态、加载、占位等文案。可传入内置语言包 `zhCN` / `enUS` |\n\n优先级:**组件 Props > `MConfigProvider` > `createMoryaUI` > 内置默认(中文)**。\n\n## 语言包\n\n组件内置文案默认中文。切换英文时传入 `enUS`:\n\n```ts\nimport { createMoryaUI, enUS, zhCN } from 'morya-ui'\nimport { createApp } from 'vue'\n\ncreateApp(App).use(createMoryaUI({ locale: enUS })).mount('#app')\n```\n\n也可以只覆盖部分文案:\n\n```ts\ncreateMoryaUI({\n locale: {\n ...zhCN,\n accept: '确定',\n },\n})\n```\n\n文档站右上角的「中 / EN」会把同一套语言包注入 `MConfigProvider`,因此示例里的空态、确认、日期等文案会跟着切换。指南与组件 Markdown 在英文下会加载对应的 `*.en.md`。\n\n## Size\n\n未传本地 `size` 的控件继承 ConfigProvider。\n\n```vue preview src=\"./demos/config/Size.zh.vue\"\n```\n\n## Density\n\n```vue preview src=\"./demos/config/Density.zh.vue\"\n```\n\n## Input variant\n\n```vue preview src=\"./demos/config/InputVariant.vue\"\n```\n\n## Locale\n\n```vue preview src=\"./demos/config/Locale.zh.vue\"\n```\n\n## appendTo + zIndex\n\n```vue preview src=\"./demos/config/AppendToZIndex.zh.vue\"\n```\n\n## 应用级:`createMoryaUI`\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\n\ncreateApp(App).use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 2000,\n locale: { accept: '确认', reject: '取消' },\n }),\n ).mount('#app')\n```\n\n## 读取配置\n\n```ts\nimport { useMConfig } from 'morya-ui'\n\nconst config = useMConfig()\n// config.value.appendTo / size / locale …\n```\n\n完整 Props 与对照表见组件文档:[ConfigProvider](/components/ConfigProvider)。\n",
25584
+ "markdown": "---\ntitle: 全局配置\norder: 8\ndescription: ConfigProvider、createMoryaUI 与 useMConfig。\n---\n\n# 全局配置\n\nMorya UI 提供应用级 / 页面级默认值,用于统一浮层挂载、尺寸、密度与文案。\n\n## 能力一览\n\n| 字段 | 说明 |\n| --- | --- |\n| `appendTo` | 浮层默认 Teleport 目标,默认 `body` |\n| `size` | 表单 / 按钮等默认尺寸 |\n| `density` | `compact` / `comfortable` / `spacious`,缩放间距与控件高度 |\n| `inputVariant` | 输入框 `outlined` / `filled` |\n| `zIndex` | 浮层基准层级 |\n| `locale` | 确认、空态、加载、占位等文案。可传入内置语言包 `zhCN` / `enUS` |\n\n优先级:**组件 Props > `MConfigProvider` > `createMoryaUI` > 内置默认(中文)**。\n\n## 语言包\n\n组件内置文案默认中文。切换英文时传入 `enUS`:\n\n```ts\nimport { createMoryaUI, enUS, zhCN } from 'morya-ui'\nimport { createApp } from 'vue'\n\ncreateApp(App).use(createMoryaUI({ locale: enUS })).mount('#app')\n```\n\n也可以只覆盖部分文案:\n\n```ts\ncreateMoryaUI({\n locale: {\n ...zhCN,\n accept: '确定',\n },\n})\n```\n\n文档站右上角的「中 / EN」会把同一套语言包注入 `MConfigProvider`,因此示例里的空态、确认、日期等文案会跟着切换。指南与组件 Markdown 在英文下会加载对应的 `*.en.md`。\n\n## Size\n\n未传本地 `size` 的控件继承 ConfigProvider。\n\n```vue preview src=\"./demos/config/Size.zh.vue\"\n```\n\n## Density\n\n```vue preview src=\"./demos/config/Density.zh.vue\"\n```\n\n## Input variant\n\n```vue preview src=\"./demos/config/InputVariant.vue\"\n```\n\n## Locale\n\n```vue preview src=\"./demos/config/Locale.zh.vue\"\n```\n\n## appendTo + zIndex\n\n```vue preview src=\"./demos/config/AppendToZIndex.zh.vue\"\n```\n\n## 应用级:`createMoryaUI`\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\n\ncreateApp(App).use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 2000,\n locale: { accept: '确认', reject: '取消' },\n }),\n ).mount('#app')\n```\n\n## 读取配置\n\n```ts\nimport { useMConfig } from 'morya-ui'\n\nconst config = useMConfig()\n// config.value.appendTo / size / locale …\n```\n\n完整 Props 与对照表见组件文档:[ConfigProvider](/components/ConfigProvider)。\n",
24973
25585
  "sections": [
24974
25586
  {
24975
25587
  "title": "",
@@ -25026,7 +25638,7 @@
25026
25638
  "en-US": {
25027
25639
  "title": "Configuration",
25028
25640
  "description": "ConfigProvider, createMoryaUI, and useMConfig.",
25029
- "markdown": "---\ntitle: Configuration\norder: 7\ndescription: ConfigProvider, createMoryaUI, and useMConfig.\n---\n\n# Configuration\n\nMorya UI provides app-level and page-level defaults for overlay mount, size, density, and copy.\n\n## Capabilities\n\n| Field | Description |\n| --- | --- |\n| `appendTo` | Default overlay Teleport target, `body` by default |\n| `size` | Default size for forms / buttons |\n| `density` | `compact` / `comfortable` / `spacious`, scales spacing and control height |\n| `inputVariant` | Input surface `outlined` / `filled` |\n| `zIndex` | Overlay z-index base |\n| `locale` | Confirm, empty, loading, and placeholder copy. Pass built-in packs `zhCN` / `enUS` |\n\nPriority: **component props > `MConfigProvider` > `createMoryaUI` > built-in default (Chinese)**.\n\n## Locale packs\n\nBuilt-in copy defaults to Chinese. Pass `enUS` to switch to English:\n\n```ts\nimport { createMoryaUI, enUS, zhCN } from 'morya-ui'\nimport { createApp } from 'vue'\n\ncreateApp(App).use(createMoryaUI({ locale: enUS })).mount('#app')\n```\n\nYou can also override a subset:\n\n```ts\ncreateMoryaUI({\n locale: {\n ...zhCN,\n accept: 'OK',\n },\n})\n```\n\nThe **中 / EN** switch in the docs header injects the same pack into `MConfigProvider`, so live examples (empty states, confirm, dates, and so on) follow the selected language. Markdown pages load `*.en.md` when English is selected.\n\n## Size\n\nControls without a local `size` inherit from ConfigProvider.\n\n```vue preview src=\"./demos/config/Size.en.vue\"\n```\n\n## Density\n\n```vue preview src=\"./demos/config/Density.en.vue\"\n```\n\n## Input variant\n\n```vue preview src=\"./demos/config/InputVariant.vue\"\n```\n\n## Locale\n\n```vue preview src=\"./demos/config/Locale.en.vue\"\n```\n\n## appendTo + zIndex\n\n```vue preview src=\"./demos/config/AppendToZIndex.en.vue\"\n```\n\n## App-level: `createMoryaUI`\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\n\ncreateApp(App).use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 2000,\n locale: { accept: 'OK', reject: 'Cancel' },\n }),\n ).mount('#app')\n```\n\n## Reading config\n\n```ts\nimport { useMConfig } from 'morya-ui'\n\nconst config = useMConfig()\n// config.value.appendTo / size / locale …\n```\n\nFull props and comparison tables: [ConfigProvider](/components/ConfigProvider).\n",
25641
+ "markdown": "---\ntitle: Configuration\norder: 8\ndescription: ConfigProvider, createMoryaUI, and useMConfig.\n---\n\n# Configuration\n\nMorya UI provides app-level and page-level defaults for overlay mount, size, density, and copy.\n\n## Capabilities\n\n| Field | Description |\n| --- | --- |\n| `appendTo` | Default overlay Teleport target, `body` by default |\n| `size` | Default size for forms / buttons |\n| `density` | `compact` / `comfortable` / `spacious`, scales spacing and control height |\n| `inputVariant` | Input surface `outlined` / `filled` |\n| `zIndex` | Overlay z-index base |\n| `locale` | Confirm, empty, loading, and placeholder copy. Pass built-in packs `zhCN` / `enUS` |\n\nPriority: **component props > `MConfigProvider` > `createMoryaUI` > built-in default (Chinese)**.\n\n## Locale packs\n\nBuilt-in copy defaults to Chinese. Pass `enUS` to switch to English:\n\n```ts\nimport { createMoryaUI, enUS, zhCN } from 'morya-ui'\nimport { createApp } from 'vue'\n\ncreateApp(App).use(createMoryaUI({ locale: enUS })).mount('#app')\n```\n\nYou can also override a subset:\n\n```ts\ncreateMoryaUI({\n locale: {\n ...zhCN,\n accept: 'OK',\n },\n})\n```\n\nThe **中 / EN** switch in the docs header injects the same pack into `MConfigProvider`, so live examples (empty states, confirm, dates, and so on) follow the selected language. Markdown pages load `*.en.md` when English is selected.\n\n## Size\n\nControls without a local `size` inherit from ConfigProvider.\n\n```vue preview src=\"./demos/config/Size.en.vue\"\n```\n\n## Density\n\n```vue preview src=\"./demos/config/Density.en.vue\"\n```\n\n## Input variant\n\n```vue preview src=\"./demos/config/InputVariant.vue\"\n```\n\n## Locale\n\n```vue preview src=\"./demos/config/Locale.en.vue\"\n```\n\n## appendTo + zIndex\n\n```vue preview src=\"./demos/config/AppendToZIndex.en.vue\"\n```\n\n## App-level: `createMoryaUI`\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\n\ncreateApp(App).use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 2000,\n locale: { accept: 'OK', reject: 'Cancel' },\n }),\n ).mount('#app')\n```\n\n## Reading config\n\n```ts\nimport { useMConfig } from 'morya-ui'\n\nconst config = useMConfig()\n// config.value.appendTo / size / locale …\n```\n\nFull props and comparison tables: [ConfigProvider](/components/ConfigProvider).\n",
25030
25642
  "sections": [
25031
25643
  {
25032
25644
  "title": "",
@@ -25088,12 +25700,12 @@
25088
25700
  "titleEn": "SSR & meta-frameworks",
25089
25701
  "description": "在 Nuxt、Astro、Vite SSR 等环境中使用 Morya UI。",
25090
25702
  "descriptionEn": "Use Morya UI with Nuxt, Astro, Vite SSR, and other server-rendered setups.",
25091
- "order": 8,
25703
+ "order": 9,
25092
25704
  "locales": {
25093
25705
  "zh-CN": {
25094
25706
  "title": "SSR 与服务端框架",
25095
25707
  "description": "在 Nuxt、Astro、Vite SSR 等环境中使用 Morya UI。",
25096
- "markdown": "---\ntitle: SSR 与服务端框架\norder: 8\ndescription: 在 Nuxt、Astro、Vite SSR 等环境中使用 Morya UI。\n---\n\n# SSR 与服务端框架\n\nMorya UI 面向 **Vue 3** 的 SSR 场景做了兼容(推荐 3.5 及以上):服务端不会访问 `document` / `window`,组件实例 id 在服务端与客户端保持一致,命令式 API(`toast` / `message` / `confirm`)在服务端自动跳过。\n\n以下框架均可接入;按场景选择 **全量 SSR** 或 **客户端 Islands**。\n\n## 通用约定\n\n| 项 | 建议 |\n| --- | --- |\n| 样式 | 在应用入口或框架配置中引入 `morya-ui/styles.css` |\n| 主题 | 优先用根级 **`MConfigProvider`** 设置 `theme` / `density`,避免在 SSR 阶段单独调用 `useTheme()` 写 `document` |\n| 命令式反馈 | `toast()`、`message()`、`confirm()` 仅在浏览器执行;SSR 期间调用不会报错,但不会渲染 |\n| 按需导入 | 配合 `morya-ui/resolver` 与 `unplugin-vue-components` 减小体积 |\n| 浮层 | Dialog / Select / Tooltip 等使用 Vue `Teleport`;SSR 可输出占位,交互在客户端水合后生效 |\n\n## Nuxt 3\n\n推荐使用官方模块 **`@morya-ui/nuxt`**(同仓库 `packages/nuxt`)。\n\n### 安装\n\n```bash\npnpm add morya-ui @morya-ui/nuxt\npnpm add -D unplugin-vue-components\n```\n\n### 配置\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\n// nuxt.config.ts\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineNuxtConfig({\n modules: ['@morya-ui/nuxt'],\n vite: {\n plugins: [\n Components({\n resolvers: [MoryaUIResolver()],\n }),\n ],\n },\n})\n```\n\n模块默认会:\n\n- 引入 `morya-ui/styles.css`\n- 将 `morya-ui` 加入 `build.transpile`\n- 在客户端注册 overlay 上下文(供 `toast` / `message` 使用)\n\n### 根布局\n\n```vue\n<!-- app.vue -->\n<script setup lang=\"ts\">\nconst theme = ref<'light' | 'dark'>('light')\n</script>\n\n<template>\n <MConfigProvider :theme=\"theme\" density=\"comfortable\">\n <NuxtPage />\n </MConfigProvider>\n</template>\n```\n\n按需导入时无需 `app.use(MoryaUI)`;若需全量注册,可在 `plugins/morya-ui.client.ts` 中 `nuxtApp.vueApp.use(MoryaUI)`。\n\n### 仅客户端组件\n\n极少数依赖浏览器专有 API 的场景(如自定义 `appendTo` 到尚未存在的节点),可用 Nuxt 的 `<ClientOnly>` 包裹。\n\n## Astro + Vue\n\n适合 **静态页 + Vue 岛**(管理后台、控制台嵌入营销站)。\n\n### 安装\n\n```bash\npnpm add morya-ui\nnpx astro add vue\n```\n\n### 在 Vue 岛中使用\n\n```astro\n---\n// src/pages/admin.astro\nimport AdminShell from '../components/AdminShell.vue'\n---\n<AdminShell client:load />\n```\n\n```vue\n<!-- src/components/AdminShell.vue -->\n<script setup lang=\"ts\">\nimport { MButton, MConfigProvider } from 'morya-ui'\nimport 'morya-ui/styles.css'\n</script>\n\n<template>\n <MConfigProvider theme=\"light\">\n <MButton label=\"Hello\" />\n </MConfigProvider>\n</template>\n```\n\n- 交互型后台推荐 `client:load` 或 `client:only`\n- 纯展示块可用 `client:visible` 延迟水合\n- Astro 本身不做 Vue SSR 时,无需处理 hydration id 问题\n\n## Vite SSR(含自定义服务端)\n\n```ts\nimport { MConfigProvider } from 'morya-ui/config-provider'\n// main.server.ts / entry-server.ts\nimport { createSSRApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\nexport function createApp() {\n const app = createSSRApp(App)\n return { app }\n}\n```\n\n客户端入口可注册 overlay 插件:\n\n```ts\n// entry-client.ts\nimport { createMoryaUI } from 'morya-ui'\n\ncreateApp(/* ... */)\n .use(createMoryaUI({ components: false }))\n .mount('#app')\n```\n\n构建时确保 `morya-ui` 进入 `ssr.noExternal`(或 `ssr: { noExternal: ['morya-ui'] }`),以便正确处理 `.vue` 与 CSS 副作用。\n\n## 其他 Vue SSR 方案\n\n| 方案 | 说明 |\n| --- | --- |\n| **Quasar (SSR mode)** | 在 `quasar.config` 的 `build.transpileDependencies` 中加入 `morya-ui`,入口引入样式 |\n| **vite-plugin-ssr / vike** | 与 Vite SSR 相同:服务端渲染 + 客户端 `createMoryaUI({ components: false })` |\n| **Inertia + Vue SSR** | 根组件包 `MConfigProvider`;命令式 API 仅在 `onMounted` 后调用 |\n\n## 已知限制\n\n- **不支持 Vue 2**;SSR 仅适用于 Vue 3。\n- **IE** 不在支持范围内(与 Vue 3 一致)。\n- 主题 `localStorage` 持久化仅在浏览器生效;SSR 首屏使用 `MConfigProvider` 或 cookie 同步主题可避免闪动。\n- 全量 E2E SSR 回归仍在完善;若遇到 hydration 警告,请提供最小复现并 [提 Issue](https://github.com/morya-space/morya-ui/issues)。\n\n## 下一步\n\n- [快速上手](/docs/quick-start):安装与导入方式\n- [全局配置](/docs/config):`MConfigProvider`\n- [主题](/docs/theme):亮暗色与 token\n",
25708
+ "markdown": "---\ntitle: SSR 与服务端框架\norder: 9\ndescription: 在 Nuxt、Astro、Vite SSR 等环境中使用 Morya UI。\n---\n\n# SSR 与服务端框架\n\nMorya UI 面向 **Vue 3** 的 SSR 场景做了兼容(推荐 3.5 及以上):服务端不会访问 `document` / `window`,组件实例 id 在服务端与客户端保持一致,命令式 API(`toast` / `message` / `confirm`)在服务端自动跳过。\n\n以下框架均可接入;按场景选择 **全量 SSR** 或 **客户端 Islands**。\n\n## 通用约定\n\n| 项 | 建议 |\n| --- | --- |\n| 样式 | 在应用入口或框架配置中引入 `morya-ui/styles.css` |\n| 主题 | 优先用根级 **`MConfigProvider`** 设置 `theme` / `density`,避免在 SSR 阶段单独调用 `useTheme()` 写 `document` |\n| 命令式反馈 | `toast()`、`message()`、`confirm()` 仅在浏览器执行;SSR 期间调用不会报错,但不会渲染 |\n| 按需导入 | 配合 `morya-ui/resolver` 与 `unplugin-vue-components` 减小体积 |\n| 浮层 | Dialog / Select / Tooltip 等使用 Vue `Teleport`;SSR 可输出占位,交互在客户端水合后生效 |\n\n## Nuxt 3\n\n推荐使用官方模块 **`@morya-ui/nuxt`**(同仓库 `packages/nuxt`)。\n\n### 安装\n\n```bash\npnpm add morya-ui @morya-ui/nuxt\npnpm add -D unplugin-vue-components\n```\n\n### 配置\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\n// nuxt.config.ts\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineNuxtConfig({\n modules: ['@morya-ui/nuxt'],\n vite: {\n plugins: [\n Components({\n resolvers: [MoryaUIResolver()],\n }),\n ],\n },\n})\n```\n\n模块默认会:\n\n- 引入 `morya-ui/styles.css`\n- 将 `morya-ui` 加入 `build.transpile`\n- 在客户端注册 overlay 上下文(供 `toast` / `message` 使用)\n\n### 根布局\n\n```vue\n<!-- app.vue -->\n<script setup lang=\"ts\">\nconst theme = ref<'light' | 'dark'>('light')\n</script>\n\n<template>\n <MConfigProvider :theme=\"theme\" density=\"comfortable\">\n <NuxtPage />\n </MConfigProvider>\n</template>\n```\n\n按需导入时无需 `app.use(MoryaUI)`;若需全量注册,可在 `plugins/morya-ui.client.ts` 中 `nuxtApp.vueApp.use(MoryaUI)`。\n\n### 仅客户端组件\n\n极少数依赖浏览器专有 API 的场景(如自定义 `appendTo` 到尚未存在的节点),可用 Nuxt 的 `<ClientOnly>` 包裹。\n\n## Astro + Vue\n\n适合 **静态页 + Vue 岛**(管理后台、控制台嵌入营销站)。\n\n### 安装\n\n```bash\npnpm add morya-ui\nnpx astro add vue\n```\n\n### 在 Vue 岛中使用\n\n```astro\n---\n// src/pages/admin.astro\nimport AdminShell from '../components/AdminShell.vue'\n---\n<AdminShell client:load />\n```\n\n```vue\n<!-- src/components/AdminShell.vue -->\n<script setup lang=\"ts\">\nimport { MButton, MConfigProvider } from 'morya-ui'\nimport 'morya-ui/styles.css'\n</script>\n\n<template>\n <MConfigProvider theme=\"light\">\n <MButton label=\"Hello\" />\n </MConfigProvider>\n</template>\n```\n\n- 交互型后台推荐 `client:load` 或 `client:only`\n- 纯展示块可用 `client:visible` 延迟水合\n- Astro 本身不做 Vue SSR 时,无需处理 hydration id 问题\n\n## Vite SSR(含自定义服务端)\n\n```ts\nimport { MConfigProvider } from 'morya-ui/config-provider'\n// main.server.ts / entry-server.ts\nimport { createSSRApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\nexport function createApp() {\n const app = createSSRApp(App)\n return { app }\n}\n```\n\n客户端入口可注册 overlay 插件:\n\n```ts\n// entry-client.ts\nimport { createMoryaUI } from 'morya-ui'\n\ncreateApp(/* ... */)\n .use(createMoryaUI({ components: false }))\n .mount('#app')\n```\n\n构建时确保 `morya-ui` 进入 `ssr.noExternal`(或 `ssr: { noExternal: ['morya-ui'] }`),以便正确处理 `.vue` 与 CSS 副作用。\n\n## 其他 Vue SSR 方案\n\n| 方案 | 说明 |\n| --- | --- |\n| **Quasar (SSR mode)** | 在 `quasar.config` 的 `build.transpileDependencies` 中加入 `morya-ui`,入口引入样式 |\n| **vite-plugin-ssr / vike** | 与 Vite SSR 相同:服务端渲染 + 客户端 `createMoryaUI({ components: false })` |\n| **Inertia + Vue SSR** | 根组件包 `MConfigProvider`;命令式 API 仅在 `onMounted` 后调用 |\n\n## 已知限制\n\n- **不支持 Vue 2**;SSR 仅适用于 Vue 3。\n- **IE** 不在支持范围内(与 Vue 3 一致)。\n- 主题 `localStorage` 持久化仅在浏览器生效;SSR 首屏使用 `MConfigProvider` 或 cookie 同步主题可避免闪动。\n- 全量 E2E SSR 回归仍在完善;若遇到 hydration 警告,请提供最小复现并 [提 Issue](https://github.com/morya-space/morya-ui/issues)。\n\n## 下一步\n\n- [快速上手](/docs/quick-start):安装与导入方式\n- [全局配置](/docs/config):`MConfigProvider`\n- [主题](/docs/theme):亮暗色与 token\n",
25097
25709
  "sections": [
25098
25710
  {
25099
25711
  "title": "",
@@ -25140,7 +25752,7 @@
25140
25752
  "en-US": {
25141
25753
  "title": "SSR & meta-frameworks",
25142
25754
  "description": "Use Morya UI with Nuxt, Astro, Vite SSR, and other server-rendered setups.",
25143
- "markdown": "---\ntitle: SSR & meta-frameworks\norder: 8\ndescription: Use Morya UI with Nuxt, Astro, Vite SSR, and other server-rendered setups.\n---\n\n# SSR & meta-frameworks\n\nMorya UI targets **Vue 3** SSR (3.5+ recommended): the server never touches `document` / `window`, instance ids stay stable across server and client, and imperative APIs (`toast` / `message` / `confirm`) no-op safely on the server.\n\nAll setups below are supported; choose **full SSR** or **client islands** based on your app.\n\n## Shared checklist\n\n| Topic | Recommendation |\n| --- | --- |\n| Styles | Import `morya-ui/styles.css` in app entry or framework config |\n| Theme | Prefer root **`MConfigProvider`** for `theme` / `density` instead of calling `useTheme()` alone during SSR |\n| Imperative APIs | `toast()`, `message()`, `confirm()` run in the browser only; SSR calls are safe no-ops |\n| On-demand | Use `morya-ui/resolver` with `unplugin-vue-components` |\n| Overlays | Dialog / Select / Tooltip use Vue `Teleport`; SSR renders placeholders, interaction hydrates on the client |\n\n## Nuxt 3\n\nUse the **`@morya-ui/nuxt`** module (`packages/nuxt` in this repo).\n\n### Install\n\n```bash\npnpm add morya-ui @morya-ui/nuxt\npnpm add -D unplugin-vue-components\n```\n\n### Config\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\n// nuxt.config.ts\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineNuxtConfig({\n modules: ['@morya-ui/nuxt'],\n vite: {\n plugins: [\n Components({\n resolvers: [MoryaUIResolver()],\n }),\n ],\n },\n})\n```\n\nThe module by default:\n\n- Adds `morya-ui/styles.css`\n- Transpiles `morya-ui` for SSR\n- Registers overlay app context on the client (for `toast` / `message`)\n\n### Root layout\n\n```vue\n<!-- app.vue -->\n<script setup lang=\"ts\">\nconst theme = ref<'light' | 'dark'>('light')\n</script>\n\n<template>\n <MConfigProvider :theme=\"theme\" density=\"comfortable\">\n <NuxtPage />\n </MConfigProvider>\n</template>\n```\n\nWith on-demand imports you do not need `app.use(MoryaUI)`; for full registration, add a client plugin with `nuxtApp.vueApp.use(MoryaUI)`.\n\n### Client-only islands\n\nWrap edge cases that need browser-only targets in `<ClientOnly>`.\n\n## Astro + Vue\n\nBest for **static sites + Vue islands** (admin shells embedded in marketing pages).\n\n### Install\n\n```bash\npnpm add morya-ui\nnpx astro add vue\n```\n\n### Vue island\n\n```astro\n---\nimport AdminShell from '../components/AdminShell.vue'\n---\n<AdminShell client:load />\n```\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton, MConfigProvider } from 'morya-ui'\nimport 'morya-ui/styles.css'\n</script>\n\n<template>\n <MConfigProvider theme=\"light\">\n <MButton label=\"Hello\" />\n </MConfigProvider>\n</template>\n```\n\nUse `client:load` or `client:only` for interactive admin UIs; `client:visible` for lazy hydration.\n\n## Vite SSR\n\n```ts\nimport { createSSRApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\nexport function createApp() {\n return { app: createSSRApp(App) }\n}\n```\n\nClient entry:\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\n\napp.use(createMoryaUI({ components: false })).mount('#app')\n```\n\nAdd `morya-ui` to `ssr.noExternal` so `.vue` and CSS side effects resolve correctly.\n\n## Other Vue SSR stacks\n\n| Stack | Notes |\n| --- | --- |\n| **Quasar SSR** | Add `morya-ui` to `build.transpileDependencies`; import styles in entry |\n| **vike / vite-plugin-ssr** | Same as Vite SSR |\n| **Inertia + Vue SSR** | Wrap with `MConfigProvider`; call imperative APIs after mount |\n\n## Limitations\n\n- **Vue 2 is not supported** (Vue 3 SSR only).\n- **IE** is out of scope.\n- Theme `localStorage` persistence is client-only; sync theme via `MConfigProvider` or cookies to avoid flash.\n- Full SSR E2E coverage is evolving; please [open an issue](https://github.com/morya-space/morya-ui/issues) with a minimal repro if you see hydration warnings.\n\n## Next\n\n- [Quick start](/docs/quick-start)\n- [Config](/docs/config)\n- [Theme](/docs/theme)\n",
25755
+ "markdown": "---\ntitle: SSR & meta-frameworks\norder: 9\ndescription: Use Morya UI with Nuxt, Astro, Vite SSR, and other server-rendered setups.\n---\n\n# SSR & meta-frameworks\n\nMorya UI targets **Vue 3** SSR (3.5+ recommended): the server never touches `document` / `window`, instance ids stay stable across server and client, and imperative APIs (`toast` / `message` / `confirm`) no-op safely on the server.\n\nAll setups below are supported; choose **full SSR** or **client islands** based on your app.\n\n## Shared checklist\n\n| Topic | Recommendation |\n| --- | --- |\n| Styles | Import `morya-ui/styles.css` in app entry or framework config |\n| Theme | Prefer root **`MConfigProvider`** for `theme` / `density` instead of calling `useTheme()` alone during SSR |\n| Imperative APIs | `toast()`, `message()`, `confirm()` run in the browser only; SSR calls are safe no-ops |\n| On-demand | Use `morya-ui/resolver` with `unplugin-vue-components` |\n| Overlays | Dialog / Select / Tooltip use Vue `Teleport`; SSR renders placeholders, interaction hydrates on the client |\n\n## Nuxt 3\n\nUse the **`@morya-ui/nuxt`** module (`packages/nuxt` in this repo).\n\n### Install\n\n```bash\npnpm add morya-ui @morya-ui/nuxt\npnpm add -D unplugin-vue-components\n```\n\n### Config\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\n// nuxt.config.ts\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineNuxtConfig({\n modules: ['@morya-ui/nuxt'],\n vite: {\n plugins: [\n Components({\n resolvers: [MoryaUIResolver()],\n }),\n ],\n },\n})\n```\n\nThe module by default:\n\n- Adds `morya-ui/styles.css`\n- Transpiles `morya-ui` for SSR\n- Registers overlay app context on the client (for `toast` / `message`)\n\n### Root layout\n\n```vue\n<!-- app.vue -->\n<script setup lang=\"ts\">\nconst theme = ref<'light' | 'dark'>('light')\n</script>\n\n<template>\n <MConfigProvider :theme=\"theme\" density=\"comfortable\">\n <NuxtPage />\n </MConfigProvider>\n</template>\n```\n\nWith on-demand imports you do not need `app.use(MoryaUI)`; for full registration, add a client plugin with `nuxtApp.vueApp.use(MoryaUI)`.\n\n### Client-only islands\n\nWrap edge cases that need browser-only targets in `<ClientOnly>`.\n\n## Astro + Vue\n\nBest for **static sites + Vue islands** (admin shells embedded in marketing pages).\n\n### Install\n\n```bash\npnpm add morya-ui\nnpx astro add vue\n```\n\n### Vue island\n\n```astro\n---\nimport AdminShell from '../components/AdminShell.vue'\n---\n<AdminShell client:load />\n```\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton, MConfigProvider } from 'morya-ui'\nimport 'morya-ui/styles.css'\n</script>\n\n<template>\n <MConfigProvider theme=\"light\">\n <MButton label=\"Hello\" />\n </MConfigProvider>\n</template>\n```\n\nUse `client:load` or `client:only` for interactive admin UIs; `client:visible` for lazy hydration.\n\n## Vite SSR\n\n```ts\nimport { createSSRApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\nexport function createApp() {\n return { app: createSSRApp(App) }\n}\n```\n\nClient entry:\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\n\napp.use(createMoryaUI({ components: false })).mount('#app')\n```\n\nAdd `morya-ui` to `ssr.noExternal` so `.vue` and CSS side effects resolve correctly.\n\n## Other Vue SSR stacks\n\n| Stack | Notes |\n| --- | --- |\n| **Quasar SSR** | Add `morya-ui` to `build.transpileDependencies`; import styles in entry |\n| **vike / vite-plugin-ssr** | Same as Vite SSR |\n| **Inertia + Vue SSR** | Wrap with `MConfigProvider`; call imperative APIs after mount |\n\n## Limitations\n\n- **Vue 2 is not supported** (Vue 3 SSR only).\n- **IE** is out of scope.\n- Theme `localStorage` persistence is client-only; sync theme via `MConfigProvider` or cookies to avoid flash.\n- Full SSR E2E coverage is evolving; please [open an issue](https://github.com/morya-space/morya-ui/issues) with a minimal repro if you see hydration warnings.\n\n## Next\n\n- [Quick start](/docs/quick-start)\n- [Config](/docs/config)\n- [Theme](/docs/theme)\n",
25144
25756
  "sections": [
25145
25757
  {
25146
25758
  "title": "",
@@ -25192,12 +25804,12 @@
25192
25804
  "titleEn": "Accessibility",
25193
25805
  "description": "使用 Morya UI 组件时的无障碍约定与检查清单。",
25194
25806
  "descriptionEn": "Accessibility conventions when using Morya UI components.",
25195
- "order": 9,
25807
+ "order": 10,
25196
25808
  "locales": {
25197
25809
  "zh-CN": {
25198
25810
  "title": "无障碍",
25199
25811
  "description": "使用 Morya UI 组件时的无障碍约定与检查清单。",
25200
- "markdown": "---\ntitle: 无障碍\norder: 9\ndescription: 使用 Morya UI 组件时的无障碍约定与检查清单。\n---\n\n# 无障碍\n\nMorya UI 以**语义化 HTML 优先、必要时补充 ARIA**为原则。组件尽量自带标签关联、键盘路径与浮层焦点管理;业务侧仍需提供有意义的文案与结构。\n\n## 快速检查清单\n\n| 场景 | 建议 |\n| --- | --- |\n| 图标按钮 | 设置 `aria-label` 或可见文本,勿仅靠图标传达含义 |\n| 表单字段 | 使用 `label`;错误时用 `invalid` + `error-message` |\n| 装饰性图标 | 省略 `label`,组件会使用 `aria-hidden` |\n| 浮层 / 对话框 | 确认 Esc 可关闭;打开后焦点在面板内 |\n| 动效敏感用户 | 使用 `useMotion()` 设为 `reduced` 或 `none` |\n| 仅颜色区分状态 | 同时提供文案、图标或 `error-message` |\n\n## 表单与校验\n\n输入类组件(`Input`、`Textarea`、`Select` 等)共享字段模式:\n\n```vue\n<MInput\n id=\"email\"\n v-model=\"email\"\n label=\"邮箱\"\n invalid\n error-message=\"请输入有效邮箱\"\n/>\n```\n\n要点:\n\n- **`label`** 会关联到控件;配合 `FloatLabel` 时也会写入 `for`。\n- **`invalid`** 会设置 `aria-invalid` 与错误样式。\n- **`error-message`** 会通过 `aria-describedby` 关联帮助/错误区域。\n- 必填请同时使用原生 `required`(若组件支持)或业务层校验提示,不要只用颜色表达。\n\n## 图标与按钮\n\n`MIcon` 仅承载**系统图标**。无 `label` 时视为装饰并隐藏;信息性图标请传 `label`:\n\n```vue\n<MIcon name=\"info\" label=\"更多信息\" />\n<MButton icon=\"search\" aria-label=\"搜索\" icon-only />\n```\n\n带文字的按钮优先用默认插槽或 `label`,不必重复 `aria-label`。\n\n## 浮层与焦点\n\n以下组件默认 Teleport 到 `body`,并在打开时锁定滚动、支持 `Escape` 关闭:\n\n- `Dialog`、`Drawer`、`CommandMenu`\n- `Select`、`Popover`、`Tooltip`(按组件实现)\n\n弹出层触发器应设置:\n\n- `aria-expanded` / `aria-controls`(如 `Popover`)\n- 可见标签或 `aria-label`\n\n模态对话框打开后,焦点应落在可交互元素上;关闭后宜将焦点还原到触发器(业务层使用 `Dialog` 时可自行管理)。\n\n## 键盘交互\n\n| 组件 | 常用按键 |\n| --- | --- |\n| `CommandMenu` | `↑`/`↓` 选择,`Enter` 执行,`Esc` 关闭 |\n| `Select` | `Enter`/`Space` 打开,`↑`/`↓` 移动选项,`Esc` 关闭 |\n| `Tabs` | 方向键在 Tab 列表间移动(实现依组件) |\n| `Slider` | 方向键调整值;可通过 `aria-label` 命名 |\n\n具体行为以各组件文档为准;新增组件请在 `docs/` 中说明键盘表。\n\n## 动效与对比度\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { setMotion } = useMotion()\nsetMotion('reduced') // 或 'none'\n```\n\n`reduced` / `none` 会缩短或关闭 `--m-motion-*` 过渡,减轻 vestibular 不适。\n\n颜色应通过 `--m-color-*` 令牌消费,以保证亮/暗主题下对比度一致。自定义主题后请在真实内容上抽查正文与错误态可读性。\n\n## 组件库内已知实践\n\n近期实现/改进包括:\n\n- **FloatLabel**:`label[for]` 关联首个输入控件\n- **Popover**:触发器 `aria-expanded` / `aria-haspopup` / `aria-controls`\n- **Slider**:单 thumb 默认 `aria-label`(可通过 prop 覆盖)\n- **Select / CascadeSelect / TreeSelect / DatePicker**:`combobox` 语义、键盘导航与字段反馈(`invalid` / `error-message` / `help-text`)\n\n## 测试建议\n\n- 使用键盘完成主流程(Tab、Enter、Esc、方向键)。\n- 使用系统屏幕阅读器(NVDA / VoiceOver)抽查表单与对话框。\n- 在 `prefers-reduced-motion: reduce` 或 `useMotion('none')` 下确认界面仍可用。\n\n## 相关\n\n- [主题](/docs/theme):动效偏好与令牌\n- [全局配置](/docs/config):语言包与默认尺寸\n",
25812
+ "markdown": "---\ntitle: 无障碍\norder: 10\ndescription: 使用 Morya UI 组件时的无障碍约定与检查清单。\n---\n\n# 无障碍\n\nMorya UI 以**语义化 HTML 优先、必要时补充 ARIA**为原则。组件尽量自带标签关联、键盘路径与浮层焦点管理;业务侧仍需提供有意义的文案与结构。\n\n## 快速检查清单\n\n| 场景 | 建议 |\n| --- | --- |\n| 图标按钮 | 设置 `aria-label` 或可见文本,勿仅靠图标传达含义 |\n| 表单字段 | 使用 `label`;错误时用 `invalid` + `error-message` |\n| 装饰性图标 | 省略 `label`,组件会使用 `aria-hidden` |\n| 浮层 / 对话框 | 确认 Esc 可关闭;打开后焦点在面板内 |\n| 动效敏感用户 | 使用 `useMotion()` 设为 `reduced` 或 `none` |\n| 仅颜色区分状态 | 同时提供文案、图标或 `error-message` |\n\n## 表单与校验\n\n输入类组件(`Input`、`Textarea`、`Select` 等)共享字段模式:\n\n```vue\n<MInput\n id=\"email\"\n v-model=\"email\"\n label=\"邮箱\"\n invalid\n error-message=\"请输入有效邮箱\"\n/>\n```\n\n要点:\n\n- **`label`** 会关联到控件;配合 `FloatLabel` 时也会写入 `for`。\n- **`invalid`** 会设置 `aria-invalid` 与错误样式。\n- **`error-message`** 会通过 `aria-describedby` 关联帮助/错误区域。\n- 必填请同时使用原生 `required`(若组件支持)或业务层校验提示,不要只用颜色表达。\n\n## 图标与按钮\n\n`MIcon` 仅承载**系统图标**。无 `label` 时视为装饰并隐藏;信息性图标请传 `label`:\n\n```vue\n<MIcon name=\"info\" label=\"更多信息\" />\n<MButton icon=\"search\" aria-label=\"搜索\" icon-only />\n```\n\n带文字的按钮优先用默认插槽或 `label`,不必重复 `aria-label`。\n\n## 浮层与焦点\n\n以下组件默认 Teleport 到 `body`,并在打开时锁定滚动、支持 `Escape` 关闭:\n\n- `Dialog`、`Drawer`、`CommandMenu`\n- `Select`、`Popover`、`Tooltip`(按组件实现)\n\n弹出层触发器应设置:\n\n- `aria-expanded` / `aria-controls`(如 `Popover`)\n- 可见标签或 `aria-label`\n\n模态对话框打开后,焦点应落在可交互元素上;关闭后宜将焦点还原到触发器(业务层使用 `Dialog` 时可自行管理)。\n\n## 键盘交互\n\n| 组件 | 常用按键 |\n| --- | --- |\n| `CommandMenu` | `↑`/`↓` 选择,`Enter` 执行,`Esc` 关闭 |\n| `Select` | `Enter`/`Space` 打开,`↑`/`↓` 移动选项,`Esc` 关闭 |\n| `Tabs` | 方向键在 Tab 列表间移动(实现依组件) |\n| `Slider` | 方向键调整值;可通过 `aria-label` 命名 |\n\n具体行为以各组件文档为准;新增组件请在 `docs/` 中说明键盘表。\n\n## 动效与对比度\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { setMotion } = useMotion()\nsetMotion('reduced') // 或 'none'\n```\n\n`reduced` / `none` 会缩短或关闭 `--m-motion-*` 过渡,减轻 vestibular 不适。\n\n颜色应通过 `--m-color-*` 令牌消费,以保证亮/暗主题下对比度一致。自定义主题后请在真实内容上抽查正文与错误态可读性。\n\n## 组件库内已知实践\n\n近期实现/改进包括:\n\n- **FloatLabel**:`label[for]` 关联首个输入控件\n- **Popover**:触发器 `aria-expanded` / `aria-haspopup` / `aria-controls`\n- **Slider**:单 thumb 默认 `aria-label`(可通过 prop 覆盖)\n- **Select / CascadeSelect / TreeSelect / DatePicker**:`combobox` 语义、键盘导航与字段反馈(`invalid` / `error-message` / `help-text`)\n\n## 测试建议\n\n- 使用键盘完成主流程(Tab、Enter、Esc、方向键)。\n- 使用系统屏幕阅读器(NVDA / VoiceOver)抽查表单与对话框。\n- 在 `prefers-reduced-motion: reduce` 或 `useMotion('none')` 下确认界面仍可用。\n\n## 相关\n\n- [主题](/docs/theme):动效偏好与令牌\n- [全局配置](/docs/config):语言包与默认尺寸\n",
25201
25813
  "sections": [
25202
25814
  {
25203
25815
  "title": "",
@@ -25254,7 +25866,7 @@
25254
25866
  "en-US": {
25255
25867
  "title": "Accessibility",
25256
25868
  "description": "Accessibility conventions when using Morya UI components.",
25257
- "markdown": "---\ntitle: Accessibility\norder: 9\ndescription: Accessibility conventions when using Morya UI components.\n---\n\n# Accessibility\n\nMorya UI favors **semantic HTML first, ARIA when necessary**. Components handle labels, keyboard paths, and overlay focus where possible; apps still must supply meaningful copy and structure.\n\n## Quick checklist\n\n| Scenario | Guidance |\n| --- | --- |\n| Icon-only buttons | Set `aria-label` or visible text—do not rely on icon shape alone |\n| Form fields | Use `label`; on failure use `invalid` + `error-message` |\n| Decorative icons | Omit `label`; the icon is `aria-hidden` |\n| Overlays / dialogs | Ensure Escape closes; focus stays manageable while open |\n| Motion sensitivity | Use `useMotion()` with `reduced` or `none` |\n| Status by color only | Add text, icons, or `error-message` |\n\n## Forms and validation\n\nInput-family components (`Input`, `Textarea`, `Select`, …) share the same field pattern:\n\n```vue\n<MInput\n id=\"email\"\n v-model=\"email\"\n label=\"Email\"\n invalid\n error-message=\"Enter a valid email address\"\n/>\n```\n\nNotes:\n\n- **`label`** wires to the control; `FloatLabel` also sets `for` on the label element.\n- **`invalid`** sets `aria-invalid` and error styling.\n- **`error-message`** is linked through `aria-describedby`.\n- Mark required fields with native `required` when supported **and** validation copy—not color alone.\n\n## Icons and buttons\n\n`MIcon` covers **system icons** only. Without `label` the icon is decorative (`aria-hidden`); informative icons need `label`:\n\n```vue\n<MIcon name=\"info\" label=\"More information\" />\n<MButton icon=\"search\" aria-label=\"Search\" icon-only />\n```\n\nPrefer default slot / `label` text on buttons; avoid duplicating `aria-label` when visible text exists.\n\n## Overlays and focus\n\nThese default to Teleport on `body`, block scroll while open, and close on Escape where applicable:\n\n- `Dialog`, `Drawer`, `CommandMenu`\n- `Select`, `Popover`, `Tooltip` (per component)\n\nTriggers should expose:\n\n- `aria-expanded` / `aria-controls` (e.g. `Popover`)\n- Visible text or `aria-label`\n\nAfter closing a modal, return focus to the trigger when your UX requires it.\n\n## Keyboard\n\n| Component | Keys |\n| --- | --- |\n| `CommandMenu` | `↑`/`↓` move, `Enter` run, `Esc` close |\n| `Select` | `Enter`/`Space` open, `↑`/`↓` options, `Esc` close |\n| `Tabs` | Arrow keys between tabs (see component doc) |\n| `Slider` | Arrow keys adjust value; override naming with `aria-label` |\n\nDocument keyboard tables in component `docs/` when adding new widgets.\n\n## Motion and contrast\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { setMotion } = useMotion()\nsetMotion('reduced') // or 'none'\n```\n\n`reduced` / `none` shortens or disables `--m-motion-*` transitions.\n\nConsume colors through `--m-color-*` tokens for light/dark parity. After theming, spot-check body text and error states on real content.\n\n## In-library improvements\n\nRecent work includes:\n\n- **FloatLabel**: `label[for]` linked to the first input\n- **Popover**: trigger `aria-expanded` / `aria-haspopup` / `aria-controls`\n- **Slider**: default `aria-label` on a single thumb (overridable)\n- **Select / CascadeSelect / TreeSelect / DatePicker**: combobox semantics, keyboard navigation, and field feedback (`invalid` / `error-message` / `help-text`)\n\n## Testing tips\n\n- Complete primary flows with keyboard only (Tab, Enter, Esc, arrows).\n- Spot-check forms and dialogs with NVDA or VoiceOver.\n- Verify usability under `prefers-reduced-motion: reduce` or `useMotion('none')`.\n\n## See also\n\n- [Theme](/docs/theme): motion preference and tokens\n- [Configuration](/docs/config): locale and defaults\n",
25869
+ "markdown": "---\ntitle: Accessibility\norder: 10\ndescription: Accessibility conventions when using Morya UI components.\n---\n\n# Accessibility\n\nMorya UI favors **semantic HTML first, ARIA when necessary**. Components handle labels, keyboard paths, and overlay focus where possible; apps still must supply meaningful copy and structure.\n\n## Quick checklist\n\n| Scenario | Guidance |\n| --- | --- |\n| Icon-only buttons | Set `aria-label` or visible text—do not rely on icon shape alone |\n| Form fields | Use `label`; on failure use `invalid` + `error-message` |\n| Decorative icons | Omit `label`; the icon is `aria-hidden` |\n| Overlays / dialogs | Ensure Escape closes; focus stays manageable while open |\n| Motion sensitivity | Use `useMotion()` with `reduced` or `none` |\n| Status by color only | Add text, icons, or `error-message` |\n\n## Forms and validation\n\nInput-family components (`Input`, `Textarea`, `Select`, …) share the same field pattern:\n\n```vue\n<MInput\n id=\"email\"\n v-model=\"email\"\n label=\"Email\"\n invalid\n error-message=\"Enter a valid email address\"\n/>\n```\n\nNotes:\n\n- **`label`** wires to the control; `FloatLabel` also sets `for` on the label element.\n- **`invalid`** sets `aria-invalid` and error styling.\n- **`error-message`** is linked through `aria-describedby`.\n- Mark required fields with native `required` when supported **and** validation copy—not color alone.\n\n## Icons and buttons\n\n`MIcon` covers **system icons** only. Without `label` the icon is decorative (`aria-hidden`); informative icons need `label`:\n\n```vue\n<MIcon name=\"info\" label=\"More information\" />\n<MButton icon=\"search\" aria-label=\"Search\" icon-only />\n```\n\nPrefer default slot / `label` text on buttons; avoid duplicating `aria-label` when visible text exists.\n\n## Overlays and focus\n\nThese default to Teleport on `body`, block scroll while open, and close on Escape where applicable:\n\n- `Dialog`, `Drawer`, `CommandMenu`\n- `Select`, `Popover`, `Tooltip` (per component)\n\nTriggers should expose:\n\n- `aria-expanded` / `aria-controls` (e.g. `Popover`)\n- Visible text or `aria-label`\n\nAfter closing a modal, return focus to the trigger when your UX requires it.\n\n## Keyboard\n\n| Component | Keys |\n| --- | --- |\n| `CommandMenu` | `↑`/`↓` move, `Enter` run, `Esc` close |\n| `Select` | `Enter`/`Space` open, `↑`/`↓` options, `Esc` close |\n| `Tabs` | Arrow keys between tabs (see component doc) |\n| `Slider` | Arrow keys adjust value; override naming with `aria-label` |\n\nDocument keyboard tables in component `docs/` when adding new widgets.\n\n## Motion and contrast\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { setMotion } = useMotion()\nsetMotion('reduced') // or 'none'\n```\n\n`reduced` / `none` shortens or disables `--m-motion-*` transitions.\n\nConsume colors through `--m-color-*` tokens for light/dark parity. After theming, spot-check body text and error states on real content.\n\n## In-library improvements\n\nRecent work includes:\n\n- **FloatLabel**: `label[for]` linked to the first input\n- **Popover**: trigger `aria-expanded` / `aria-haspopup` / `aria-controls`\n- **Slider**: default `aria-label` on a single thumb (overridable)\n- **Select / CascadeSelect / TreeSelect / DatePicker**: combobox semantics, keyboard navigation, and field feedback (`invalid` / `error-message` / `help-text`)\n\n## Testing tips\n\n- Complete primary flows with keyboard only (Tab, Enter, Esc, arrows).\n- Spot-check forms and dialogs with NVDA or VoiceOver.\n- Verify usability under `prefers-reduced-motion: reduce` or `useMotion('none')`.\n\n## See also\n\n- [Theme](/docs/theme): motion preference and tokens\n- [Configuration](/docs/config): locale and defaults\n",
25258
25870
  "sections": [
25259
25871
  {
25260
25872
  "title": "",
@@ -25314,81 +25926,61 @@
25314
25926
  "id": "ai-setup",
25315
25927
  "title": "AI 接入",
25316
25928
  "titleEn": "AI setup",
25317
- "description": "用 @morya-ui/setup 一键安装组件库、Agent Skill、Cursor 规则与 MCP。",
25318
- "descriptionEn": "One-shot install of the library, Agent skill, Cursor rules, and MCP via @morya-ui/setup.",
25319
- "order": 9,
25929
+ "description": "用 AI 生成业务页面时,如何配合 @morya-ui/setupAgent Skill MCP。",
25930
+ "descriptionEn": "How @morya-ui/setup, Agent skill, and MCP work together for AI-assisted pages.",
25931
+ "order": 11,
25320
25932
  "locales": {
25321
25933
  "zh-CN": {
25322
25934
  "title": "AI 接入",
25323
- "description": "用 @morya-ui/setup 一键安装组件库、Agent Skill、Cursor 规则与 MCP。",
25324
- "markdown": "---\ntitle: AI 接入\norder: 9\ndescription: 用 @morya-ui/setup 一键安装组件库、Agent Skill、Cursor 规则与 MCP。\n---\n\n# AI 接入\n\n面向 **用 AI 生成业务页面** 的业务项目。推荐用 [`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) 一次装好组件库与 AI 侧配置;日常手写代码仍可只 `pnpm add morya-ui`。\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完成后 **重启 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 --skip-install --skip-template --skip-styles --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\n模板源在仓库 [`ai-design-config/`](https://github.com/morya-space/morya-ui/tree/main/ai-design-config);CLI 细节见 [`packages/setup`](https://github.com/morya-space/morya-ui/tree/main/packages/setup)。\n\n## 与 Skill / MCP 的关系\n\n- **Setup**:一次性把库 + AI 配置装进项目 \n- **[Agent Skill](/docs/agent-skill)**:按需指导如何用 `morya-ui` 做页面 \n- **MCP**:运行时检索真实组件 API / 示例 \n\n工具列表与多客户端配置见 [Agent MCP](/docs/mcp)。只想手写配置 MCP、不跑 setup 时,也可直接按该页操作。\n\n## 下一步\n\n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 何时用、表面地图 \n- [Agent MCP](/docs/mcp):工具与客户端配置 \n- [快速上手](/docs/quick-start):手写安装与最小示例 \n- [组件](/components):浏览 API 与预览\n",
25935
+ "description": "用 AI 生成业务页面时,如何配合 @morya-ui/setupAgent Skill MCP。",
25936
+ "markdown": "---\ntitle: AI 接入\norder: 11\ndescription: 用 AI 生成业务页面时,如何配合 @morya-ui/setupAgent Skill MCP。\n---\n\n# AI 接入\n\n面向 **用 AI 生成业务页面** 的业务项目。先用 [`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) 把库与 AI 配置装进项目(命令与选项见 [一键接入](/docs/setup)),再按本文约定生成页面。\n\n日常手写代码仍可只 `pnpm add morya-ui`,见 [快速上手](/docs/quick-start)。\n\n## 推荐流程\n\n1. 在业务项目根目录执行 `npx @morya-ui/setup`(或已装库时用 `npx @morya-ui/setup ai`)\n2. **重启 Cursor**(或重载 MCP)\n3. 生成页面前让 Agent 先读 `DESIGN.md`,需要时再读黄金样例与 [Agent Skill](/docs/agent-skill)\n4. 不确定组件 API 时走 [Agent MCP](/docs/mcp),不要臆造 props\n\n## 与 Skill / MCP 的关系\n\n- **[一键接入](/docs/setup)**:把库与 AI 配置写入项目 \n- **[Agent Skill](/docs/agent-skill)**:按需指导如何用 `morya-ui` 做页面 \n- **MCP**:运行时检索真实组件 API / 示例 \n\n工具列表与多客户端配置见 [Agent MCP](/docs/mcp)。也可以不跑 setup,按该页手写 MCP。\n\n## 下一步\n\n- [一键接入](/docs/setup):`@morya-ui/setup` 命令与落地文件 \n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 何时用、表面地图 \n- [Agent MCP](/docs/mcp):工具与客户端配置 \n- [快速上手](/docs/quick-start):手写安装与最小示例 \n- [组件](/components):浏览 API 与预览\n",
25325
25937
  "sections": [
25326
25938
  {
25327
25939
  "title": "",
25328
25940
  "id": "overview",
25329
- "body": "# AI 接入\n\n面向 **用 AI 生成业务页面** 的业务项目。推荐用 [`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) 一次装好组件库与 AI 侧配置;日常手写代码仍可只 `pnpm add morya-ui`。"
25941
+ "body": "# AI 接入\n\n面向 **用 AI 生成业务页面** 的业务项目。先用 [`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) 把库与 AI 配置装进项目(命令与选项见 [一键接入](/docs/setup)),再按本文约定生成页面。\n\n日常手写代码仍可只 `pnpm add morya-ui`,见 [快速上手](/docs/quick-start)。"
25330
25942
  },
25331
25943
  {
25332
- "title": "一键命令",
25333
- "id": "一键命令",
25334
- "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完成后 **重启 Cursor**(或重载 MCP),生成页面前让 Agent 先读 `DESIGN.md`。"
25335
- },
25336
- {
25337
- "title": "常用选项",
25338
- "id": "常用选项",
25339
- "body": "| 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 --skip-install --skip-template --skip-styles --skip-scripts\n```"
25340
- },
25341
- {
25342
- "title": "会落到项目里的内容",
25343
- "id": "会落到项目里的内容",
25344
- "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\n模板源在仓库 [`ai-design-config/`](https://github.com/morya-space/morya-ui/tree/main/ai-design-config);CLI 细节见 [`packages/setup`](https://github.com/morya-space/morya-ui/tree/main/packages/setup)。"
25944
+ "title": "推荐流程",
25945
+ "id": "推荐流程",
25946
+ "body": "1. 在业务项目根目录执行 `npx @morya-ui/setup`(或已装库时用 `npx @morya-ui/setup ai`)\n2. **重启 Cursor**(或重载 MCP)\n3. 生成页面前让 Agent 先读 `DESIGN.md`,需要时再读黄金样例与 [Agent Skill](/docs/agent-skill)\n4. 不确定组件 API 时走 [Agent MCP](/docs/mcp),不要臆造 props"
25345
25947
  },
25346
25948
  {
25347
25949
  "title": "与 Skill / MCP 的关系",
25348
25950
  "id": "与-skill-mcp-的关系",
25349
- "body": "- **Setup**:一次性把库 + AI 配置装进项目 \n- **[Agent Skill](/docs/agent-skill)**:按需指导如何用 `morya-ui` 做页面 \n- **MCP**:运行时检索真实组件 API / 示例 \n\n工具列表与多客户端配置见 [Agent MCP](/docs/mcp)。只想手写配置 MCP、不跑 setup 时,也可直接按该页操作。"
25951
+ "body": "- **[一键接入](/docs/setup)**:把库与 AI 配置写入项目 \n- **[Agent Skill](/docs/agent-skill)**:按需指导如何用 `morya-ui` 做页面 \n- **MCP**:运行时检索真实组件 API / 示例 \n\n工具列表与多客户端配置见 [Agent MCP](/docs/mcp)。也可以不跑 setup,按该页手写 MCP。"
25350
25952
  },
25351
25953
  {
25352
25954
  "title": "下一步",
25353
25955
  "id": "下一步",
25354
- "body": "- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 何时用、表面地图 \n- [Agent MCP](/docs/mcp):工具与客户端配置 \n- [快速上手](/docs/quick-start):手写安装与最小示例 \n- [组件](/components):浏览 API 与预览"
25956
+ "body": "- [一键接入](/docs/setup):`@morya-ui/setup` 命令与落地文件 \n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 何时用、表面地图 \n- [Agent MCP](/docs/mcp):工具与客户端配置 \n- [快速上手](/docs/quick-start):手写安装与最小示例 \n- [组件](/components):浏览 API 与预览"
25355
25957
  }
25356
25958
  ]
25357
25959
  },
25358
25960
  "en-US": {
25359
25961
  "title": "AI setup",
25360
- "description": "One-shot install of the library, Agent skill, Cursor rules, and MCP via @morya-ui/setup.",
25361
- "markdown": "---\ntitle: AI setup\norder: 9\ndescription: One-shot install of the library, Agent skill, Cursor rules, and MCP via @morya-ui/setup.\n---\n\n# AI setup\n\nFor **AI-assisted page generation** in consumer apps. Prefer [`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) to install the library and AI config together. Hand-written apps can still use only `pnpm add morya-ui`.\n\n## One command\n\nFrom the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\nThis 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'` into the app entry\n5. Add a `check:colors` script when missing\n\nThen **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, library already installed:\n\n```bash\nnpx @morya-ui/setup --skip-install --skip-template --skip-styles --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\nTemplate source: [`ai-design-config/`](https://github.com/morya-space/morya-ui/tree/main/ai-design-config). CLI details: [`packages/setup`](https://github.com/morya-space/morya-ui/tree/main/packages/setup).\n\n## Relation to Skill / MCP\n\n- **Setup**: one-shot project onboarding (library + AI config)\n- **[Agent Skill](/docs/agent-skill)**: on-demand guidance for building pages with `morya-ui`\n- **MCP**: runtime doc lookup for AI clients\n\nTools and multi-client configs: [Agent MCP](/docs/mcp). You can configure MCP by hand from that page without running setup.\n\n## Next steps\n\n- [Agent Skill](/docs/agent-skill): when to use `morya-ui-pages`, surface map\n- [Agent MCP](/docs/mcp): tools and client config\n- [Quick start](/docs/quick-start): manual install and a minimal example\n- [Components](/components): browse APIs and previews",
25962
+ "description": "How @morya-ui/setup, Agent skill, and MCP work together for AI-assisted pages.",
25963
+ "markdown": "---\ntitle: AI setup\norder: 11\ndescription: How @morya-ui/setup, Agent skill, and MCP work together for AI-assisted pages.\n---\n\n# AI setup\n\nFor **AI-assisted page generation** in consumer apps. Install the library and AI config with [`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) (commands and options: [One-shot setup](/docs/setup)), then follow this page when generating pages.\n\nHand-written apps can still use only `pnpm add morya-ui` see [Quick start](/docs/quick-start).\n\n## Recommended flow\n\n1. From the app root run `npx @morya-ui/setup` (or `npx @morya-ui/setup ai` if the library is already installed)\n2. **Restart Cursor** (or reload MCP)\n3. Have the agent read `DESIGN.md` before generating pages; use golden pages and [Agent Skill](/docs/agent-skill) as needed\n4. Look up real APIs via [Agent MCP](/docs/mcp) do not invent props\n\n## Relation to Skill / MCP\n\n- **[One-shot setup](/docs/setup)**: write the library and AI config into the project \n- **[Agent Skill](/docs/agent-skill)**: on-demand guidance for building pages with `morya-ui` \n- **MCP**: runtime doc lookup for AI clients \n\nTools and multi-client configs: [Agent MCP](/docs/mcp). You can configure MCP by hand from that page without running setup.\n\n## Next steps\n\n- [One-shot setup](/docs/setup): `@morya-ui/setup` commands and files \n- [Agent Skill](/docs/agent-skill): when to use `morya-ui-pages`, surface map \n- [Agent MCP](/docs/mcp): tools and client config \n- [Quick start](/docs/quick-start): manual install and a minimal example \n- [Components](/components): browse APIs and previews\n",
25362
25964
  "sections": [
25363
25965
  {
25364
25966
  "title": "",
25365
25967
  "id": "overview",
25366
- "body": "# AI setup\n\nFor **AI-assisted page generation** in consumer apps. Prefer [`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) to install the library and AI config together. Hand-written apps can still use only `pnpm add morya-ui`."
25968
+ "body": "# AI setup\n\nFor **AI-assisted page generation** in consumer apps. Install the library and AI config with [`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) (commands and options: [One-shot setup](/docs/setup)), then follow this page when generating pages.\n\nHand-written apps can still use only `pnpm add morya-ui` — see [Quick start](/docs/quick-start)."
25367
25969
  },
25368
25970
  {
25369
- "title": "One command",
25370
- "id": "one-command",
25371
- "body": "From the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\nThis 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'` into the app entry\n5. Add a `check:colors` script when missing\n\nThen **restart Cursor** (or reload MCP). Have the agent read `DESIGN.md` before generating pages."
25372
- },
25373
- {
25374
- "title": "Options",
25375
- "id": "options",
25376
- "body": "| 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, library already installed:\n\n```bash\nnpx @morya-ui/setup --skip-install --skip-template --skip-styles --skip-scripts\n```"
25377
- },
25378
- {
25379
- "title": "What lands in the project",
25380
- "id": "what-lands-in-the-project",
25381
- "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\nTemplate source: [`ai-design-config/`](https://github.com/morya-space/morya-ui/tree/main/ai-design-config). CLI details: [`packages/setup`](https://github.com/morya-space/morya-ui/tree/main/packages/setup)."
25971
+ "title": "Recommended flow",
25972
+ "id": "recommended-flow",
25973
+ "body": "1. From the app root run `npx @morya-ui/setup` (or `npx @morya-ui/setup ai` if the library is already installed)\n2. **Restart Cursor** (or reload MCP)\n3. Have the agent read `DESIGN.md` before generating pages; use golden pages and [Agent Skill](/docs/agent-skill) as needed\n4. Look up real APIs via [Agent MCP](/docs/mcp) do not invent props"
25382
25974
  },
25383
25975
  {
25384
25976
  "title": "Relation to Skill / MCP",
25385
25977
  "id": "relation-to-skill-mcp",
25386
- "body": "- **Setup**: one-shot project onboarding (library + AI config)\n- **[Agent Skill](/docs/agent-skill)**: on-demand guidance for building pages with `morya-ui`\n- **MCP**: runtime doc lookup for AI clients\n\nTools and multi-client configs: [Agent MCP](/docs/mcp). You can configure MCP by hand from that page without running setup."
25978
+ "body": "- **[One-shot setup](/docs/setup)**: write the library and AI config into the project \n- **[Agent Skill](/docs/agent-skill)**: on-demand guidance for building pages with `morya-ui` \n- **MCP**: runtime doc lookup for AI clients \n\nTools and multi-client configs: [Agent MCP](/docs/mcp). You can configure MCP by hand from that page without running setup."
25387
25979
  },
25388
25980
  {
25389
25981
  "title": "Next steps",
25390
25982
  "id": "next-steps",
25391
- "body": "- [Agent Skill](/docs/agent-skill): when to use `morya-ui-pages`, surface map\n- [Agent MCP](/docs/mcp): tools and client config\n- [Quick start](/docs/quick-start): manual install and a minimal example\n- [Components](/components): browse APIs and previews"
25983
+ "body": "- [One-shot setup](/docs/setup): `@morya-ui/setup` commands and files \n- [Agent Skill](/docs/agent-skill): when to use `morya-ui-pages`, surface map \n- [Agent MCP](/docs/mcp): tools and client config \n- [Quick start](/docs/quick-start): manual install and a minimal example \n- [Components](/components): browse APIs and previews"
25392
25984
  }
25393
25985
  ]
25394
25986
  }
@@ -25400,22 +25992,22 @@
25400
25992
  "titleEn": "Agent Skill",
25401
25993
  "description": "消费方 morya-ui-pages skill:何时触发、与 rules/MCP 分工、页面类型地图。",
25402
25994
  "descriptionEn": "Consumer morya-ui-pages skill — when it triggers, vs rules/MCP, and the surface map.",
25403
- "order": 10,
25995
+ "order": 12,
25404
25996
  "locales": {
25405
25997
  "zh-CN": {
25406
25998
  "title": "Agent Skill",
25407
25999
  "description": "消费方 morya-ui-pages skill:何时触发、与 rules/MCP 分工、页面类型地图。",
25408
- "markdown": "---\ntitle: Agent Skill\norder: 10\ndescription: 消费方 morya-ui-pages skill:何时触发、与 rules/MCP 分工、页面类型地图。\n---\n\n# Agent Skill\n\n消费方用 AI 生成 **基于 `morya-ui` 的业务页面** 时,应加载 **`morya-ui-pages`** skill。它规定组件契约、页面类型与工作流;**不是**组件库源码里写新组件用的 skill。\n\n安装方式见 [AI 接入](/docs/ai-setup)(`npx @morya-ui/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源文件在仓库 [`ai-design-config/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/ai-design-config/.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| [AI 接入](/docs/ai-setup) / `@morya-ui/setup` | 一次性把库 + skill + rules + MCP 装进项目 |\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- [AI 接入](/docs/ai-setup):安装 skill 与其它 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",
25409
26001
  "sections": [
25410
26002
  {
25411
26003
  "title": "",
25412
26004
  "id": "overview",
25413
- "body": "# Agent Skill\n\n消费方用 AI 生成 **基于 `morya-ui` 的业务页面** 时,应加载 **`morya-ui-pages`** skill。它规定组件契约、页面类型与工作流;**不是**组件库源码里写新组件用的 skill。\n\n安装方式见 [AI 接入](/docs/ai-setup)(`npx @morya-ui/setup` 会复制到项目)。本文说明 skill **是什么、何时用、和其它配置怎么分工**。"
26005
+ "body": "# 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 **是什么、何时用、和其它配置怎么分工**。"
25414
26006
  },
25415
26007
  {
25416
26008
  "title": "装到哪里",
25417
26009
  "id": "装到哪里",
25418
- "body": "```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # 布局、表面、令牌、反馈、检查清单等\n```\n\n支持 Agent Skills 自动发现的客户端(如 Cursor)会从 `.agents/skills` 读取。生成列表 / 表单 / 登录 / 落地等页面前,应优先匹配本 skill。\n\n源文件在仓库 [`ai-design-config/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/ai-design-config/.agents/skills/morya-ui-pages),随 `@morya-ui/setup` 的 template 同步。"
26010
+ "body": "```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 同步。"
25419
26011
  },
25420
26012
  {
25421
26013
  "title": "何时触发",
@@ -25425,7 +26017,7 @@
25425
26017
  {
25426
26018
  "title": "与其它配置的分工",
25427
26019
  "id": "与其它配置的分工",
25428
- "body": "| 层 | 角色 |\n| --- | --- |\n| [AI 接入](/docs/ai-setup) / `@morya-ui/setup` | 一次性把库 + skill + rules + MCP 装进项目 |\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. **工艺** — 先定表面类型,再做视觉;后台偏克制,落地 / 品牌向可有意表达,但仍上令牌、上组件"
26020
+ "body": "| 层 | 角色 |\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. **工艺** — 先定表面类型,再做视觉;后台偏克制,落地 / 品牌向可有意表达,但仍上令牌、上组件"
25429
26021
  },
25430
26022
  {
25431
26023
  "title": "页面类型(Surface)地图",
@@ -25435,29 +26027,29 @@
25435
26027
  {
25436
26028
  "title": "Agent 推荐工作流(摘要)",
25437
26029
  "id": "agent-推荐工作流-摘要",
25438
- "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` 为准,本文不重复全文。"
25439
26031
  },
25440
26032
  {
25441
26033
  "title": "下一步",
25442
26034
  "id": "下一步",
25443
- "body": "- [AI 接入](/docs/ai-setup):安装 skill 与其它 AI 配置 \n- [Agent MCP](/docs/mcp):工具与客户端配置 \n- [快速上手](/docs/quick-start):手写安装组件库 \n- [组件](/components):浏览 API"
26035
+ "body": "- [一键接入](/docs/setup):安装 skill 与其它配置 \n- [AI 接入](/docs/ai-setup):用 AI 生成页面时的流程 \n- [Agent MCP](/docs/mcp):工具与客户端配置 \n- [快速上手](/docs/quick-start):手写安装组件库 \n- [组件](/components):浏览 API"
25444
26036
  }
25445
26037
  ]
25446
26038
  },
25447
26039
  "en-US": {
25448
26040
  "title": "Agent Skill",
25449
26041
  "description": "Consumer morya-ui-pages skill — when it triggers, vs rules/MCP, and the surface map.",
25450
- "markdown": "---\ntitle: Agent Skill\norder: 10\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 [AI setup](/docs/ai-setup) (`npx @morya-ui/setup` copies it into the project). 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: [`ai-design-config/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/ai-design-config/.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| [AI setup](/docs/ai-setup) / `@morya-ui/setup` | One-shot install of library + skill + rules + MCP |\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- [AI setup](/docs/ai-setup): install the skill and related AI config \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",
25451
26043
  "sections": [
25452
26044
  {
25453
26045
  "title": "",
25454
26046
  "id": "overview",
25455
- "body": "# 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 [AI setup](/docs/ai-setup) (`npx @morya-ui/setup` copies it into the project). This page explains **what it is, when to use it, and how it relates to other config**."
26047
+ "body": "# 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**."
25456
26048
  },
25457
26049
  {
25458
26050
  "title": "Where it lives",
25459
26051
  "id": "where-it-lives",
25460
- "body": "```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: [`ai-design-config/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/ai-design-config/.agents/skills/morya-ui-pages), synced into the `@morya-ui/setup` template."
26052
+ "body": "```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."
25461
26053
  },
25462
26054
  {
25463
26055
  "title": "When it triggers",
@@ -25467,7 +26059,7 @@
25467
26059
  {
25468
26060
  "title": "How it relates to other config",
25469
26061
  "id": "how-it-relates-to-other-config",
25470
- "body": "| Layer | Role |\n| --- | --- |\n| [AI setup](/docs/ai-setup) / `@morya-ui/setup` | One-shot install of library + skill + rules + MCP |\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"
26062
+ "body": "| 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"
25471
26063
  },
25472
26064
  {
25473
26065
  "title": "Surface map",
@@ -25477,12 +26069,12 @@
25477
26069
  {
25478
26070
  "title": "Recommended agent workflow (summary)",
25479
26071
  "id": "recommended-agent-workflow-summary",
25480
- "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."
25481
26073
  },
25482
26074
  {
25483
26075
  "title": "Next steps",
25484
26076
  "id": "next-steps",
25485
- "body": "- [AI setup](/docs/ai-setup): install the skill and related AI config \n- [Agent MCP](/docs/mcp): tools and client config \n- [Quick start](/docs/quick-start): manual library install \n- [Components](/components): browse APIs"
26077
+ "body": "- [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"
25486
26078
  }
25487
26079
  ]
25488
26080
  }
@@ -25494,17 +26086,17 @@
25494
26086
  "titleEn": "Agent MCP",
25495
26087
  "description": "可选的 MCP 服务,供支持 Model Context Protocol 的 AI 客户端检索本库文档。",
25496
26088
  "descriptionEn": "Optional MCP server for AI clients that support the Model Context Protocol.",
25497
- "order": 11,
26089
+ "order": 13,
25498
26090
  "locales": {
25499
26091
  "zh-CN": {
25500
26092
  "title": "Agent MCP",
25501
26093
  "description": "可选的 MCP 服务,供支持 Model Context Protocol 的 AI 客户端检索本库文档。",
25502
- "markdown": "---\ntitle: Agent MCP\norder: 11\ndescription: 可选的 MCP 服务,供支持 Model Context Protocol 的 AI 客户端检索本库文档。\n---\n\n# Agent MCP\n\n[`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp) 是可选的 [Model Context Protocol](https://modelcontextprotocol.io/)(stdio)服务。它把本站组件文档、示例与指南做成可检索工具,方便 **支持 MCP 的 AI 客户端** 按真实 API 生成代码。\n\n日常使用组件库 **不需要** 安装或配置 MCP。应用里仍然只依赖:\n\n```bash\npnpm add morya-ui\n```\n\n```ts\nimport 'morya-ui/styles.css'\n```\n\n若要连同 Agent Skill、Cursor 规则一起装好,见 [AI 接入](/docs/ai-setup);Skill 本身说明见 [Agent Skill](/docs/agent-skill)。\n\n## 接入方式\n\nMCP 客户端通过 stdio 启动本包即可:\n\n```bash\nnpx -y @morya-ui/mcp\n```\n\n通用写法:\n\n```json\n{\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n}\n```\n\n字段名因客户端而异,只要支持 MCP stdio 即可接入。\n\n### 常见客户端配置示例\n\n以下为常见产品的配置片段,键名可能随版本变化,以各产品官方文档为准。\n\n**Cursor**(`.cursor/mcp.json` 或用户级 MCP 配置):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Claude Desktop / Claude Code**(`claude_desktop_config.json` 等):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Windsurf**(MCP 设置中的 servers 配置):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Cline**(VS Code 扩展设置中的 MCP servers):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Zed**(`settings.json` → `context_servers`):\n\n```json\n{\n \"context_servers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Continue**(`config.json` / YAML 中的 MCP servers,字段名以当前版本为准):\n\n```json\n{\n \"mcpServers\": [\n {\n \"name\": \"morya-ui\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n ]\n}\n```\n\n## 可用工具\n\n### 基础 — 查组件文档\n\n| 工具 | 作用 |\n| --- | --- |\n| `list` | 列出组件 / 指南 / 示例 / 分类 / 页面模式 |\n| `search` | 搜索文档、示例、页面模式与组件选型指南 |\n| `get_component` | 读取组件说明与 API |\n| `get_example` | 获取源码示例 |\n| `get_guide` | 读取指南 |\n| `get_setup` | 安装与初始化说明 |\n| `validate_usage` | 对照文档粗检 props / events 用法 |\n| `version` | 版本与目录状态 |\n\n### 高级 — 页面组合(可选)\n\n| 工具 | 作用 |\n| --- | --- |\n| `list_patterns` | 列出可复用的页面组合模式 |\n| `get_pattern` | 读取模式的结构、布局与交互规则 |\n| `recommend_page` | 根据页面意图推荐模式;可附带 starter 脚手架 |\n| `get_design_rules` | 设计令牌与 MPage* 组合配方 |\n| `recommend_component` | 列出、阅读或推荐组件选型指南 |\n| `list_golden_pages` | 列出黄金样例页面 |\n| `get_golden_page` | 读取黄金样例 Vue 源码 |\n| `list_page_snippets` | 列出可复用的页面区块 snippet |\n| `get_page_snippet` | 读取局部区块 snippet(筛选区、工具栏等) |\n| `validate_page` | 校验页面组合、间距与双边框问题 |\n\n多数工具支持 `mode`:`zh`(默认)或 `en`。\n\n### 推荐工作流\n\n**查单个组件:** `search` / `get_component` → `get_example` → `validate_usage`\n\n**规划整页:** `recommend_page` → `get_golden_page` → `get_pattern` → `get_design_rules` → `get_component` / `get_example` → `validate_page`\n\n**改局部区块:** `get_page_snippet(section)` → `get_component` / `get_example` → `validate_usage` → `validate_page`\n\n需要 starter 代码时,给 `recommend_page` 传 `includeScaffold: true`:\n\n```json\n{\n \"intent\": \"油井管理列表\",\n \"pageType\": \"list\",\n \"features\": [\"筛选\", \"新增\", \"分页\"],\n \"includeScaffold\": true\n}\n```\n\n`recommend_component` 用法:\n\n- 不传 `query` 和 `decision` → 列出全部选型指南\n- 只传 `decision`(如 `overlay-choice`)→ 阅读某一指南\n- 传 `query` → 根据问题推荐组件\n\n## 对话示例\n\n接入后,可直接让助手调用本服务,例如:\n\n> 用 morya-ui 的 MCP 查一下 Dialog 的 props,并给一个带确认 / 取消按钮的示例。\n\n> 搜索和「日期」相关的组件,选一个适合表单的,按文档写出最小用法。\n\n> 根据 MCP 里 Button 的文档,写一个 `severity=\"danger\"` 的删除按钮,并校验 props 是否合法。\n\n助手应先调用工具,再基于返回内容生成类似:\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <MButton label=\"删除\" severity=\"danger\" />\n</template>\n```\n\n## 与文档站的关系\n\n目录与本站同源(组件 `docs/` + 指南 Markdown)。官网文档更新后,维护者重新发布 `@morya-ui/mcp`,客户端通过 `npx -y` 即可拿到新版本。\n\n更多实现细节见仓库内 [packages/ui-mcp/README.md](https://github.com/morya-space/morya-ui/tree/main/packages/ui-mcp)。\n\n## 下一步\n\n- [AI 接入](/docs/ai-setup):`npx @morya-ui/setup`、skill 与 Cursor MCP\n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 何时用、表面地图\n- [快速上手](/docs/quick-start):在应用中安装并使用组件\n- [组件](/components):浏览全部组件与交互示例\n",
26094
+ "markdown": "---\ntitle: Agent MCP\norder: 13\ndescription: 可选的 MCP 服务,供支持 Model Context Protocol 的 AI 客户端检索本库文档。\n---\n\n# Agent MCP\n\n[`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp) 是可选的 [Model Context Protocol](https://modelcontextprotocol.io/)(stdio)服务。它把本站组件文档、示例与指南做成可检索工具,方便 **支持 MCP 的 AI 客户端** 按真实 API 生成代码。\n\n日常使用组件库 **不需要** 安装或配置 MCP。应用里仍然只依赖:\n\n```bash\npnpm add morya-ui\n```\n\n```ts\nimport 'morya-ui/styles.css'\n```\n\n若要连同 Agent Skill、Cursor 规则一起装好,见 [一键接入](/docs/setup);AI 流程见 [AI 接入](/docs/ai-setup);Skill 本身说明见 [Agent Skill](/docs/agent-skill)。\n\n## 接入方式\n\nMCP 客户端通过 stdio 启动本包即可:\n\n```bash\nnpx -y @morya-ui/mcp\n```\n\n通用写法:\n\n```json\n{\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n}\n```\n\n字段名因客户端而异,只要支持 MCP stdio 即可接入。\n\n### 常见客户端配置示例\n\n以下为常见产品的配置片段,键名可能随版本变化,以各产品官方文档为准。\n\n**Cursor**(`.cursor/mcp.json` 或用户级 MCP 配置):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Claude Desktop / Claude Code**(`claude_desktop_config.json` 等):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Windsurf**(MCP 设置中的 servers 配置):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Cline**(VS Code 扩展设置中的 MCP servers):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Zed**(`settings.json` → `context_servers`):\n\n```json\n{\n \"context_servers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Continue**(`config.json` / YAML 中的 MCP servers,字段名以当前版本为准):\n\n```json\n{\n \"mcpServers\": [\n {\n \"name\": \"morya-ui\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n ]\n}\n```\n\n## 可用工具\n\n### 基础 — 查组件文档\n\n| 工具 | 作用 |\n| --- | --- |\n| `list` | 列出组件 / 指南 / 示例 / 分类 / 页面模式 |\n| `search` | 搜索文档、示例、页面模式与组件选型指南 |\n| `get_component` | 读取组件说明与 API |\n| `get_example` | 获取源码示例 |\n| `get_guide` | 读取指南 |\n| `get_setup` | 安装与初始化说明 |\n| `validate_usage` | 对照文档粗检 props / events 用法 |\n| `version` | 版本与目录状态 |\n\n### 高级 — 页面组合(可选)\n\n| 工具 | 作用 |\n| --- | --- |\n| `list_patterns` | 列出可复用的页面组合模式 |\n| `get_pattern` | 读取模式的结构、布局与交互规则 |\n| `recommend_page` | 根据页面意图推荐模式;可附带 starter 脚手架 |\n| `get_design_rules` | 设计令牌与 MPage* 组合配方 |\n| `recommend_component` | 列出、阅读或推荐组件选型指南 |\n| `list_golden_pages` | 列出黄金样例页面 |\n| `get_golden_page` | 读取黄金样例 Vue 源码 |\n| `list_page_snippets` | 列出可复用的页面区块 snippet |\n| `get_page_snippet` | 读取局部区块 snippet(筛选区、工具栏等) |\n| `validate_page` | 校验页面组合、间距与双边框问题 |\n\n多数工具支持 `mode`:`zh`(默认)或 `en`。\n\n### 推荐工作流\n\n**查单个组件:** `search` / `get_component` → `get_example` → `validate_usage`\n\n**规划整页:** `recommend_page` → `get_golden_page` → `get_pattern` → `get_design_rules` → `get_component` / `get_example` → `validate_page`\n\n**改局部区块:** `get_page_snippet(section)` → `get_component` / `get_example` → `validate_usage` → `validate_page`\n\n需要 starter 代码时,给 `recommend_page` 传 `includeScaffold: true`:\n\n```json\n{\n \"intent\": \"油井管理列表\",\n \"pageType\": \"list\",\n \"features\": [\"筛选\", \"新增\", \"分页\"],\n \"includeScaffold\": true\n}\n```\n\n`recommend_component` 用法:\n\n- 不传 `query` 和 `decision` → 列出全部选型指南\n- 只传 `decision`(如 `overlay-choice`)→ 阅读某一指南\n- 传 `query` → 根据问题推荐组件\n\n## 对话示例\n\n接入后,可直接让助手调用本服务,例如:\n\n> 用 morya-ui 的 MCP 查一下 Dialog 的 props,并给一个带确认 / 取消按钮的示例。\n\n> 搜索和「日期」相关的组件,选一个适合表单的,按文档写出最小用法。\n\n> 根据 MCP 里 Button 的文档,写一个 `severity=\"danger\"` 的删除按钮,并校验 props 是否合法。\n\n助手应先调用工具,再基于返回内容生成类似:\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <MButton label=\"删除\" severity=\"danger\" />\n</template>\n```\n\n## 与文档站的关系\n\n目录与本站同源(组件 `docs/` + 指南 Markdown)。官网文档更新后,维护者重新发布 `@morya-ui/mcp`,客户端通过 `npx -y` 即可拿到新版本。\n\n更多实现细节见仓库内 [packages/ui-mcp/README.md](https://github.com/morya-space/morya-ui/tree/main/packages/ui-mcp)。\n\n## 下一步\n\n- [AI 接入](/docs/ai-setup):`npx @morya-ui/setup`、skill 与 Cursor MCP\n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 何时用、表面地图\n- [快速上手](/docs/quick-start):在应用中安装并使用组件\n- [组件](/components):浏览全部组件与交互示例\n",
25503
26095
  "sections": [
25504
26096
  {
25505
26097
  "title": "",
25506
26098
  "id": "overview",
25507
- "body": "# Agent MCP\n\n[`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp) 是可选的 [Model Context Protocol](https://modelcontextprotocol.io/)(stdio)服务。它把本站组件文档、示例与指南做成可检索工具,方便 **支持 MCP 的 AI 客户端** 按真实 API 生成代码。\n\n日常使用组件库 **不需要** 安装或配置 MCP。应用里仍然只依赖:\n\n```bash\npnpm add morya-ui\n```\n\n```ts\nimport 'morya-ui/styles.css'\n```\n\n若要连同 Agent Skill、Cursor 规则一起装好,见 [AI 接入](/docs/ai-setup);Skill 本身说明见 [Agent Skill](/docs/agent-skill)。"
26099
+ "body": "# Agent MCP\n\n[`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp) 是可选的 [Model Context Protocol](https://modelcontextprotocol.io/)(stdio)服务。它把本站组件文档、示例与指南做成可检索工具,方便 **支持 MCP 的 AI 客户端** 按真实 API 生成代码。\n\n日常使用组件库 **不需要** 安装或配置 MCP。应用里仍然只依赖:\n\n```bash\npnpm add morya-ui\n```\n\n```ts\nimport 'morya-ui/styles.css'\n```\n\n若要连同 Agent Skill、Cursor 规则一起装好,见 [一键接入](/docs/setup);AI 流程见 [AI 接入](/docs/ai-setup);Skill 本身说明见 [Agent Skill](/docs/agent-skill)。"
25508
26100
  },
25509
26101
  {
25510
26102
  "title": "接入方式",
@@ -25536,12 +26128,12 @@
25536
26128
  "en-US": {
25537
26129
  "title": "Agent MCP",
25538
26130
  "description": "Optional MCP server for AI clients that support the Model Context Protocol.",
25539
- "markdown": "---\ntitle: Agent MCP\norder: 11\ndescription: Optional MCP server for AI clients that support the Model Context Protocol.\n---\n\n# Agent MCP\n\n[`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp) is an optional [Model Context Protocol](https://modelcontextprotocol.io/) (stdio) server. It indexes this site’s component docs, examples, and guides so **any MCP-capable AI client** can look up the real API.\n\nYou do **not** need MCP to use the component library. Apps still only depend on:\n\n```bash\npnpm add morya-ui\n```\n\n```ts\nimport 'morya-ui/styles.css'\n```\n\nFor Agent skill, Cursor rules, and writing MCP in one step, see [AI setup](/docs/ai-setup). Skill behavior: [Agent Skill](/docs/agent-skill).\n\n## How to connect\n\nMCP clients start the package over stdio:\n\n```bash\nnpx -y @morya-ui/mcp\n```\n\nGeneric shape:\n\n```json\n{\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n}\n```\n\nField names differ by client. Any client that supports MCP stdio can connect.\n\n### Common client config examples\n\nSnippets for popular products. Key names may change across versions — check each product’s docs.\n\n**Cursor** (`.cursor/mcp.json` or user-level MCP settings):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Claude Desktop / Claude Code** (`claude_desktop_config.json`, etc.):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Windsurf** (MCP servers in settings):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Cline** (MCP servers in the VS Code extension settings):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Zed** (`settings.json` → `context_servers`):\n\n```json\n{\n \"context_servers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Continue** (`config.json` / YAML MCP servers — follow the current schema):\n\n```json\n{\n \"mcpServers\": [\n {\n \"name\": \"morya-ui\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n ]\n}\n```\n\n## Tools\n\n### Core — component docs\n\n| Tool | Purpose |\n| --- | --- |\n| `list` | List components / guides / examples / categories / patterns |\n| `search` | Search docs, examples, patterns, and decision guides |\n| `get_component` | Read component docs and API |\n| `get_example` | Return a source example |\n| `get_guide` | Read a guide |\n| `get_setup` | Install and setup guidance |\n| `validate_usage` | Soft-check usage against documented props/events |\n| `version` | Version and catalog status |\n\n### Advanced — page composition (optional)\n\n| Tool | Purpose |\n| --- | --- |\n| `list_patterns` | List reusable page composition patterns |\n| `get_pattern` | Read a pattern's structure, layout, and rules |\n| `recommend_page` | Recommend a pattern from page intent; optional starter scaffold |\n| `get_design_rules` | Design-token and composition rules |\n| `recommend_component` | List, read, or recommend component selection guides |\n\nMost tools accept `mode`: `zh` (default) or `en`.\n\n### Recommended workflow\n\n**Look up a component:** `search` / `get_component` → `get_example` → `validate_usage`\n\n**Plan a page:** `recommend_page` → `get_pattern` → `get_component` / `get_example` → `get_design_rules`; use `recommend_component` when choosing between similar components\n\nPass `includeScaffold: true` to `recommend_page` for starter Vue code:\n\n```json\n{\n \"intent\": \"Oil well management list\",\n \"pageType\": \"list\",\n \"features\": [\"filters\", \"create\", \"pagination\"],\n \"includeScaffold\": true\n}\n```\n\n`recommend_component` modes:\n\n- omit `query` and `decision` → list decision guides\n- `decision` only (e.g. `overlay-choice`) → read one guide\n- `query` → recommend a component for a UI question\n\n## Prompt examples\n\nAfter connecting, you can ask the assistant to use this server, for example:\n\n> Use the morya-ui MCP to look up Dialog props and give an example with confirm / cancel actions.\n\n> Search for date-related components, pick one suitable for forms, and write a minimal usage from the docs.\n\n> Following the Button docs from MCP, write a delete button with `severity=\"danger\"` and validate the props.\n\nThe assistant should call tools first, then produce something like:\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <MButton label=\"Delete\" severity=\"danger\" />\n</template>\n```\n\n## Relation to this site\n\nThe catalog is generated from the same sources as this site (component `docs/` + guide Markdown). After docs change, maintainers republish `@morya-ui/mcp`; clients using `npx -y` pick up the new release.\n\nImplementation notes live in [packages/ui-mcp/README.md](https://github.com/morya-space/morya-ui/tree/main/packages/ui-mcp).\n\n## Next steps\n\n- [AI setup](/docs/ai-setup): one-shot library + skill + MCP\n- [Agent Skill](/docs/agent-skill): when to use `morya-ui-pages`\n- [Quick start](/docs/quick-start): install and use components in an app\n- [Components](/components): browse live examples and APIs\n",
26131
+ "markdown": "---\ntitle: Agent MCP\norder: 13\ndescription: Optional MCP server for AI clients that support the Model Context Protocol.\n---\n\n# Agent MCP\n\n[`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp) is an optional [Model Context Protocol](https://modelcontextprotocol.io/) (stdio) server. It indexes this site’s component docs, examples, and guides so **any MCP-capable AI client** can look up the real API.\n\nYou do **not** need MCP to use the component library. Apps still only depend on:\n\n```bash\npnpm add morya-ui\n```\n\n```ts\nimport 'morya-ui/styles.css'\n```\n\nFor Agent skill, Cursor rules, and writing MCP in one step, see [One-shot setup](/docs/setup). AI workflow: [AI setup](/docs/ai-setup). Skill behavior: [Agent Skill](/docs/agent-skill).\n\n## How to connect\n\nMCP clients start the package over stdio:\n\n```bash\nnpx -y @morya-ui/mcp\n```\n\nGeneric shape:\n\n```json\n{\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n}\n```\n\nField names differ by client. Any client that supports MCP stdio can connect.\n\n### Common client config examples\n\nSnippets for popular products. Key names may change across versions — check each product’s docs.\n\n**Cursor** (`.cursor/mcp.json` or user-level MCP settings):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Claude Desktop / Claude Code** (`claude_desktop_config.json`, etc.):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Windsurf** (MCP servers in settings):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Cline** (MCP servers in the VS Code extension settings):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Zed** (`settings.json` → `context_servers`):\n\n```json\n{\n \"context_servers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Continue** (`config.json` / YAML MCP servers — follow the current schema):\n\n```json\n{\n \"mcpServers\": [\n {\n \"name\": \"morya-ui\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n ]\n}\n```\n\n## Tools\n\n### Core — component docs\n\n| Tool | Purpose |\n| --- | --- |\n| `list` | List components / guides / examples / categories / patterns |\n| `search` | Search docs, examples, patterns, and decision guides |\n| `get_component` | Read component docs and API |\n| `get_example` | Return a source example |\n| `get_guide` | Read a guide |\n| `get_setup` | Install and setup guidance |\n| `validate_usage` | Soft-check usage against documented props/events |\n| `version` | Version and catalog status |\n\n### Advanced — page composition (optional)\n\n| Tool | Purpose |\n| --- | --- |\n| `list_patterns` | List reusable page composition patterns |\n| `get_pattern` | Read a pattern's structure, layout, and rules |\n| `recommend_page` | Recommend a pattern from page intent; optional starter scaffold |\n| `get_design_rules` | Design-token and composition rules |\n| `recommend_component` | List, read, or recommend component selection guides |\n\nMost tools accept `mode`: `zh` (default) or `en`.\n\n### Recommended workflow\n\n**Look up a component:** `search` / `get_component` → `get_example` → `validate_usage`\n\n**Plan a page:** `recommend_page` → `get_pattern` → `get_component` / `get_example` → `get_design_rules`; use `recommend_component` when choosing between similar components\n\nPass `includeScaffold: true` to `recommend_page` for starter Vue code:\n\n```json\n{\n \"intent\": \"Oil well management list\",\n \"pageType\": \"list\",\n \"features\": [\"filters\", \"create\", \"pagination\"],\n \"includeScaffold\": true\n}\n```\n\n`recommend_component` modes:\n\n- omit `query` and `decision` → list decision guides\n- `decision` only (e.g. `overlay-choice`) → read one guide\n- `query` → recommend a component for a UI question\n\n## Prompt examples\n\nAfter connecting, you can ask the assistant to use this server, for example:\n\n> Use the morya-ui MCP to look up Dialog props and give an example with confirm / cancel actions.\n\n> Search for date-related components, pick one suitable for forms, and write a minimal usage from the docs.\n\n> Following the Button docs from MCP, write a delete button with `severity=\"danger\"` and validate the props.\n\nThe assistant should call tools first, then produce something like:\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <MButton label=\"Delete\" severity=\"danger\" />\n</template>\n```\n\n## Relation to this site\n\nThe catalog is generated from the same sources as this site (component `docs/` + guide Markdown). After docs change, maintainers republish `@morya-ui/mcp`; clients using `npx -y` pick up the new release.\n\nImplementation notes live in [packages/ui-mcp/README.md](https://github.com/morya-space/morya-ui/tree/main/packages/ui-mcp).\n\n## Next steps\n\n- [One-shot setup](/docs/setup): `npx @morya-ui/setup`\n- [AI setup](/docs/ai-setup): Agent skill and MCP workflow\n- [Agent Skill](/docs/agent-skill): when to use `morya-ui-pages`\n- [Quick start](/docs/quick-start): install and use components in an app\n- [Components](/components): browse live examples and APIs\n",
25540
26132
  "sections": [
25541
26133
  {
25542
26134
  "title": "",
25543
26135
  "id": "overview",
25544
- "body": "# Agent MCP\n\n[`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp) is an optional [Model Context Protocol](https://modelcontextprotocol.io/) (stdio) server. It indexes this site’s component docs, examples, and guides so **any MCP-capable AI client** can look up the real API.\n\nYou do **not** need MCP to use the component library. Apps still only depend on:\n\n```bash\npnpm add morya-ui\n```\n\n```ts\nimport 'morya-ui/styles.css'\n```\n\nFor Agent skill, Cursor rules, and writing MCP in one step, see [AI setup](/docs/ai-setup). Skill behavior: [Agent Skill](/docs/agent-skill)."
26136
+ "body": "# Agent MCP\n\n[`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp) is an optional [Model Context Protocol](https://modelcontextprotocol.io/) (stdio) server. It indexes this site’s component docs, examples, and guides so **any MCP-capable AI client** can look up the real API.\n\nYou do **not** need MCP to use the component library. Apps still only depend on:\n\n```bash\npnpm add morya-ui\n```\n\n```ts\nimport 'morya-ui/styles.css'\n```\n\nFor Agent skill, Cursor rules, and writing MCP in one step, see [One-shot setup](/docs/setup). AI workflow: [AI setup](/docs/ai-setup). Skill behavior: [Agent Skill](/docs/agent-skill)."
25545
26137
  },
25546
26138
  {
25547
26139
  "title": "How to connect",
@@ -25566,7 +26158,7 @@
25566
26158
  {
25567
26159
  "title": "Next steps",
25568
26160
  "id": "next-steps",
25569
- "body": "- [AI setup](/docs/ai-setup): one-shot library + skill + MCP\n- [Agent Skill](/docs/agent-skill): when to use `morya-ui-pages`\n- [Quick start](/docs/quick-start): install and use components in an app\n- [Components](/components): browse live examples and APIs"
26161
+ "body": "- [One-shot setup](/docs/setup): `npx @morya-ui/setup`\n- [AI setup](/docs/ai-setup): Agent skill and MCP workflow\n- [Agent Skill](/docs/agent-skill): when to use `morya-ui-pages`\n- [Quick start](/docs/quick-start): install and use components in an app\n- [Components](/components): browse live examples and APIs"
25570
26162
  }
25571
26163
  ]
25572
26164
  }