@morya-ui/mcp 0.4.0 → 0.4.2

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-30T07:47:11.558Z",
2
+ "generatedAt": "2026-10-09T09:31:59.453Z",
3
3
  "library": {
4
4
  "name": "morya-ui",
5
- "version": "0.4.0"
5
+ "version": "0.4.2"
6
6
  },
7
7
  "mcp": {
8
8
  "name": "@morya-ui/mcp",
9
- "version": "0.4.0"
9
+ "version": "0.4.2"
10
10
  },
11
11
  "components": [
12
12
  {
@@ -101,7 +101,7 @@
101
101
  "sectionId": "extra",
102
102
  "lang": "vue",
103
103
  "preview": true,
104
- "code": "<script setup lang=\"ts\">\nimport { MAccordion, MButton } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst active = ref('a')\nconst tabs = [\n { value: 'a', header: 'Section A' },\n]\n</script>\n\n<template>\n <MAccordion v-model=\"active\" :tabs=\"tabs\">\n <template #extra=\"{ tab }\">\n <MButton :label=\"tab.header\" size=\"small\" text />\n </template>\n <template #a>\n <p style=\"margin:0\">\n Content.\n </p>\n </template>\n </MAccordion>\n</template>",
104
+ "code": "<script setup lang=\"ts\">\nimport { MAccordion, MButton } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst active = ref('a')\nconst tabs = [\n { value: 'a', header: 'Section A' },\n]\n</script>\n\n<template>\n <MAccordion v-model=\"active\" :tabs=\"tabs\">\n <template #extra=\"{ tab }\">\n <MButton :label=\"tab.header\" size=\"small\" type=\"text\"/>\n </template>\n <template #a>\n <p style=\"margin:0\">\n Content.\n </p>\n </template>\n </MAccordion>\n</template>",
105
105
  "locale": "zh-CN"
106
106
  },
107
107
  {
@@ -137,7 +137,7 @@
137
137
  "sectionId": "extra",
138
138
  "lang": "vue",
139
139
  "preview": true,
140
- "code": "<script setup lang=\"ts\">\nimport { MAccordion, MButton } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst active = ref('a')\nconst tabs = [\n { value: 'a', header: 'Section A' },\n]\n</script>\n\n<template>\n <MAccordion v-model=\"active\" :tabs=\"tabs\">\n <template #extra=\"{ tab }\">\n <MButton :label=\"tab.header\" size=\"small\" text />\n </template>\n <template #a>\n <p style=\"margin:0\">\n Content.\n </p>\n </template>\n </MAccordion>\n</template>",
140
+ "code": "<script setup lang=\"ts\">\nimport { MAccordion, MButton } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst active = ref('a')\nconst tabs = [\n { value: 'a', header: 'Section A' },\n]\n</script>\n\n<template>\n <MAccordion v-model=\"active\" :tabs=\"tabs\">\n <template #extra=\"{ tab }\">\n <MButton :label=\"tab.header\" size=\"small\" type=\"text\"/>\n </template>\n <template #a>\n <p style=\"margin:0\">\n Content.\n </p>\n </template>\n </MAccordion>\n</template>",
141
141
  "locale": "en-US"
142
142
  }
143
143
  ],
@@ -302,7 +302,7 @@
302
302
  "sectionId": "基础用法",
303
303
  "lang": "vue",
304
304
  "preview": true,
305
- "code": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { MAffix, MButton } from 'morya-ui'\n\nconst top = ref(80)\n</script>\n\n<template>\n <div style=\"height: 320px; overflow: auto; border: 1px solid var(--m-color-border); padding: var(--m-space-4);\">\n <p>向下滚动,按钮在距顶部 {{ top }}px 时固定。</p>\n <div style=\"height: 120px\" />\n <MAffix :offset-top=\"top\">\n <MButton severity=\"primary\">\n Affix at {{ top }}px\n </MButton>\n </MAffix>\n <div style=\"height: 480px\" />\n </div>\n</template>",
305
+ "code": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { MAffix, MButton } from 'morya-ui'\n\nconst top = ref(80)\n</script>\n\n<template>\n <div style=\"height: 320px; overflow: auto; border: 1px solid var(--m-color-border); padding: var(--m-space-4);\">\n <p>向下滚动,按钮在距顶部 {{ top }}px 时固定。</p>\n <div style=\"height: 120px\" />\n <MAffix :offset-top=\"top\">\n <MButton type=\"primary\">\n Affix at {{ top }}px\n </MButton>\n </MAffix>\n <div style=\"height: 480px\" />\n </div>\n</template>",
306
306
  "locale": "zh-CN"
307
307
  },
308
308
  {
@@ -320,7 +320,7 @@
320
320
  "sectionId": "basic",
321
321
  "lang": "vue",
322
322
  "preview": true,
323
- "code": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { MAffix, MButton } from 'morya-ui'\n\nconst top = ref(80)\n</script>\n\n<template>\n <div style=\"height: 320px; overflow: auto; border: 1px solid var(--m-color-border); padding: var(--m-space-4);\">\n <p>向下滚动,按钮在距顶部 {{ top }}px 时固定。</p>\n <div style=\"height: 120px\" />\n <MAffix :offset-top=\"top\">\n <MButton severity=\"primary\">\n Affix at {{ top }}px\n </MButton>\n </MAffix>\n <div style=\"height: 480px\" />\n </div>\n</template>",
323
+ "code": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { MAffix, MButton } from 'morya-ui'\n\nconst top = ref(80)\n</script>\n\n<template>\n <div style=\"height: 320px; overflow: auto; border: 1px solid var(--m-color-border); padding: var(--m-space-4);\">\n <p>向下滚动,按钮在距顶部 {{ top }}px 时固定。</p>\n <div style=\"height: 120px\" />\n <MAffix :offset-top=\"top\">\n <MButton type=\"primary\">\n Affix at {{ top }}px\n </MButton>\n </MAffix>\n <div style=\"height: 480px\" />\n </div>\n</template>",
324
324
  "locale": "en-US"
325
325
  }
326
326
  ],
@@ -510,7 +510,7 @@
510
510
  "sectionId": "操作区",
511
511
  "lang": "vue",
512
512
  "preview": true,
513
- "code": "<script setup lang=\"ts\">\nimport { MAlert, MButton, message } from 'morya-ui'\n\nfunction onUndo() {\n message.info('已撤销')\n}\n</script>\n\n<template>\n <MAlert severity=\"info\">\n <template #title>\n 已归档\n </template>\n 该记录已移入归档。你可以撤销此次操作。\n <template #action>\n <MButton\n size=\"small\"\n text\n @click=\"onUndo\"\n >\n 撤销\n </MButton>\n </template>\n </MAlert>\n</template>",
513
+ "code": "<script setup lang=\"ts\">\nimport { MAlert, MButton, message } from 'morya-ui'\n\nfunction onUndo() {\n message.info('已撤销')\n}\n</script>\n\n<template>\n <MAlert severity=\"info\">\n <template #title>\n 已归档\n </template>\n 该记录已移入归档。你可以撤销此次操作。\n <template #action>\n <MButton size=\"small\" @click=\"onUndo\" type=\"text\">\n 撤销\n </MButton>\n </template>\n </MAlert>\n</template>",
514
514
  "locale": "zh-CN"
515
515
  },
516
516
  {
@@ -564,7 +564,7 @@
564
564
  "sectionId": "action",
565
565
  "lang": "vue",
566
566
  "preview": true,
567
- "code": "<script setup lang=\"ts\">\nimport { MAlert, MButton, message } from 'morya-ui'\n\nfunction onUndo() {\n message.info('已撤销')\n}\n</script>\n\n<template>\n <MAlert severity=\"info\">\n <template #title>\n 已归档\n </template>\n 该记录已移入归档。你可以撤销此次操作。\n <template #action>\n <MButton\n size=\"small\"\n text\n @click=\"onUndo\"\n >\n 撤销\n </MButton>\n </template>\n </MAlert>\n</template>",
567
+ "code": "<script setup lang=\"ts\">\nimport { MAlert, MButton, message } from 'morya-ui'\n\nfunction onUndo() {\n message.info('已撤销')\n}\n</script>\n\n<template>\n <MAlert severity=\"info\">\n <template #title>\n 已归档\n </template>\n 该记录已移入归档。你可以撤销此次操作。\n <template #action>\n <MButton size=\"small\" @click=\"onUndo\" type=\"text\">\n 撤销\n </MButton>\n </template>\n </MAlert>\n</template>",
568
568
  "locale": "en-US"
569
569
  },
570
570
  {
@@ -1495,6 +1495,12 @@
1495
1495
  "type": "boolean",
1496
1496
  "default": "false",
1497
1497
  "description": "脉冲动画。"
1498
+ },
1499
+ {
1500
+ "name": "pt",
1501
+ "type": "[RootPassThrough](/docs/types#RootPassThrough) `{ root? }",
1502
+ "default": "—",
1503
+ "description": "DOM 透传,见 [样式与 attrs](/docs/attrs)."
1498
1504
  }
1499
1505
  ],
1500
1506
  "events": [],
@@ -1548,7 +1554,7 @@
1548
1554
  "sectionId": "overlay",
1549
1555
  "lang": "vue",
1550
1556
  "preview": true,
1551
- "code": "<script setup lang=\"ts\">\nimport { MBadge, MButton } from 'morya-ui'\n</script>\n\n<template>\n <div style=\"display:flex;flex-wrap:wrap;gap:1.5rem;align-items:center\">\n <MBadge :value=\"120\" :max=\"99\">\n <MButton label=\"Inbox\" severity=\"secondary\" />\n </MBadge>\n <MBadge processing>\n <MButton label=\"Live\" icon=\"check\" />\n </MBadge>\n </div>\n</template>",
1557
+ "code": "<script setup lang=\"ts\">\nimport { MBadge, MButton } from 'morya-ui'\n</script>\n\n<template>\n <div style=\"display:flex;flex-wrap:wrap;gap:1.5rem;align-items:center\">\n <MBadge :value=\"120\" :max=\"99\">\n <MButton label=\"Inbox\"/>\n </MBadge>\n <MBadge processing>\n <MButton label=\"Live\" icon=\"check\" />\n </MBadge>\n </div>\n</template>",
1552
1558
  "locale": "zh-CN"
1553
1559
  },
1554
1560
  {
@@ -1593,7 +1599,7 @@
1593
1599
  "sectionId": "overlay",
1594
1600
  "lang": "vue",
1595
1601
  "preview": true,
1596
- "code": "<script setup lang=\"ts\">\nimport { MBadge, MButton } from 'morya-ui'\n</script>\n\n<template>\n <div style=\"display:flex;flex-wrap:wrap;gap:1.5rem;align-items:center\">\n <MBadge :value=\"120\" :max=\"99\">\n <MButton label=\"Inbox\" severity=\"secondary\" />\n </MBadge>\n <MBadge processing>\n <MButton label=\"Live\" icon=\"check\" />\n </MBadge>\n </div>\n</template>",
1602
+ "code": "<script setup lang=\"ts\">\nimport { MBadge, MButton } from 'morya-ui'\n</script>\n\n<template>\n <div style=\"display:flex;flex-wrap:wrap;gap:1.5rem;align-items:center\">\n <MBadge :value=\"120\" :max=\"99\">\n <MButton label=\"Inbox\"/>\n </MBadge>\n <MBadge processing>\n <MButton label=\"Live\" icon=\"check\" />\n </MBadge>\n </div>\n</template>",
1597
1603
  "locale": "en-US"
1598
1604
  }
1599
1605
  ],
@@ -1635,7 +1641,7 @@
1635
1641
  {
1636
1642
  "id": "props",
1637
1643
  "title": "Props",
1638
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `string \\| number` | — | 角标内容。省略时显示为圆点。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | 语义色。`warning` 为兼容别名,映射为 `warn`。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸;`sm` / `lg` 为别名。 |\n| `max` | `number` | — | 数字上限,超出显示 `{max}+`。 |\n| `offset` | `[number, number]` | — | 包裹模式下的位移 `[x, y]`。 |\n| `processing` | `boolean` | `false` | 脉冲动画。 |"
1644
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `string \\| number` | — | 角标内容。省略时显示为圆点。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | 语义色。`warning` 为兼容别名,映射为 `warn`。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸;`sm` / `lg` 为别名。 |\n| `max` | `number` | — | 数字上限,超出显示 `{max}+`。 |\n| `offset` | `[number, number]` | — | 包裹模式下的位移 `[x, y]`。 |\n| `processing` | `boolean` | `false` | 脉冲动画。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
1639
1645
  },
1640
1646
  {
1641
1647
  "id": "slots",
@@ -1653,7 +1659,7 @@
1653
1659
  "body": "无自定义事件。"
1654
1660
  }
1655
1661
  ],
1656
- "markdown": "---\ntitle: Badge\ncategory: 01 / BASIC\ndescription: 状态角标或圆点。\n---\n\n# Badge\n\n状态角标或圆点,用于数量与状态提示。\n\n## 引入\n\n```ts\nimport { MBadge } from 'morya-ui'\n```\n\n## 基础用法\n\n传入 `value` 展示文案或数字;省略 `value` 时渲染为圆点。\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\n使用 `severity` 定义语义色;省略时为 primary。兼容旧值 `warning`(映射为 `warn`)。\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Size\n\n`size` 支持 `small` / `large`,以及别名 `sm` / `lg`。\n\n```vue preview src=\"./demos/Size.vue\"\n```\n\n## Overlay\n\n默认插槽包裹子节点;`max` 超出时显示 `99+`,`processing` 显示脉冲。\n\n```vue preview src=\"./demos/Overlay.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `string \\| number` | — | 角标内容。省略时显示为圆点。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | 语义色。`warning` 为兼容别名,映射为 `warn`。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸;`sm` / `lg` 为别名。 |\n| `max` | `number` | — | 数字上限,超出显示 `{max}+`。 |\n| `offset` | `[number, number]` | — | 包裹模式下的位移 `[x, y]`。 |\n| `processing` | `boolean` | `false` | 脉冲动画。 |\n\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 被角标包裹的内容。 |\n\n## 无障碍\n\n- 角标数字变化时,若状态重要,请同步更新附近可见文案或 `aria-live` 区域。\n- 包裹模式下,勿让角标成为唯一的状态提示。\n\n## Events\n\n无自定义事件。\n"
1662
+ "markdown": "---\ntitle: Badge\ncategory: 01 / BASIC\ndescription: 状态角标或圆点。\n---\n\n# Badge\n\n状态角标或圆点,用于数量与状态提示。\n\n## 引入\n\n```ts\nimport { MBadge } from 'morya-ui'\n```\n\n## 基础用法\n\n传入 `value` 展示文案或数字;省略 `value` 时渲染为圆点。\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\n使用 `severity` 定义语义色;省略时为 primary。兼容旧值 `warning`(映射为 `warn`)。\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Size\n\n`size` 支持 `small` / `large`,以及别名 `sm` / `lg`。\n\n```vue preview src=\"./demos/Size.vue\"\n```\n\n## Overlay\n\n默认插槽包裹子节点;`max` 超出时显示 `99+`,`processing` 显示脉冲。\n\n```vue preview src=\"./demos/Overlay.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `string \\| number` | — | 角标内容。省略时显示为圆点。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | 语义色。`warning` 为兼容别名,映射为 `warn`。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸;`sm` / `lg` 为别名。 |\n| `max` | `number` | — | 数字上限,超出显示 `{max}+`。 |\n| `offset` | `[number, number]` | — | 包裹模式下的位移 `[x, y]`。 |\n| `processing` | `boolean` | `false` | 脉冲动画。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 被角标包裹的内容。 |\n\n## 无障碍\n\n- 角标数字变化时,若状态重要,请同步更新附近可见文案或 `aria-live` 区域。\n- 包裹模式下,勿让角标成为唯一的状态提示。\n\n## Events\n\n无自定义事件。\n"
1657
1663
  },
1658
1664
  "en-US": {
1659
1665
  "title": "Badge",
@@ -1692,7 +1698,7 @@
1692
1698
  {
1693
1699
  "id": "props",
1694
1700
  "title": "Props",
1695
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `string \\| number` | 鈥?| Badge content. Renders as a dot when omitted. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | Semantic color. `warning` is a compatibility alias mapped to `warn`. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size; `sm` / `lg` are aliases. |\n| `max` | `number` | 鈥?| Cap numeric values as `{max}+`. |\n| `offset` | `[number, number]` | 鈥?| Offset `[x, y]` when wrapping content. |\n| `processing` | `boolean` | `false` | Pulse animation. |"
1701
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `string \\| number` | 鈥?| Badge content. Renders as a dot when omitted. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | Semantic color. `warning` is a compatibility alias mapped to `warn`. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size; `sm` / `lg` are aliases. |\n| `max` | `number` | 鈥?| Cap numeric values as `{max}+`. |\n| `offset` | `[number, number]` | 鈥?| Offset `[x, y]` when wrapping content. |\n| `processing` | `boolean` | `false` | Pulse animation. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |"
1696
1702
  },
1697
1703
  {
1698
1704
  "id": "slots",
@@ -1710,7 +1716,7 @@
1710
1716
  "body": "No custom events."
1711
1717
  }
1712
1718
  ],
1713
- "markdown": "---\ntitle: Badge\ncategory: 01 / BASIC\ndescription: Status badge or dot.\n---\n\n# Badge\n\nStatus badge or dot for counts and status cues.\n\n## Import\n\n```ts\nimport { MBadge } from 'morya-ui'\n```\n\n## Basic\n\nPass `value` to show text or a number; omit `value` to render a dot.\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\nUse `severity` for semantic color; defaults to primary when omitted. Legacy value `warning` is supported (mapped to `warn`).\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Size\n\n`size` supports `small` / `large`, plus aliases `sm` / `lg`.\n\n```vue preview src=\"./demos/Size.vue\"\n```\n\n## Overlay\n\nWrap content with the default slot. `max` caps numeric values; `processing` pulses.\n\n```vue preview src=\"./demos/Overlay.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `string \\| number` | 鈥?| Badge content. Renders as a dot when omitted. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | Semantic color. `warning` is a compatibility alias mapped to `warn`. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size; `sm` / `lg` are aliases. |\n| `max` | `number` | 鈥?| Cap numeric values as `{max}+`. |\n| `offset` | `[number, number]` | 鈥?| Offset `[x, y]` when wrapping content. |\n| `processing` | `boolean` | `false` | Pulse animation. |\n\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Content to overlay. |\n\n## Accessibility\n\n- When badge counts matter, update nearby visible text or an `aria-live` region.\n- Do not rely on the badge alone as the only status indicator.\n\n## Events\n\nNo custom events.\n"
1719
+ "markdown": "---\ntitle: Badge\ncategory: 01 / BASIC\ndescription: Status badge or dot.\n---\n\n# Badge\n\nStatus badge or dot for counts and status cues.\n\n## Import\n\n```ts\nimport { MBadge } from 'morya-ui'\n```\n\n## Basic\n\nPass `value` to show text or a number; omit `value` to render a dot.\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\nUse `severity` for semantic color; defaults to primary when omitted. Legacy value `warning` is supported (mapped to `warn`).\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Size\n\n`size` supports `small` / `large`, plus aliases `sm` / `lg`.\n\n```vue preview src=\"./demos/Size.vue\"\n```\n\n## Overlay\n\nWrap content with the default slot. `max` caps numeric values; `processing` pulses.\n\n```vue preview src=\"./demos/Overlay.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `string \\| number` | 鈥?| Badge content. Renders as a dot when omitted. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | Semantic color. `warning` is a compatibility alias mapped to `warn`. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size; `sm` / `lg` are aliases. |\n| `max` | `number` | 鈥?| Cap numeric values as `{max}+`. |\n| `offset` | `[number, number]` | 鈥?| Offset `[x, y]` when wrapping content. |\n| `processing` | `boolean` | `false` | Pulse animation. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |\n\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Content to overlay. |\n\n## Accessibility\n\n- When badge counts matter, update nearby visible text or an `aria-live` region.\n- Do not rely on the badge alone as the only status indicator.\n\n## Events\n\nNo custom events.\n"
1714
1720
  }
1715
1721
  }
1716
1722
  },
@@ -2059,171 +2065,129 @@
2059
2065
  "name": "Button",
2060
2066
  "exportName": "MButton",
2061
2067
  "category": "01 / BASIC",
2062
- "description": "按钮用于触发即时动作。",
2063
- "descriptionEn": "Button triggers an immediate action.",
2068
+ "description": "触发即时操作的按钮。",
2069
+ "descriptionEn": "A button that triggers an immediate action.",
2064
2070
  "import": "import { MButton } from 'morya-ui'",
2065
2071
  "props": [
2066
2072
  {
2067
- "name": "label",
2068
- "type": "string",
2069
- "default": "—",
2070
- "description": "按钮文案。存在默认插槽内容时以插槽为准。"
2071
- },
2072
- {
2073
- "name": "icon",
2074
- "type": "IconName | Component",
2075
- "default": "—",
2076
- "description": "图标名称或自定义组件。"
2077
- },
2078
- {
2079
- "name": "iconPos",
2080
- "type": "'left' | 'right' | 'top' | 'bottom'",
2081
- "default": "'left'",
2082
- "description": "图标相对标签的位置。"
2083
- },
2084
- {
2085
- "name": "iconOnly",
2086
- "type": "boolean",
2087
- "default": "false",
2088
- "description": "强制方形纯图标按钮。"
2089
- },
2090
- {
2091
- "name": "badge",
2092
- "type": "string",
2093
- "default": "—",
2094
- "description": "徽标文本。"
2095
- },
2096
- {
2097
- "name": "badgeSeverity",
2098
- "type": "'secondary' | 'info' | 'success' | 'warn' | 'danger' | 'contrast' | null",
2099
- "default": "null",
2100
- "description": "徽标语义色。"
2101
- },
2102
- {
2103
- "name": "severity",
2104
- "type": "'secondary' | 'success' | 'info' | 'warn' | 'help' | 'danger' | 'contrast'",
2105
- "default": "—",
2106
- "description": "语义色。省略时为 primary。"
2073
+ "name": "type",
2074
+ "type": "'default' | 'primary' | 'dashed' | 'link' | 'text'",
2075
+ "default": "'default'",
2076
+ "description": "语法糖。同时设置 `color` 与 `variant` 时以后者为准。"
2107
2077
  },
2108
2078
  {
2109
2079
  "name": "color",
2110
- "type": "string",
2080
+ "type": "'default' | 'primary' | 'danger' | 'success' | 'info' | 'warning' | 'help' | 'contrast'",
2111
2081
  "default": "—",
2112
- "description": "自定义颜色,覆盖 `severity`。"
2113
- },
2114
- {
2115
- "name": "size",
2116
- "type": "'small' | 'large' | 'sm' | 'md' | 'lg'",
2117
- "default": "—",
2118
- "description": "尺寸。默认中等;兼容 `sm` / `lg`。"
2082
+ "description": "颜色轴。"
2119
2083
  },
2120
2084
  {
2121
2085
  "name": "variant",
2122
- "type": "'outlined' | 'dashed' | 'text' | 'link' | 'ghost' | 'quaternary'",
2086
+ "type": "'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'",
2123
2087
  "default": "—",
2124
- "description": "样式变体快捷方式,等价于对应布尔 prop。"
2088
+ "description": "变体轴。"
2125
2089
  },
2126
2090
  {
2127
- "name": "outlined",
2091
+ "name": "danger",
2128
2092
  "type": "boolean",
2129
2093
  "default": "false",
2130
- "description": "描边按钮。"
2094
+ "description": "危险色语法糖。设置了 `color` 时以 `color` 为准。"
2131
2095
  },
2132
2096
  {
2133
- "name": "dashed",
2097
+ "name": "ghost",
2134
2098
  "type": "boolean",
2135
2099
  "default": "false",
2136
- "description": "虚线边框。"
2100
+ "description": "透明背景。对 `text` / `link` 无效。"
2137
2101
  },
2138
2102
  {
2139
- "name": "text",
2140
- "type": "boolean",
2141
- "default": "false",
2142
- "description": "文字按钮。"
2103
+ "name": "shape",
2104
+ "type": "'default' | 'circle' | 'round' | 'square'",
2105
+ "default": "'default'",
2106
+ "description": "形状。"
2143
2107
  },
2144
2108
  {
2145
- "name": "link",
2146
- "type": "boolean",
2147
- "default": "false",
2148
- "description": "链接按钮。"
2109
+ "name": "size",
2110
+ "type": "'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'",
2111
+ "default": "—",
2112
+ "description": "尺寸;可继承 ConfigProvider。"
2149
2113
  },
2150
2114
  {
2151
- "name": "underline",
2115
+ "name": "block",
2152
2116
  "type": "boolean",
2153
- "default": "true",
2154
- "description": "`link` 悬浮下划线。设为 `false` 可关闭。"
2117
+ "default": "false",
2118
+ "description": "宽度撑满父容器。"
2155
2119
  },
2156
2120
  {
2157
- "name": "ghost",
2158
- "type": "boolean",
2121
+ "name": "loading",
2122
+ "type": "boolean | { delay?: number; icon?: IconName | Component }",
2159
2123
  "default": "false",
2160
- "description": "浅色填充,等同于 `text` 的悬浮态。"
2124
+ "description": "加载中;可延迟出现并自定义图标。"
2161
2125
  },
2162
2126
  {
2163
- "name": "quaternary",
2127
+ "name": "disabled",
2164
2128
  "type": "boolean",
2165
2129
  "default": "false",
2166
- "description": "极轻量文字按钮。"
2130
+ "description": "禁用;可继承 ConfigProvider。"
2167
2131
  },
2168
2132
  {
2169
- "name": "plain",
2170
- "type": "boolean",
2171
- "default": "false",
2172
- "description": "浅色填充,等同于 `outlined` 的悬浮态;也可与 `text` / `outlined` 组合弱化。"
2133
+ "name": "htmlType",
2134
+ "type": "'button' | 'submit' | 'reset'",
2135
+ "default": "'button'",
2136
+ "description": "原生 `button` 的 `type`。"
2173
2137
  },
2174
2138
  {
2175
- "name": "raised",
2176
- "type": "boolean",
2177
- "default": "false",
2178
- "description": "浮起阴影。"
2139
+ "name": "href",
2140
+ "type": "string",
2141
+ "default": "—",
2142
+ "description": "设置后渲染为 `<a>`。"
2179
2143
  },
2180
2144
  {
2181
- "name": "rounded",
2182
- "type": "boolean",
2183
- "default": "false",
2184
- "description": "全圆角(兼容;推荐 `shape=\"round\"`)。"
2145
+ "name": "target",
2146
+ "type": "string",
2147
+ "default": "—",
2148
+ "description": "链接 `target`,需配合 `href`。"
2185
2149
  },
2186
2150
  {
2187
- "name": "shape",
2188
- "type": "'default' | 'circle' | 'round' | 'square'",
2189
- "default": "'default'",
2190
- "description": "形状。"
2151
+ "name": "label",
2152
+ "type": "string",
2153
+ "default": "—",
2154
+ "description": "文案;默认插槽优先。"
2191
2155
  },
2192
2156
  {
2193
- "name": "fluid",
2194
- "type": "boolean",
2195
- "default": "false",
2196
- "description": "宽度撑满容器。"
2157
+ "name": "icon",
2158
+ "type": "IconName | Component",
2159
+ "default": "—",
2160
+ "description": "图标名称或组件。"
2197
2161
  },
2198
2162
  {
2199
- "name": "loading",
2163
+ "name": "iconPlacement",
2164
+ "type": "'start' | 'end'",
2165
+ "default": "'start'",
2166
+ "description": "图标位置。"
2167
+ },
2168
+ {
2169
+ "name": "iconOnly",
2200
2170
  "type": "boolean",
2201
2171
  "default": "false",
2202
- "description": "加载中,禁用点击并显示 spinner。"
2172
+ "description": "强制纯图标方形按钮。"
2203
2173
  },
2204
2174
  {
2205
- "name": "disabled",
2175
+ "name": "autoInsertSpace",
2206
2176
  "type": "boolean",
2207
- "default": "false",
2208
- "description": "禁用。"
2177
+ "default": "true",
2178
+ "description": "两个汉字之间插入空格。"
2209
2179
  },
2210
2180
  {
2211
2181
  "name": "ripple",
2212
2182
  "type": "boolean",
2213
2183
  "default": "false",
2214
- "description": "点击水波纹。设为 `true` 可开启。"
2184
+ "description": "点击水波纹。"
2215
2185
  },
2216
2186
  {
2217
2187
  "name": "press",
2218
2188
  "type": "boolean",
2219
2189
  "default": "false",
2220
- "description": "按下时轻微缩放。设为 `true` 可开启。"
2221
- },
2222
- {
2223
- "name": "nativeType",
2224
- "type": "'button' | 'submit' | 'reset'",
2225
- "default": "'button'",
2226
- "description": "原生 button type。"
2190
+ "description": "按下缩放。"
2227
2191
  },
2228
2192
  {
2229
2193
  "name": "autofocus",
@@ -2235,11 +2199,11 @@
2235
2199
  "name": "ariaLabel",
2236
2200
  "type": "string",
2237
2201
  "default": "—",
2238
- "description": "组合的可访问名称。"
2202
+ "description": "组的可访问名称。"
2239
2203
  },
2240
2204
  {
2241
2205
  "name": "pt",
2242
- "type": "[RootPassThrough](/docs/types#RootPassThrough) `{ root? }",
2206
+ "type": "{ root? }",
2243
2207
  "default": "—",
2244
2208
  "description": "组容器透传。"
2245
2209
  }
@@ -2248,7 +2212,7 @@
2248
2212
  {
2249
2213
  "name": "click",
2250
2214
  "payload": "MouseEvent",
2251
- "description": "启用状态下点击触发。"
2215
+ "description": "点击时触发;`loading` / `disabled` 时不触发。"
2252
2216
  }
2253
2217
  ],
2254
2218
  "slots": [
@@ -2268,11 +2232,11 @@
2268
2232
  "methods": [
2269
2233
  {
2270
2234
  "name": "focus",
2271
- "description": "聚焦底层 button。"
2235
+ "description": "聚焦根元素。"
2272
2236
  },
2273
2237
  {
2274
2238
  "name": "ref",
2275
- "description": "底层 `HTMLButtonElement`。"
2239
+ "description": "根 `HTMLButtonElement` 或 `HTMLAnchorElement`。"
2276
2240
  }
2277
2241
  ],
2278
2242
  "examples": [
@@ -2282,7 +2246,7 @@
2282
2246
  "sectionId": "引入",
2283
2247
  "lang": "ts",
2284
2248
  "preview": false,
2285
- "code": "import { MButton } from \"morya-ui\";",
2249
+ "code": "import { MButton, MButtonGroup } from 'morya-ui'",
2286
2250
  "locale": "zh-CN"
2287
2251
  },
2288
2252
  {
@@ -2291,7 +2255,7 @@
2291
2255
  "sectionId": "代码演示",
2292
2256
  "lang": "vue",
2293
2257
  "preview": true,
2294
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton>Submit</MButton>\n <MButton label=\"Label Prop\" />\n <MButton severity=\"secondary\" label=\"Secondary\" />\n </div>\n</template>",
2258
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" label=\"Primary\" />\n <MButton label=\"Default\" />\n <MButton type=\"dashed\" label=\"Dashed\" />\n <MButton type=\"text\" label=\"Text\" />\n <MButton type=\"link\" label=\"Link\" />\n </MFlex>\n</template>",
2295
2259
  "locale": "zh-CN"
2296
2260
  },
2297
2261
  {
@@ -2300,7 +2264,7 @@
2300
2264
  "sectionId": "代码演示",
2301
2265
  "lang": "vue",
2302
2266
  "preview": true,
2303
- "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <MSpace wrap>\n <MButton label=\"Primary\" />\n <MButton\n severity=\"secondary\"\n label=\"Default\"\n />\n <MButton\n variant=\"dashed\"\n label=\"Dashed\"\n />\n <MButton\n text\n label=\"Text\"\n />\n <MButton\n link\n label=\"Link\"\n />\n <MButton\n severity=\"danger\"\n label=\"Danger\"\n />\n </MSpace>\n</template>",
2267
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex vertical gap=\"medium\">\n <MFlex gap=\"small\" wrap>\n <MButton color=\"primary\" variant=\"solid\" label=\"Solid\" />\n <MButton color=\"primary\" variant=\"outlined\" label=\"Outlined\" />\n <MButton color=\"primary\" variant=\"dashed\" label=\"Dashed\" />\n <MButton color=\"primary\" variant=\"filled\" label=\"Filled\" />\n <MButton color=\"primary\" variant=\"text\" label=\"Text\" />\n <MButton color=\"primary\" variant=\"link\" label=\"Link\" />\n </MFlex>\n <MFlex gap=\"small\" wrap>\n <MButton color=\"danger\" variant=\"solid\" label=\"Danger\" />\n <MButton color=\"success\" variant=\"solid\" label=\"Success\" />\n <MButton color=\"info\" variant=\"filled\" label=\"Info\" />\n <MButton color=\"warning\" variant=\"outlined\" label=\"Warning\" />\n <MButton color=\"contrast\" variant=\"solid\" label=\"Contrast\" />\n </MFlex>\n </MFlex>\n</template>",
2304
2268
  "locale": "zh-CN"
2305
2269
  },
2306
2270
  {
@@ -2309,7 +2273,7 @@
2309
2273
  "sectionId": "代码演示",
2310
2274
  "lang": "vue",
2311
2275
  "preview": true,
2312
- "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <MSpace wrap>\n <MButton label=\"Default\" />\n <MButton\n shape=\"round\"\n label=\"Round\"\n />\n <MButton\n shape=\"circle\"\n icon=\"search\"\n icon-only\n aria-label=\"Search\"\n />\n <MButton\n shape=\"square\"\n icon=\"edit\"\n icon-only\n aria-label=\"Edit\"\n />\n </MSpace>\n</template>",
2276
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap align=\"center\">\n <MButton type=\"primary\" icon=\"search\" label=\"Search\" />\n <MButton icon=\"search\" icon-placement=\"end\" label=\"Search\" />\n <MButton type=\"primary\" icon=\"plus\" icon-only aria-label=\"Add\" />\n <MButton shape=\"circle\" icon=\"edit\" aria-label=\"Edit\" />\n </MFlex>\n</template>",
2313
2277
  "locale": "zh-CN"
2314
2278
  },
2315
2279
  {
@@ -2318,7 +2282,7 @@
2318
2282
  "sectionId": "代码演示",
2319
2283
  "lang": "vue",
2320
2284
  "preview": true,
2321
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Primary\" />\n <MButton label=\"Secondary\" severity=\"secondary\" />\n <MButton label=\"Success\" severity=\"success\" />\n <MButton label=\"Info\" severity=\"info\" />\n <MButton label=\"Warn\" severity=\"warn\" />\n <MButton label=\"Help\" severity=\"help\" />\n <MButton label=\"Danger\" severity=\"danger\" />\n <MButton label=\"Contrast\" severity=\"contrast\" />\n </div>\n</template>",
2285
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap align=\"center\">\n <MButton type=\"primary\" size=\"small\" label=\"Small\" />\n <MButton type=\"primary\" size=\"medium\" label=\"Medium\" />\n <MButton type=\"primary\" size=\"large\" label=\"Large\" />\n <MButton type=\"primary\" size=\"small\" icon=\"search\" icon-only aria-label=\"Search small\" />\n <MButton type=\"primary\" size=\"large\" icon=\"search\" icon-only aria-label=\"Search large\" />\n </MFlex>\n</template>",
2322
2286
  "locale": "zh-CN"
2323
2287
  },
2324
2288
  {
@@ -2327,7 +2291,7 @@
2327
2291
  "sectionId": "代码演示",
2328
2292
  "lang": "vue",
2329
2293
  "preview": true,
2330
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-4 w-full\">\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Outlined\" outlined />\n <MButton label=\"Success\" severity=\"success\" outlined />\n <MButton label=\"Danger\" severity=\"danger\" outlined />\n </div>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Raised\" raised />\n <MButton label=\"Rounded\" rounded />\n <MButton label=\"Plain\" plain />\n <MButton label=\"Plain Text\" text plain />\n </div>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Small\" size=\"small\" />\n <MButton label=\"Large\" size=\"large\" />\n <MButton label=\"Fluid\" fluid />\n </div>\n </div>\n</template>",
2294
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap align=\"center\">\n <MButton type=\"primary\" label=\"Default\" />\n <MButton type=\"primary\" shape=\"round\" label=\"Round\" />\n <MButton type=\"primary\" shape=\"circle\" icon=\"search\" aria-label=\"Search\" />\n <MButton type=\"primary\" shape=\"square\" icon=\"plus\" aria-label=\"Add\" />\n </MFlex>\n</template>",
2331
2295
  "locale": "zh-CN"
2332
2296
  },
2333
2297
  {
@@ -2336,7 +2300,7 @@
2336
2300
  "sectionId": "代码演示",
2337
2301
  "lang": "vue",
2338
2302
  "preview": true,
2339
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Text\" text />\n <MButton label=\"Text Danger\" text severity=\"danger\" />\n <MButton label=\"Link\" link />\n <MButton label=\"Link No Underline\" link :underline=\"false\" />\n <MButton label=\"Link Secondary\" link severity=\"secondary\" />\n </div>\n</template>",
2303
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" danger label=\"Primary\" />\n <MButton danger label=\"Default\" />\n <MButton type=\"dashed\" danger label=\"Dashed\" />\n <MButton type=\"text\" danger label=\"Text\" />\n <MButton type=\"link\" danger label=\"Link\" />\n </MFlex>\n</template>",
2340
2304
  "locale": "zh-CN"
2341
2305
  },
2342
2306
  {
@@ -2345,7 +2309,7 @@
2345
2309
  "sectionId": "代码演示",
2346
2310
  "lang": "vue",
2347
2311
  "preview": true,
2348
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Ghost\" ghost />\n <MButton label=\"Ghost Danger\" ghost severity=\"danger\" />\n <MButton label=\"Quaternary\" quaternary />\n <MButton label=\"Custom\" color=\"#e11d48\" />\n </div>\n</template>",
2312
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <div\n class=\"rounded-md p-4\"\n style=\"background: linear-gradient(135deg, #0f172a, #1d4ed8)\"\n >\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" ghost label=\"Primary Ghost\" />\n <MButton ghost label=\"Default Ghost\" />\n <MButton type=\"dashed\" ghost label=\"Dashed Ghost\" />\n <MButton type=\"primary\" danger ghost label=\"Danger Ghost\" />\n </MFlex>\n </div>\n</template>",
2349
2313
  "locale": "zh-CN"
2350
2314
  },
2351
2315
  {
@@ -2354,7 +2318,7 @@
2354
2318
  "sectionId": "代码演示",
2355
2319
  "lang": "vue",
2356
2320
  "preview": true,
2357
- "code": "<script setup lang=\"ts\">\nimport { MButton, MButtonGroup } from 'morya-ui'\n</script>\n\n<template>\n <MButtonGroup aria-label=\"对齐\">\n <MButton label=\"左\" />\n <MButton label=\"中\" severity=\"secondary\" />\n <MButton label=\"右\" severity=\"secondary\" />\n </MButtonGroup>\n</template>",
2321
+ "code": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { MButton, MFlex } from 'morya-ui'\n\nconst loading = ref(false)\n\nfunction toggle() {\n loading.value = true\n window.setTimeout(() => {\n loading.value = false\n }, 2000)\n}\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" label=\"Always\" loading />\n <MButton label=\"Delayed\" :loading=\"{ delay: 400 }\" />\n <MButton type=\"primary\" :loading=\"loading\" label=\"Click me\" @click=\"toggle\" />\n </MFlex>\n</template>",
2358
2322
  "locale": "zh-CN"
2359
2323
  },
2360
2324
  {
@@ -2363,7 +2327,7 @@
2363
2327
  "sectionId": "代码演示",
2364
2328
  "lang": "vue",
2365
2329
  "preview": true,
2366
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton icon=\"check\" label=\"Save\" />\n <MButton icon=\"search\" label=\"Search\" icon-pos=\"right\" severity=\"secondary\" />\n <MButton icon=\"plus\" icon-only rounded aria-label=\"Add\" />\n <MButton icon=\"trash\" icon-only rounded outlined severity=\"danger\" aria-label=\"Delete\" />\n <MButton label=\"Messages\" badge=\"2\" badge-severity=\"danger\" severity=\"secondary\" />\n </div>\n</template>",
2330
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" label=\"Primary\" disabled />\n <MButton label=\"Default\" disabled />\n <MButton type=\"dashed\" label=\"Dashed\" disabled />\n <MButton type=\"text\" label=\"Text\" disabled />\n <MButton type=\"link\" label=\"Link\" disabled />\n <MButton type=\"primary\" danger label=\"Danger\" disabled />\n </MFlex>\n</template>",
2367
2331
  "locale": "zh-CN"
2368
2332
  },
2369
2333
  {
@@ -2372,7 +2336,7 @@
2372
2336
  "sectionId": "代码演示",
2373
2337
  "lang": "vue",
2374
2338
  "preview": true,
2375
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst loading = ref(false)\n\nfunction toggleLoading() {\n loading.value = true\n window.setTimeout(() => {\n loading.value = false\n }, 900)\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Search\" icon=\"search\" :loading=\"loading\" @click=\"toggleLoading\" />\n <MButton label=\"Always Loading\" loading severity=\"secondary\" />\n </div>\n</template>",
2339
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex vertical gap=\"small\" class=\"w-full\">\n <MButton type=\"primary\" block label=\"Primary Block\" />\n <MButton block label=\"Default Block\" />\n <MButton type=\"dashed\" block label=\"Dashed Block\" />\n </MFlex>\n</template>",
2376
2340
  "locale": "zh-CN"
2377
2341
  },
2378
2342
  {
@@ -2381,7 +2345,34 @@
2381
2345
  "sectionId": "代码演示",
2382
2346
  "lang": "vue",
2383
2347
  "preview": true,
2384
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Disabled\" disabled />\n <MButton label=\"Disabled Outlined\" outlined disabled />\n <MButton label=\"Disabled Text\" text disabled />\n </div>\n</template>",
2348
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MButtonGroup, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex vertical gap=\"medium\">\n <MButtonGroup aria-label=\"行内操作\">\n <MButton label=\"编辑\" />\n <MButton label=\"分享\" />\n <MButton danger label=\"删除\" />\n </MButtonGroup>\n <MButtonGroup block aria-label=\"表单操作\">\n <MButton label=\"取消\" />\n <MButton type=\"primary\" label=\"确认\" />\n </MButtonGroup>\n </MFlex>\n</template>",
2349
+ "locale": "zh-CN"
2350
+ },
2351
+ {
2352
+ "id": "代码演示-12",
2353
+ "section": "代码演示",
2354
+ "sectionId": "代码演示",
2355
+ "lang": "vue",
2356
+ "preview": true,
2357
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" ripple label=\"Ripple\" />\n <MButton type=\"primary\" press label=\"Press\" />\n <MButton type=\"primary\" ripple press label=\"Both\" />\n </MFlex>\n</template>",
2358
+ "locale": "zh-CN"
2359
+ },
2360
+ {
2361
+ "id": "faq-1",
2362
+ "section": "FAQ",
2363
+ "sectionId": "faq",
2364
+ "lang": "vue",
2365
+ "preview": false,
2366
+ "code": "<MButton type=\"primary\">保存</MButton>",
2367
+ "locale": "zh-CN"
2368
+ },
2369
+ {
2370
+ "id": "faq-2",
2371
+ "section": "FAQ",
2372
+ "sectionId": "faq",
2373
+ "lang": "vue",
2374
+ "preview": false,
2375
+ "code": "<MButton color=\"primary\" variant=\"solid\">保存</MButton>",
2385
2376
  "locale": "zh-CN"
2386
2377
  },
2387
2378
  {
@@ -2390,7 +2381,7 @@
2390
2381
  "sectionId": "import",
2391
2382
  "lang": "ts",
2392
2383
  "preview": false,
2393
- "code": "import { MButton } from \"morya-ui\";",
2384
+ "code": "import { MButton, MButtonGroup } from 'morya-ui'",
2394
2385
  "locale": "en-US"
2395
2386
  },
2396
2387
  {
@@ -2399,7 +2390,7 @@
2399
2390
  "sectionId": "examples",
2400
2391
  "lang": "vue",
2401
2392
  "preview": true,
2402
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton>Submit</MButton>\n <MButton label=\"Label Prop\" />\n <MButton severity=\"secondary\" label=\"Secondary\" />\n </div>\n</template>",
2393
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" label=\"Primary\" />\n <MButton label=\"Default\" />\n <MButton type=\"dashed\" label=\"Dashed\" />\n <MButton type=\"text\" label=\"Text\" />\n <MButton type=\"link\" label=\"Link\" />\n </MFlex>\n</template>",
2403
2394
  "locale": "en-US"
2404
2395
  },
2405
2396
  {
@@ -2408,7 +2399,7 @@
2408
2399
  "sectionId": "examples",
2409
2400
  "lang": "vue",
2410
2401
  "preview": true,
2411
- "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <MSpace wrap>\n <MButton label=\"Primary\" />\n <MButton\n severity=\"secondary\"\n label=\"Default\"\n />\n <MButton\n variant=\"dashed\"\n label=\"Dashed\"\n />\n <MButton\n text\n label=\"Text\"\n />\n <MButton\n link\n label=\"Link\"\n />\n <MButton\n severity=\"danger\"\n label=\"Danger\"\n />\n </MSpace>\n</template>",
2402
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex vertical gap=\"medium\">\n <MFlex gap=\"small\" wrap>\n <MButton color=\"primary\" variant=\"solid\" label=\"Solid\" />\n <MButton color=\"primary\" variant=\"outlined\" label=\"Outlined\" />\n <MButton color=\"primary\" variant=\"dashed\" label=\"Dashed\" />\n <MButton color=\"primary\" variant=\"filled\" label=\"Filled\" />\n <MButton color=\"primary\" variant=\"text\" label=\"Text\" />\n <MButton color=\"primary\" variant=\"link\" label=\"Link\" />\n </MFlex>\n <MFlex gap=\"small\" wrap>\n <MButton color=\"danger\" variant=\"solid\" label=\"Danger\" />\n <MButton color=\"success\" variant=\"solid\" label=\"Success\" />\n <MButton color=\"info\" variant=\"filled\" label=\"Info\" />\n <MButton color=\"warning\" variant=\"outlined\" label=\"Warning\" />\n <MButton color=\"contrast\" variant=\"solid\" label=\"Contrast\" />\n </MFlex>\n </MFlex>\n</template>",
2412
2403
  "locale": "en-US"
2413
2404
  },
2414
2405
  {
@@ -2417,7 +2408,7 @@
2417
2408
  "sectionId": "examples",
2418
2409
  "lang": "vue",
2419
2410
  "preview": true,
2420
- "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <MSpace wrap>\n <MButton label=\"Default\" />\n <MButton\n shape=\"round\"\n label=\"Round\"\n />\n <MButton\n shape=\"circle\"\n icon=\"search\"\n icon-only\n aria-label=\"Search\"\n />\n <MButton\n shape=\"square\"\n icon=\"edit\"\n icon-only\n aria-label=\"Edit\"\n />\n </MSpace>\n</template>",
2411
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap align=\"center\">\n <MButton type=\"primary\" icon=\"search\" label=\"Search\" />\n <MButton icon=\"search\" icon-placement=\"end\" label=\"Search\" />\n <MButton type=\"primary\" icon=\"plus\" icon-only aria-label=\"Add\" />\n <MButton shape=\"circle\" icon=\"edit\" aria-label=\"Edit\" />\n </MFlex>\n</template>",
2421
2412
  "locale": "en-US"
2422
2413
  },
2423
2414
  {
@@ -2426,7 +2417,7 @@
2426
2417
  "sectionId": "examples",
2427
2418
  "lang": "vue",
2428
2419
  "preview": true,
2429
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Primary\" />\n <MButton label=\"Secondary\" severity=\"secondary\" />\n <MButton label=\"Success\" severity=\"success\" />\n <MButton label=\"Info\" severity=\"info\" />\n <MButton label=\"Warn\" severity=\"warn\" />\n <MButton label=\"Help\" severity=\"help\" />\n <MButton label=\"Danger\" severity=\"danger\" />\n <MButton label=\"Contrast\" severity=\"contrast\" />\n </div>\n</template>",
2420
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap align=\"center\">\n <MButton type=\"primary\" size=\"small\" label=\"Small\" />\n <MButton type=\"primary\" size=\"medium\" label=\"Medium\" />\n <MButton type=\"primary\" size=\"large\" label=\"Large\" />\n <MButton type=\"primary\" size=\"small\" icon=\"search\" icon-only aria-label=\"Search small\" />\n <MButton type=\"primary\" size=\"large\" icon=\"search\" icon-only aria-label=\"Search large\" />\n </MFlex>\n</template>",
2430
2421
  "locale": "en-US"
2431
2422
  },
2432
2423
  {
@@ -2435,7 +2426,7 @@
2435
2426
  "sectionId": "examples",
2436
2427
  "lang": "vue",
2437
2428
  "preview": true,
2438
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-4 w-full\">\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Outlined\" outlined />\n <MButton label=\"Success\" severity=\"success\" outlined />\n <MButton label=\"Danger\" severity=\"danger\" outlined />\n </div>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Raised\" raised />\n <MButton label=\"Rounded\" rounded />\n <MButton label=\"Plain\" plain />\n <MButton label=\"Plain Text\" text plain />\n </div>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Small\" size=\"small\" />\n <MButton label=\"Large\" size=\"large\" />\n <MButton label=\"Fluid\" fluid />\n </div>\n </div>\n</template>",
2429
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap align=\"center\">\n <MButton type=\"primary\" label=\"Default\" />\n <MButton type=\"primary\" shape=\"round\" label=\"Round\" />\n <MButton type=\"primary\" shape=\"circle\" icon=\"search\" aria-label=\"Search\" />\n <MButton type=\"primary\" shape=\"square\" icon=\"plus\" aria-label=\"Add\" />\n </MFlex>\n</template>",
2439
2430
  "locale": "en-US"
2440
2431
  },
2441
2432
  {
@@ -2444,7 +2435,7 @@
2444
2435
  "sectionId": "examples",
2445
2436
  "lang": "vue",
2446
2437
  "preview": true,
2447
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Text\" text />\n <MButton label=\"Text Danger\" text severity=\"danger\" />\n <MButton label=\"Link\" link />\n <MButton label=\"Link No Underline\" link :underline=\"false\" />\n <MButton label=\"Link Secondary\" link severity=\"secondary\" />\n </div>\n</template>",
2438
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" danger label=\"Primary\" />\n <MButton danger label=\"Default\" />\n <MButton type=\"dashed\" danger label=\"Dashed\" />\n <MButton type=\"text\" danger label=\"Text\" />\n <MButton type=\"link\" danger label=\"Link\" />\n </MFlex>\n</template>",
2448
2439
  "locale": "en-US"
2449
2440
  },
2450
2441
  {
@@ -2453,7 +2444,7 @@
2453
2444
  "sectionId": "examples",
2454
2445
  "lang": "vue",
2455
2446
  "preview": true,
2456
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Ghost\" ghost />\n <MButton label=\"Ghost Danger\" ghost severity=\"danger\" />\n <MButton label=\"Quaternary\" quaternary />\n <MButton label=\"Custom\" color=\"#e11d48\" />\n </div>\n</template>",
2447
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <div\n class=\"rounded-md p-4\"\n style=\"background: linear-gradient(135deg, #0f172a, #1d4ed8)\"\n >\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" ghost label=\"Primary Ghost\" />\n <MButton ghost label=\"Default Ghost\" />\n <MButton type=\"dashed\" ghost label=\"Dashed Ghost\" />\n <MButton type=\"primary\" danger ghost label=\"Danger Ghost\" />\n </MFlex>\n </div>\n</template>",
2457
2448
  "locale": "en-US"
2458
2449
  },
2459
2450
  {
@@ -2462,7 +2453,7 @@
2462
2453
  "sectionId": "examples",
2463
2454
  "lang": "vue",
2464
2455
  "preview": true,
2465
- "code": "<script setup lang=\"ts\">\nimport { MButton, MButtonGroup } from 'morya-ui'\n</script>\n\n<template>\n <MButtonGroup aria-label=\"Align\">\n <MButton label=\"Left\" />\n <MButton label=\"Center\" severity=\"secondary\" />\n <MButton label=\"Right\" severity=\"secondary\" />\n </MButtonGroup>\n</template>",
2456
+ "code": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { MButton, MFlex } from 'morya-ui'\n\nconst loading = ref(false)\n\nfunction toggle() {\n loading.value = true\n window.setTimeout(() => {\n loading.value = false\n }, 2000)\n}\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" label=\"Always\" loading />\n <MButton label=\"Delayed\" :loading=\"{ delay: 400 }\" />\n <MButton type=\"primary\" :loading=\"loading\" label=\"Click me\" @click=\"toggle\" />\n </MFlex>\n</template>",
2466
2457
  "locale": "en-US"
2467
2458
  },
2468
2459
  {
@@ -2471,7 +2462,7 @@
2471
2462
  "sectionId": "examples",
2472
2463
  "lang": "vue",
2473
2464
  "preview": true,
2474
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton icon=\"check\" label=\"Save\" />\n <MButton icon=\"search\" label=\"Search\" icon-pos=\"right\" severity=\"secondary\" />\n <MButton icon=\"plus\" icon-only rounded aria-label=\"Add\" />\n <MButton icon=\"trash\" icon-only rounded outlined severity=\"danger\" aria-label=\"Delete\" />\n <MButton label=\"Messages\" badge=\"2\" badge-severity=\"danger\" severity=\"secondary\" />\n </div>\n</template>",
2465
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" label=\"Primary\" disabled />\n <MButton label=\"Default\" disabled />\n <MButton type=\"dashed\" label=\"Dashed\" disabled />\n <MButton type=\"text\" label=\"Text\" disabled />\n <MButton type=\"link\" label=\"Link\" disabled />\n <MButton type=\"primary\" danger label=\"Danger\" disabled />\n </MFlex>\n</template>",
2475
2466
  "locale": "en-US"
2476
2467
  },
2477
2468
  {
@@ -2480,7 +2471,7 @@
2480
2471
  "sectionId": "examples",
2481
2472
  "lang": "vue",
2482
2473
  "preview": true,
2483
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst loading = ref(false)\n\nfunction toggleLoading() {\n loading.value = true\n window.setTimeout(() => {\n loading.value = false\n }, 900)\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Search\" icon=\"search\" :loading=\"loading\" @click=\"toggleLoading\" />\n <MButton label=\"Always Loading\" loading severity=\"secondary\" />\n </div>\n</template>",
2474
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex vertical gap=\"small\" class=\"w-full\">\n <MButton type=\"primary\" block label=\"Primary Block\" />\n <MButton block label=\"Default Block\" />\n <MButton type=\"dashed\" block label=\"Dashed Block\" />\n </MFlex>\n</template>",
2484
2475
  "locale": "en-US"
2485
2476
  },
2486
2477
  {
@@ -2489,114 +2480,141 @@
2489
2480
  "sectionId": "examples",
2490
2481
  "lang": "vue",
2491
2482
  "preview": true,
2492
- "code": "<script setup lang=\"ts\">\nimport { MButton } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Disabled\" disabled />\n <MButton label=\"Disabled Outlined\" outlined disabled />\n <MButton label=\"Disabled Text\" text disabled />\n </div>\n</template>",
2483
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MButtonGroup, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex vertical gap=\"medium\">\n <MButtonGroup aria-label=\"Row actions\">\n <MButton label=\"Edit\" />\n <MButton label=\"Share\" />\n <MButton danger label=\"Delete\" />\n </MButtonGroup>\n <MButtonGroup block aria-label=\"Form actions\">\n <MButton label=\"Cancel\" />\n <MButton type=\"primary\" label=\"Confirm\" />\n </MButtonGroup>\n </MFlex>\n</template>",
2484
+ "locale": "en-US"
2485
+ },
2486
+ {
2487
+ "id": "examples-12",
2488
+ "section": "Examples",
2489
+ "sectionId": "examples",
2490
+ "lang": "vue",
2491
+ "preview": true,
2492
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex gap=\"small\" wrap>\n <MButton type=\"primary\" ripple label=\"Ripple\" />\n <MButton type=\"primary\" press label=\"Press\" />\n <MButton type=\"primary\" ripple press label=\"Both\" />\n </MFlex>\n</template>",
2493
+ "locale": "en-US"
2494
+ },
2495
+ {
2496
+ "id": "faq-1",
2497
+ "section": "FAQ",
2498
+ "sectionId": "faq",
2499
+ "lang": "vue",
2500
+ "preview": false,
2501
+ "code": "<MButton type=\"primary\">Save</MButton>",
2502
+ "locale": "en-US"
2503
+ },
2504
+ {
2505
+ "id": "faq-2",
2506
+ "section": "FAQ",
2507
+ "sectionId": "faq",
2508
+ "lang": "vue",
2509
+ "preview": false,
2510
+ "code": "<MButton color=\"primary\" variant=\"solid\">Save</MButton>",
2493
2511
  "locale": "en-US"
2494
2512
  }
2495
2513
  ],
2496
2514
  "locales": {
2497
2515
  "zh-CN": {
2498
2516
  "title": "Button",
2499
- "description": "按钮用于触发即时动作。",
2517
+ "description": "触发即时操作的按钮。",
2500
2518
  "sections": [
2501
2519
  {
2502
2520
  "id": "overview",
2503
2521
  "title": "",
2504
- "body": "# Button\n\n按钮用于触发即时动作。"
2522
+ "body": "# Button\n\n触发提交、确认、导航等即时操作。"
2505
2523
  },
2506
2524
  {
2507
2525
  "id": "何时使用",
2508
2526
  "title": "何时使用",
2509
- "body": "- 需要触发表单提交、确认、导航或其它即时操作时。\n- 页面主操作使用默认(primary)按钮;次要操作用 `severity=\"secondary\"` 或 `outlined` / `text`。\n- 危险、破坏性操作用 `severity=\"danger\"`;轻量内联操作用 `text` 或 `link`。\n- 相邻一组互斥或相关操作用 `MButtonGroup`。"
2527
+ "body": "- 主操作:`type=\"primary\"`,同一操作区通常只放一个。\n- 次操作:默认按钮,或 `type=\"dashed\"` / `type=\"text\"`。\n- 内联导航或弱操作:`type=\"link\"` / `type=\"text\"`。\n- 破坏性操作:加 `danger`,并配合确认。\n- 相邻操作需要拼成一组时:用 `MButtonGroup`(仅视觉拼组)。"
2510
2528
  },
2511
2529
  {
2512
2530
  "id": "引入",
2513
2531
  "title": "引入",
2514
- "body": "```ts\nimport { MButton } from \"morya-ui\";\n```"
2532
+ "body": "```ts\nimport { MButton, MButtonGroup } from 'morya-ui'\n```"
2515
2533
  },
2516
2534
  {
2517
2535
  "id": "代码演示",
2518
2536
  "title": "代码演示",
2519
- "body": "### 基础用法\n\n通过默认插槽或 `label` 展示按钮文案。\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n### 类型\n\n常用组合:`severity=\"secondary\"` 默认样式、`variant=\"dashed\"` 虚线、`text` / `link` 文字链、`severity=\"danger\"` 危险、`fluid` 通栏。\n\n```vue preview src=\"./demos/VariantTypes.vue\"\n\n```\n\n### Shape\n\n`shape`:`default` / `round` / `circle` / `square`。旧 `rounded` 等价于 `shape=\"round\"`。\n\n```vue preview src=\"./demos/Shape.vue\"\n\n```\n\n### Severity\n\n使用 `severity` 定义按钮语义色;省略时为 primary。\n\n```vue preview src=\"./demos/Severity.vue\"\n\n```\n\n### Styles\n\n`outlined`、`text`、`link`、`raised`、`rounded`、`plain` 可自由组合。\n\n```vue preview src=\"./demos/Styles.vue\"\n\n```\n\n### Text & Link\n\n`text` 为轻量文字按钮;`link` 呈现为无背景的内联链接样式,默认悬浮下划线,设 `:underline=\"false\"` 可关闭。二者均可与 `severity` 组合。\n\n```vue preview src=\"./demos/TextAndLink.vue\"\n\n```\n\n### Ghost & Quaternary\n\n`ghost` 为浅色填充,等同于 `text` 的悬浮态;`quaternary` 更克制,适合工具栏次要操作。也可通过 `variant` 指定。\n\n```vue preview src=\"./demos/GhostAndQuaternary.vue\"\n\n```\n\n### Button Group\n\n`MButtonGroup` 将相邻按钮拼成一组。\n\n```vue preview src=\"./demos/ButtonGroup.zh.vue\"\n\n```\n\n### Icons & Badge\n\n支持 `icon`、`iconPos`、`iconOnly`,以及 `badge` 徽标。\n\n```vue preview src=\"./demos/IconsAndBadge.vue\"\n\n```\n\n### Loading\n\n`loading` 状态下显示 spinner 并阻止点击。\n\n```vue preview src=\"./demos/Loading.vue\"\n\n```\n\n### Disabled\n\n```vue preview src=\"./demos/Disabled.vue\"\n\n```"
2537
+ "body": "### 基础用法\n\n`type` 是 `color` + `variant` 的语法糖。省略时为默认描边按钮。\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n### 颜色与变体\n\n需要更细控制时直接设 `color` 与 `variant`;二者同时存在时优先于 `type`。\n\n```vue preview src=\"./demos/ColorVariant.vue\"\n\n```\n\n### 图标\n\n`icon` 可配名称或组件;`iconPlacement` 控制位置;纯图标请提供 `ariaLabel`。\n\n```vue preview src=\"./demos/Icon.vue\"\n\n```\n\n### 尺寸\n\n```vue preview src=\"./demos/Size.vue\"\n\n```\n\n### 形状\n\n`shape`:`default` / `round` / `circle` / `square`。\n\n```vue preview src=\"./demos/Shape.vue\"\n\n```\n\n### 危险按钮\n\n`danger` 将颜色切到危险色,并保留当前 `type` / `variant` 形态。\n\n```vue preview src=\"./demos/Danger.vue\"\n\n```\n\n### 幽灵按钮\n\n`ghost` 让背景透明,适合深色或复杂底图。对 `text` / `link` 无效。\n\n```vue preview src=\"./demos/Ghost.vue\"\n\n```\n\n### 加载中\n\n`loading` 可为布尔值,或 `{ delay, icon }`。加载中会禁用点击。\n\n```vue preview src=\"./demos/Loading.vue\"\n\n```\n\n### 不可用\n\n```vue preview src=\"./demos/Disabled.vue\"\n\n```\n\n### Block\n\n`block` 让按钮宽度撑满父容器。\n\n```vue preview src=\"./demos/Block.vue\"\n\n```\n\n### 按钮组\n\n`MButtonGroup` 只做视觉拼组(圆角与边框衔接),没有选中态。需要互斥切换时用 [`SelectButton`](/components/SelectButton)。\n\n```vue preview src=\"./demos/ButtonGroup.zh.vue\"\n\n```\n\n### 水波纹与按压\n\n`ripple` / `press` 默认关闭,需要时显式开启。\n\n```vue preview src=\"./demos/RipplePress.vue\"\n\n```"
2520
2538
  },
2521
2539
  {
2522
2540
  "id": "api",
2523
2541
  "title": "API",
2524
- "body": "### Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --------------- | ---------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- |\n| `label` | `string` | — | 按钮文案。存在默认插槽内容时以插槽为准。 |\n| `icon` | `IconName \\| Component` | — | 图标名称或自定义组件。 |\n| `iconPos` | `'left' \\| 'right' \\| 'top' \\| 'bottom'` | `'left'` | 图标相对标签的位置。 |\n| `iconOnly` | `boolean` | `false` | 强制方形纯图标按钮。 |\n| `badge` | `string` | — | 徽标文本。 |\n| `badgeSeverity` | `'secondary' \\| 'info' \\| 'success' \\| 'warn' \\| 'danger' \\| 'contrast' \\| null` | `null` | 徽标语义色。 |\n| `severity` | `'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast'` | — | 语义色。省略时为 primary。 |\n| `color` | `string` | — | 自定义颜色,覆盖 `severity`。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。默认中等;兼容 `sm` / `lg`。 |\n| `variant` | `'outlined' \\| 'dashed' \\| 'text' \\| 'link' \\| 'ghost' \\| 'quaternary'` | — | 样式变体快捷方式,等价于对应布尔 prop。 |\n| `outlined` | `boolean` | `false` | 描边按钮。 |\n| `dashed` | `boolean` | `false` | 虚线边框。 |\n| `text` | `boolean` | `false` | 文字按钮。 |\n| `link` | `boolean` | `false` | 链接按钮。 |\n| `underline` | `boolean` | `true` | `link` 悬浮下划线。设为 `false` 可关闭。 |\n| `ghost` | `boolean` | `false` | 浅色填充,等同于 `text` 的悬浮态。 |\n| `quaternary` | `boolean` | `false` | 极轻量文字按钮。 |\n| `plain` | `boolean` | `false` | 浅色填充,等同于 `outlined` 的悬浮态;也可与 `text` / `outlined` 组合弱化。 |\n| `raised` | `boolean` | `false` | 浮起阴影。 |\n| `rounded` | `boolean` | `false` | 全圆角(兼容;推荐 `shape=\"round\"`)。 |\n| `shape` | `'default' \\| 'circle' \\| 'round' \\| 'square'` | `'default'` | 形状。 |\n| `fluid` | `boolean` | `false` | 宽度撑满容器。 |\n| `loading` | `boolean` | `false` | 加载中,禁用点击并显示 spinner。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `ripple` | `boolean` | `false` | 点击水波纹。设为 `true` 可开启。 |\n| `press` | `boolean` | `false` | 按下时轻微缩放。设为 `true` 可开启。 |\n| `nativeType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | 原生 button type。 |\n| `autofocus` | `boolean` | `false` | 原生 autofocus。 |\n| `ariaLabel` | `string` | — | 可访问名称;图标按钮建议提供。 |\n\n### Events\n\n| 事件名 | 参数 | 说明 |\n| ------- | ------------ | -------------------- |\n| `click` | `MouseEvent` | 启用状态下点击触发。 |\n\n### Slots\n\n| 插槽名 | 说明 |\n| ------------- | -------------------------- |\n| `default` | 按钮内容,优先于 `label`。 |\n| `icon` | 自定义图标。 |\n| `loadingicon` | 自定义加载图标。 |\n\n### Instance\n\n| 方法 / 属性 | 说明 |\n| ----------- | -------------------------- |\n| `focus()` | 聚焦底层 button。 |\n| `ref` | 底层 `HTMLButtonElement`。 |\n\n### Props — ButtonGroup\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `fluid` | `boolean` | `false` | 宽度撑满容器。 |\n| `ariaLabel` | `string` | — | 组合的可访问名称。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | 组容器透传。 |"
2542
+ "body": "推荐组合顺序:`type` → `shape` → `size` → `loading` → `disabled`。\n\n### Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `type` | `'default' \\| 'primary' \\| 'dashed' \\| 'link' \\| 'text'` | `'default'` | 语法糖。同时设置 `color` 与 `variant` 时以后者为准。 |\n| `color` | `'default' \\| 'primary' \\| 'danger' \\| 'success' \\| 'info' \\| 'warning' \\| 'help' \\| 'contrast'` | — | 颜色轴。 |\n| `variant` | `'solid' \\| 'outlined' \\| 'dashed' \\| 'filled' \\| 'text' \\| 'link'` | — | 变体轴。 |\n| `danger` | `boolean` | `false` | 危险色语法糖。设置了 `color` 时以 `color` 为准。 |\n| `ghost` | `boolean` | `false` | 透明背景。对 `text` / `link` 无效。 |\n| `shape` | `'default' \\| 'circle' \\| 'round' \\| 'square'` | `'default'` | 形状。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸;可继承 ConfigProvider。 |\n| `block` | `boolean` | `false` | 宽度撑满父容器。 |\n| `loading` | `boolean \\| { delay?: number; icon?: IconName \\| Component }` | `false` | 加载中;可延迟出现并自定义图标。 |\n| `disabled` | `boolean` | `false` | 禁用;可继承 ConfigProvider。 |\n| `htmlType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | 原生 `button` 的 `type`。 |\n| `href` | `string` | — | 设置后渲染为 `<a>`。 |\n| `target` | `string` | — | 链接 `target`,需配合 `href`。 |\n| `label` | `string` | — | 文案;默认插槽优先。 |\n| `icon` | `IconName \\| Component` | — | 图标名称或组件。 |\n| `iconPlacement` | `'start' \\| 'end'` | `'start'` | 图标位置。 |\n| `iconOnly` | `boolean` | `false` | 强制纯图标方形按钮。 |\n| `autoInsertSpace` | `boolean` | `true` | 两个汉字之间插入空格。 |\n| `ripple` | `boolean` | `false` | 点击水波纹。 |\n| `press` | `boolean` | `false` | 按下缩放。 |\n| `autofocus` | `boolean` | `false` | 原生 autofocus。 |\n| `ariaLabel` | `string` | — | 可访问名称;纯图标按钮建议提供。 |\n| `pt` | `{ root?, icon?, content? }` | — | 语义结构透传。 |\n\n### Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `click` | `MouseEvent` | 点击时触发;`loading` / `disabled` 时不触发。 |\n\n### Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 按钮内容,优先于 `label`。 |\n| `icon` | 自定义图标。 |\n| `loadingicon` | 自定义加载图标。 |\n\n### Instance\n\n| 方法 / 属性 | 说明 |\n| --- | --- |\n| `focus()` | 聚焦根元素。 |\n| `ref` | 根 `HTMLButtonElement` 或 `HTMLAnchorElement`。 |\n\n### MButtonGroup Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `block` | `boolean` | `false` | 宽度撑满父容器。 |\n| `ariaLabel` | `string` | — | 组的可访问名称。 |\n| `pt` | `{ root? }` | — | 组容器透传。 |"
2525
2543
  },
2526
2544
  {
2527
2545
  "id": "design-token",
2528
2546
  "title": "Design Token",
2529
- "body": "复用全局 `--m-*` 令牌,见[设计令牌](/docs/design-tokens)。组件级 `--m-button-*` 表将在后续补充。"
2547
+ "body": "复用全局 `--m-*` 令牌,见[设计令牌](/docs/design-tokens)。按钮在根节点暴露 `--m-button-*`(尺寸、圆角、色阶、填充透明度、动效等),主题切换时跟随 `--m-color-*` / `--m-control-*` / `--m-motion-*`。"
2530
2548
  },
2531
2549
  {
2532
2550
  "id": "semantic-dom",
2533
2551
  "title": "Semantic DOM",
2534
- "body": "`MButton` 是叶子组件:根节点即原生 `<button class=\"m-button\">`,`class` / `style` / 事件直接落在该元素上(见[样式与 attrs](/docs/attrs)、[Common Props](/docs/common-props))。\n\n```text\nbutton.m-button ← 根(交互元素)\n span.m-button__ripple ← 可选:ripple 层\n span.m-button__icon ← 图标 / loading spinner(aria-hidden)\n span.m-button__spinner ← loading 时\n span.m-button__label ← 文案(插槽或 label)\n span.m-button__badge* ← 可选徽标\n```\n\n`MButton` 本身不暴露 `pt`;拼组用 `MButtonGroup` 的 `pt.root` 修改组容器。绑定样式时优先针对 `.m-button`,再按需覆盖 `__icon` / `__label` / `__badge`。"
2552
+ "body": "根节点即交互元素:有 `href` 时为 `<a class=\"m-button\">`,否则为 `<button class=\"m-button\">`。\n\n```text\nbutton.m-button / a.m-button\n span.m-button__ripple* ← ripple 开启时\n span.m-button__icon* ← 图标 / loading\n span.m-button__label* ← 文案\n```\n\n可用 `pt.root` / `pt.icon` / `pt.content` 覆盖各节点。更多约定见[样式与 attrs](/docs/attrs)、[Common Props](/docs/common-props)。"
2535
2553
  },
2536
2554
  {
2537
2555
  "id": "faq",
2538
2556
  "title": "FAQ",
2539
- "body": "### `severity` 和 `variant` 有什么区别?\n\n`severity` 控制语义色(如 `danger`、`success`);省略时为 primary。`variant`(或对应布尔 prop)控制样式形态,如 `outlined`、`text`、`link`、`ghost`。二者可组合,例如 `severity=\"danger\"` + `variant=\"outlined\"`。\n\n### `text` 和 `link` 该怎么选?`rounded` 和 `shape` 呢?\n\n`text` 是轻量文字按钮;`link` 更接近内联链接(默认悬浮下划线)。形状优先用 `shape`(`round` / `circle` / `square`);旧的 `rounded` 仍可用,等价于 `shape=\"round\"`。"
2557
+ "body": "### `type` 和 `color` / `variant` 怎么选?\n\n日常优先用 `type`。需要跨色系细调时再用 `color` + `variant`;二者齐全时覆盖 `type`。\n\n| `type` | 等价于 |\n| --- | --- |\n| `primary` | `color=\"primary\"` + `variant=\"solid\"` |\n| `default` | `color=\"default\"` + `variant=\"outlined\"` |\n| `dashed` | `color=\"default\"` + `variant=\"dashed\"` |\n| `text` | `color=\"default\"` + `variant=\"text\"` |\n| `link` | `color=\"link\"` + `variant=\"link\"` |\n\n```vue\n<MButton type=\"primary\">保存</MButton>\n```\n\n等同于\n\n```vue\n<MButton color=\"primary\" variant=\"solid\">保存</MButton>\n```\n\n### Button 的 `color` 和其它组件的 `severity`?\n\nButton 使用 `color` / `variant`。Badge、Tag、Alert、Message、Toast 等反馈组件仍使用 `severity`。\n\n### `text` 和 `link` 怎么区分?\n\n`type=\"text\"`(或 `variant=\"text\"`)保留按钮热区与高度;`type=\"link\"` 更接近内联链接。"
2540
2558
  },
2541
2559
  {
2542
2560
  "id": "无障碍",
2543
2561
  "title": "无障碍",
2544
- "body": "- 渲染原生 `<button>`。\n- 纯图标按钮请设置 `ariaLabel`(或可访问的文本标签)。\n- `loading` 时设置 `aria-busy`,并禁用交互。"
2562
+ "body": "- 默认渲染原生 `<button>`;设置 `href` 时渲染 `<a>`。\n- 纯图标按钮请设置 `ariaLabel`(或可见文本)。\n- `loading` 时设置 `aria-busy`,并阻止点击。\n- 禁用的链接按钮会去掉 `href`,并设置 `aria-disabled` 与 `tabindex=\"-1\"`。"
2545
2563
  }
2546
2564
  ],
2547
- "markdown": "---\ntitle: Button\ncategory: 01 / BASIC\ndescription: 按钮用于触发即时动作。\n---\n\n# Button\n\n按钮用于触发即时动作。\n\n## 何时使用\n\n- 需要触发表单提交、确认、导航或其它即时操作时。\n- 页面主操作使用默认(primary)按钮;次要操作用 `severity=\"secondary\"` 或 `outlined` / `text`。\n- 危险、破坏性操作用 `severity=\"danger\"`;轻量内联操作用 `text` 或 `link`。\n- 相邻一组互斥或相关操作用 `MButtonGroup`。\n\n## 引入\n\n```ts\nimport { MButton } from \"morya-ui\";\n```\n\n## 代码演示\n\n### 基础用法\n\n通过默认插槽或 `label` 展示按钮文案。\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n### 类型\n\n常用组合:`severity=\"secondary\"` 默认样式、`variant=\"dashed\"` 虚线、`text` / `link` 文字链、`severity=\"danger\"` 危险、`fluid` 通栏。\n\n```vue preview src=\"./demos/VariantTypes.vue\"\n\n```\n\n### Shape\n\n`shape`:`default` / `round` / `circle` / `square`。旧 `rounded` 等价于 `shape=\"round\"`。\n\n```vue preview src=\"./demos/Shape.vue\"\n\n```\n\n### Severity\n\n使用 `severity` 定义按钮语义色;省略时为 primary。\n\n```vue preview src=\"./demos/Severity.vue\"\n\n```\n\n### Styles\n\n`outlined`、`text`、`link`、`raised`、`rounded`、`plain` 可自由组合。\n\n```vue preview src=\"./demos/Styles.vue\"\n\n```\n\n### Text & Link\n\n`text` 为轻量文字按钮;`link` 呈现为无背景的内联链接样式,默认悬浮下划线,设 `:underline=\"false\"` 可关闭。二者均可与 `severity` 组合。\n\n```vue preview src=\"./demos/TextAndLink.vue\"\n\n```\n\n### Ghost & Quaternary\n\n`ghost` 为浅色填充,等同于 `text` 的悬浮态;`quaternary` 更克制,适合工具栏次要操作。也可通过 `variant` 指定。\n\n```vue preview src=\"./demos/GhostAndQuaternary.vue\"\n\n```\n\n### Button Group\n\n`MButtonGroup` 将相邻按钮拼成一组。\n\n```vue preview src=\"./demos/ButtonGroup.zh.vue\"\n\n```\n\n### Icons & Badge\n\n支持 `icon`、`iconPos`、`iconOnly`,以及 `badge` 徽标。\n\n```vue preview src=\"./demos/IconsAndBadge.vue\"\n\n```\n\n### Loading\n\n`loading` 状态下显示 spinner 并阻止点击。\n\n```vue preview src=\"./demos/Loading.vue\"\n\n```\n\n### Disabled\n\n```vue preview src=\"./demos/Disabled.vue\"\n\n```\n\n## API\n\n### Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --------------- | ---------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- |\n| `label` | `string` | — | 按钮文案。存在默认插槽内容时以插槽为准。 |\n| `icon` | `IconName \\| Component` | — | 图标名称或自定义组件。 |\n| `iconPos` | `'left' \\| 'right' \\| 'top' \\| 'bottom'` | `'left'` | 图标相对标签的位置。 |\n| `iconOnly` | `boolean` | `false` | 强制方形纯图标按钮。 |\n| `badge` | `string` | — | 徽标文本。 |\n| `badgeSeverity` | `'secondary' \\| 'info' \\| 'success' \\| 'warn' \\| 'danger' \\| 'contrast' \\| null` | `null` | 徽标语义色。 |\n| `severity` | `'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast'` | — | 语义色。省略时为 primary。 |\n| `color` | `string` | — | 自定义颜色,覆盖 `severity`。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。默认中等;兼容 `sm` / `lg`。 |\n| `variant` | `'outlined' \\| 'dashed' \\| 'text' \\| 'link' \\| 'ghost' \\| 'quaternary'` | — | 样式变体快捷方式,等价于对应布尔 prop。 |\n| `outlined` | `boolean` | `false` | 描边按钮。 |\n| `dashed` | `boolean` | `false` | 虚线边框。 |\n| `text` | `boolean` | `false` | 文字按钮。 |\n| `link` | `boolean` | `false` | 链接按钮。 |\n| `underline` | `boolean` | `true` | `link` 悬浮下划线。设为 `false` 可关闭。 |\n| `ghost` | `boolean` | `false` | 浅色填充,等同于 `text` 的悬浮态。 |\n| `quaternary` | `boolean` | `false` | 极轻量文字按钮。 |\n| `plain` | `boolean` | `false` | 浅色填充,等同于 `outlined` 的悬浮态;也可与 `text` / `outlined` 组合弱化。 |\n| `raised` | `boolean` | `false` | 浮起阴影。 |\n| `rounded` | `boolean` | `false` | 全圆角(兼容;推荐 `shape=\"round\"`)。 |\n| `shape` | `'default' \\| 'circle' \\| 'round' \\| 'square'` | `'default'` | 形状。 |\n| `fluid` | `boolean` | `false` | 宽度撑满容器。 |\n| `loading` | `boolean` | `false` | 加载中,禁用点击并显示 spinner。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `ripple` | `boolean` | `false` | 点击水波纹。设为 `true` 可开启。 |\n| `press` | `boolean` | `false` | 按下时轻微缩放。设为 `true` 可开启。 |\n| `nativeType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | 原生 button type。 |\n| `autofocus` | `boolean` | `false` | 原生 autofocus。 |\n| `ariaLabel` | `string` | — | 可访问名称;图标按钮建议提供。 |\n\n### Events\n\n| 事件名 | 参数 | 说明 |\n| ------- | ------------ | -------------------- |\n| `click` | `MouseEvent` | 启用状态下点击触发。 |\n\n### Slots\n\n| 插槽名 | 说明 |\n| ------------- | -------------------------- |\n| `default` | 按钮内容,优先于 `label`。 |\n| `icon` | 自定义图标。 |\n| `loadingicon` | 自定义加载图标。 |\n\n### Instance\n\n| 方法 / 属性 | 说明 |\n| ----------- | -------------------------- |\n| `focus()` | 聚焦底层 button。 |\n| `ref` | 底层 `HTMLButtonElement`。 |\n\n### Props — ButtonGroup\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `fluid` | `boolean` | `false` | 宽度撑满容器。 |\n| `ariaLabel` | `string` | — | 组合的可访问名称。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | 组容器透传。 |\n\n## Design Token\n\n复用全局 `--m-*` 令牌,见[设计令牌](/docs/design-tokens)。组件级 `--m-button-*` 表将在后续补充。\n\n## Semantic DOM\n\n`MButton` 是叶子组件:根节点即原生 `<button class=\"m-button\">`,`class` / `style` / 事件直接落在该元素上(见[样式与 attrs](/docs/attrs)、[Common Props](/docs/common-props))。\n\n```text\nbutton.m-button ← 根(交互元素)\n span.m-button__ripple ← 可选:ripple 层\n span.m-button__icon ← 图标 / loading spinner(aria-hidden)\n span.m-button__spinner ← loading 时\n span.m-button__label ← 文案(插槽或 label)\n span.m-button__badge* ← 可选徽标\n```\n\n`MButton` 本身不暴露 `pt`;拼组用 `MButtonGroup` 的 `pt.root` 修改组容器。绑定样式时优先针对 `.m-button`,再按需覆盖 `__icon` / `__label` / `__badge`。\n\n## FAQ\n\n### `severity` 和 `variant` 有什么区别?\n\n`severity` 控制语义色(如 `danger`、`success`);省略时为 primary。`variant`(或对应布尔 prop)控制样式形态,如 `outlined`、`text`、`link`、`ghost`。二者可组合,例如 `severity=\"danger\"` + `variant=\"outlined\"`。\n\n### `text` 和 `link` 该怎么选?`rounded` 和 `shape` 呢?\n\n`text` 是轻量文字按钮;`link` 更接近内联链接(默认悬浮下划线)。形状优先用 `shape`(`round` / `circle` / `square`);旧的 `rounded` 仍可用,等价于 `shape=\"round\"`。\n\n## 无障碍\n\n- 渲染原生 `<button>`。\n- 纯图标按钮请设置 `ariaLabel`(或可访问的文本标签)。\n- `loading` 时设置 `aria-busy`,并禁用交互。\n"
2565
+ "markdown": "---\ntitle: Button\ncategory: 01 / BASIC\ndescription: 触发即时操作的按钮。\n---\n\n# Button\n\n触发提交、确认、导航等即时操作。\n\n## 何时使用\n\n- 主操作:`type=\"primary\"`,同一操作区通常只放一个。\n- 次操作:默认按钮,或 `type=\"dashed\"` / `type=\"text\"`。\n- 内联导航或弱操作:`type=\"link\"` / `type=\"text\"`。\n- 破坏性操作:加 `danger`,并配合确认。\n- 相邻操作需要拼成一组时:用 `MButtonGroup`(仅视觉拼组)。\n\n## 引入\n\n```ts\nimport { MButton, MButtonGroup } from 'morya-ui'\n```\n\n## 代码演示\n\n### 基础用法\n\n`type` 是 `color` + `variant` 的语法糖。省略时为默认描边按钮。\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n### 颜色与变体\n\n需要更细控制时直接设 `color` 与 `variant`;二者同时存在时优先于 `type`。\n\n```vue preview src=\"./demos/ColorVariant.vue\"\n\n```\n\n### 图标\n\n`icon` 可配名称或组件;`iconPlacement` 控制位置;纯图标请提供 `ariaLabel`。\n\n```vue preview src=\"./demos/Icon.vue\"\n\n```\n\n### 尺寸\n\n```vue preview src=\"./demos/Size.vue\"\n\n```\n\n### 形状\n\n`shape`:`default` / `round` / `circle` / `square`。\n\n```vue preview src=\"./demos/Shape.vue\"\n\n```\n\n### 危险按钮\n\n`danger` 将颜色切到危险色,并保留当前 `type` / `variant` 形态。\n\n```vue preview src=\"./demos/Danger.vue\"\n\n```\n\n### 幽灵按钮\n\n`ghost` 让背景透明,适合深色或复杂底图。对 `text` / `link` 无效。\n\n```vue preview src=\"./demos/Ghost.vue\"\n\n```\n\n### 加载中\n\n`loading` 可为布尔值,或 `{ delay, icon }`。加载中会禁用点击。\n\n```vue preview src=\"./demos/Loading.vue\"\n\n```\n\n### 不可用\n\n```vue preview src=\"./demos/Disabled.vue\"\n\n```\n\n### Block\n\n`block` 让按钮宽度撑满父容器。\n\n```vue preview src=\"./demos/Block.vue\"\n\n```\n\n### 按钮组\n\n`MButtonGroup` 只做视觉拼组(圆角与边框衔接),没有选中态。需要互斥切换时用 [`SelectButton`](/components/SelectButton)。\n\n```vue preview src=\"./demos/ButtonGroup.zh.vue\"\n\n```\n\n### 水波纹与按压\n\n`ripple` / `press` 默认关闭,需要时显式开启。\n\n```vue preview src=\"./demos/RipplePress.vue\"\n\n```\n\n## API\n\n推荐组合顺序:`type` → `shape` → `size` → `loading` → `disabled`。\n\n### Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `type` | `'default' \\| 'primary' \\| 'dashed' \\| 'link' \\| 'text'` | `'default'` | 语法糖。同时设置 `color` 与 `variant` 时以后者为准。 |\n| `color` | `'default' \\| 'primary' \\| 'danger' \\| 'success' \\| 'info' \\| 'warning' \\| 'help' \\| 'contrast'` | — | 颜色轴。 |\n| `variant` | `'solid' \\| 'outlined' \\| 'dashed' \\| 'filled' \\| 'text' \\| 'link'` | — | 变体轴。 |\n| `danger` | `boolean` | `false` | 危险色语法糖。设置了 `color` 时以 `color` 为准。 |\n| `ghost` | `boolean` | `false` | 透明背景。对 `text` / `link` 无效。 |\n| `shape` | `'default' \\| 'circle' \\| 'round' \\| 'square'` | `'default'` | 形状。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸;可继承 ConfigProvider。 |\n| `block` | `boolean` | `false` | 宽度撑满父容器。 |\n| `loading` | `boolean \\| { delay?: number; icon?: IconName \\| Component }` | `false` | 加载中;可延迟出现并自定义图标。 |\n| `disabled` | `boolean` | `false` | 禁用;可继承 ConfigProvider。 |\n| `htmlType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | 原生 `button` 的 `type`。 |\n| `href` | `string` | — | 设置后渲染为 `<a>`。 |\n| `target` | `string` | — | 链接 `target`,需配合 `href`。 |\n| `label` | `string` | — | 文案;默认插槽优先。 |\n| `icon` | `IconName \\| Component` | — | 图标名称或组件。 |\n| `iconPlacement` | `'start' \\| 'end'` | `'start'` | 图标位置。 |\n| `iconOnly` | `boolean` | `false` | 强制纯图标方形按钮。 |\n| `autoInsertSpace` | `boolean` | `true` | 两个汉字之间插入空格。 |\n| `ripple` | `boolean` | `false` | 点击水波纹。 |\n| `press` | `boolean` | `false` | 按下缩放。 |\n| `autofocus` | `boolean` | `false` | 原生 autofocus。 |\n| `ariaLabel` | `string` | — | 可访问名称;纯图标按钮建议提供。 |\n| `pt` | `{ root?, icon?, content? }` | — | 语义结构透传。 |\n\n### Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `click` | `MouseEvent` | 点击时触发;`loading` / `disabled` 时不触发。 |\n\n### Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 按钮内容,优先于 `label`。 |\n| `icon` | 自定义图标。 |\n| `loadingicon` | 自定义加载图标。 |\n\n### Instance\n\n| 方法 / 属性 | 说明 |\n| --- | --- |\n| `focus()` | 聚焦根元素。 |\n| `ref` | 根 `HTMLButtonElement` 或 `HTMLAnchorElement`。 |\n\n### MButtonGroup Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `block` | `boolean` | `false` | 宽度撑满父容器。 |\n| `ariaLabel` | `string` | — | 组的可访问名称。 |\n| `pt` | `{ root? }` | — | 组容器透传。 |\n\n## Design Token\n\n复用全局 `--m-*` 令牌,见[设计令牌](/docs/design-tokens)。按钮在根节点暴露 `--m-button-*`(尺寸、圆角、色阶、填充透明度、动效等),主题切换时跟随 `--m-color-*` / `--m-control-*` / `--m-motion-*`。\n\n## Semantic DOM\n\n根节点即交互元素:有 `href` 时为 `<a class=\"m-button\">`,否则为 `<button class=\"m-button\">`。\n\n```text\nbutton.m-button / a.m-button\n span.m-button__ripple* ← ripple 开启时\n span.m-button__icon* ← 图标 / loading\n span.m-button__label* ← 文案\n```\n\n可用 `pt.root` / `pt.icon` / `pt.content` 覆盖各节点。更多约定见[样式与 attrs](/docs/attrs)、[Common Props](/docs/common-props)。\n\n## FAQ\n\n### `type` 和 `color` / `variant` 怎么选?\n\n日常优先用 `type`。需要跨色系细调时再用 `color` + `variant`;二者齐全时覆盖 `type`。\n\n| `type` | 等价于 |\n| --- | --- |\n| `primary` | `color=\"primary\"` + `variant=\"solid\"` |\n| `default` | `color=\"default\"` + `variant=\"outlined\"` |\n| `dashed` | `color=\"default\"` + `variant=\"dashed\"` |\n| `text` | `color=\"default\"` + `variant=\"text\"` |\n| `link` | `color=\"link\"` + `variant=\"link\"` |\n\n```vue\n<MButton type=\"primary\">保存</MButton>\n```\n\n等同于\n\n```vue\n<MButton color=\"primary\" variant=\"solid\">保存</MButton>\n```\n\n### Button 的 `color` 和其它组件的 `severity`?\n\nButton 使用 `color` / `variant`。Badge、Tag、Alert、Message、Toast 等反馈组件仍使用 `severity`。\n\n### `text` 和 `link` 怎么区分?\n\n`type=\"text\"`(或 `variant=\"text\"`)保留按钮热区与高度;`type=\"link\"` 更接近内联链接。\n\n## 无障碍\n\n- 默认渲染原生 `<button>`;设置 `href` 时渲染 `<a>`。\n- 纯图标按钮请设置 `ariaLabel`(或可见文本)。\n- `loading` 时设置 `aria-busy`,并阻止点击。\n- 禁用的链接按钮会去掉 `href`,并设置 `aria-disabled` 与 `tabindex=\"-1\"`。\n"
2548
2566
  },
2549
2567
  "en-US": {
2550
2568
  "title": "Button",
2551
- "description": "Button triggers an immediate action.",
2569
+ "description": "A button that triggers an immediate action.",
2552
2570
  "sections": [
2553
2571
  {
2554
2572
  "id": "overview",
2555
2573
  "title": "",
2556
- "body": "# Button\n\nButton triggers an immediate action."
2574
+ "body": "# Button\n\nUse Button for submit, confirm, navigate, and other immediate actions."
2557
2575
  },
2558
2576
  {
2559
2577
  "id": "when-to-use",
2560
2578
  "title": "When to use",
2561
- "body": "- Use when the user needs to trigger a submit, confirm, navigate, or other immediate action.\n- Prefer the default (primary) button for the main action; use `severity=\"secondary\"` or `outlined` / `text` for secondary actions.\n- Use `severity=\"danger\"` for destructive actions; use `text` or `link` for lightweight inline actions.\n- Use `MButtonGroup` when adjacent buttons belong together."
2579
+ "body": "- Primary action: `type=\"primary\"`. Keep one primary action in a region.\n- Secondary action: the default button, or `type=\"dashed\"` / `type=\"text\"`.\n- Inline or low-emphasis action: `type=\"link\"` / `type=\"text\"`.\n- Destructive action: add `danger`, and confirm when needed.\n- Adjacent actions that should look joined: wrap them in `MButtonGroup` (visual only)."
2562
2580
  },
2563
2581
  {
2564
2582
  "id": "import",
2565
2583
  "title": "Import",
2566
- "body": "```ts\nimport { MButton } from \"morya-ui\";\n```"
2584
+ "body": "```ts\nimport { MButton, MButtonGroup } from 'morya-ui'\n```"
2567
2585
  },
2568
2586
  {
2569
2587
  "id": "examples",
2570
2588
  "title": "Examples",
2571
- "body": "### Basic\n\nShow button text via the default slot or the `label` prop.\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n### Types\n\nCommon combinations: default primary, `severity=\"secondary\"`, `variant=\"dashed\"`, `text` / `link`, `severity=\"danger\"`, and `fluid` for full width.\n\n```vue preview src=\"./demos/VariantTypes.vue\"\n\n```\n\n### Shape\n\n`shape`: `default` / `round` / `circle` / `square`. Legacy `rounded` maps to `shape=\"round\"`.\n\n```vue preview src=\"./demos/Shape.vue\"\n\n```\n\n### Severity\n\nUse `severity` for semantic color; defaults to primary when omitted.\n\n```vue preview src=\"./demos/Severity.vue\"\n\n```\n\n### Styles\n\n`outlined`, `text`, `link`, `raised`, `rounded`, and `plain` can be combined freely.\n\n```vue preview src=\"./demos/Styles.vue\"\n\n```\n\n### Text & Link\n\n`text` is a lightweight text button; `link` renders as a backgroundless inline link style with underline on hover by default. Set `:underline=\"false\"` to disable. Both can be combined with `severity`.\n\n```vue preview src=\"./demos/TextAndLink.vue\"\n\n```\n\n### Ghost & Quaternary\n\n`ghost` is a soft fill matching text hover; `quaternary` is quieter for secondary toolbar actions. Both can be set via `variant`.\n\n```vue preview src=\"./demos/GhostAndQuaternary.vue\"\n\n```\n\n### Button Group\n\n`MButtonGroup` joins adjacent buttons.\n\n```vue preview src=\"./demos/ButtonGroup.en.vue\"\n\n```\n\n### Icons & Badge\n\nSupports `icon`, `iconPos`, `iconOnly`, and a `badge`.\n\n```vue preview src=\"./demos/IconsAndBadge.vue\"\n\n```\n\n### Loading\n\nIn the `loading` state, a spinner is shown and clicks are blocked.\n\n```vue preview src=\"./demos/Loading.vue\"\n\n```\n\n### Disabled\n\n```vue preview src=\"./demos/Disabled.vue\"\n\n```"
2589
+ "body": "### Basic\n\n`type` is sugar for a `color` + `variant` pair. Omit it for the default outlined button.\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n### Color & variant\n\nSet `color` and `variant` for finer control. When both are set, they win over `type`.\n\n```vue preview src=\"./demos/ColorVariant.vue\"\n\n```\n\n### Icon\n\n`icon` accepts a name or component. Use `iconPlacement` for position. Icon-only buttons need `ariaLabel`.\n\n```vue preview src=\"./demos/Icon.vue\"\n\n```\n\n### Size\n\n```vue preview src=\"./demos/Size.vue\"\n\n```\n\n### Shape\n\n`shape`: `default` / `round` / `circle` / `square`.\n\n```vue preview src=\"./demos/Shape.vue\"\n\n```\n\n### Danger\n\n`danger` switches the color to danger while keeping the current `type` / `variant` look.\n\n```vue preview src=\"./demos/Danger.vue\"\n\n```\n\n### Ghost\n\n`ghost` makes the background transparent for dark or busy surfaces. It is ignored for `text` / `link`.\n\n```vue preview src=\"./demos/Ghost.vue\"\n\n```\n\n### Loading\n\n`loading` accepts a boolean or `{ delay, icon }`. Clicks are blocked while loading.\n\n```vue preview src=\"./demos/Loading.vue\"\n\n```\n\n### Disabled\n\n```vue preview src=\"./demos/Disabled.vue\"\n\n```\n\n### Block\n\n`block` stretches the button to the parent width.\n\n```vue preview src=\"./demos/Block.vue\"\n\n```\n\n### Button group\n\n`MButtonGroup` only joins adjacent buttons visually. It has no selected state. For mutually exclusive switching, use [`SelectButton`](/components/SelectButton).\n\n```vue preview src=\"./demos/ButtonGroup.en.vue\"\n\n```\n\n### Ripple & press\n\n`ripple` and `press` are off by default. Turn them on when you want the motion.\n\n```vue preview src=\"./demos/RipplePress.vue\"\n\n```"
2572
2590
  },
2573
2591
  {
2574
2592
  "id": "api",
2575
2593
  "title": "API",
2576
- "body": "### Props\n\n| Prop | Type | Default | Description |\n| --------------- | ---------------------------------------------------------------------------------- | ---------- | --------------------------------------------------------------------- |\n| `label` | `string` | — | Button text. Default slot content takes precedence when present. |\n| `icon` | `IconName \\| Component` | — | Icon name or custom component. |\n| `iconPos` | `'left' \\| 'right' \\| 'top' \\| 'bottom'` | `'left'` | Icon position relative to the label. |\n| `iconOnly` | `boolean` | `false` | Force a square icon-only button. |\n| `badge` | `string` | — | Badge text. |\n| `badgeSeverity` | `'secondary' \\| 'info' \\| 'success' \\| 'warn' \\| 'danger' \\| 'contrast' \\| null` | `null` | Badge semantic color. |\n| `severity` | `'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast'` | — | Semantic color. Defaults to primary when omitted. |\n| `color` | `string` | — | Custom color; overrides `severity`. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Size. Medium by default; `sm` / `lg` aliases supported. |\n| `variant` | `'outlined' \\| 'text' \\| 'link' \\| 'ghost' \\| 'quaternary'` | — | Style variant shortcut, equivalent to the matching boolean prop. |\n| `outlined` | `boolean` | `false` | Outlined button. |\n| `text` | `boolean` | `false` | Text button. |\n| `link` | `boolean` | `false` | Link button. |\n| `underline` | `boolean` | `true` | Underline on hover for `link`. Set `false` to disable. |\n| `ghost` | `boolean` | `false` | Soft fill matching text hover. |\n| `quaternary` | `boolean` | `false` | Extra-quiet text button. |\n| `plain` | `boolean` | `false` | Soft fill matching outlined hover; can also mute `text` / `outlined`. |\n| `raised` | `boolean` | `false` | Raised shadow. |\n| `rounded` | `boolean` | `false` | Fully rounded. |\n| `fluid` | `boolean` | `false` | Stretch to full container width. |\n| `loading` | `boolean` | `false` | Loading state; disables clicks and shows a spinner. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `ripple` | `boolean` | `false` | Click ripple ink. Set `true` to enable. |\n| `press` | `boolean` | `false` | Slight scale while pressed. Set `true` to enable. |\n| `nativeType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | Native button type. |\n| `autofocus` | `boolean` | `false` | Native autofocus. |\n| `ariaLabel` | `string` | — | Accessible name; recommended for icon-only buttons. |\n\n### Events\n\n| Event | Prop | Description |\n| ------- | ------------ | ---------------------------- |\n| `click` | `MouseEvent` | Fired on click when enabled. |\n\n### Slots\n\n| Slot | Description |\n| ------------- | ---------------------------------------------- |\n| `default` | Button content; takes precedence over `label`. |\n| `icon` | Custom icon. |\n| `loadingicon` | Custom loading icon. |\n\n### Instance\n\n| Method / Property | Description |\n| ----------------- | ------------------------------- |\n| `focus()` | Focus the underlying button. |\n| `ref` | Underlying `HTMLButtonElement`. |\n\n### Props — ButtonGroup\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `fluid` | `boolean` | `false` | Stretch to full container width. |\n| `ariaLabel` | `string` | — | Accessible name for the group. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Group wrapper pass-through. |"
2594
+ "body": "Suggested composition order: `type` → `shape` → `size` → `loading` → `disabled`.\n\n### Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `type` | `'default' \\| 'primary' \\| 'dashed' \\| 'link' \\| 'text'` | `'default'` | Sugar. When both `color` and `variant` are set, they win. |\n| `color` | `'default' \\| 'primary' \\| 'danger' \\| 'success' \\| 'info' \\| 'warning' \\| 'help' \\| 'contrast'` | — | Color axis. |\n| `variant` | `'solid' \\| 'outlined' \\| 'dashed' \\| 'filled' \\| 'text' \\| 'link'` | — | Variant axis. |\n| `danger` | `boolean` | `false` | Danger-color sugar. `color` wins when set. |\n| `ghost` | `boolean` | `false` | Transparent background. Ignored for `text` / `link`. |\n| `shape` | `'default' \\| 'circle' \\| 'round' \\| 'square'` | `'default'` | Corner shape. |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Size; can inherit from ConfigProvider. |\n| `block` | `boolean` | `false` | Stretch to the parent width. |\n| `loading` | `boolean \\| { delay?: number; icon?: IconName \\| Component }` | `false` | Loading state with optional delay and icon. |\n| `disabled` | `boolean` | `false` | Disabled; can inherit from ConfigProvider. |\n| `htmlType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | Native button `type`. |\n| `href` | `string` | — | Renders as `<a>` when set. |\n| `target` | `string` | — | Anchor `target`; requires `href`. |\n| `label` | `string` | — | Label text; the default slot wins when present. |\n| `icon` | `IconName \\| Component` | — | Icon name or component. |\n| `iconPlacement` | `'start' \\| 'end'` | `'start'` | Icon placement. |\n| `iconOnly` | `boolean` | `false` | Force a square icon-only button. |\n| `autoInsertSpace` | `boolean` | `true` | Insert a space between two Chinese characters. |\n| `ripple` | `boolean` | `false` | Click ripple. |\n| `press` | `boolean` | `false` | Press scale. |\n| `autofocus` | `boolean` | `false` | Native autofocus. |\n| `ariaLabel` | `string` | — | Accessible name; recommended for icon-only buttons. |\n| `pt` | `{ root?, icon?, content? }` | — | Semantic DOM pass-through. |\n\n### Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `click` | `MouseEvent` | Fired on click; suppressed while `loading` / `disabled`. |\n\n### Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Button content; wins over `label`. |\n| `icon` | Custom icon. |\n| `loadingicon` | Custom loading icon. |\n\n### Instance\n\n| Member | Description |\n| --- | --- |\n| `focus()` | Focus the root element. |\n| `ref` | Root `HTMLButtonElement` or `HTMLAnchorElement`. |\n\n### MButtonGroup Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `block` | `boolean` | `false` | Stretch to the parent width. |\n| `ariaLabel` | `string` | — | Accessible name for the group. |\n| `pt` | `{ root? }` | — | Group wrapper pass-through. |"
2577
2595
  },
2578
2596
  {
2579
2597
  "id": "design-token",
2580
2598
  "title": "Design Token",
2581
- "body": "Reuses global `--m-*` tokens; see [Design Tokens](/docs/design-tokens). A component-level `--m-button-*` table will follow later."
2599
+ "body": "Reuses global `--m-*` tokens; see [Design Tokens](/docs/design-tokens). Button exposes `--m-button-*` on the root (size, radius, tones, fill opacity, motion). Theme switches follow `--m-color-*` / `--m-control-*` / `--m-motion-*`."
2582
2600
  },
2583
2601
  {
2584
2602
  "id": "semantic-dom",
2585
2603
  "title": "Semantic DOM",
2586
- "body": "`MButton` is a leaf control: the root is the native `<button class=\"m-button\">`. `class` / `style` / events land on that element (see [Attrs](/docs/attrs) and [Common Props](/docs/common-props)).\n\n```text\nbutton.m-button ← root (interactive element)\n span.m-button__ripple ← optional ripple layer\n span.m-button__icon ← icon / loading spinner (aria-hidden)\n span.m-button__spinner ← while loading\n span.m-button__label ← label (slot or `label` prop)\n span.m-button__badge* ← optional badge\n```\n\n`MButton` itself does not expose `pt`; use `MButtonGroup` `pt.root` for the group wrapper. Target `.m-button` first when styling, then `__icon` / `__label` / `__badge` as needed."
2604
+ "body": "The root is the interactive element: `<a class=\"m-button\">` when `href` is set, otherwise `<button class=\"m-button\">`.\n\n```text\nbutton.m-button / a.m-button\n span.m-button__ripple* ← when ripple is on\n span.m-button__icon* ← icon / loading\n span.m-button__label* ← label\n```\n\nOverride parts with `pt.root` / `pt.icon` / `pt.content`. See also [Attrs](/docs/attrs) and [Common Props](/docs/common-props)."
2587
2605
  },
2588
2606
  {
2589
2607
  "id": "faq",
2590
2608
  "title": "FAQ",
2591
- "body": "### What is the difference between `severity` and `variant`?\n\n`severity` sets the semantic color (e.g. `danger`, `success`); primary is used when omitted. `variant` (or the matching boolean prop) sets the visual style such as `outlined`, `text`, `link`, or `ghost`. They compose, e.g. `severity=\"danger\"` + `variant=\"outlined\"`.\n\n### When should I use `text` vs `link`, or `rounded` vs `shape`?\n\n`text` is a lightweight text button; `link` behaves more like an inline link (underline on hover by default). Prefer `shape` (`round` / `circle` / `square`) for geometry; legacy `rounded` still works and maps to `shape=\"round\"`."
2609
+ "body": "### How do I choose between `type` and `color` / `variant`?\n\nPrefer `type` for everyday use. Reach for `color` + `variant` when you need finer cross-tone control. When both axes are set, they override `type`.\n\n| `type` | Equals |\n| --- | --- |\n| `primary` | `color=\"primary\"` + `variant=\"solid\"` |\n| `default` | `color=\"default\"` + `variant=\"outlined\"` |\n| `dashed` | `color=\"default\"` + `variant=\"dashed\"` |\n| `text` | `color=\"default\"` + `variant=\"text\"` |\n| `link` | `color=\"link\"` + `variant=\"link\"` |\n\n```vue\n<MButton type=\"primary\">Save</MButton>\n```\n\nequals\n\n```vue\n<MButton color=\"primary\" variant=\"solid\">Save</MButton>\n```\n\n### Button `color` vs other components' `severity`?\n\nButton uses `color` / `variant`. Feedback components such as Badge, Tag, Alert, Message, and Toast still use `severity`.\n\n### `text` vs `link`?\n\n`type=\"text\"` (or `variant=\"text\"`) keeps button height and hit area. `type=\"link\"` is closer to an inline link."
2592
2610
  },
2593
2611
  {
2594
2612
  "id": "accessibility",
2595
2613
  "title": "Accessibility",
2596
- "body": "- Renders a native `<button>`.\n- For icon-only buttons, set `ariaLabel` (or provide an accessible text label).\n- Sets `aria-busy` while `loading` and disables interaction."
2614
+ "body": "- Renders a native `<button>` by default; renders `<a>` when `href` is set.\n- Provide `ariaLabel` (or visible text) for icon-only buttons.\n- Sets `aria-busy` while `loading` and blocks interaction.\n- A disabled link button drops `href` and sets `aria-disabled` with `tabindex=\"-1\"`."
2597
2615
  }
2598
2616
  ],
2599
- "markdown": "---\ntitle: Button\ncategory: 01 / BASIC\ndescription: Button triggers an immediate action.\n---\n\n# Button\n\nButton triggers an immediate action.\n\n## When to use\n\n- Use when the user needs to trigger a submit, confirm, navigate, or other immediate action.\n- Prefer the default (primary) button for the main action; use `severity=\"secondary\"` or `outlined` / `text` for secondary actions.\n- Use `severity=\"danger\"` for destructive actions; use `text` or `link` for lightweight inline actions.\n- Use `MButtonGroup` when adjacent buttons belong together.\n\n## Import\n\n```ts\nimport { MButton } from \"morya-ui\";\n```\n\n## Examples\n\n### Basic\n\nShow button text via the default slot or the `label` prop.\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n### Types\n\nCommon combinations: default primary, `severity=\"secondary\"`, `variant=\"dashed\"`, `text` / `link`, `severity=\"danger\"`, and `fluid` for full width.\n\n```vue preview src=\"./demos/VariantTypes.vue\"\n\n```\n\n### Shape\n\n`shape`: `default` / `round` / `circle` / `square`. Legacy `rounded` maps to `shape=\"round\"`.\n\n```vue preview src=\"./demos/Shape.vue\"\n\n```\n\n### Severity\n\nUse `severity` for semantic color; defaults to primary when omitted.\n\n```vue preview src=\"./demos/Severity.vue\"\n\n```\n\n### Styles\n\n`outlined`, `text`, `link`, `raised`, `rounded`, and `plain` can be combined freely.\n\n```vue preview src=\"./demos/Styles.vue\"\n\n```\n\n### Text & Link\n\n`text` is a lightweight text button; `link` renders as a backgroundless inline link style with underline on hover by default. Set `:underline=\"false\"` to disable. Both can be combined with `severity`.\n\n```vue preview src=\"./demos/TextAndLink.vue\"\n\n```\n\n### Ghost & Quaternary\n\n`ghost` is a soft fill matching text hover; `quaternary` is quieter for secondary toolbar actions. Both can be set via `variant`.\n\n```vue preview src=\"./demos/GhostAndQuaternary.vue\"\n\n```\n\n### Button Group\n\n`MButtonGroup` joins adjacent buttons.\n\n```vue preview src=\"./demos/ButtonGroup.en.vue\"\n\n```\n\n### Icons & Badge\n\nSupports `icon`, `iconPos`, `iconOnly`, and a `badge`.\n\n```vue preview src=\"./demos/IconsAndBadge.vue\"\n\n```\n\n### Loading\n\nIn the `loading` state, a spinner is shown and clicks are blocked.\n\n```vue preview src=\"./demos/Loading.vue\"\n\n```\n\n### Disabled\n\n```vue preview src=\"./demos/Disabled.vue\"\n\n```\n\n## API\n\n### Props\n\n| Prop | Type | Default | Description |\n| --------------- | ---------------------------------------------------------------------------------- | ---------- | --------------------------------------------------------------------- |\n| `label` | `string` | — | Button text. Default slot content takes precedence when present. |\n| `icon` | `IconName \\| Component` | — | Icon name or custom component. |\n| `iconPos` | `'left' \\| 'right' \\| 'top' \\| 'bottom'` | `'left'` | Icon position relative to the label. |\n| `iconOnly` | `boolean` | `false` | Force a square icon-only button. |\n| `badge` | `string` | — | Badge text. |\n| `badgeSeverity` | `'secondary' \\| 'info' \\| 'success' \\| 'warn' \\| 'danger' \\| 'contrast' \\| null` | `null` | Badge semantic color. |\n| `severity` | `'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast'` | — | Semantic color. Defaults to primary when omitted. |\n| `color` | `string` | — | Custom color; overrides `severity`. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Size. Medium by default; `sm` / `lg` aliases supported. |\n| `variant` | `'outlined' \\| 'text' \\| 'link' \\| 'ghost' \\| 'quaternary'` | — | Style variant shortcut, equivalent to the matching boolean prop. |\n| `outlined` | `boolean` | `false` | Outlined button. |\n| `text` | `boolean` | `false` | Text button. |\n| `link` | `boolean` | `false` | Link button. |\n| `underline` | `boolean` | `true` | Underline on hover for `link`. Set `false` to disable. |\n| `ghost` | `boolean` | `false` | Soft fill matching text hover. |\n| `quaternary` | `boolean` | `false` | Extra-quiet text button. |\n| `plain` | `boolean` | `false` | Soft fill matching outlined hover; can also mute `text` / `outlined`. |\n| `raised` | `boolean` | `false` | Raised shadow. |\n| `rounded` | `boolean` | `false` | Fully rounded. |\n| `fluid` | `boolean` | `false` | Stretch to full container width. |\n| `loading` | `boolean` | `false` | Loading state; disables clicks and shows a spinner. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `ripple` | `boolean` | `false` | Click ripple ink. Set `true` to enable. |\n| `press` | `boolean` | `false` | Slight scale while pressed. Set `true` to enable. |\n| `nativeType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | Native button type. |\n| `autofocus` | `boolean` | `false` | Native autofocus. |\n| `ariaLabel` | `string` | — | Accessible name; recommended for icon-only buttons. |\n\n### Events\n\n| Event | Prop | Description |\n| ------- | ------------ | ---------------------------- |\n| `click` | `MouseEvent` | Fired on click when enabled. |\n\n### Slots\n\n| Slot | Description |\n| ------------- | ---------------------------------------------- |\n| `default` | Button content; takes precedence over `label`. |\n| `icon` | Custom icon. |\n| `loadingicon` | Custom loading icon. |\n\n### Instance\n\n| Method / Property | Description |\n| ----------------- | ------------------------------- |\n| `focus()` | Focus the underlying button. |\n| `ref` | Underlying `HTMLButtonElement`. |\n\n### Props — ButtonGroup\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `fluid` | `boolean` | `false` | Stretch to full container width. |\n| `ariaLabel` | `string` | — | Accessible name for the group. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Group wrapper pass-through. |\n\n## Design Token\n\nReuses global `--m-*` tokens; see [Design Tokens](/docs/design-tokens). A component-level `--m-button-*` table will follow later.\n\n## Semantic DOM\n\n`MButton` is a leaf control: the root is the native `<button class=\"m-button\">`. `class` / `style` / events land on that element (see [Attrs](/docs/attrs) and [Common Props](/docs/common-props)).\n\n```text\nbutton.m-button ← root (interactive element)\n span.m-button__ripple ← optional ripple layer\n span.m-button__icon ← icon / loading spinner (aria-hidden)\n span.m-button__spinner ← while loading\n span.m-button__label ← label (slot or `label` prop)\n span.m-button__badge* ← optional badge\n```\n\n`MButton` itself does not expose `pt`; use `MButtonGroup` `pt.root` for the group wrapper. Target `.m-button` first when styling, then `__icon` / `__label` / `__badge` as needed.\n\n## FAQ\n\n### What is the difference between `severity` and `variant`?\n\n`severity` sets the semantic color (e.g. `danger`, `success`); primary is used when omitted. `variant` (or the matching boolean prop) sets the visual style such as `outlined`, `text`, `link`, or `ghost`. They compose, e.g. `severity=\"danger\"` + `variant=\"outlined\"`.\n\n### When should I use `text` vs `link`, or `rounded` vs `shape`?\n\n`text` is a lightweight text button; `link` behaves more like an inline link (underline on hover by default). Prefer `shape` (`round` / `circle` / `square`) for geometry; legacy `rounded` still works and maps to `shape=\"round\"`.\n\n## Accessibility\n\n- Renders a native `<button>`.\n- For icon-only buttons, set `ariaLabel` (or provide an accessible text label).\n- Sets `aria-busy` while `loading` and disables interaction.\n"
2617
+ "markdown": "---\ntitle: Button\ncategory: 01 / BASIC\ndescription: A button that triggers an immediate action.\n---\n\n# Button\n\nUse Button for submit, confirm, navigate, and other immediate actions.\n\n## When to use\n\n- Primary action: `type=\"primary\"`. Keep one primary action in a region.\n- Secondary action: the default button, or `type=\"dashed\"` / `type=\"text\"`.\n- Inline or low-emphasis action: `type=\"link\"` / `type=\"text\"`.\n- Destructive action: add `danger`, and confirm when needed.\n- Adjacent actions that should look joined: wrap them in `MButtonGroup` (visual only).\n\n## Import\n\n```ts\nimport { MButton, MButtonGroup } from 'morya-ui'\n```\n\n## Examples\n\n### Basic\n\n`type` is sugar for a `color` + `variant` pair. Omit it for the default outlined button.\n\n```vue preview src=\"./demos/Basic.vue\"\n\n```\n\n### Color & variant\n\nSet `color` and `variant` for finer control. When both are set, they win over `type`.\n\n```vue preview src=\"./demos/ColorVariant.vue\"\n\n```\n\n### Icon\n\n`icon` accepts a name or component. Use `iconPlacement` for position. Icon-only buttons need `ariaLabel`.\n\n```vue preview src=\"./demos/Icon.vue\"\n\n```\n\n### Size\n\n```vue preview src=\"./demos/Size.vue\"\n\n```\n\n### Shape\n\n`shape`: `default` / `round` / `circle` / `square`.\n\n```vue preview src=\"./demos/Shape.vue\"\n\n```\n\n### Danger\n\n`danger` switches the color to danger while keeping the current `type` / `variant` look.\n\n```vue preview src=\"./demos/Danger.vue\"\n\n```\n\n### Ghost\n\n`ghost` makes the background transparent for dark or busy surfaces. It is ignored for `text` / `link`.\n\n```vue preview src=\"./demos/Ghost.vue\"\n\n```\n\n### Loading\n\n`loading` accepts a boolean or `{ delay, icon }`. Clicks are blocked while loading.\n\n```vue preview src=\"./demos/Loading.vue\"\n\n```\n\n### Disabled\n\n```vue preview src=\"./demos/Disabled.vue\"\n\n```\n\n### Block\n\n`block` stretches the button to the parent width.\n\n```vue preview src=\"./demos/Block.vue\"\n\n```\n\n### Button group\n\n`MButtonGroup` only joins adjacent buttons visually. It has no selected state. For mutually exclusive switching, use [`SelectButton`](/components/SelectButton).\n\n```vue preview src=\"./demos/ButtonGroup.en.vue\"\n\n```\n\n### Ripple & press\n\n`ripple` and `press` are off by default. Turn them on when you want the motion.\n\n```vue preview src=\"./demos/RipplePress.vue\"\n\n```\n\n## API\n\nSuggested composition order: `type` → `shape` → `size` → `loading` → `disabled`.\n\n### Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `type` | `'default' \\| 'primary' \\| 'dashed' \\| 'link' \\| 'text'` | `'default'` | Sugar. When both `color` and `variant` are set, they win. |\n| `color` | `'default' \\| 'primary' \\| 'danger' \\| 'success' \\| 'info' \\| 'warning' \\| 'help' \\| 'contrast'` | — | Color axis. |\n| `variant` | `'solid' \\| 'outlined' \\| 'dashed' \\| 'filled' \\| 'text' \\| 'link'` | — | Variant axis. |\n| `danger` | `boolean` | `false` | Danger-color sugar. `color` wins when set. |\n| `ghost` | `boolean` | `false` | Transparent background. Ignored for `text` / `link`. |\n| `shape` | `'default' \\| 'circle' \\| 'round' \\| 'square'` | `'default'` | Corner shape. |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Size; can inherit from ConfigProvider. |\n| `block` | `boolean` | `false` | Stretch to the parent width. |\n| `loading` | `boolean \\| { delay?: number; icon?: IconName \\| Component }` | `false` | Loading state with optional delay and icon. |\n| `disabled` | `boolean` | `false` | Disabled; can inherit from ConfigProvider. |\n| `htmlType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | Native button `type`. |\n| `href` | `string` | — | Renders as `<a>` when set. |\n| `target` | `string` | — | Anchor `target`; requires `href`. |\n| `label` | `string` | — | Label text; the default slot wins when present. |\n| `icon` | `IconName \\| Component` | — | Icon name or component. |\n| `iconPlacement` | `'start' \\| 'end'` | `'start'` | Icon placement. |\n| `iconOnly` | `boolean` | `false` | Force a square icon-only button. |\n| `autoInsertSpace` | `boolean` | `true` | Insert a space between two Chinese characters. |\n| `ripple` | `boolean` | `false` | Click ripple. |\n| `press` | `boolean` | `false` | Press scale. |\n| `autofocus` | `boolean` | `false` | Native autofocus. |\n| `ariaLabel` | `string` | — | Accessible name; recommended for icon-only buttons. |\n| `pt` | `{ root?, icon?, content? }` | — | Semantic DOM pass-through. |\n\n### Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `click` | `MouseEvent` | Fired on click; suppressed while `loading` / `disabled`. |\n\n### Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Button content; wins over `label`. |\n| `icon` | Custom icon. |\n| `loadingicon` | Custom loading icon. |\n\n### Instance\n\n| Member | Description |\n| --- | --- |\n| `focus()` | Focus the root element. |\n| `ref` | Root `HTMLButtonElement` or `HTMLAnchorElement`. |\n\n### MButtonGroup Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `block` | `boolean` | `false` | Stretch to the parent width. |\n| `ariaLabel` | `string` | — | Accessible name for the group. |\n| `pt` | `{ root? }` | — | Group wrapper pass-through. |\n\n## Design Token\n\nReuses global `--m-*` tokens; see [Design Tokens](/docs/design-tokens). Button exposes `--m-button-*` on the root (size, radius, tones, fill opacity, motion). Theme switches follow `--m-color-*` / `--m-control-*` / `--m-motion-*`.\n\n## Semantic DOM\n\nThe root is the interactive element: `<a class=\"m-button\">` when `href` is set, otherwise `<button class=\"m-button\">`.\n\n```text\nbutton.m-button / a.m-button\n span.m-button__ripple* ← when ripple is on\n span.m-button__icon* ← icon / loading\n span.m-button__label* ← label\n```\n\nOverride parts with `pt.root` / `pt.icon` / `pt.content`. See also [Attrs](/docs/attrs) and [Common Props](/docs/common-props).\n\n## FAQ\n\n### How do I choose between `type` and `color` / `variant`?\n\nPrefer `type` for everyday use. Reach for `color` + `variant` when you need finer cross-tone control. When both axes are set, they override `type`.\n\n| `type` | Equals |\n| --- | --- |\n| `primary` | `color=\"primary\"` + `variant=\"solid\"` |\n| `default` | `color=\"default\"` + `variant=\"outlined\"` |\n| `dashed` | `color=\"default\"` + `variant=\"dashed\"` |\n| `text` | `color=\"default\"` + `variant=\"text\"` |\n| `link` | `color=\"link\"` + `variant=\"link\"` |\n\n```vue\n<MButton type=\"primary\">Save</MButton>\n```\n\nequals\n\n```vue\n<MButton color=\"primary\" variant=\"solid\">Save</MButton>\n```\n\n### Button `color` vs other components' `severity`?\n\nButton uses `color` / `variant`. Feedback components such as Badge, Tag, Alert, Message, and Toast still use `severity`.\n\n### `text` vs `link`?\n\n`type=\"text\"` (or `variant=\"text\"`) keeps button height and hit area. `type=\"link\"` is closer to an inline link.\n\n## Accessibility\n\n- Renders a native `<button>` by default; renders `<a>` when `href` is set.\n- Provide `ariaLabel` (or visible text) for icon-only buttons.\n- Sets `aria-busy` while `loading` and blocks interaction.\n- A disabled link button drops `href` and sets `aria-disabled` with `tabindex=\"-1\"`.\n"
2600
2618
  }
2601
2619
  }
2602
2620
  },
@@ -2929,7 +2947,7 @@
2929
2947
  "sectionId": "基础用法",
2930
2948
  "lang": "vue",
2931
2949
  "preview": true,
2932
- "code": "<script setup lang=\"ts\">\nimport { MButton, MCard } from 'morya-ui'\n</script>\n\n<template>\n <MCard title=\"Project overview\" subtitle=\"Updated 2 hours ago\">\n <p style=\"margin:0;color:var(--m-color-text-muted)\">\n Title and subtitle align in the header. Body content stays in the default slot.\n </p>\n <template #footer>\n <div style=\"display:flex;gap:0.75rem;justify-content:flex-end;width:100%\">\n <MButton label=\"Dismiss\" severity=\"secondary\" text />\n <MButton label=\"Continue\" />\n </div>\n </template>\n </MCard>\n</template>",
2950
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MCard } from 'morya-ui'\n</script>\n\n<template>\n <MCard title=\"Project overview\" subtitle=\"Updated 2 hours ago\">\n <p style=\"margin:0;color:var(--m-color-text-muted)\">\n Title and subtitle align in the header. Body content stays in the default slot.\n </p>\n <template #footer>\n <div style=\"display:flex;gap:0.75rem;justify-content:flex-end;width:100%\">\n <MButton label=\"Dismiss\" type=\"text\"/>\n <MButton label=\"Continue\" />\n </div>\n </template>\n </MCard>\n</template>",
2933
2951
  "locale": "zh-CN"
2934
2952
  },
2935
2953
  {
@@ -2956,7 +2974,7 @@
2956
2974
  "sectionId": "shadow",
2957
2975
  "lang": "vue",
2958
2976
  "preview": true,
2959
- "code": "<script setup lang=\"ts\">\nimport { MCard } from 'morya-ui'\n</script>\n\n<template>\n <div style=\"display:grid;gap:var(--m-space-4);max-width:28rem;padding:var(--m-space-2)\">\n <MCard title=\"Flat (default)\" shadow=\"never\">\n Flat surface; use `shadow=\"hover\"` when you want elevation on interaction only.\n </MCard>\n <MCard title=\"Hover shadow\" shadow=\"hover\">\n Same elevation as `always`, shown only on hover (`--m-card-shadow-rest`).\n </MCard>\n <MCard title=\"Always elevated\" shadow=\"always\">\n Resting shadow (`--m-card-shadow-rest` → `--m-shadow-raised`); use for dashboard modules.\n </MCard>\n </div>\n</template>",
2977
+ "code": "<script setup lang=\"ts\">\nimport { MCard, MInput } from 'morya-ui'\nimport { ref } from 'vue';\n\nconst inputValue = ref('')\n</script>\n\n<template>\n <div style=\"display:grid;gap:var(--m-space-4);max-width:28rem;padding:var(--m-space-2)\">\n <MCard title=\"Flat (default)\" shadow=\"never\">\n Flat surface; use `shadow=\"hover\"` when you want elevation on interaction only.\n </MCard>\n <MCard title=\"Hover shadow\" shadow=\"hover\">\n Same elevation as `always`, shown only on hover (`--m-card-shadow-rest`).\n\n <MInput v-model=\"inputValue\" placeholder=\"Hover me\" />\n </MCard>\n <MCard title=\"Always elevated\" shadow=\"always\">\n Resting shadow (`--m-card-shadow-rest` → `--m-shadow-raised`); use for dashboard modules.\n </MCard>\n </div>\n</template>",
2960
2978
  "locale": "zh-CN"
2961
2979
  },
2962
2980
  {
@@ -2974,7 +2992,7 @@
2974
2992
  "sectionId": "basic",
2975
2993
  "lang": "vue",
2976
2994
  "preview": true,
2977
- "code": "<script setup lang=\"ts\">\nimport { MButton, MCard } from 'morya-ui'\n</script>\n\n<template>\n <MCard title=\"Project overview\" subtitle=\"Updated 2 hours ago\">\n <p style=\"margin:0;color:var(--m-color-text-muted)\">\n Title and subtitle align in the header. Body content stays in the default slot.\n </p>\n <template #footer>\n <div style=\"display:flex;gap:0.75rem;justify-content:flex-end;width:100%\">\n <MButton label=\"Dismiss\" severity=\"secondary\" text />\n <MButton label=\"Continue\" />\n </div>\n </template>\n </MCard>\n</template>",
2995
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MCard } from 'morya-ui'\n</script>\n\n<template>\n <MCard title=\"Project overview\" subtitle=\"Updated 2 hours ago\">\n <p style=\"margin:0;color:var(--m-color-text-muted)\">\n Title and subtitle align in the header. Body content stays in the default slot.\n </p>\n <template #footer>\n <div style=\"display:flex;gap:0.75rem;justify-content:flex-end;width:100%\">\n <MButton label=\"Dismiss\" type=\"text\"/>\n <MButton label=\"Continue\" />\n </div>\n </template>\n </MCard>\n</template>",
2978
2996
  "locale": "en-US"
2979
2997
  },
2980
2998
  {
@@ -3001,7 +3019,7 @@
3001
3019
  "sectionId": "shadow",
3002
3020
  "lang": "vue",
3003
3021
  "preview": true,
3004
- "code": "<script setup lang=\"ts\">\nimport { MCard } from 'morya-ui'\n</script>\n\n<template>\n <div style=\"display:grid;gap:var(--m-space-4);max-width:28rem;padding:var(--m-space-2)\">\n <MCard title=\"Flat (default)\" shadow=\"never\">\n Flat surface; use `shadow=\"hover\"` when you want elevation on interaction only.\n </MCard>\n <MCard title=\"Hover shadow\" shadow=\"hover\">\n Same elevation as `always`, shown only on hover (`--m-card-shadow-rest`).\n </MCard>\n <MCard title=\"Always elevated\" shadow=\"always\">\n Resting shadow (`--m-card-shadow-rest` → `--m-shadow-raised`); use for dashboard modules.\n </MCard>\n </div>\n</template>",
3022
+ "code": "<script setup lang=\"ts\">\nimport { MCard, MInput } from 'morya-ui'\nimport { ref } from 'vue';\n\nconst inputValue = ref('')\n</script>\n\n<template>\n <div style=\"display:grid;gap:var(--m-space-4);max-width:28rem;padding:var(--m-space-2)\">\n <MCard title=\"Flat (default)\" shadow=\"never\">\n Flat surface; use `shadow=\"hover\"` when you want elevation on interaction only.\n </MCard>\n <MCard title=\"Hover shadow\" shadow=\"hover\">\n Same elevation as `always`, shown only on hover (`--m-card-shadow-rest`).\n\n <MInput v-model=\"inputValue\" placeholder=\"Hover me\" />\n </MCard>\n <MCard title=\"Always elevated\" shadow=\"always\">\n Resting shadow (`--m-card-shadow-rest` → `--m-shadow-raised`); use for dashboard modules.\n </MCard>\n </div>\n</template>",
3005
3023
  "locale": "en-US"
3006
3024
  }
3007
3025
  ],
@@ -3127,79 +3145,176 @@
3127
3145
  "name": "Carousel",
3128
3146
  "exportName": "MCarousel",
3129
3147
  "category": "03 / DATA",
3130
- "description": "轮播展示一组内容项。",
3131
- "descriptionEn": "Carousel for a set of content items.",
3148
+ "description": "轮播展示一组内容项,支持滑动 / 淡入 / 卡片效果。",
3149
+ "descriptionEn": "Carousel for a set of content items with slide / fade / card effects.",
3132
3150
  "import": "import { MCarousel } from 'morya-ui'",
3133
3151
  "props": [
3134
3152
  {
3135
- "name": "value",
3136
- "type": "unknown[]",
3153
+ "name": "currentIndex",
3154
+ "type": "number",
3137
3155
  "default": "—",
3138
- "description": "内容列表。"
3156
+ "description": "受控当前页,配合 `v-model:currentIndex`。"
3139
3157
  },
3140
3158
  {
3141
- "name": "numVisible",
3159
+ "name": "defaultIndex",
3142
3160
  "type": "number",
3161
+ "default": "0",
3162
+ "description": "非受控初始页。"
3163
+ },
3164
+ {
3165
+ "name": "showArrow",
3166
+ "type": "boolean",
3167
+ "default": "false",
3168
+ "description": "显示箭头。"
3169
+ },
3170
+ {
3171
+ "name": "showDots",
3172
+ "type": "boolean",
3173
+ "default": "true",
3174
+ "description": "显示指示点。"
3175
+ },
3176
+ {
3177
+ "name": "dotType",
3178
+ "type": "'dot' | 'line'",
3179
+ "default": "'dot'",
3180
+ "description": "指示点样式。"
3181
+ },
3182
+ {
3183
+ "name": "dotPlacement",
3184
+ "type": "'top' | 'bottom' | 'left' | 'right'",
3185
+ "default": "'bottom'",
3186
+ "description": "指示点位置。"
3187
+ },
3188
+ {
3189
+ "name": "slidesPerView",
3190
+ "type": "number | 'auto'",
3143
3191
  "default": "1",
3144
- "description": "同时可见项数。"
3192
+ "description": "一屏可见数量(`slide`)。"
3193
+ },
3194
+ {
3195
+ "name": "spaceBetween",
3196
+ "type": "number",
3197
+ "default": "0",
3198
+ "description": "幻灯片间距(px)。"
3145
3199
  },
3146
3200
  {
3147
- "name": "circular",
3201
+ "name": "centeredSlides",
3148
3202
  "type": "boolean",
3149
3203
  "default": "false",
3150
- "description": "循环翻页。"
3204
+ "description": "居中当前页。"
3205
+ },
3206
+ {
3207
+ "name": "direction",
3208
+ "type": "'horizontal' | 'vertical'",
3209
+ "default": "'horizontal'",
3210
+ "description": "方向。"
3151
3211
  },
3152
3212
  {
3153
3213
  "name": "autoplay",
3154
3214
  "type": "boolean",
3155
3215
  "default": "false",
3156
- "description": "自动翻页。"
3216
+ "description": "自动播放。"
3157
3217
  },
3158
3218
  {
3159
3219
  "name": "interval",
3160
3220
  "type": "number",
3161
- "default": "3000",
3162
- "description": "自动翻页间隔(毫秒)。"
3221
+ "default": "5000",
3222
+ "description": "自动播放间隔(ms)。"
3163
3223
  },
3164
3224
  {
3165
- "name": "showArrows",
3225
+ "name": "loop",
3166
3226
  "type": "boolean",
3167
3227
  "default": "true",
3168
- "description": "显示左右箭头。"
3228
+ "description": "循环。"
3229
+ },
3230
+ {
3231
+ "name": "effect",
3232
+ "type": "'slide' | 'fade' | 'card'",
3233
+ "default": "'slide'",
3234
+ "description": "过渡效果。"
3235
+ },
3236
+ {
3237
+ "name": "trigger",
3238
+ "type": "'click' | 'hover'",
3239
+ "default": "'click'",
3240
+ "description": "指示点触发方式。"
3169
3241
  },
3170
3242
  {
3171
- "name": "showIndicators",
3243
+ "name": "touchable",
3172
3244
  "type": "boolean",
3173
3245
  "default": "true",
3174
- "description": "显示指示点。"
3246
+ "description": "触摸滑动。"
3175
3247
  },
3176
3248
  {
3177
- "name": "page",
3249
+ "name": "draggable",
3250
+ "type": "boolean",
3251
+ "default": "false",
3252
+ "description": "鼠标拖拽。"
3253
+ },
3254
+ {
3255
+ "name": "mousewheel",
3256
+ "type": "boolean",
3257
+ "default": "false",
3258
+ "description": "滚轮切换。"
3259
+ },
3260
+ {
3261
+ "name": "keyboard",
3262
+ "type": "boolean",
3263
+ "default": "false",
3264
+ "description": "方向键切换(需聚焦)。"
3265
+ },
3266
+ {
3267
+ "name": "transitionDuration",
3178
3268
  "type": "number",
3179
- "default": "—",
3180
- "description": "—"
3269
+ "default": "300",
3270
+ "description": "过渡时长(ms)。"
3181
3271
  },
3182
3272
  {
3183
3273
  "name": "pt",
3184
3274
  "type": "[RootPassThrough](/docs/types#RootPassThrough) `{ root? }",
3185
3275
  "default": "—",
3186
- "description": "DOM 透传,见 [样式与 attrs](/docs/attrs)."
3276
+ "description": "DOM 透传。"
3187
3277
  }
3188
3278
  ],
3189
3279
  "events": [
3190
3280
  {
3191
- "name": "update:page",
3192
- "payload": "number",
3193
- "description": "页码变化。"
3281
+ "name": "update:currentIndex",
3282
+ "payload": "(currentIndex, lastIndex)",
3283
+ "description": "当前页变化。"
3194
3284
  }
3195
3285
  ],
3196
3286
  "slots": [
3197
3287
  {
3198
- "name": "item",
3199
- "description": "`{ item, index }` 单项。"
3288
+ "name": "default",
3289
+ "description": "幻灯片内容,建议使用 `MCarouselItem`。"
3290
+ },
3291
+ {
3292
+ "name": "arrow",
3293
+ "description": "`{ prev, next, total, currentIndex }` 自定义箭头。"
3294
+ },
3295
+ {
3296
+ "name": "dots",
3297
+ "description": "`{ total, currentIndex, to }` 自定义指示点。"
3298
+ }
3299
+ ],
3300
+ "methods": [
3301
+ {
3302
+ "name": "prev",
3303
+ "description": "上一页。"
3304
+ },
3305
+ {
3306
+ "name": "next",
3307
+ "description": "下一页。"
3308
+ },
3309
+ {
3310
+ "name": "to",
3311
+ "description": "跳到指定页。"
3312
+ },
3313
+ {
3314
+ "name": "getCurrentIndex",
3315
+ "description": "获取当前页。"
3200
3316
  }
3201
3317
  ],
3202
- "methods": [],
3203
3318
  "examples": [
3204
3319
  {
3205
3320
  "id": "引入-1",
@@ -3207,7 +3322,7 @@
3207
3322
  "sectionId": "引入",
3208
3323
  "lang": "ts",
3209
3324
  "preview": false,
3210
- "code": "import { MCarousel } from 'morya-ui'",
3325
+ "code": "import { MCarousel, MCarouselItem } from 'morya-ui'",
3211
3326
  "locale": "zh-CN"
3212
3327
  },
3213
3328
  {
@@ -3216,7 +3331,7 @@
3216
3331
  "sectionId": "基础用法",
3217
3332
  "lang": "vue",
3218
3333
  "preview": true,
3219
- "code": "<script setup lang=\"ts\">\nimport { MCarousel } from 'morya-ui'\n\nconst value = ['春', '夏', '秋', '冬']\n</script>\n\n<template>\n <MCarousel :value=\"value\" :num-visible=\"1\" circular>\n <template #item=\"{ item }\">\n <div style=\"padding:2rem;text-align:center;background:var(--m-color-surface-muted, #f3f4f6);border-radius:var(--m-radius-md)\">\n {{ item }}\n </div>\n </template>\n </MCarousel>\n</template>",
3334
+ "code": "<script setup lang=\"ts\">\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n\nconst slides = [\n { title: '春', color: 'color-mix(in srgb, var(--m-color-success) 18%, var(--m-color-surface))' },\n { title: '夏', color: 'color-mix(in srgb, var(--m-color-warning) 18%, var(--m-color-surface))' },\n { title: '秋', color: 'color-mix(in srgb, var(--m-color-danger) 16%, var(--m-color-surface))' },\n { title: '冬', color: 'color-mix(in srgb, var(--m-color-info) 18%, var(--m-color-surface))' },\n]\n</script>\n\n<template>\n <MCarousel show-arrow style=\"height: 180px\">\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"slide.title\"\n >\n <div\n style=\"\n align-items: center;\n display: flex;\n font-size: 1.5rem;\n height: 100%;\n justify-content: center;\n border-radius: var(--m-radius-md);\n \"\n :style=\"{ background: slide.color }\"\n >\n {{ slide.title }}\n </div>\n </MCarouselItem>\n </MCarousel>\n</template>",
3220
3335
  "locale": "zh-CN"
3221
3336
  },
3222
3337
  {
@@ -3225,7 +3340,34 @@
3225
3340
  "sectionId": "autoplay",
3226
3341
  "lang": "vue",
3227
3342
  "preview": true,
3228
- "code": "<script setup lang=\"ts\">\nimport { MCarousel } from 'morya-ui'\n\nconst value = ['A', 'B', 'C']\n</script>\n\n<template>\n <MCarousel :value=\"value\" autoplay :interval=\"4000\" :show-arrows=\"false\">\n <template #item=\"{ item }\">\n <div style=\"padding:1.5rem;text-align:center;background:var(--m-color-surface-muted, #f3f4f6);border-radius:var(--m-radius-md)\">\n {{ item }}\n </div>\n </template>\n </MCarousel>\n</template>",
3343
+ "code": "<script setup lang=\"ts\">\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n\nconst slides = ['01', '02', '03', '04']\n</script>\n\n<template>\n <MCarousel\n autoplay\n :interval=\"4000\"\n show-arrow\n style=\"height: 160px\"\n >\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"slide\"\n >\n <div\n style=\"\n align-items: center;\n background: var(--m-color-surface-muted, #f3f4f6);\n border-radius: var(--m-radius-md);\n display: flex;\n font-size: 2rem;\n height: 100%;\n justify-content: center;\n \"\n >\n {{ slide }}\n </div>\n </MCarouselItem>\n </MCarousel>\n</template>",
3344
+ "locale": "zh-CN"
3345
+ },
3346
+ {
3347
+ "id": "过渡效果-1",
3348
+ "section": "过渡效果",
3349
+ "sectionId": "过渡效果",
3350
+ "lang": "vue",
3351
+ "preview": true,
3352
+ "code": "<script setup lang=\"ts\">\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n\nconst slides = ['卡片 A', '卡片 B', '卡片 C', '卡片 D']\n</script>\n\n<template>\n <div class=\"demo-stack\">\n <MCarousel\n class=\"demo-carousel\"\n effect=\"fade\"\n show-arrow\n >\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"`fade-${slide}`\"\n >\n <div class=\"demo-slide\">\n Fade · {{ slide }}\n </div>\n </MCarouselItem>\n </MCarousel>\n\n <MCarousel\n class=\"demo-carousel demo-carousel--card\"\n effect=\"card\"\n show-arrow\n >\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"`card-${slide}`\"\n >\n <div class=\"demo-slide demo-slide--card\">\n Card · {{ slide }}\n </div>\n </MCarouselItem>\n </MCarousel>\n </div>\n</template>\n\n<style scoped>\n.demo-stack {\n display: grid;\n gap: 1.5rem;\n width: 100%;\n}\n\n.demo-carousel {\n height: 140px;\n width: 100%;\n}\n\n.demo-carousel--card {\n height: 160px;\n}\n\n.demo-slide {\n align-items: center;\n background: color-mix(in srgb, var(--m-color-primary) 12%, var(--m-color-surface));\n border-radius: var(--m-radius-md);\n box-sizing: border-box;\n display: flex;\n height: 100%;\n justify-content: center;\n width: 100%;\n}\n\n.demo-slide--card {\n background: var(--m-color-surface);\n border: var(--m-border-width) solid var(--m-color-border);\n box-shadow: var(--m-shadow-md);\n}\n</style>",
3353
+ "locale": "zh-CN"
3354
+ },
3355
+ {
3356
+ "id": "多图同屏-1",
3357
+ "section": "多图同屏",
3358
+ "sectionId": "多图同屏",
3359
+ "lang": "vue",
3360
+ "preview": true,
3361
+ "code": "<script setup lang=\"ts\">\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n\nconst slides = ['一', '二', '三', '四', '五', '六']\n</script>\n\n<template>\n <MCarousel\n :slides-per-view=\"3\"\n :space-between=\"12\"\n :loop=\"false\"\n show-arrow\n draggable\n style=\"height: 120px\"\n >\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"slide\"\n >\n <div\n style=\"\n align-items: center;\n background: var(--m-color-surface-muted, #f3f4f6);\n border-radius: var(--m-radius-md);\n display: flex;\n height: 100%;\n justify-content: center;\n \"\n >\n {{ slide }}\n </div>\n </MCarouselItem>\n </MCarousel>\n</template>",
3362
+ "locale": "zh-CN"
3363
+ },
3364
+ {
3365
+ "id": "纵向-1",
3366
+ "section": "纵向",
3367
+ "sectionId": "纵向",
3368
+ "lang": "vue",
3369
+ "preview": true,
3370
+ "code": "<script setup lang=\"ts\">\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n\nconst slides = ['上', '中', '下']\n</script>\n\n<template>\n <MCarousel\n direction=\"vertical\"\n show-arrow\n dot-placement=\"right\"\n dot-type=\"line\"\n style=\"height: 200px\"\n >\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"slide\"\n >\n <div\n style=\"\n align-items: center;\n background: color-mix(in srgb, var(--m-color-primary) 10%, var(--m-color-surface));\n border-radius: var(--m-radius-md);\n display: flex;\n height: 100%;\n justify-content: center;\n \"\n >\n {{ slide }}\n </div>\n </MCarouselItem>\n </MCarousel>\n</template>",
3229
3371
  "locale": "zh-CN"
3230
3372
  },
3231
3373
  {
@@ -3234,7 +3376,7 @@
3234
3376
  "sectionId": "import",
3235
3377
  "lang": "ts",
3236
3378
  "preview": false,
3237
- "code": "import { MCarousel } from 'morya-ui'",
3379
+ "code": "import { MCarousel, MCarouselItem } from 'morya-ui'",
3238
3380
  "locale": "en-US"
3239
3381
  },
3240
3382
  {
@@ -3243,7 +3385,7 @@
3243
3385
  "sectionId": "basic",
3244
3386
  "lang": "vue",
3245
3387
  "preview": true,
3246
- "code": "<script setup lang=\"ts\">\nimport { MCarousel } from 'morya-ui'\n\nconst value = ['Spring', 'Summer', 'Autumn', 'Winter']\n</script>\n\n<template>\n <MCarousel :value=\"value\" :num-visible=\"1\" circular>\n <template #item=\"{ item }\">\n <div style=\"padding:2rem;text-align:center;background:var(--m-color-surface-muted, #f3f4f6);border-radius:var(--m-radius-md)\">\n {{ item }}\n </div>\n </template>\n </MCarousel>\n</template>",
3388
+ "code": "<script setup lang=\"ts\">\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n\nconst slides = [\n { title: 'Spring', color: 'color-mix(in srgb, var(--m-color-success) 18%, var(--m-color-surface))' },\n { title: 'Summer', color: 'color-mix(in srgb, var(--m-color-warning) 18%, var(--m-color-surface))' },\n { title: 'Autumn', color: 'color-mix(in srgb, var(--m-color-danger) 16%, var(--m-color-surface))' },\n { title: 'Winter', color: 'color-mix(in srgb, var(--m-color-info) 18%, var(--m-color-surface))' },\n]\n</script>\n\n<template>\n <MCarousel show-arrow style=\"height: 180px\">\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"slide.title\"\n >\n <div\n style=\"\n align-items: center;\n display: flex;\n font-size: 1.5rem;\n height: 100%;\n justify-content: center;\n border-radius: var(--m-radius-md);\n \"\n :style=\"{ background: slide.color }\"\n >\n {{ slide.title }}\n </div>\n </MCarouselItem>\n </MCarousel>\n</template>",
3247
3389
  "locale": "en-US"
3248
3390
  },
3249
3391
  {
@@ -3252,24 +3394,51 @@
3252
3394
  "sectionId": "autoplay",
3253
3395
  "lang": "vue",
3254
3396
  "preview": true,
3255
- "code": "<script setup lang=\"ts\">\nimport { MCarousel } from 'morya-ui'\n\nconst value = ['A', 'B', 'C']\n</script>\n\n<template>\n <MCarousel :value=\"value\" autoplay :interval=\"4000\" :show-arrows=\"false\">\n <template #item=\"{ item }\">\n <div style=\"padding:1.5rem;text-align:center;background:var(--m-color-surface-muted, #f3f4f6);border-radius:var(--m-radius-md)\">\n {{ item }}\n </div>\n </template>\n </MCarousel>\n</template>",
3397
+ "code": "<script setup lang=\"ts\">\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n\nconst slides = ['01', '02', '03', '04']\n</script>\n\n<template>\n <MCarousel\n autoplay\n :interval=\"4000\"\n show-arrow\n style=\"height: 160px\"\n >\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"slide\"\n >\n <div\n style=\"\n align-items: center;\n background: var(--m-color-surface-muted, #f3f4f6);\n border-radius: var(--m-radius-md);\n display: flex;\n font-size: 2rem;\n height: 100%;\n justify-content: center;\n \"\n >\n {{ slide }}\n </div>\n </MCarouselItem>\n </MCarousel>\n</template>",
3398
+ "locale": "en-US"
3399
+ },
3400
+ {
3401
+ "id": "effects-1",
3402
+ "section": "Effects",
3403
+ "sectionId": "effects",
3404
+ "lang": "vue",
3405
+ "preview": true,
3406
+ "code": "<script setup lang=\"ts\">\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n\nconst slides = ['Card A', 'Card B', 'Card C', 'Card D']\n</script>\n\n<template>\n <div class=\"demo-stack\">\n <MCarousel\n class=\"demo-carousel\"\n effect=\"fade\"\n show-arrow\n >\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"`fade-${slide}`\"\n >\n <div class=\"demo-slide\">\n Fade · {{ slide }}\n </div>\n </MCarouselItem>\n </MCarousel>\n\n <MCarousel\n class=\"demo-carousel demo-carousel--card\"\n effect=\"card\"\n show-arrow\n >\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"`card-${slide}`\"\n >\n <div class=\"demo-slide demo-slide--card\">\n Card · {{ slide }}\n </div>\n </MCarouselItem>\n </MCarousel>\n </div>\n</template>\n\n<style scoped>\n.demo-stack {\n display: grid;\n gap: 1.5rem;\n width: 100%;\n}\n\n.demo-carousel {\n height: 140px;\n width: 100%;\n}\n\n.demo-carousel--card {\n height: 160px;\n}\n\n.demo-slide {\n align-items: center;\n background: color-mix(in srgb, var(--m-color-primary) 12%, var(--m-color-surface));\n border-radius: var(--m-radius-md);\n box-sizing: border-box;\n display: flex;\n height: 100%;\n justify-content: center;\n width: 100%;\n}\n\n.demo-slide--card {\n background: var(--m-color-surface);\n border: var(--m-border-width) solid var(--m-color-border);\n box-shadow: var(--m-shadow-md);\n}\n</style>",
3407
+ "locale": "en-US"
3408
+ },
3409
+ {
3410
+ "id": "multiple-slides-1",
3411
+ "section": "Multiple slides",
3412
+ "sectionId": "multiple-slides",
3413
+ "lang": "vue",
3414
+ "preview": true,
3415
+ "code": "<script setup lang=\"ts\">\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n\nconst slides = ['One', 'Two', 'Three', 'Four', 'Five', 'Six']\n</script>\n\n<template>\n <MCarousel\n :slides-per-view=\"3\"\n :space-between=\"12\"\n :loop=\"false\"\n show-arrow\n draggable\n style=\"height: 120px\"\n >\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"slide\"\n >\n <div\n style=\"\n align-items: center;\n background: var(--m-color-surface-muted, #f3f4f6);\n border-radius: var(--m-radius-md);\n display: flex;\n height: 100%;\n justify-content: center;\n \"\n >\n {{ slide }}\n </div>\n </MCarouselItem>\n </MCarousel>\n</template>",
3416
+ "locale": "en-US"
3417
+ },
3418
+ {
3419
+ "id": "vertical-1",
3420
+ "section": "Vertical",
3421
+ "sectionId": "vertical",
3422
+ "lang": "vue",
3423
+ "preview": true,
3424
+ "code": "<script setup lang=\"ts\">\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n\nconst slides = ['Top', 'Middle', 'Bottom']\n</script>\n\n<template>\n <MCarousel\n direction=\"vertical\"\n show-arrow\n dot-placement=\"right\"\n dot-type=\"line\"\n style=\"height: 200px\"\n >\n <MCarouselItem\n v-for=\"slide in slides\"\n :key=\"slide\"\n >\n <div\n style=\"\n align-items: center;\n background: color-mix(in srgb, var(--m-color-primary) 10%, var(--m-color-surface));\n border-radius: var(--m-radius-md);\n display: flex;\n height: 100%;\n justify-content: center;\n \"\n >\n {{ slide }}\n </div>\n </MCarouselItem>\n </MCarousel>\n</template>",
3256
3425
  "locale": "en-US"
3257
3426
  }
3258
3427
  ],
3259
3428
  "locales": {
3260
3429
  "zh-CN": {
3261
3430
  "title": "Carousel",
3262
- "description": "轮播展示一组内容项。",
3431
+ "description": "轮播展示一组内容项,支持滑动 / 淡入 / 卡片效果。",
3263
3432
  "sections": [
3264
3433
  {
3265
3434
  "id": "overview",
3266
3435
  "title": "",
3267
- "body": "# Carousel\n\n按 `numVisible` 窗口滑动展示内容。"
3436
+ "body": "# Carousel\n\n支持默认插槽 + `MCarouselItem`、多种过渡、指示点样式与方位、触摸/拖拽/滚轮/键盘、自动播放。"
3268
3437
  },
3269
3438
  {
3270
3439
  "id": "引入",
3271
3440
  "title": "引入",
3272
- "body": "```ts\nimport { MCarousel } from 'morya-ui'\n```"
3441
+ "body": "```ts\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n```"
3273
3442
  },
3274
3443
  {
3275
3444
  "id": "基础用法",
@@ -3279,39 +3448,59 @@
3279
3448
  {
3280
3449
  "id": "autoplay",
3281
3450
  "title": "Autoplay",
3282
- "body": "`autoplay` 按 `interval`(默认 3000ms)自动翻页。`show-arrows` / `show-indicators` 控制箭头与指示点。\n\n```vue preview src=\"./demos/Autoplay.vue\"\n```"
3451
+ "body": "`autoplay` 按 `interval`(默认 5000ms)自动切换;悬停或聚焦时暂停。\n\n```vue preview src=\"./demos/Autoplay.vue\"\n```"
3452
+ },
3453
+ {
3454
+ "id": "过渡效果",
3455
+ "title": "过渡效果",
3456
+ "body": "`effect` 支持 `slide`(默认)、`fade`、`card`。\n\n```vue preview src=\"./demos/Effects.zh.vue\"\n```"
3457
+ },
3458
+ {
3459
+ "id": "多图同屏",
3460
+ "title": "多图同屏",
3461
+ "body": "`slides-per-view` + `space-between` 控制一屏可见数量与间距;可配合 `draggable` 鼠标拖拽。\n\n```vue preview src=\"./demos/MultiView.zh.vue\"\n```"
3462
+ },
3463
+ {
3464
+ "id": "纵向",
3465
+ "title": "纵向",
3466
+ "body": "`direction=\"vertical\"`,指示点可用 `dot-placement` / `dot-type` 调整。\n\n```vue preview src=\"./demos/Vertical.zh.vue\"\n```"
3283
3467
  },
3284
3468
  {
3285
3469
  "id": "props",
3286
3470
  "title": "Props",
3287
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `unknown[]` | — | 内容列表。 |\n| `numVisible` | `number` | `1` | 同时可见项数。 |\n| `circular` | `boolean` | `false` | 循环翻页。 |\n| `autoplay` | `boolean` | `false` | 自动翻页。 |\n| `interval` | `number` | `3000` | 自动翻页间隔(毫秒)。 |\n| `showArrows` | `boolean` | `true` | 显示左右箭头。 |\n| `showIndicators` | `boolean` | `true` | 显示指示点。 |\n| `page` | `number` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
3471
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `currentIndex` | `number` | — | 受控当前页,配合 `v-model:currentIndex`。 |\n| `defaultIndex` | `number` | `0` | 非受控初始页。 |\n| `showArrow` | `boolean` | `false` | 显示箭头。 |\n| `showDots` | `boolean` | `true` | 显示指示点。 |\n| `dotType` | `'dot' \\| 'line'` | `'dot'` | 指示点样式。 |\n| `dotPlacement` | `'top' \\| 'bottom' \\| 'left' \\| 'right'` | `'bottom'` | 指示点位置。 |\n| `slidesPerView` | `number \\| 'auto'` | `1` | 一屏可见数量(`slide`)。 |\n| `spaceBetween` | `number` | `0` | 幻灯片间距(px)。 |\n| `centeredSlides` | `boolean` | `false` | 居中当前页。 |\n| `direction` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 方向。 |\n| `autoplay` | `boolean` | `false` | 自动播放。 |\n| `interval` | `number` | `5000` | 自动播放间隔(ms)。 |\n| `loop` | `boolean` | `true` | 循环。 |\n| `effect` | `'slide' \\| 'fade' \\| 'card'` | `'slide'` | 过渡效果。 |\n| `trigger` | `'click' \\| 'hover'` | `'click'` | 指示点触发方式。 |\n| `touchable` | `boolean` | `true` | 触摸滑动。 |\n| `draggable` | `boolean` | `false` | 鼠标拖拽。 |\n| `mousewheel` | `boolean` | `false` | 滚轮切换。 |\n| `keyboard` | `boolean` | `false` | 方向键切换(需聚焦)。 |\n| `transitionDuration` | `number` | `300` | 过渡时长(ms)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传。 |"
3288
3472
  },
3289
3473
  {
3290
3474
  "id": "slots",
3291
3475
  "title": "Slots",
3292
- "body": "| 插槽 | 说明 |\n| --- | --- |\n| `item` | `{ item, index }` 单项。 |"
3476
+ "body": "| 插槽 | 说明 |\n| --- | --- |\n| `default` | 幻灯片内容,建议使用 `MCarouselItem`。 |\n| `arrow` | `{ prev, next, total, currentIndex }` 自定义箭头。 |\n| `dots` | `{ total, currentIndex, to }` 自定义指示点。 |"
3293
3477
  },
3294
3478
  {
3295
3479
  "id": "events",
3296
3480
  "title": "Events",
3297
- "body": "| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:page` | `number` | 页码变化。 |"
3481
+ "body": "| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:currentIndex` | `(currentIndex, lastIndex)` | 当前页变化。 |"
3482
+ },
3483
+ {
3484
+ "id": "methods",
3485
+ "title": "Methods",
3486
+ "body": "| 方法 | 说明 |\n| --- | --- |\n| `prev()` | 上一页。 |\n| `next()` | 下一页。 |\n| `to(index)` | 跳到指定页。 |\n| `getCurrentIndex()` | 获取当前页。 |"
3298
3487
  }
3299
3488
  ],
3300
- "markdown": "---\ntitle: Carousel\ncategory: 03 / DATA\ndescription: 轮播展示一组内容项。\n---\n\n# Carousel\n\n按 `numVisible` 窗口滑动展示内容。\n\n## 引入\n\n```ts\nimport { MCarousel } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Autoplay\n\n`autoplay` 按 `interval`(默认 3000ms)自动翻页。`show-arrows` / `show-indicators` 控制箭头与指示点。\n\n```vue preview src=\"./demos/Autoplay.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `unknown[]` | — | 内容列表。 |\n| `numVisible` | `number` | `1` | 同时可见项数。 |\n| `circular` | `boolean` | `false` | 循环翻页。 |\n| `autoplay` | `boolean` | `false` | 自动翻页。 |\n| `interval` | `number` | `3000` | 自动翻页间隔(毫秒)。 |\n| `showArrows` | `boolean` | `true` | 显示左右箭头。 |\n| `showIndicators` | `boolean` | `true` | 显示指示点。 |\n| `page` | `number` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Slots\n\n| 插槽 | 说明 |\n| --- | --- |\n| `item` | `{ item, index }` 单项。 |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:page` | `number` | 页码变化。 |\n"
3489
+ "markdown": "---\ntitle: Carousel\ncategory: 03 / DATA\ndescription: 轮播展示一组内容项,支持滑动 / 淡入 / 卡片效果。\n---\n\n# Carousel\n\n支持默认插槽 + `MCarouselItem`、多种过渡、指示点样式与方位、触摸/拖拽/滚轮/键盘、自动播放。\n\n## 引入\n\n```ts\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Autoplay\n\n`autoplay` 按 `interval`(默认 5000ms)自动切换;悬停或聚焦时暂停。\n\n```vue preview src=\"./demos/Autoplay.vue\"\n```\n\n## 过渡效果\n\n`effect` 支持 `slide`(默认)、`fade`、`card`。\n\n```vue preview src=\"./demos/Effects.zh.vue\"\n```\n\n## 多图同屏\n\n`slides-per-view` + `space-between` 控制一屏可见数量与间距;可配合 `draggable` 鼠标拖拽。\n\n```vue preview src=\"./demos/MultiView.zh.vue\"\n```\n\n## 纵向\n\n`direction=\"vertical\"`,指示点可用 `dot-placement` / `dot-type` 调整。\n\n```vue preview src=\"./demos/Vertical.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `currentIndex` | `number` | — | 受控当前页,配合 `v-model:currentIndex`。 |\n| `defaultIndex` | `number` | `0` | 非受控初始页。 |\n| `showArrow` | `boolean` | `false` | 显示箭头。 |\n| `showDots` | `boolean` | `true` | 显示指示点。 |\n| `dotType` | `'dot' \\| 'line'` | `'dot'` | 指示点样式。 |\n| `dotPlacement` | `'top' \\| 'bottom' \\| 'left' \\| 'right'` | `'bottom'` | 指示点位置。 |\n| `slidesPerView` | `number \\| 'auto'` | `1` | 一屏可见数量(`slide`)。 |\n| `spaceBetween` | `number` | `0` | 幻灯片间距(px)。 |\n| `centeredSlides` | `boolean` | `false` | 居中当前页。 |\n| `direction` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 方向。 |\n| `autoplay` | `boolean` | `false` | 自动播放。 |\n| `interval` | `number` | `5000` | 自动播放间隔(ms)。 |\n| `loop` | `boolean` | `true` | 循环。 |\n| `effect` | `'slide' \\| 'fade' \\| 'card'` | `'slide'` | 过渡效果。 |\n| `trigger` | `'click' \\| 'hover'` | `'click'` | 指示点触发方式。 |\n| `touchable` | `boolean` | `true` | 触摸滑动。 |\n| `draggable` | `boolean` | `false` | 鼠标拖拽。 |\n| `mousewheel` | `boolean` | `false` | 滚轮切换。 |\n| `keyboard` | `boolean` | `false` | 方向键切换(需聚焦)。 |\n| `transitionDuration` | `number` | `300` | 过渡时长(ms)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传。 |\n\n## Slots\n\n| 插槽 | 说明 |\n| --- | --- |\n| `default` | 幻灯片内容,建议使用 `MCarouselItem`。 |\n| `arrow` | `{ prev, next, total, currentIndex }` 自定义箭头。 |\n| `dots` | `{ total, currentIndex, to }` 自定义指示点。 |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:currentIndex` | `(currentIndex, lastIndex)` | 当前页变化。 |\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `prev()` | 上一页。 |\n| `next()` | 下一页。 |\n| `to(index)` | 跳到指定页。 |\n| `getCurrentIndex()` | 获取当前页。 |\n"
3301
3490
  },
3302
3491
  "en-US": {
3303
3492
  "title": "Carousel",
3304
- "description": "Carousel for a set of content items.",
3493
+ "description": "Carousel for a set of content items with slide / fade / card effects.",
3305
3494
  "sections": [
3306
3495
  {
3307
3496
  "id": "overview",
3308
3497
  "title": "",
3309
- "body": "# Carousel\n\nSlides content in a window of `numVisible` items."
3498
+ "body": "# Carousel\n\nSupports a default slot + `MCarouselItem`, multiple effects, dot styles/placement, touch/drag/wheel/keyboard, and autoplay."
3310
3499
  },
3311
3500
  {
3312
3501
  "id": "import",
3313
3502
  "title": "Import",
3314
- "body": "```ts\nimport { MCarousel } from 'morya-ui'\n```"
3503
+ "body": "```ts\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n```"
3315
3504
  },
3316
3505
  {
3317
3506
  "id": "basic",
@@ -3321,25 +3510,45 @@
3321
3510
  {
3322
3511
  "id": "autoplay",
3323
3512
  "title": "Autoplay",
3324
- "body": "`autoplay` advances pages every `interval` (default 3000ms). `show-arrows` / `show-indicators` control arrows and dots.\n\n```vue preview src=\"./demos/Autoplay.vue\"\n```"
3513
+ "body": "`autoplay` advances every `interval` (default 5000ms). Pauses on hover/focus.\n\n```vue preview src=\"./demos/Autoplay.vue\"\n```"
3514
+ },
3515
+ {
3516
+ "id": "effects",
3517
+ "title": "Effects",
3518
+ "body": "`effect` supports `slide` (default), `fade`, and `card`.\n\n```vue preview src=\"./demos/Effects.en.vue\"\n```"
3519
+ },
3520
+ {
3521
+ "id": "multiple-slides",
3522
+ "title": "Multiple slides",
3523
+ "body": "Use `slides-per-view` + `space-between`. Enable `draggable` for mouse drag.\n\n```vue preview src=\"./demos/MultiView.en.vue\"\n```"
3524
+ },
3525
+ {
3526
+ "id": "vertical",
3527
+ "title": "Vertical",
3528
+ "body": "Set `direction=\"vertical\"`. Tune dots with `dot-placement` / `dot-type`.\n\n```vue preview src=\"./demos/Vertical.en.vue\"\n```"
3325
3529
  },
3326
3530
  {
3327
3531
  "id": "props",
3328
3532
  "title": "Props",
3329
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `unknown[]` | — | Content list. |\n| `numVisible` | `number` | `1` | Number of items visible at once. |\n| `circular` | `boolean` | `false` | Loop paging. |\n| `autoplay` | `boolean` | `false` | Auto-advance. |\n| `interval` | `number` | `3000` | Autoplay interval in milliseconds. |\n| `showArrows` | `boolean` | `true` | Show prev/next arrows. |\n| `showIndicators` | `boolean` | `true` | Show page dots. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
3533
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `currentIndex` | `number` | — | Controlled index (`v-model:currentIndex`). |\n| `defaultIndex` | `number` | `0` | Uncontrolled initial index. |\n| `showArrow` | `boolean` | `false` | Show arrows. |\n| `showDots` | `boolean` | `true` | Show dots. |\n| `dotType` | `'dot' \\| 'line'` | `'dot'` | Dot style. |\n| `dotPlacement` | `'top' \\| 'bottom' \\| 'left' \\| 'right'` | `'bottom'` | Dot placement. |\n| `slidesPerView` | `number \\| 'auto'` | `1` | Visible slides (`slide`). |\n| `spaceBetween` | `number` | `0` | Gap between slides (px). |\n| `centeredSlides` | `boolean` | `false` | Center the active slide. |\n| `direction` | `'horizontal' \\| 'vertical'` | `'horizontal'` | Orientation. |\n| `autoplay` | `boolean` | `false` | Auto play. |\n| `interval` | `number` | `5000` | Autoplay interval (ms). |\n| `loop` | `boolean` | `true` | Loop. |\n| `effect` | `'slide' \\| 'fade' \\| 'card'` | `'slide'` | Transition effect. |\n| `trigger` | `'click' \\| 'hover'` | `'click'` | How dots activate slides. |\n| `touchable` | `boolean` | `true` | Touch swipe. |\n| `draggable` | `boolean` | `false` | Mouse drag. |\n| `mousewheel` | `boolean` | `false` | Mouse wheel. |\n| `keyboard` | `boolean` | `false` | Arrow keys when focused. |\n| `transitionDuration` | `number` | `300` | Transition duration (ms). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through. |"
3330
3534
  },
3331
3535
  {
3332
3536
  "id": "slots",
3333
3537
  "title": "Slots",
3334
- "body": "| Slot | Description |\n| --- | --- |\n| `item` | `{ item, index }` for each item. |"
3538
+ "body": "| Slot | Description |\n| --- | --- |\n| `default` | Slides; prefer `MCarouselItem`. |\n| `arrow` | `{ prev, next, total, currentIndex }` custom arrows. |\n| `dots` | `{ total, currentIndex, to }` custom dots. |"
3335
3539
  },
3336
3540
  {
3337
3541
  "id": "events",
3338
3542
  "title": "Events",
3339
- "body": "| Event | Prop | Description |\n| --- | --- | --- |\n| `update:page` | `number` | Page change. |"
3543
+ "body": "| Event | Payload | Description |\n| --- | --- | --- |\n| `update:currentIndex` | `(currentIndex, lastIndex)` | Active index changed. |"
3544
+ },
3545
+ {
3546
+ "id": "methods",
3547
+ "title": "Methods",
3548
+ "body": "| Method | Description |\n| --- | --- |\n| `prev()` | Go to previous. |\n| `next()` | Go to next. |\n| `to(index)` | Jump to index. |\n| `getCurrentIndex()` | Read current index. |"
3340
3549
  }
3341
3550
  ],
3342
- "markdown": "---\ntitle: Carousel\ncategory: 03 / DATA\ndescription: Carousel for a set of content items.\n---\n\n# Carousel\n\nSlides content in a window of `numVisible` items.\n\n## Import\n\n```ts\nimport { MCarousel } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Autoplay\n\n`autoplay` advances pages every `interval` (default 3000ms). `show-arrows` / `show-indicators` control arrows and dots.\n\n```vue preview src=\"./demos/Autoplay.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `unknown[]` | — | Content list. |\n| `numVisible` | `number` | `1` | Number of items visible at once. |\n| `circular` | `boolean` | `false` | Loop paging. |\n| `autoplay` | `boolean` | `false` | Auto-advance. |\n| `interval` | `number` | `3000` | Autoplay interval in milliseconds. |\n| `showArrows` | `boolean` | `true` | Show prev/next arrows. |\n| `showIndicators` | `boolean` | `true` | Show page dots. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `item` | `{ item, index }` for each item. |\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `update:page` | `number` | Page change. |\n"
3551
+ "markdown": "---\ntitle: Carousel\ncategory: 03 / DATA\ndescription: Carousel for a set of content items with slide / fade / card effects.\n---\n\n# Carousel\n\nSupports a default slot + `MCarouselItem`, multiple effects, dot styles/placement, touch/drag/wheel/keyboard, and autoplay.\n\n## Import\n\n```ts\nimport { MCarousel, MCarouselItem } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Autoplay\n\n`autoplay` advances every `interval` (default 5000ms). Pauses on hover/focus.\n\n```vue preview src=\"./demos/Autoplay.vue\"\n```\n\n## Effects\n\n`effect` supports `slide` (default), `fade`, and `card`.\n\n```vue preview src=\"./demos/Effects.en.vue\"\n```\n\n## Multiple slides\n\nUse `slides-per-view` + `space-between`. Enable `draggable` for mouse drag.\n\n```vue preview src=\"./demos/MultiView.en.vue\"\n```\n\n## Vertical\n\nSet `direction=\"vertical\"`. Tune dots with `dot-placement` / `dot-type`.\n\n```vue preview src=\"./demos/Vertical.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `currentIndex` | `number` | — | Controlled index (`v-model:currentIndex`). |\n| `defaultIndex` | `number` | `0` | Uncontrolled initial index. |\n| `showArrow` | `boolean` | `false` | Show arrows. |\n| `showDots` | `boolean` | `true` | Show dots. |\n| `dotType` | `'dot' \\| 'line'` | `'dot'` | Dot style. |\n| `dotPlacement` | `'top' \\| 'bottom' \\| 'left' \\| 'right'` | `'bottom'` | Dot placement. |\n| `slidesPerView` | `number \\| 'auto'` | `1` | Visible slides (`slide`). |\n| `spaceBetween` | `number` | `0` | Gap between slides (px). |\n| `centeredSlides` | `boolean` | `false` | Center the active slide. |\n| `direction` | `'horizontal' \\| 'vertical'` | `'horizontal'` | Orientation. |\n| `autoplay` | `boolean` | `false` | Auto play. |\n| `interval` | `number` | `5000` | Autoplay interval (ms). |\n| `loop` | `boolean` | `true` | Loop. |\n| `effect` | `'slide' \\| 'fade' \\| 'card'` | `'slide'` | Transition effect. |\n| `trigger` | `'click' \\| 'hover'` | `'click'` | How dots activate slides. |\n| `touchable` | `boolean` | `true` | Touch swipe. |\n| `draggable` | `boolean` | `false` | Mouse drag. |\n| `mousewheel` | `boolean` | `false` | Mouse wheel. |\n| `keyboard` | `boolean` | `false` | Arrow keys when focused. |\n| `transitionDuration` | `number` | `300` | Transition duration (ms). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Slides; prefer `MCarouselItem`. |\n| `arrow` | `{ prev, next, total, currentIndex }` custom arrows. |\n| `dots` | `{ total, currentIndex, to }` custom dots. |\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `update:currentIndex` | `(currentIndex, lastIndex)` | Active index changed. |\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `prev()` | Go to previous. |\n| `next()` | Go to next. |\n| `to(index)` | Jump to index. |\n| `getCurrentIndex()` | Read current index. |\n"
3343
3552
  }
3344
3553
  }
3345
3554
  },
@@ -4064,6 +4273,12 @@
4064
4273
  "type": "'small' | 'large' | 'sm' | 'md' | 'lg'",
4065
4274
  "default": "—",
4066
4275
  "description": "尺寸。"
4276
+ },
4277
+ {
4278
+ "name": "pt",
4279
+ "type": "[RootPassThrough](/docs/types#RootPassThrough) `{ root? }",
4280
+ "default": "—",
4281
+ "description": "DOM 透传,见 [样式与 attrs](/docs/attrs)."
4067
4282
  }
4068
4283
  ],
4069
4284
  "events": [
@@ -4145,7 +4360,7 @@
4145
4360
  {
4146
4361
  "id": "props",
4147
4362
  "title": "Props",
4148
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 芯片文案。 |\n| `icon` | [IconName](/docs/types#IconName) | — | 前置图标名称。 |\n| `image` | `string` | — | 前置图片 URL(优先于 icon)。 |\n| `removable` | `boolean` | `false` | 显示 × 移除按钮。 |\n| `disabled` | `boolean` | `false` | 禁用交互。 |\n| `severity` | `MTagSeverity \\| 'warning'` | — | 语义色。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |"
4363
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 芯片文案。 |\n| `icon` | [IconName](/docs/types#IconName) | — | 前置图标名称。 |\n| `image` | `string` | — | 前置图片 URL(优先于 icon)。 |\n| `removable` | `boolean` | `false` | 显示 × 移除按钮。 |\n| `disabled` | `boolean` | `false` | 禁用交互。 |\n| `severity` | `MTagSeverity \\| 'warning'` | — | 语义色。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
4149
4364
  },
4150
4365
  {
4151
4366
  "id": "events",
@@ -4158,7 +4373,7 @@
4158
4373
  "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 标签内容。 |\n| `icon` | 前置图标。 |"
4159
4374
  }
4160
4375
  ],
4161
- "markdown": "---\ntitle: Chip\ncategory: 01 / BASIC\ndescription: 芯片用于展示标签化信息,可带图标、图片与移除操作。\n---\n\n# Chip\n\n芯片用于展示简短标签信息,可选图标/图片与移除按钮。\n\n## 引入\n\n```ts\nimport { MChip } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 芯片文案。 |\n| `icon` | [IconName](/docs/types#IconName) | — | 前置图标名称。 |\n| `image` | `string` | — | 前置图片 URL(优先于 icon)。 |\n| `removable` | `boolean` | `false` | 显示 × 移除按钮。 |\n| `disabled` | `boolean` | `false` | 禁用交互。 |\n| `severity` | `MTagSeverity \\| 'warning'` | — | 语义色。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `remove` | `MouseEvent` | 点击移除按钮时触发。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 标签内容。 |\n| `icon` | 前置图标。 |\n"
4376
+ "markdown": "---\ntitle: Chip\ncategory: 01 / BASIC\ndescription: 芯片用于展示标签化信息,可带图标、图片与移除操作。\n---\n\n# Chip\n\n芯片用于展示简短标签信息,可选图标/图片与移除按钮。\n\n## 引入\n\n```ts\nimport { MChip } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 芯片文案。 |\n| `icon` | [IconName](/docs/types#IconName) | — | 前置图标名称。 |\n| `image` | `string` | — | 前置图片 URL(优先于 icon)。 |\n| `removable` | `boolean` | `false` | 显示 × 移除按钮。 |\n| `disabled` | `boolean` | `false` | 禁用交互。 |\n| `severity` | `MTagSeverity \\| 'warning'` | — | 语义色。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `remove` | `MouseEvent` | 点击移除按钮时触发。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 标签内容。 |\n| `icon` | 前置图标。 |\n"
4162
4377
  },
4163
4378
  "en-US": {
4164
4379
  "title": "Chip",
@@ -4182,7 +4397,7 @@
4182
4397
  {
4183
4398
  "id": "props",
4184
4399
  "title": "Props",
4185
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `label` | `string` | 鈥?| Chip text. |\n| `icon` | [IconName](/docs/types#IconName) | 鈥?| Leading icon name. |\n| `image` | `string` | 鈥?| Leading image URL (takes precedence over icon). |\n| `removable` | `boolean` | `false` | Show 脳 remove button. |\n| `disabled` | `boolean` | `false` | Disable interaction. |\n| `severity` | `MTagSeverity \\| 'warning'` | 鈥?| Semantic color. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size. |"
4400
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `label` | `string` | 鈥?| Chip text. |\n| `icon` | [IconName](/docs/types#IconName) | 鈥?| Leading icon name. |\n| `image` | `string` | 鈥?| Leading image URL (takes precedence over icon). |\n| `removable` | `boolean` | `false` | Show 脳 remove button. |\n| `disabled` | `boolean` | `false` | Disable interaction. |\n| `severity` | `MTagSeverity \\| 'warning'` | 鈥?| Semantic color. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |"
4186
4401
  },
4187
4402
  {
4188
4403
  "id": "events",
@@ -4195,7 +4410,7 @@
4195
4410
  "body": "| Slot | Description |\n| --- | --- |\n| `default` | Label content. |\n| `icon` | Leading icon. |"
4196
4411
  }
4197
4412
  ],
4198
- "markdown": "---\ntitle: Chip\ncategory: 01 / BASIC\ndescription: Chip displays tagged information, optionally with an icon, image, and remove action.\n---\n\n# Chip\n\nChip displays short tagged information, with optional icon/image and a remove button.\n\n## Import\n\n```ts\nimport { MChip } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `label` | `string` | 鈥?| Chip text. |\n| `icon` | [IconName](/docs/types#IconName) | 鈥?| Leading icon name. |\n| `image` | `string` | 鈥?| Leading image URL (takes precedence over icon). |\n| `removable` | `boolean` | `false` | Show 脳 remove button. |\n| `disabled` | `boolean` | `false` | Disable interaction. |\n| `severity` | `MTagSeverity \\| 'warning'` | 鈥?| Semantic color. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size. |\n\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `remove` | `MouseEvent` | Fired when the remove button is clicked. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Label content. |\n| `icon` | Leading icon. |\n"
4413
+ "markdown": "---\ntitle: Chip\ncategory: 01 / BASIC\ndescription: Chip displays tagged information, optionally with an icon, image, and remove action.\n---\n\n# Chip\n\nChip displays short tagged information, with optional icon/image and a remove button.\n\n## Import\n\n```ts\nimport { MChip } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `label` | `string` | 鈥?| Chip text. |\n| `icon` | [IconName](/docs/types#IconName) | 鈥?| Leading icon name. |\n| `image` | `string` | 鈥?| Leading image URL (takes precedence over icon). |\n| `removable` | `boolean` | `false` | Show 脳 remove button. |\n| `disabled` | `boolean` | `false` | Disable interaction. |\n| `severity` | `MTagSeverity \\| 'warning'` | 鈥?| Semantic color. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `remove` | `MouseEvent` | Fired when the remove button is clicked. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Label content. |\n| `icon` | Leading icon. |\n"
4199
4414
  }
4200
4415
  }
4201
4416
  },
@@ -4852,10 +5067,10 @@
4852
5067
  "description": "取消按钮文案。"
4853
5068
  },
4854
5069
  {
4855
- "name": "acceptSeverity",
4856
- "type": "[ButtonSeverity](/docs/types#ButtonSeverity)",
5070
+ "name": "acceptColor",
5071
+ "type": "[ButtonColor](/docs/types#ButtonColor)",
4857
5072
  "default": "—",
4858
- "description": "确认按钮语义色。"
5073
+ "description": "确认按钮颜色。"
4859
5074
  },
4860
5075
  {
4861
5076
  "name": "type",
@@ -4972,7 +5187,7 @@
4972
5187
  "sectionId": "基础用法",
4973
5188
  "lang": "vue",
4974
5189
  "preview": true,
4975
- "code": "<script setup lang=\"ts\">\nimport { MButton, MConfirmDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst visible = ref(false)\n</script>\n\n<template>\n <MButton label=\"删除\" severity=\"danger\" @click=\"visible = true\" />\n <MConfirmDialog\n v-model=\"visible\"\n header=\"删除确认\"\n message=\"确定要删除该项吗?此操作不可撤销。\"\n accept-label=\"删除\"\n reject-label=\"取消\"\n accept-severity=\"danger\"\n />\n</template>",
5190
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MConfirmDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst visible = ref(false)\n</script>\n\n<template>\n <MButton label=\"删除\" @click=\"visible = true\" danger type=\"primary\"/>\n <MConfirmDialog\n v-model=\"visible\"\n header=\"删除确认\"\n message=\"确定要删除该项吗?此操作不可撤销。\"\n accept-label=\"删除\"\n reject-label=\"取消\"\n accept-color=\"danger\"\n />\n</template>",
4976
5191
  "locale": "zh-CN"
4977
5192
  },
4978
5193
  {
@@ -4990,7 +5205,7 @@
4990
5205
  "sectionId": "basic",
4991
5206
  "lang": "vue",
4992
5207
  "preview": true,
4993
- "code": "<script setup lang=\"ts\">\nimport { MButton, MConfirmDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst visible = ref(false)\n</script>\n\n<template>\n <MButton label=\"Delete\" severity=\"danger\" @click=\"visible = true\" />\n <MConfirmDialog\n v-model=\"visible\"\n header=\"Confirm delete\"\n message=\"Are you sure you want to delete this item? This action cannot be undone.\"\n accept-label=\"Delete\"\n reject-label=\"Cancel\"\n accept-severity=\"danger\"\n />\n</template>",
5208
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MConfirmDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst visible = ref(false)\n</script>\n\n<template>\n <MButton label=\"Delete\" @click=\"visible = true\" danger type=\"primary\"/>\n <MConfirmDialog\n v-model=\"visible\"\n header=\"Confirm delete\"\n message=\"Are you sure you want to delete this item? This action cannot be undone.\"\n accept-label=\"Delete\"\n reject-label=\"Cancel\"\n accept-color=\"danger\"\n />\n</template>",
4994
5209
  "locale": "en-US"
4995
5210
  }
4996
5211
  ],
@@ -5017,7 +5232,7 @@
5017
5232
  {
5018
5233
  "id": "props",
5019
5234
  "title": "Props",
5020
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 是否可见。 |\n| `header` | `string` | `'确认'` | 标题。 |\n| `message` | `string` | — | 正文。 |\n| `acceptLabel` | `string` | `'确认'` | 确认按钮文案。 |\n| `rejectLabel` | `string` | `'取消'` | 取消按钮文案。 |\n| `acceptSeverity` | [ButtonSeverity](/docs/types#ButtonSeverity) | — | 确认按钮语义色。 |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | 正文状态图标;确认流程用本组件,Dialog `type` 只做标题图标。 |\n| `loading` | `boolean` | `false` | 确认按钮加载中。 |\n| `beforeAccept` | `() => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭、不触发 `accept`。 |\n| `beforeReject` | `() => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭、不触发 `reject`。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `transition` | `string \\| false` | `'zoom'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `blockScroll` | `boolean` | — | — |\n| `closeOnEsc` | `boolean` | — | — |\n| `closeOnOutsideClick` | `boolean` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
5235
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 是否可见。 |\n| `header` | `string` | `'确认'` | 标题。 |\n| `message` | `string` | — | 正文。 |\n| `acceptLabel` | `string` | `'确认'` | 确认按钮文案。 |\n| `rejectLabel` | `string` | `'取消'` | 取消按钮文案。 |\n| `acceptColor` | [ButtonColor](/docs/types#ButtonColor) | — | 确认按钮颜色。 |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | 正文状态图标;确认流程用本组件,Dialog `type` 只做标题图标。 |\n| `loading` | `boolean` | `false` | 确认按钮加载中。 |\n| `beforeAccept` | `() => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭、不触发 `accept`。 |\n| `beforeReject` | `() => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭、不触发 `reject`。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `transition` | `string \\| false` | `'zoom'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `blockScroll` | `boolean` | — | — |\n| `closeOnEsc` | `boolean` | — | — |\n| `closeOnOutsideClick` | `boolean` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
5021
5236
  },
5022
5237
  {
5023
5238
  "id": "events",
@@ -5030,7 +5245,7 @@
5030
5245
  "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 对话框正文。 |\n| `footer` | 自定义 `footer` 内容。 |\n| `header` | 自定义 `header` 内容。 |"
5031
5246
  }
5032
5247
  ],
5033
- "markdown": "---\ntitle: ConfirmDialog\ncategory: 05 / FEEDBACK\ndescription: 确认 / 取消对话框,复用 Dialog 浮层样式。\n---\n\n# ConfirmDialog\n\n需要用户明确确认时使用的模态对话框。\n\n## 引入\n\n```ts\nimport { MButton, MConfirmDialog } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 是否可见。 |\n| `header` | `string` | `'确认'` | 标题。 |\n| `message` | `string` | — | 正文。 |\n| `acceptLabel` | `string` | `'确认'` | 确认按钮文案。 |\n| `rejectLabel` | `string` | `'取消'` | 取消按钮文案。 |\n| `acceptSeverity` | [ButtonSeverity](/docs/types#ButtonSeverity) | — | 确认按钮语义色。 |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | 正文状态图标;确认流程用本组件,Dialog `type` 只做标题图标。 |\n| `loading` | `boolean` | `false` | 确认按钮加载中。 |\n| `beforeAccept` | `() => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭、不触发 `accept`。 |\n| `beforeReject` | `() => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭、不触发 `reject`。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `transition` | `string \\| false` | `'zoom'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `blockScroll` | `boolean` | — | — |\n| `closeOnEsc` | `boolean` | — | — |\n| `closeOnOutsideClick` | `boolean` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `boolean` | 可见性变化。 |\n| `accept` | — | 点击确认。 |\n| `reject` | — | 点击取消或关闭。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 对话框正文。 |\n| `footer` | 自定义 `footer` 内容。 |\n| `header` | 自定义 `header` 内容。 |\n"
5248
+ "markdown": "---\ntitle: ConfirmDialog\ncategory: 05 / FEEDBACK\ndescription: 确认 / 取消对话框,复用 Dialog 浮层样式。\n---\n\n# ConfirmDialog\n\n需要用户明确确认时使用的模态对话框。\n\n## 引入\n\n```ts\nimport { MButton, MConfirmDialog } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 是否可见。 |\n| `header` | `string` | `'确认'` | 标题。 |\n| `message` | `string` | — | 正文。 |\n| `acceptLabel` | `string` | `'确认'` | 确认按钮文案。 |\n| `rejectLabel` | `string` | `'取消'` | 取消按钮文案。 |\n| `acceptColor` | [ButtonColor](/docs/types#ButtonColor) | — | 确认按钮颜色。 |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | 正文状态图标;确认流程用本组件,Dialog `type` 只做标题图标。 |\n| `loading` | `boolean` | `false` | 确认按钮加载中。 |\n| `beforeAccept` | `() => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭、不触发 `accept`。 |\n| `beforeReject` | `() => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭、不触发 `reject`。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `transition` | `string \\| false` | `'zoom'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `blockScroll` | `boolean` | — | — |\n| `closeOnEsc` | `boolean` | — | — |\n| `closeOnOutsideClick` | `boolean` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `boolean` | 可见性变化。 |\n| `accept` | — | 点击确认。 |\n| `reject` | — | 点击取消或关闭。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 对话框正文。 |\n| `footer` | 自定义 `footer` 内容。 |\n| `header` | 自定义 `header` 内容。 |\n"
5034
5249
  },
5035
5250
  "en-US": {
5036
5251
  "title": "ConfirmDialog",
@@ -5054,7 +5269,7 @@
5054
5269
  {
5055
5270
  "id": "props",
5056
5271
  "title": "Props",
5057
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. |\n| `header` | `string` | locale `confirm` | Title. |\n| `message` | `string` | — | Body text. |\n| `acceptLabel` | `string` | locale `accept` | Accept button label. |\n| `rejectLabel` | `string` | locale `reject` | Reject button label. |\n| `acceptSeverity` | [ButtonSeverity](/docs/types#ButtonSeverity) | — | Accept button semantic color. |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | Status icon beside the message. |\n| `loading` | `boolean` | `false` | Loading state on the accept button. |\n| `beforeAccept` | `() => unknown \\| Promise<unknown>` | — | Return `false` to keep open and skip `accept`. |\n| `beforeReject` | `() => unknown \\| Promise<unknown>` | — | Return `false` to keep open and skip `reject`. |\n| `teleport` | `boolean` | `true` | Overlay Teleport; defaults to `body`. |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target; `'self'` / `false` renders in place. |\n| `transition` | `string \\| false` | `'zoom'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
5272
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. |\n| `header` | `string` | locale `confirm` | Title. |\n| `message` | `string` | — | Body text. |\n| `acceptLabel` | `string` | locale `accept` | Accept button label. |\n| `rejectLabel` | `string` | locale `reject` | Reject button label. |\n| `acceptColor` | [ButtonColor](/docs/types#ButtonColor) | — | Accept button color. |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | Status icon beside the message. |\n| `loading` | `boolean` | `false` | Loading state on the accept button. |\n| `beforeAccept` | `() => unknown \\| Promise<unknown>` | — | Return `false` to keep open and skip `accept`. |\n| `beforeReject` | `() => unknown \\| Promise<unknown>` | — | Return `false` to keep open and skip `reject`. |\n| `teleport` | `boolean` | `true` | Overlay Teleport; defaults to `body`. |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target; `'self'` / `false` renders in place. |\n| `transition` | `string \\| false` | `'zoom'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
5058
5273
  },
5059
5274
  {
5060
5275
  "id": "events",
@@ -5067,7 +5282,7 @@
5067
5282
  "body": "| Slot | Description |\n| --- | --- |\n| `default` | Dialog body. |"
5068
5283
  }
5069
5284
  ],
5070
- "markdown": "---\ntitle: ConfirmDialog\ncategory: 05 / FEEDBACK\ndescription: Confirm / cancel dialog that reuses Dialog overlay styling.\n---\n\n# ConfirmDialog\n\nModal dialog used when the user must explicitly confirm an action.\n\n## Import\n\n```ts\nimport { MButton, MConfirmDialog } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. |\n| `header` | `string` | locale `confirm` | Title. |\n| `message` | `string` | — | Body text. |\n| `acceptLabel` | `string` | locale `accept` | Accept button label. |\n| `rejectLabel` | `string` | locale `reject` | Reject button label. |\n| `acceptSeverity` | [ButtonSeverity](/docs/types#ButtonSeverity) | — | Accept button semantic color. |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | Status icon beside the message. |\n| `loading` | `boolean` | `false` | Loading state on the accept button. |\n| `beforeAccept` | `() => unknown \\| Promise<unknown>` | — | Return `false` to keep open and skip `accept`. |\n| `beforeReject` | `() => unknown \\| Promise<unknown>` | — | Return `false` to keep open and skip `reject`. |\n| `teleport` | `boolean` | `true` | Overlay Teleport; defaults to `body`. |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target; `'self'` / `false` renders in place. |\n| `transition` | `string \\| false` | `'zoom'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\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` | `boolean` | Visibility change. |\n| `accept` | — | Accept clicked. |\n| `reject` | — | Reject clicked or dialog closed. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Dialog body. |\n"
5285
+ "markdown": "---\ntitle: ConfirmDialog\ncategory: 05 / FEEDBACK\ndescription: Confirm / cancel dialog that reuses Dialog overlay styling.\n---\n\n# ConfirmDialog\n\nModal dialog used when the user must explicitly confirm an action.\n\n## Import\n\n```ts\nimport { MButton, MConfirmDialog } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. |\n| `header` | `string` | locale `confirm` | Title. |\n| `message` | `string` | — | Body text. |\n| `acceptLabel` | `string` | locale `accept` | Accept button label. |\n| `rejectLabel` | `string` | locale `reject` | Reject button label. |\n| `acceptColor` | [ButtonColor](/docs/types#ButtonColor) | — | Accept button color. |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | Status icon beside the message. |\n| `loading` | `boolean` | `false` | Loading state on the accept button. |\n| `beforeAccept` | `() => unknown \\| Promise<unknown>` | — | Return `false` to keep open and skip `accept`. |\n| `beforeReject` | `() => unknown \\| Promise<unknown>` | — | Return `false` to keep open and skip `reject`. |\n| `teleport` | `boolean` | `true` | Overlay Teleport; defaults to `body`. |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target; `'self'` / `false` renders in place. |\n| `transition` | `string \\| false` | `'zoom'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\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` | `boolean` | Visibility change. |\n| `accept` | — | Accept clicked. |\n| `reject` | — | Reject clicked or dialog closed. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Dialog body. |\n"
5071
5286
  }
5072
5287
  }
5073
5288
  },
@@ -5153,8 +5368,8 @@
5153
5368
  "description": "进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。"
5154
5369
  },
5155
5370
  {
5156
- "name": "acceptSeverity",
5157
- "type": "[ButtonSeverity](/docs/types#ButtonSeverity)",
5371
+ "name": "acceptColor",
5372
+ "type": "[ButtonColor](/docs/types#ButtonColor)",
5158
5373
  "default": "—",
5159
5374
  "description": "—"
5160
5375
  },
@@ -5205,7 +5420,7 @@
5205
5420
  "sectionId": "基础用法",
5206
5421
  "lang": "vue",
5207
5422
  "preview": true,
5208
- "code": "<script setup lang=\"ts\">\nimport { MButton, MConfirmPopup } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst target = ref<HTMLElement | null>(null)\n\nfunction ask(event: MouseEvent) {\n target.value = event.currentTarget as HTMLElement\n open.value = true\n}\n</script>\n\n<template>\n <MButton label=\"删除\" severity=\"danger\" @click=\"ask\" />\n <MConfirmPopup v-model=\"open\" :target=\"target\" message=\"确认删除?\" icon=\"info\" placement=\"top\" />\n</template>",
5423
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MConfirmPopup } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst target = ref<HTMLElement | null>(null)\n\nfunction ask(event: MouseEvent) {\n target.value = event.currentTarget as HTMLElement\n open.value = true\n}\n</script>\n\n<template>\n <MButton label=\"删除\" @click=\"ask\" danger type=\"primary\"/>\n <MConfirmPopup v-model=\"open\" :target=\"target\" message=\"确认删除?\" icon=\"info\" placement=\"top\" />\n</template>",
5209
5424
  "locale": "zh-CN"
5210
5425
  },
5211
5426
  {
@@ -5232,7 +5447,7 @@
5232
5447
  "sectionId": "basic",
5233
5448
  "lang": "vue",
5234
5449
  "preview": true,
5235
- "code": "<script setup lang=\"ts\">\nimport { MButton, MConfirmPopup } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst target = ref<HTMLElement | null>(null)\n\nfunction ask(event: MouseEvent) {\n target.value = event.currentTarget as HTMLElement\n open.value = true\n}\n</script>\n\n<template>\n <MButton label=\"Delete\" severity=\"danger\" @click=\"ask\" />\n <MConfirmPopup v-model=\"open\" :target=\"target\" message=\"Delete this item?\" icon=\"info\" placement=\"top\" />\n</template>",
5450
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MConfirmPopup } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst target = ref<HTMLElement | null>(null)\n\nfunction ask(event: MouseEvent) {\n target.value = event.currentTarget as HTMLElement\n open.value = true\n}\n</script>\n\n<template>\n <MButton label=\"Delete\" @click=\"ask\" danger type=\"primary\"/>\n <MConfirmPopup v-model=\"open\" :target=\"target\" message=\"Delete this item?\" icon=\"info\" placement=\"top\" />\n</template>",
5236
5451
  "locale": "en-US"
5237
5452
  },
5238
5453
  {
@@ -5273,7 +5488,7 @@
5273
5488
  {
5274
5489
  "id": "props",
5275
5490
  "title": "Props",
5276
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 是否显示。 |\n| `message` | `string` | — | 提示文案。 |\n| `acceptLabel` / `rejectLabel` | `string` | `确认` / `取消` | 按钮。 |\n| `icon` | [IconName](/docs/types#IconName) | — | 文案旁图标。 |\n| `beforeAccept` | `() => boolean \\| Promise<boolean>` | — | 返回 `false` 时保持打开。 |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right'` | `'bottom'` | 相对 `target` 的位置。 |\n| `target` | `HTMLElement \\| null` | — | 锚点。 |\n| `position` | `{ top, left } \\| null` | — | 无锚点时的坐标。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `transition` | `string \\| false` | `'scale-fade'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `acceptSeverity` | [ButtonSeverity](/docs/types#ButtonSeverity) | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
5491
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 是否显示。 |\n| `message` | `string` | — | 提示文案。 |\n| `acceptLabel` / `rejectLabel` | `string` | `确认` / `取消` | 按钮。 |\n| `icon` | [IconName](/docs/types#IconName) | — | 文案旁图标。 |\n| `beforeAccept` | `() => boolean \\| Promise<boolean>` | — | 返回 `false` 时保持打开。 |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right'` | `'bottom'` | 相对 `target` 的位置。 |\n| `target` | `HTMLElement \\| null` | — | 锚点。 |\n| `position` | `{ top, left } \\| null` | — | 无锚点时的坐标。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `transition` | `string \\| false` | `'scale-fade'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `acceptColor` | [ButtonColor](/docs/types#ButtonColor) | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
5277
5492
  },
5278
5493
  {
5279
5494
  "id": "events",
@@ -5286,7 +5501,7 @@
5286
5501
  "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 弹出层正文。 |"
5287
5502
  }
5288
5503
  ],
5289
- "markdown": "---\ntitle: ConfirmPopup\ncategory: 05 / FEEDBACK\ndescription: 锚定在目标旁的确认气泡。\n---\n\n# ConfirmPopup\n\n轻量确认浮层,支持 `target` 或坐标定位。\n\n## 引入\n\n```ts\nimport { MConfirmPopup } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Before accept\n\n`beforeAccept` 返回 `false` 时保持打开且不触发 `accept`。\n\n```vue preview src=\"./demos/BeforeAccept.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 是否显示。 |\n| `message` | `string` | — | 提示文案。 |\n| `acceptLabel` / `rejectLabel` | `string` | `确认` / `取消` | 按钮。 |\n| `icon` | [IconName](/docs/types#IconName) | — | 文案旁图标。 |\n| `beforeAccept` | `() => boolean \\| Promise<boolean>` | — | 返回 `false` 时保持打开。 |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right'` | `'bottom'` | 相对 `target` 的位置。 |\n| `target` | `HTMLElement \\| null` | — | 锚点。 |\n| `position` | `{ top, left } \\| null` | — | 无锚点时的坐标。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `transition` | `string \\| false` | `'scale-fade'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `acceptSeverity` | [ButtonSeverity](/docs/types#ButtonSeverity) | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `boolean` | 显隐。 |\n| `accept` / `reject` | — | 确认 / 取消。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 弹出层正文。 |\n"
5504
+ "markdown": "---\ntitle: ConfirmPopup\ncategory: 05 / FEEDBACK\ndescription: 锚定在目标旁的确认气泡。\n---\n\n# ConfirmPopup\n\n轻量确认浮层,支持 `target` 或坐标定位。\n\n## 引入\n\n```ts\nimport { MConfirmPopup } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Before accept\n\n`beforeAccept` 返回 `false` 时保持打开且不触发 `accept`。\n\n```vue preview src=\"./demos/BeforeAccept.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 是否显示。 |\n| `message` | `string` | — | 提示文案。 |\n| `acceptLabel` / `rejectLabel` | `string` | `确认` / `取消` | 按钮。 |\n| `icon` | [IconName](/docs/types#IconName) | — | 文案旁图标。 |\n| `beforeAccept` | `() => boolean \\| Promise<boolean>` | — | 返回 `false` 时保持打开。 |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right'` | `'bottom'` | 相对 `target` 的位置。 |\n| `target` | `HTMLElement \\| null` | — | 锚点。 |\n| `position` | `{ top, left } \\| null` | — | 无锚点时的坐标。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `transition` | `string \\| false` | `'scale-fade'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `acceptColor` | [ButtonColor](/docs/types#ButtonColor) | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `boolean` | 显隐。 |\n| `accept` / `reject` | — | 确认 / 取消。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 弹出层正文。 |\n"
5290
5505
  },
5291
5506
  "en-US": {
5292
5507
  "title": "ConfirmPopup",
@@ -6751,10 +6966,10 @@
6751
6966
  "description": "预设页脚按钮;有 `footer` 插槽时忽略"
6752
6967
  },
6753
6968
  {
6754
- "name": "positiveSeverity",
6755
- "type": "[ButtonSeverity](/docs/types#ButtonSeverity)",
6969
+ "name": "positiveColor",
6970
+ "type": "[ButtonColor](/docs/types#ButtonColor)",
6756
6971
  "default": "—",
6757
- "description": "确认按钮语义色"
6972
+ "description": "确认按钮颜色"
6758
6973
  },
6759
6974
  {
6760
6975
  "name": "onPositiveClick",
@@ -6902,7 +7117,7 @@
6902
7117
  "sectionId": "positions",
6903
7118
  "lang": "vue",
6904
7119
  "preview": true,
6905
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst position = ref<'center' | 'top' | 'topright' | 'bottomleft'>('center')\n\nfunction openAt(next: 'center' | 'top' | 'topright' | 'bottomleft') {\n position.value = next\n open.value = true\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Center\" size=\"small\" @click=\"openAt('center')\" />\n <MButton label=\"Top\" size=\"small\" severity=\"secondary\" @click=\"openAt('top')\" />\n <MButton label=\"Top Right\" size=\"small\" @click=\"openAt('topright')\" />\n <MButton label=\"Bottom Left\" size=\"small\" severity=\"secondary\" @click=\"openAt('bottomleft')\" />\n <MDialog v-model=\"open\" :header=\"`Position: ${position}`\" :position=\"position\">\n <p style=\"margin:0\">\n Dialog can dock to edges and corners.\n </p>\n </MDialog>\n </div>\n</template>",
7120
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst position = ref<'center' | 'top' | 'topright' | 'bottomleft'>('center')\n\nfunction openAt(next: 'center' | 'top' | 'topright' | 'bottomleft') {\n position.value = next\n open.value = true\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Center\" size=\"small\" @click=\"openAt('center')\" />\n <MButton label=\"Top\" size=\"small\" @click=\"openAt('top')\"/>\n <MButton label=\"Top Right\" size=\"small\" @click=\"openAt('topright')\" />\n <MButton label=\"Bottom Left\" size=\"small\" @click=\"openAt('bottomleft')\"/>\n <MDialog v-model=\"open\" :header=\"`Position: ${position}`\" :position=\"position\">\n <p style=\"margin:0\">\n Dialog can dock to edges and corners.\n </p>\n </MDialog>\n </div>\n</template>",
6906
7121
  "locale": "zh-CN"
6907
7122
  },
6908
7123
  {
@@ -6911,7 +7126,7 @@
6911
7126
  "sectionId": "footer-actions",
6912
7127
  "lang": "vue",
6913
7128
  "preview": true,
6914
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"With Footer\" @click=\"open = true\" />\n <MDialog v-model=\"open\" header=\"Save changes\" width=\"28rem\">\n <p style=\"margin:0\">\n Footer slot is for primary and secondary actions.\n </p>\n <template #footer>\n <div style=\"display:flex;gap:0.75rem;justify-content:flex-end;width:100%\">\n <MButton label=\"Cancel\" severity=\"secondary\" text @click=\"open = false\" />\n <MButton label=\"Confirm\" @click=\"open = false\" />\n </div>\n </template>\n </MDialog>\n </div>\n</template>",
7129
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"With Footer\" @click=\"open = true\" />\n <MDialog v-model=\"open\" header=\"Save changes\" width=\"28rem\">\n <p style=\"margin:0\">\n Footer slot is for primary and secondary actions.\n </p>\n <template #footer>\n <div style=\"display:flex;gap:0.75rem;justify-content:flex-end;width:100%\">\n <MButton label=\"Cancel\" @click=\"open = false\" type=\"text\"/>\n <MButton label=\"Confirm\" @click=\"open = false\" />\n </div>\n </template>\n </MDialog>\n </div>\n</template>",
6915
7130
  "locale": "zh-CN"
6916
7131
  },
6917
7132
  {
@@ -6920,7 +7135,7 @@
6920
7135
  "sectionId": "no-dismiss-mask",
6921
7136
  "lang": "vue",
6922
7137
  "preview": true,
6923
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"No Mask Dismiss\" severity=\"secondary\" @click=\"open = true\" />\n <MDialog v-model=\"open\" header=\"Stay open\" :dismissable-mask=\"false\">\n <p style=\"margin:0\">\n Click the mask — the dialog stays open. Use the close button or Esc.\n </p>\n </MDialog>\n </div>\n</template>",
7138
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"No Mask Dismiss\" @click=\"open = true\"/>\n <MDialog v-model=\"open\" header=\"Stay open\" :dismissable-mask=\"false\">\n <p style=\"margin:0\">\n Click the mask — the dialog stays open. Use the close button or Esc.\n </p>\n </MDialog>\n </div>\n</template>",
6924
7139
  "locale": "zh-CN"
6925
7140
  },
6926
7141
  {
@@ -6974,7 +7189,7 @@
6974
7189
  "sectionId": "positions",
6975
7190
  "lang": "vue",
6976
7191
  "preview": true,
6977
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst position = ref<'center' | 'top' | 'topright' | 'bottomleft'>('center')\n\nfunction openAt(next: 'center' | 'top' | 'topright' | 'bottomleft') {\n position.value = next\n open.value = true\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Center\" size=\"small\" @click=\"openAt('center')\" />\n <MButton label=\"Top\" size=\"small\" severity=\"secondary\" @click=\"openAt('top')\" />\n <MButton label=\"Top Right\" size=\"small\" @click=\"openAt('topright')\" />\n <MButton label=\"Bottom Left\" size=\"small\" severity=\"secondary\" @click=\"openAt('bottomleft')\" />\n <MDialog v-model=\"open\" :header=\"`Position: ${position}`\" :position=\"position\">\n <p style=\"margin:0\">\n Dialog can dock to edges and corners.\n </p>\n </MDialog>\n </div>\n</template>",
7192
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst position = ref<'center' | 'top' | 'topright' | 'bottomleft'>('center')\n\nfunction openAt(next: 'center' | 'top' | 'topright' | 'bottomleft') {\n position.value = next\n open.value = true\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Center\" size=\"small\" @click=\"openAt('center')\" />\n <MButton label=\"Top\" size=\"small\" @click=\"openAt('top')\"/>\n <MButton label=\"Top Right\" size=\"small\" @click=\"openAt('topright')\" />\n <MButton label=\"Bottom Left\" size=\"small\" @click=\"openAt('bottomleft')\"/>\n <MDialog v-model=\"open\" :header=\"`Position: ${position}`\" :position=\"position\">\n <p style=\"margin:0\">\n Dialog can dock to edges and corners.\n </p>\n </MDialog>\n </div>\n</template>",
6978
7193
  "locale": "en-US"
6979
7194
  },
6980
7195
  {
@@ -6983,7 +7198,7 @@
6983
7198
  "sectionId": "footer-actions",
6984
7199
  "lang": "vue",
6985
7200
  "preview": true,
6986
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"With Footer\" @click=\"open = true\" />\n <MDialog v-model=\"open\" header=\"Save changes\" width=\"28rem\">\n <p style=\"margin:0\">\n Footer slot is for primary and secondary actions.\n </p>\n <template #footer>\n <div style=\"display:flex;gap:0.75rem;justify-content:flex-end;width:100%\">\n <MButton label=\"Cancel\" severity=\"secondary\" text @click=\"open = false\" />\n <MButton label=\"Confirm\" @click=\"open = false\" />\n </div>\n </template>\n </MDialog>\n </div>\n</template>",
7201
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"With Footer\" @click=\"open = true\" />\n <MDialog v-model=\"open\" header=\"Save changes\" width=\"28rem\">\n <p style=\"margin:0\">\n Footer slot is for primary and secondary actions.\n </p>\n <template #footer>\n <div style=\"display:flex;gap:0.75rem;justify-content:flex-end;width:100%\">\n <MButton label=\"Cancel\" @click=\"open = false\" type=\"text\"/>\n <MButton label=\"Confirm\" @click=\"open = false\" />\n </div>\n </template>\n </MDialog>\n </div>\n</template>",
6987
7202
  "locale": "en-US"
6988
7203
  },
6989
7204
  {
@@ -6992,7 +7207,7 @@
6992
7207
  "sectionId": "no-dismiss-mask",
6993
7208
  "lang": "vue",
6994
7209
  "preview": true,
6995
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"No Mask Dismiss\" severity=\"secondary\" @click=\"open = true\" />\n <MDialog v-model=\"open\" header=\"Stay open\" :dismissable-mask=\"false\">\n <p style=\"margin:0\">\n Click the mask — the dialog stays open. Use the close button or Esc.\n </p>\n </MDialog>\n </div>\n</template>",
7210
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDialog } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"No Mask Dismiss\" @click=\"open = true\"/>\n <MDialog v-model=\"open\" header=\"Stay open\" :dismissable-mask=\"false\">\n <p style=\"margin:0\">\n Click the mask — the dialog stays open. Use the close button or Esc.\n </p>\n </MDialog>\n </div>\n</template>",
6996
7211
  "locale": "en-US"
6997
7212
  },
6998
7213
  {
@@ -7071,7 +7286,7 @@
7071
7286
  {
7072
7287
  "id": "props",
7073
7288
  "title": "Props",
7074
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 可见性。配合 `v-model` 使用。 |\n| `title` | `string` | — | 标题文案。 |\n| `header` | `string` | — | `title` 的别名。 |\n| `closeOnEsc` | `boolean` | `true` | 按 Esc 关闭。 |\n| `blockScroll` | `boolean` | `true` | 打开时锁定页面滚动(`modal` 时生效)。 |\n| `closeOnOutsideClick` | `boolean` | `true` | 点击遮罩关闭。 |\n| `dismissableMask` | `boolean` | — | `closeOnOutsideClick` 的别名。 |\n| `maskClosable` | `boolean` | — | `closeOnOutsideClick` 的别名。 |\n| `closable` | `boolean` | `true` | 显示关闭按钮。 |\n| `maximizable` | `boolean` | `false` | 显示最大化 / 还原按钮。 |\n| `modal` | `boolean` | `true` | 遮罩层。 |\n| `position` | `'center' \\| 'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'topleft' \\| 'topright' \\| 'bottomleft' \\| 'bottomright'` | `'center'` | 对话框位置。 |\n| `centered` | `boolean` | — | 垂直居中:`true` → `center`,`false` → `top`;省略时用 `position`。 |\n| `width` | `string` | — | 对话框宽度(最大化时忽略)。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | 挂载目标;`'self'` 就地渲染。 |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | 标题状态图标;`warning` 与 `warn` 同义 |\n| `positiveText` / `negativeText` | `string` | — | 预设页脚按钮;有 `footer` 插槽时忽略 |\n| `positiveSeverity` | [ButtonSeverity](/docs/types#ButtonSeverity) | — | 确认按钮语义色 |\n| `onPositiveClick` / `onNegativeClick` | `(e) => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭 |\n| `beforeClose` | `() => unknown \\| Promise<unknown>` | — | X / Esc / 遮罩关闭前;返回 `false` 则保持打开 |\n| `ariaLabel` | `string` | — | 对话框可访问名称。 |\n| `transition` | `string \\| false` | `'zoom'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | 遮罩层(backdrop)透传,键名 `root`。 |"
7289
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 可见性。配合 `v-model` 使用。 |\n| `title` | `string` | — | 标题文案。 |\n| `header` | `string` | — | `title` 的别名。 |\n| `closeOnEsc` | `boolean` | `true` | 按 Esc 关闭。 |\n| `blockScroll` | `boolean` | `true` | 打开时锁定页面滚动(`modal` 时生效)。 |\n| `closeOnOutsideClick` | `boolean` | `true` | 点击遮罩关闭。 |\n| `dismissableMask` | `boolean` | — | `closeOnOutsideClick` 的别名。 |\n| `maskClosable` | `boolean` | — | `closeOnOutsideClick` 的别名。 |\n| `closable` | `boolean` | `true` | 显示关闭按钮。 |\n| `maximizable` | `boolean` | `false` | 显示最大化 / 还原按钮。 |\n| `modal` | `boolean` | `true` | 遮罩层。 |\n| `position` | `'center' \\| 'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'topleft' \\| 'topright' \\| 'bottomleft' \\| 'bottomright'` | `'center'` | 对话框位置。 |\n| `centered` | `boolean` | — | 垂直居中:`true` → `center`,`false` → `top`;省略时用 `position`。 |\n| `width` | `string` | — | 对话框宽度(最大化时忽略)。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | 挂载目标;`'self'` 就地渲染。 |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | 标题状态图标;`warning` 与 `warn` 同义 |\n| `positiveText` / `negativeText` | `string` | — | 预设页脚按钮;有 `footer` 插槽时忽略 |\n| `positiveColor` | [ButtonColor](/docs/types#ButtonColor) | — | 确认按钮颜色 |\n| `onPositiveClick` / `onNegativeClick` | `(e) => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭 |\n| `beforeClose` | `() => unknown \\| Promise<unknown>` | — | X / Esc / 遮罩关闭前;返回 `false` 则保持打开 |\n| `ariaLabel` | `string` | — | 对话框可访问名称。 |\n| `transition` | `string \\| false` | `'zoom'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | 遮罩层(backdrop)透传,键名 `root`。 |"
7075
7290
  },
7076
7291
  {
7077
7292
  "id": "样式与-attrs",
@@ -7096,10 +7311,10 @@
7096
7311
  {
7097
7312
  "id": "命令式调用-usemodal-modal",
7098
7313
  "title": "命令式调用(useModal / modal)",
7099
- "body": "不写模板也能弹出对话框:\n\n```ts\nimport { modal, useModal } from 'morya-ui'\n\n// 模块级单例\nmodal.confirm({\n title: '确认删除?',\n content: '删除后不可恢复',\n onOk: async () => { await remove() },\n})\n\n// 或组件内作用域实例\nconst dialog = useModal()\ndialog.success({ title: '已保存' })\n```\n\n每个调用返回 `{ destroy, update }`:`update` 可在打开时改标题/内容,`destroy` 立即关闭并卸载。`modal.destroyAll()` 关闭全部由该 API 创建的对话框。\n\n| 方法 | 说明 |\n| --- | --- |\n| `info(options)` | 信息弹窗(默认无取消按钮) |\n| `success(options)` | 成功弹窗 |\n| `warning(options)` | 警告弹窗 |\n| `error(options)` | 错误弹窗 |\n| `confirm(options)` | 确认弹窗(默认显示取消按钮) |\n| `destroyAll()` | 关闭全部 |\n\n`options` 传字符串等价于 `{ content: '...' }`。\n\n| 字段 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 标题 |\n| `content` | `string \\| VNode` | — | 内容 |\n| `type` | `DialogType` | — | 头部状态图标 |\n| `okText` / `cancelText` | `string` | locale | 按钮文案 |\n| `showCancel` | `boolean` | 状态弹窗 `false`,`confirm` `true` | 是否显示取消按钮 |\n| `okSeverity` | `ButtonSeverity` | `'primary'` | 确认按钮语义色 |\n| `width` / `position` / `centered` | 同 Dialog | — | 布局 |\n| `maskClosable` | `boolean` | `false` | 点击遮罩关闭 |\n| `onOk` | `() => void \\| Promise<void>` | — | 确认回调;返回 Promise 时按钮进入 loading |\n| `onCancel` | `() => void` | — | 取消 / 关闭回调 |\n| `afterClose` | `() => void` | — | 关闭动画结束后回调 |\n\n> 命令式弹窗就地渲染在挂载容器内(不 Teleport),便于精确销毁。\n| `footer` | 底部操作区。 |"
7314
+ "body": "不写模板也能弹出对话框:\n\n```ts\nimport { modal, useModal } from 'morya-ui'\n\n// 模块级单例\nmodal.confirm({\n title: '确认删除?',\n content: '删除后不可恢复',\n onOk: async () => { await remove() },\n})\n\n// 或组件内作用域实例\nconst dialog = useModal()\ndialog.success({ title: '已保存' })\n```\n\n每个调用返回 `{ destroy, update }`:`update` 可在打开时改标题/内容,`destroy` 立即关闭并卸载。`modal.destroyAll()` 关闭全部由该 API 创建的对话框。\n\n| 方法 | 说明 |\n| --- | --- |\n| `info(options)` | 信息弹窗(默认无取消按钮) |\n| `success(options)` | 成功弹窗 |\n| `warning(options)` | 警告弹窗 |\n| `error(options)` | 错误弹窗 |\n| `confirm(options)` | 确认弹窗(默认显示取消按钮) |\n| `destroyAll()` | 关闭全部 |\n\n`options` 传字符串等价于 `{ content: '...' }`。\n\n| 字段 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 标题 |\n| `content` | `string \\| VNode` | — | 内容 |\n| `type` | `DialogType` | — | 头部状态图标 |\n| `okText` / `cancelText` | `string` | locale | 按钮文案 |\n| `showCancel` | `boolean` | 状态弹窗 `false`,`confirm` `true` | 是否显示取消按钮 |\n| `okColor` | `ButtonColor` | `'primary'` | 确认按钮颜色 |\n| `width` / `position` / `centered` | 同 Dialog | — | 布局 |\n| `maskClosable` | `boolean` | `false` | 点击遮罩关闭 |\n| `onOk` | `() => void \\| Promise<void>` | — | 确认回调;返回 Promise 时按钮进入 loading |\n| `onCancel` | `() => void` | — | 取消 / 关闭回调 |\n| `afterClose` | `() => void` | — | 关闭动画结束后回调 |\n\n> 命令式弹窗就地渲染在挂载容器内(不 Teleport),便于精确销毁。\n| `footer` | 底部操作区。 |"
7100
7315
  }
7101
7316
  ],
7102
- "markdown": "---\ntitle: Dialog\ncategory: 05 / FEEDBACK\ndescription: 模态对话框。支持预设页脚、异步关闭拦截、状态 type。\n---\n\n# Dialog\n\n模态对话框。可见性使用 `v-model`(`modelValue`),对应 的 `visible`。\n\n## 引入\n\n```ts\nimport { MButton, MDialog } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Positions\n\n支持 `center` / `top` / `bottom` / `left` / `right` 以及四角位置。\n\n```vue preview src=\"./demos/Positions.vue\"\n```\n\n## Footer actions\n\n```vue preview src=\"./demos/FooterActions.vue\"\n```\n\n## No dismiss mask\n\n`dismissableMask={false}`(或 `closeOnOutsideClick={false}` / `maskClosable={false}`)时点击遮罩不关闭。\n\n```vue preview src=\"./demos/NoDismissMask.vue\"\n```\n\n## Maximizable\n\n`maximizable` 在标题栏提供最大化 / 还原切换。\n\n```vue preview src=\"./demos/Maximizable.vue\"\n```\n\n## 预设页脚与异步关闭\n\n`positiveText` / `negativeText` 生成确认 / 取消按钮(`footer` 插槽优先)。处理函数返回 `false`(含 Promise)则保持打开。确认型流程请用 [ConfirmDialog](/components/ConfirmDialog);`type` 只负责 Dialog 标题图标。\n\n```vue preview src=\"./demos/PresetFooterAndAsyncClose.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 可见性。配合 `v-model` 使用。 |\n| `title` | `string` | — | 标题文案。 |\n| `header` | `string` | — | `title` 的别名。 |\n| `closeOnEsc` | `boolean` | `true` | 按 Esc 关闭。 |\n| `blockScroll` | `boolean` | `true` | 打开时锁定页面滚动(`modal` 时生效)。 |\n| `closeOnOutsideClick` | `boolean` | `true` | 点击遮罩关闭。 |\n| `dismissableMask` | `boolean` | — | `closeOnOutsideClick` 的别名。 |\n| `maskClosable` | `boolean` | — | `closeOnOutsideClick` 的别名。 |\n| `closable` | `boolean` | `true` | 显示关闭按钮。 |\n| `maximizable` | `boolean` | `false` | 显示最大化 / 还原按钮。 |\n| `modal` | `boolean` | `true` | 遮罩层。 |\n| `position` | `'center' \\| 'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'topleft' \\| 'topright' \\| 'bottomleft' \\| 'bottomright'` | `'center'` | 对话框位置。 |\n| `centered` | `boolean` | — | 垂直居中:`true` → `center`,`false` → `top`;省略时用 `position`。 |\n| `width` | `string` | — | 对话框宽度(最大化时忽略)。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | 挂载目标;`'self'` 就地渲染。 |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | 标题状态图标;`warning` 与 `warn` 同义 |\n| `positiveText` / `negativeText` | `string` | — | 预设页脚按钮;有 `footer` 插槽时忽略 |\n| `positiveSeverity` | [ButtonSeverity](/docs/types#ButtonSeverity) | — | 确认按钮语义色 |\n| `onPositiveClick` / `onNegativeClick` | `(e) => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭 |\n| `beforeClose` | `() => unknown \\| Promise<unknown>` | — | X / Esc / 遮罩关闭前;返回 `false` 则保持打开 |\n| `ariaLabel` | `string` | — | 对话框可访问名称。 |\n| `transition` | `string \\| false` | `'zoom'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | 遮罩层(backdrop)透传,键名 `root`。 |\n\n## 样式与 attrs\n\nDialog Teleport 到 `body` 后,你在组件上写的 fallthrough attrs(`class`、`style`、`data-*`、`title` 等)落在**遮罩层**(`.m-dialog-backdrop`),不是内层 `.m-dialog` 面板。面板宽度用 `width` prop;内层 DOM 用 `pt`。详见 [样式与 attrs](/docs/attrs)。\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `boolean` | 可见性变化。 |\n| `close` | — | 关闭时触发。 |\n| `show` | — | 打开时触发。 |\n| `hide` | — | 关闭后触发。 |\n| `maximize` | — | 进入最大化。 |\n| `unmaximize` | — | 退出最大化。 |\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `close()` | 关闭对话框(等同取消/关闭动作)。 |\n| `maximize()` | 最大化;已最大化时无操作。 |\n| `unmaximize()` | 退出最大化。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 对话框内容。 |\n| `header` | 自定义标题区。 |\n| `footer` | 底部操作区。 |\n\n## 命令式调用(useModal / modal)\n\n不写模板也能弹出对话框:\n\n```ts\nimport { modal, useModal } from 'morya-ui'\n\n// 模块级单例\nmodal.confirm({\n title: '确认删除?',\n content: '删除后不可恢复',\n onOk: async () => { await remove() },\n})\n\n// 或组件内作用域实例\nconst dialog = useModal()\ndialog.success({ title: '已保存' })\n```\n\n每个调用返回 `{ destroy, update }`:`update` 可在打开时改标题/内容,`destroy` 立即关闭并卸载。`modal.destroyAll()` 关闭全部由该 API 创建的对话框。\n\n| 方法 | 说明 |\n| --- | --- |\n| `info(options)` | 信息弹窗(默认无取消按钮) |\n| `success(options)` | 成功弹窗 |\n| `warning(options)` | 警告弹窗 |\n| `error(options)` | 错误弹窗 |\n| `confirm(options)` | 确认弹窗(默认显示取消按钮) |\n| `destroyAll()` | 关闭全部 |\n\n`options` 传字符串等价于 `{ content: '...' }`。\n\n| 字段 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 标题 |\n| `content` | `string \\| VNode` | — | 内容 |\n| `type` | `DialogType` | — | 头部状态图标 |\n| `okText` / `cancelText` | `string` | locale | 按钮文案 |\n| `showCancel` | `boolean` | 状态弹窗 `false`,`confirm` `true` | 是否显示取消按钮 |\n| `okSeverity` | `ButtonSeverity` | `'primary'` | 确认按钮语义色 |\n| `width` / `position` / `centered` | 同 Dialog | — | 布局 |\n| `maskClosable` | `boolean` | `false` | 点击遮罩关闭 |\n| `onOk` | `() => void \\| Promise<void>` | — | 确认回调;返回 Promise 时按钮进入 loading |\n| `onCancel` | `() => void` | — | 取消 / 关闭回调 |\n| `afterClose` | `() => void` | — | 关闭动画结束后回调 |\n\n> 命令式弹窗就地渲染在挂载容器内(不 Teleport),便于精确销毁。\n| `footer` | 底部操作区。 |\n"
7317
+ "markdown": "---\ntitle: Dialog\ncategory: 05 / FEEDBACK\ndescription: 模态对话框。支持预设页脚、异步关闭拦截、状态 type。\n---\n\n# Dialog\n\n模态对话框。可见性使用 `v-model`(`modelValue`),对应 的 `visible`。\n\n## 引入\n\n```ts\nimport { MButton, MDialog } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Positions\n\n支持 `center` / `top` / `bottom` / `left` / `right` 以及四角位置。\n\n```vue preview src=\"./demos/Positions.vue\"\n```\n\n## Footer actions\n\n```vue preview src=\"./demos/FooterActions.vue\"\n```\n\n## No dismiss mask\n\n`dismissableMask={false}`(或 `closeOnOutsideClick={false}` / `maskClosable={false}`)时点击遮罩不关闭。\n\n```vue preview src=\"./demos/NoDismissMask.vue\"\n```\n\n## Maximizable\n\n`maximizable` 在标题栏提供最大化 / 还原切换。\n\n```vue preview src=\"./demos/Maximizable.vue\"\n```\n\n## 预设页脚与异步关闭\n\n`positiveText` / `negativeText` 生成确认 / 取消按钮(`footer` 插槽优先)。处理函数返回 `false`(含 Promise)则保持打开。确认型流程请用 [ConfirmDialog](/components/ConfirmDialog);`type` 只负责 Dialog 标题图标。\n\n```vue preview src=\"./demos/PresetFooterAndAsyncClose.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 可见性。配合 `v-model` 使用。 |\n| `title` | `string` | — | 标题文案。 |\n| `header` | `string` | — | `title` 的别名。 |\n| `closeOnEsc` | `boolean` | `true` | 按 Esc 关闭。 |\n| `blockScroll` | `boolean` | `true` | 打开时锁定页面滚动(`modal` 时生效)。 |\n| `closeOnOutsideClick` | `boolean` | `true` | 点击遮罩关闭。 |\n| `dismissableMask` | `boolean` | — | `closeOnOutsideClick` 的别名。 |\n| `maskClosable` | `boolean` | — | `closeOnOutsideClick` 的别名。 |\n| `closable` | `boolean` | `true` | 显示关闭按钮。 |\n| `maximizable` | `boolean` | `false` | 显示最大化 / 还原按钮。 |\n| `modal` | `boolean` | `true` | 遮罩层。 |\n| `position` | `'center' \\| 'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'topleft' \\| 'topright' \\| 'bottomleft' \\| 'bottomright'` | `'center'` | 对话框位置。 |\n| `centered` | `boolean` | — | 垂直居中:`true` → `center`,`false` → `top`;省略时用 `position`。 |\n| `width` | `string` | — | 对话框宽度(最大化时忽略)。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | 挂载目标;`'self'` 就地渲染。 |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | 标题状态图标;`warning` 与 `warn` 同义 |\n| `positiveText` / `negativeText` | `string` | — | 预设页脚按钮;有 `footer` 插槽时忽略 |\n| `positiveColor` | [ButtonColor](/docs/types#ButtonColor) | — | 确认按钮颜色 |\n| `onPositiveClick` / `onNegativeClick` | `(e) => unknown \\| Promise<unknown>` | — | 返回 `false` 则不关闭 |\n| `beforeClose` | `() => unknown \\| Promise<unknown>` | — | X / Esc / 遮罩关闭前;返回 `false` 则保持打开 |\n| `ariaLabel` | `string` | — | 对话框可访问名称。 |\n| `transition` | `string \\| false` | `'zoom'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | 遮罩层(backdrop)透传,键名 `root`。 |\n\n## 样式与 attrs\n\nDialog Teleport 到 `body` 后,你在组件上写的 fallthrough attrs(`class`、`style`、`data-*`、`title` 等)落在**遮罩层**(`.m-dialog-backdrop`),不是内层 `.m-dialog` 面板。面板宽度用 `width` prop;内层 DOM 用 `pt`。详见 [样式与 attrs](/docs/attrs)。\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `boolean` | 可见性变化。 |\n| `close` | — | 关闭时触发。 |\n| `show` | — | 打开时触发。 |\n| `hide` | — | 关闭后触发。 |\n| `maximize` | — | 进入最大化。 |\n| `unmaximize` | — | 退出最大化。 |\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `close()` | 关闭对话框(等同取消/关闭动作)。 |\n| `maximize()` | 最大化;已最大化时无操作。 |\n| `unmaximize()` | 退出最大化。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 对话框内容。 |\n| `header` | 自定义标题区。 |\n| `footer` | 底部操作区。 |\n\n## 命令式调用(useModal / modal)\n\n不写模板也能弹出对话框:\n\n```ts\nimport { modal, useModal } from 'morya-ui'\n\n// 模块级单例\nmodal.confirm({\n title: '确认删除?',\n content: '删除后不可恢复',\n onOk: async () => { await remove() },\n})\n\n// 或组件内作用域实例\nconst dialog = useModal()\ndialog.success({ title: '已保存' })\n```\n\n每个调用返回 `{ destroy, update }`:`update` 可在打开时改标题/内容,`destroy` 立即关闭并卸载。`modal.destroyAll()` 关闭全部由该 API 创建的对话框。\n\n| 方法 | 说明 |\n| --- | --- |\n| `info(options)` | 信息弹窗(默认无取消按钮) |\n| `success(options)` | 成功弹窗 |\n| `warning(options)` | 警告弹窗 |\n| `error(options)` | 错误弹窗 |\n| `confirm(options)` | 确认弹窗(默认显示取消按钮) |\n| `destroyAll()` | 关闭全部 |\n\n`options` 传字符串等价于 `{ content: '...' }`。\n\n| 字段 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 标题 |\n| `content` | `string \\| VNode` | — | 内容 |\n| `type` | `DialogType` | — | 头部状态图标 |\n| `okText` / `cancelText` | `string` | locale | 按钮文案 |\n| `showCancel` | `boolean` | 状态弹窗 `false`,`confirm` `true` | 是否显示取消按钮 |\n| `okColor` | `ButtonColor` | `'primary'` | 确认按钮颜色 |\n| `width` / `position` / `centered` | 同 Dialog | — | 布局 |\n| `maskClosable` | `boolean` | `false` | 点击遮罩关闭 |\n| `onOk` | `() => void \\| Promise<void>` | — | 确认回调;返回 Promise 时按钮进入 loading |\n| `onCancel` | `() => void` | — | 取消 / 关闭回调 |\n| `afterClose` | `() => void` | — | 关闭动画结束后回调 |\n\n> 命令式弹窗就地渲染在挂载容器内(不 Teleport),便于精确销毁。\n| `footer` | 底部操作区。 |\n"
7103
7318
  },
7104
7319
  "en-US": {
7105
7320
  "title": "Dialog",
@@ -7148,7 +7363,7 @@
7148
7363
  {
7149
7364
  "id": "props",
7150
7365
  "title": "Props",
7151
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. Use with `v-model`. |\n| `title` | `string` | — | Title text. |\n| `header` | `string` | — | Alias of `title`. |\n| `closeOnEsc` | `boolean` | `true` | Close on Esc. |\n| `blockScroll` | `boolean` | `true` | Lock page scroll while open (when `modal` is true). |\n| `closeOnOutsideClick` | `boolean` | `true` | Close when clicking the mask. |\n| `dismissableMask` | `boolean` | — | Alias of `closeOnOutsideClick`. |\n| `maskClosable` | `boolean` | — | Alias of `closeOnOutsideClick` . |\n| `closable` | `boolean` | `true` | Show the close button. |\n| `maximizable` | `boolean` | `false` | Show the maximize / restore button. |\n| `modal` | `boolean` | `true` | Overlay mask. |\n| `position` | `'center' \\| 'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'topleft' \\| 'topright' \\| 'bottomleft' \\| 'bottomright'` | `'center'` | Dialog position. |\n| `centered` | `boolean` | — | Vertical centering: `true` → `center`, `false` → `top`; omit to use `position`. |\n| `width` | `string` | — | Dialog width (ignored when maximized). |\n| `teleport` | `boolean` | `true` | Overlay Teleport; mounts to `body` by default. |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | Mount target; `'self'` renders in place. |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | Status icon in the header; `warning` is an alias of `warn` |\n| `positiveText` / `negativeText` | `string` | — | Preset footer buttons; ignored when the `footer` slot is used |\n| `positiveSeverity` | [ButtonSeverity](/docs/types#ButtonSeverity) | — | Confirm button severity |\n| `onPositiveClick` / `onNegativeClick` | `(e) => unknown \\| Promise<unknown>` | — | Return `false` to keep the dialog open |\n| `beforeClose` | `() => unknown \\| Promise<unknown>` | — | Runs before X / Esc / mask dismiss; return `false` to keep open |\n| `ariaLabel` | `string` | — | Accessible dialog name. |\n| `transition` | `string \\| false` | `'zoom'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Backdrop pass-through; key `root`. |"
7366
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. Use with `v-model`. |\n| `title` | `string` | — | Title text. |\n| `header` | `string` | — | Alias of `title`. |\n| `closeOnEsc` | `boolean` | `true` | Close on Esc. |\n| `blockScroll` | `boolean` | `true` | Lock page scroll while open (when `modal` is true). |\n| `closeOnOutsideClick` | `boolean` | `true` | Close when clicking the mask. |\n| `dismissableMask` | `boolean` | — | Alias of `closeOnOutsideClick`. |\n| `maskClosable` | `boolean` | — | Alias of `closeOnOutsideClick` . |\n| `closable` | `boolean` | `true` | Show the close button. |\n| `maximizable` | `boolean` | `false` | Show the maximize / restore button. |\n| `modal` | `boolean` | `true` | Overlay mask. |\n| `position` | `'center' \\| 'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'topleft' \\| 'topright' \\| 'bottomleft' \\| 'bottomright'` | `'center'` | Dialog position. |\n| `centered` | `boolean` | — | Vertical centering: `true` → `center`, `false` → `top`; omit to use `position`. |\n| `width` | `string` | — | Dialog width (ignored when maximized). |\n| `teleport` | `boolean` | `true` | Overlay Teleport; mounts to `body` by default. |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | Mount target; `'self'` renders in place. |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | Status icon in the header; `warning` is an alias of `warn` |\n| `positiveText` / `negativeText` | `string` | — | Preset footer buttons; ignored when the `footer` slot is used |\n| `positiveColor` | [ButtonColor](/docs/types#ButtonColor) | — | Confirm button color |\n| `onPositiveClick` / `onNegativeClick` | `(e) => unknown \\| Promise<unknown>` | — | Return `false` to keep the dialog open |\n| `beforeClose` | `() => unknown \\| Promise<unknown>` | — | Runs before X / Esc / mask dismiss; return `false` to keep open |\n| `ariaLabel` | `string` | — | Accessible dialog name. |\n| `transition` | `string \\| false` | `'zoom'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Backdrop pass-through; key `root`. |"
7152
7367
  },
7153
7368
  {
7154
7369
  "id": "styling-attrs",
@@ -7173,10 +7388,10 @@
7173
7388
  {
7174
7389
  "id": "imperative-api-usemodal-modal",
7175
7390
  "title": "Imperative API (useModal / modal)",
7176
- "body": "Open dialogs without writing a template:\n\n```ts\nimport { modal, useModal } from 'morya-ui'\n\n// Module-level singleton\nmodal.confirm({\n title: 'Delete this item?',\n content: 'This cannot be undone',\n onOk: async () => { await remove() },\n})\n\n// Or a component-scoped instance\nconst dialog = useModal()\ndialog.success({ title: 'Saved' })\n```\n\nEvery call returns `{ destroy, update }`: `update` patches the title / content while open, `destroy` closes and unmounts immediately. `modal.destroyAll()` closes every dialog created through the API.\n\n| Method | Description |\n| --- | --- |\n| `info(options)` | Message dialog (no cancel button by default) |\n| `success(options)` | Success dialog |\n| `warning(options)` | Warning dialog |\n| `error(options)` | Error dialog |\n| `confirm(options)` | Confirmation dialog (cancel button shown by default) |\n| `destroyAll()` | Close all |\n\nPassing a string as `options` is shorthand for `{ content: '...' }`.\n\n| Field | Type | Default | Description |\n| --- | --- | --- | --- |\n| `title` | `string` | — | Title |\n| `content` | `string \\| VNode` | — | Body |\n| `type` | `DialogType` | — | Header status icon |\n| `okText` / `cancelText` | `string` | locale | Button labels |\n| `showCancel` | `boolean` | `false` for status helpers, `true` for `confirm` | Show the cancel button |\n| `okSeverity` | `ButtonSeverity` | `'primary'` | Confirm button tone |\n| `width` / `position` / `centered` | as Dialog | — | Layout |\n| `maskClosable` | `boolean` | `false` | Dismiss by clicking the mask |\n| `onOk` | `() => void \\| Promise<void>` | — | Confirm handler; a returned Promise puts the button in a loading state |\n| `onCancel` | `() => void` | — | Cancel / dismiss handler |\n| `afterClose` | `() => void` | — | Called after the close transition |\n\n> Imperative dialogs render in place inside their mount container (no Teleport) so they can be destroyed precisely."
7391
+ "body": "Open dialogs without writing a template:\n\n```ts\nimport { modal, useModal } from 'morya-ui'\n\n// Module-level singleton\nmodal.confirm({\n title: 'Delete this item?',\n content: 'This cannot be undone',\n onOk: async () => { await remove() },\n})\n\n// Or a component-scoped instance\nconst dialog = useModal()\ndialog.success({ title: 'Saved' })\n```\n\nEvery call returns `{ destroy, update }`: `update` patches the title / content while open, `destroy` closes and unmounts immediately. `modal.destroyAll()` closes every dialog created through the API.\n\n| Method | Description |\n| --- | --- |\n| `info(options)` | Message dialog (no cancel button by default) |\n| `success(options)` | Success dialog |\n| `warning(options)` | Warning dialog |\n| `error(options)` | Error dialog |\n| `confirm(options)` | Confirmation dialog (cancel button shown by default) |\n| `destroyAll()` | Close all |\n\nPassing a string as `options` is shorthand for `{ content: '...' }`.\n\n| Field | Type | Default | Description |\n| --- | --- | --- | --- |\n| `title` | `string` | — | Title |\n| `content` | `string \\| VNode` | — | Body |\n| `type` | `DialogType` | — | Header status icon |\n| `okText` / `cancelText` | `string` | locale | Button labels |\n| `showCancel` | `boolean` | `false` for status helpers, `true` for `confirm` | Show the cancel button |\n| `okColor` | `ButtonColor` | `'primary'` | Confirm button color |\n| `width` / `position` / `centered` | as Dialog | — | Layout |\n| `maskClosable` | `boolean` | `false` | Dismiss by clicking the mask |\n| `onOk` | `() => void \\| Promise<void>` | — | Confirm handler; a returned Promise puts the button in a loading state |\n| `onCancel` | `() => void` | — | Cancel / dismiss handler |\n| `afterClose` | `() => void` | — | Called after the close transition |\n\n> Imperative dialogs render in place inside their mount container (no Teleport) so they can be destroyed precisely."
7177
7392
  }
7178
7393
  ],
7179
- "markdown": "---\ntitle: Dialog\ncategory: 05 / FEEDBACK\ndescription: Modal dialog with preset footer actions, async close guards, and status type.\n---\n\n# Dialog\n\nModal dialog. Visibility uses `v-model` (`modelValue`), corresponding to `visible`.\n\n## Import\n\n```ts\nimport { MButton, MDialog } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Positions\n\nSupports `center` / `top` / `bottom` / `left` / `right` and the four corner positions.\n\n```vue preview src=\"./demos/Positions.vue\"\n```\n\n## Footer actions\n\n```vue preview src=\"./demos/FooterActions.vue\"\n```\n\n## No dismiss mask\n\nWith `dismissableMask={false}` (or `closeOnOutsideClick={false}` / `maskClosable={false}`), clicking the mask does not close the dialog.\n\n```vue preview src=\"./demos/NoDismissMask.vue\"\n```\n\n## Maximizable\n\n`maximizable` adds a maximize / restore toggle in the title bar.\n\n```vue preview src=\"./demos/Maximizable.vue\"\n```\n\n## Preset footer and async close\n\n`positiveText` / `negativeText` render confirm / cancel buttons (`footer` slot wins). Return `false` (including from a Promise) to keep the dialog open. Use [ConfirmDialog](/components/ConfirmDialog) for accept/reject flows; Dialog `type` is a header icon only.\n\n```vue preview src=\"./demos/PresetFooterAndAsyncClose.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. Use with `v-model`. |\n| `title` | `string` | — | Title text. |\n| `header` | `string` | — | Alias of `title`. |\n| `closeOnEsc` | `boolean` | `true` | Close on Esc. |\n| `blockScroll` | `boolean` | `true` | Lock page scroll while open (when `modal` is true). |\n| `closeOnOutsideClick` | `boolean` | `true` | Close when clicking the mask. |\n| `dismissableMask` | `boolean` | — | Alias of `closeOnOutsideClick`. |\n| `maskClosable` | `boolean` | — | Alias of `closeOnOutsideClick` . |\n| `closable` | `boolean` | `true` | Show the close button. |\n| `maximizable` | `boolean` | `false` | Show the maximize / restore button. |\n| `modal` | `boolean` | `true` | Overlay mask. |\n| `position` | `'center' \\| 'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'topleft' \\| 'topright' \\| 'bottomleft' \\| 'bottomright'` | `'center'` | Dialog position. |\n| `centered` | `boolean` | — | Vertical centering: `true` → `center`, `false` → `top`; omit to use `position`. |\n| `width` | `string` | — | Dialog width (ignored when maximized). |\n| `teleport` | `boolean` | `true` | Overlay Teleport; mounts to `body` by default. |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | Mount target; `'self'` renders in place. |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | Status icon in the header; `warning` is an alias of `warn` |\n| `positiveText` / `negativeText` | `string` | — | Preset footer buttons; ignored when the `footer` slot is used |\n| `positiveSeverity` | [ButtonSeverity](/docs/types#ButtonSeverity) | — | Confirm button severity |\n| `onPositiveClick` / `onNegativeClick` | `(e) => unknown \\| Promise<unknown>` | — | Return `false` to keep the dialog open |\n| `beforeClose` | `() => unknown \\| Promise<unknown>` | — | Runs before X / Esc / mask dismiss; return `false` to keep open |\n| `ariaLabel` | `string` | — | Accessible dialog name. |\n| `transition` | `string \\| false` | `'zoom'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Backdrop pass-through; key `root`. |\n\n## Styling & attrs\n\nAfter Teleport, fallthrough attrs on `<MDialog>` (`class`, `style`, `data-*`, `title`, …) land on the **backdrop** (`.m-dialog-backdrop`), not the inner `.m-dialog` panel. Use the `width` prop for panel width; use `pt` for inner DOM. See [Styling & attrs](/docs/attrs).\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `update:modelValue` | `boolean` | Visibility change. |\n| `close` | — | Emitted when closing. |\n| `show` | — | Emitted when opening. |\n| `hide` | — | Emitted after closing. |\n| `maximize` | — | Enter maximize. |\n| `unmaximize` | — | Exit maximize. |\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `close()` | Close the dialog (same as the cancel/close action). |\n| `maximize()` | Maximize; no-op when already maximized. |\n| `unmaximize()` | Leave the maximized state. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Dialog content. |\n| `header` | Custom header area. |\n| `footer` | Footer actions. |\n\n## Imperative API (useModal / modal)\n\nOpen dialogs without writing a template:\n\n```ts\nimport { modal, useModal } from 'morya-ui'\n\n// Module-level singleton\nmodal.confirm({\n title: 'Delete this item?',\n content: 'This cannot be undone',\n onOk: async () => { await remove() },\n})\n\n// Or a component-scoped instance\nconst dialog = useModal()\ndialog.success({ title: 'Saved' })\n```\n\nEvery call returns `{ destroy, update }`: `update` patches the title / content while open, `destroy` closes and unmounts immediately. `modal.destroyAll()` closes every dialog created through the API.\n\n| Method | Description |\n| --- | --- |\n| `info(options)` | Message dialog (no cancel button by default) |\n| `success(options)` | Success dialog |\n| `warning(options)` | Warning dialog |\n| `error(options)` | Error dialog |\n| `confirm(options)` | Confirmation dialog (cancel button shown by default) |\n| `destroyAll()` | Close all |\n\nPassing a string as `options` is shorthand for `{ content: '...' }`.\n\n| Field | Type | Default | Description |\n| --- | --- | --- | --- |\n| `title` | `string` | — | Title |\n| `content` | `string \\| VNode` | — | Body |\n| `type` | `DialogType` | — | Header status icon |\n| `okText` / `cancelText` | `string` | locale | Button labels |\n| `showCancel` | `boolean` | `false` for status helpers, `true` for `confirm` | Show the cancel button |\n| `okSeverity` | `ButtonSeverity` | `'primary'` | Confirm button tone |\n| `width` / `position` / `centered` | as Dialog | — | Layout |\n| `maskClosable` | `boolean` | `false` | Dismiss by clicking the mask |\n| `onOk` | `() => void \\| Promise<void>` | — | Confirm handler; a returned Promise puts the button in a loading state |\n| `onCancel` | `() => void` | — | Cancel / dismiss handler |\n| `afterClose` | `() => void` | — | Called after the close transition |\n\n> Imperative dialogs render in place inside their mount container (no Teleport) so they can be destroyed precisely.\n"
7394
+ "markdown": "---\ntitle: Dialog\ncategory: 05 / FEEDBACK\ndescription: Modal dialog with preset footer actions, async close guards, and status type.\n---\n\n# Dialog\n\nModal dialog. Visibility uses `v-model` (`modelValue`), corresponding to `visible`.\n\n## Import\n\n```ts\nimport { MButton, MDialog } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Positions\n\nSupports `center` / `top` / `bottom` / `left` / `right` and the four corner positions.\n\n```vue preview src=\"./demos/Positions.vue\"\n```\n\n## Footer actions\n\n```vue preview src=\"./demos/FooterActions.vue\"\n```\n\n## No dismiss mask\n\nWith `dismissableMask={false}` (or `closeOnOutsideClick={false}` / `maskClosable={false}`), clicking the mask does not close the dialog.\n\n```vue preview src=\"./demos/NoDismissMask.vue\"\n```\n\n## Maximizable\n\n`maximizable` adds a maximize / restore toggle in the title bar.\n\n```vue preview src=\"./demos/Maximizable.vue\"\n```\n\n## Preset footer and async close\n\n`positiveText` / `negativeText` render confirm / cancel buttons (`footer` slot wins). Return `false` (including from a Promise) to keep the dialog open. Use [ConfirmDialog](/components/ConfirmDialog) for accept/reject flows; Dialog `type` is a header icon only.\n\n```vue preview src=\"./demos/PresetFooterAndAsyncClose.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. Use with `v-model`. |\n| `title` | `string` | — | Title text. |\n| `header` | `string` | — | Alias of `title`. |\n| `closeOnEsc` | `boolean` | `true` | Close on Esc. |\n| `blockScroll` | `boolean` | `true` | Lock page scroll while open (when `modal` is true). |\n| `closeOnOutsideClick` | `boolean` | `true` | Close when clicking the mask. |\n| `dismissableMask` | `boolean` | — | Alias of `closeOnOutsideClick`. |\n| `maskClosable` | `boolean` | — | Alias of `closeOnOutsideClick` . |\n| `closable` | `boolean` | `true` | Show the close button. |\n| `maximizable` | `boolean` | `false` | Show the maximize / restore button. |\n| `modal` | `boolean` | `true` | Overlay mask. |\n| `position` | `'center' \\| 'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'topleft' \\| 'topright' \\| 'bottomleft' \\| 'bottomright'` | `'center'` | Dialog position. |\n| `centered` | `boolean` | — | Vertical centering: `true` → `center`, `false` → `top`; omit to use `position`. |\n| `width` | `string` | — | Dialog width (ignored when maximized). |\n| `teleport` | `boolean` | `true` | Overlay Teleport; mounts to `body` by default. |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | Mount target; `'self'` renders in place. |\n| `type` | `'info' \\| 'success' \\| 'warning' \\| 'error'` | — | Status icon in the header; `warning` is an alias of `warn` |\n| `positiveText` / `negativeText` | `string` | — | Preset footer buttons; ignored when the `footer` slot is used |\n| `positiveColor` | [ButtonColor](/docs/types#ButtonColor) | — | Confirm button color |\n| `onPositiveClick` / `onNegativeClick` | `(e) => unknown \\| Promise<unknown>` | — | Return `false` to keep the dialog open |\n| `beforeClose` | `() => unknown \\| Promise<unknown>` | — | Runs before X / Esc / mask dismiss; return `false` to keep open |\n| `ariaLabel` | `string` | — | Accessible dialog name. |\n| `transition` | `string \\| false` | `'zoom'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Backdrop pass-through; key `root`. |\n\n## Styling & attrs\n\nAfter Teleport, fallthrough attrs on `<MDialog>` (`class`, `style`, `data-*`, `title`, …) land on the **backdrop** (`.m-dialog-backdrop`), not the inner `.m-dialog` panel. Use the `width` prop for panel width; use `pt` for inner DOM. See [Styling & attrs](/docs/attrs).\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `update:modelValue` | `boolean` | Visibility change. |\n| `close` | — | Emitted when closing. |\n| `show` | — | Emitted when opening. |\n| `hide` | — | Emitted after closing. |\n| `maximize` | — | Enter maximize. |\n| `unmaximize` | — | Exit maximize. |\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `close()` | Close the dialog (same as the cancel/close action). |\n| `maximize()` | Maximize; no-op when already maximized. |\n| `unmaximize()` | Leave the maximized state. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Dialog content. |\n| `header` | Custom header area. |\n| `footer` | Footer actions. |\n\n## Imperative API (useModal / modal)\n\nOpen dialogs without writing a template:\n\n```ts\nimport { modal, useModal } from 'morya-ui'\n\n// Module-level singleton\nmodal.confirm({\n title: 'Delete this item?',\n content: 'This cannot be undone',\n onOk: async () => { await remove() },\n})\n\n// Or a component-scoped instance\nconst dialog = useModal()\ndialog.success({ title: 'Saved' })\n```\n\nEvery call returns `{ destroy, update }`: `update` patches the title / content while open, `destroy` closes and unmounts immediately. `modal.destroyAll()` closes every dialog created through the API.\n\n| Method | Description |\n| --- | --- |\n| `info(options)` | Message dialog (no cancel button by default) |\n| `success(options)` | Success dialog |\n| `warning(options)` | Warning dialog |\n| `error(options)` | Error dialog |\n| `confirm(options)` | Confirmation dialog (cancel button shown by default) |\n| `destroyAll()` | Close all |\n\nPassing a string as `options` is shorthand for `{ content: '...' }`.\n\n| Field | Type | Default | Description |\n| --- | --- | --- | --- |\n| `title` | `string` | — | Title |\n| `content` | `string \\| VNode` | — | Body |\n| `type` | `DialogType` | — | Header status icon |\n| `okText` / `cancelText` | `string` | locale | Button labels |\n| `showCancel` | `boolean` | `false` for status helpers, `true` for `confirm` | Show the cancel button |\n| `okColor` | `ButtonColor` | `'primary'` | Confirm button color |\n| `width` / `position` / `centered` | as Dialog | — | Layout |\n| `maskClosable` | `boolean` | `false` | Dismiss by clicking the mask |\n| `onOk` | `() => void \\| Promise<void>` | — | Confirm handler; a returned Promise puts the button in a loading state |\n| `onCancel` | `() => void` | — | Cancel / dismiss handler |\n| `afterClose` | `() => void` | — | Called after the close transition |\n\n> Imperative dialogs render in place inside their mount container (no Teleport) so they can be destroyed precisely.\n"
7180
7395
  }
7181
7396
  }
7182
7397
  },
@@ -7236,6 +7451,12 @@
7236
7451
  "type": "string",
7237
7452
  "default": "—",
7238
7453
  "description": "中间标签文案。存在默认插槽时以插槽为准。"
7454
+ },
7455
+ {
7456
+ "name": "pt",
7457
+ "type": "[RootPassThrough](/docs/types#RootPassThrough) `{ root? }",
7458
+ "default": "—",
7459
+ "description": "DOM 透传,见 [样式与 attrs](/docs/attrs)."
7239
7460
  }
7240
7461
  ],
7241
7462
  "events": [],
@@ -7422,7 +7643,7 @@
7422
7643
  {
7423
7644
  "id": "props",
7424
7645
  "title": "Props",
7425
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 布局方向。 |\n| `orientation` | `'horizontal' \\| 'vertical'` | — | `layout` 的别名。 |\n| `type` | `'solid' \\| 'dashed' \\| 'dotted'` | `'solid'` | 线条样式(含虚线 / 点线)。 |\n| `align` | `'left' \\| 'center' \\| 'right'` | `'center'` | 水平分隔带标签时的标签对齐。 |\n| `titlePlacement` | `'left' \\| 'center' \\| 'right'` | — | `align` 的别名;传入时优先。 |\n| `plain` | `boolean` | `false` | 标签使用正文样式。 |\n| `size` | `'small' \\| 'medium' \\| 'large'` | — | 水平分隔的上下间距(`--m-space-*`)。 |\n| `label` | `string` | — | 中间标签文案。存在默认插槽时以插槽为准。 |"
7646
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 布局方向。 |\n| `orientation` | `'horizontal' \\| 'vertical'` | — | `layout` 的别名。 |\n| `type` | `'solid' \\| 'dashed' \\| 'dotted'` | `'solid'` | 线条样式(含虚线 / 点线)。 |\n| `align` | `'left' \\| 'center' \\| 'right'` | `'center'` | 水平分隔带标签时的标签对齐。 |\n| `titlePlacement` | `'left' \\| 'center' \\| 'right'` | — | `align` 的别名;传入时优先。 |\n| `plain` | `boolean` | `false` | 标签使用正文样式。 |\n| `size` | `'small' \\| 'medium' \\| 'large'` | — | 水平分隔的上下间距(`--m-space-*`)。 |\n| `label` | `string` | — | 中间标签文案。存在默认插槽时以插槽为准。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
7426
7647
  },
7427
7648
  {
7428
7649
  "id": "slots",
@@ -7435,7 +7656,7 @@
7435
7656
  "body": "无自定义事件。"
7436
7657
  }
7437
7658
  ],
7438
- "markdown": "---\ntitle: Divider\ncategory: 01 / BASIC\ndescription: 内容分隔线。\n---\n\n# Divider\n\n内容分隔线,可带标签。\n\n## 引入\n\n```ts\nimport { MDivider } from 'morya-ui'\n```\n\n## 基础用法\n\n默认水平实线分隔。\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Type\n\n`type` 支持 `solid`、`dashed`、`dotted`。\n\n```vue preview src=\"./demos/Type.vue\"\n```\n\n## Align\n\n水平分隔且带标签时,可用 `align` 控制标签位置。\n\n```vue preview src=\"./demos/Align.vue\"\n```\n\n## Title placement\n\n`titlePlacement` 是 `align` 的别名。\n\n```vue preview src=\"./demos/TitlePlacement.vue\"\n```\n\n## Layout\n\n`layout` 控制水平 / 垂直;`orientation` 为别名。\n\n```vue preview src=\"./demos/Layout.vue\"\n```\n\n## Plain\n\n`plain` 让标签使用正文样式(默认偏标题字重)。\n\n```vue preview src=\"./demos/Plain.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 布局方向。 |\n| `orientation` | `'horizontal' \\| 'vertical'` | — | `layout` 的别名。 |\n| `type` | `'solid' \\| 'dashed' \\| 'dotted'` | `'solid'` | 线条样式(含虚线 / 点线)。 |\n| `align` | `'left' \\| 'center' \\| 'right'` | `'center'` | 水平分隔带标签时的标签对齐。 |\n| `titlePlacement` | `'left' \\| 'center' \\| 'right'` | — | `align` 的别名;传入时优先。 |\n| `plain` | `boolean` | `false` | 标签使用正文样式。 |\n| `size` | `'small' \\| 'medium' \\| 'large'` | — | 水平分隔的上下间距(`--m-space-*`)。 |\n| `label` | `string` | — | 中间标签文案。存在默认插槽时以插槽为准。 |\n\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 标签内容,优先于 `label`。 |\n\n## Events\n\n无自定义事件。\n"
7659
+ "markdown": "---\ntitle: Divider\ncategory: 01 / BASIC\ndescription: 内容分隔线。\n---\n\n# Divider\n\n内容分隔线,可带标签。\n\n## 引入\n\n```ts\nimport { MDivider } from 'morya-ui'\n```\n\n## 基础用法\n\n默认水平实线分隔。\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Type\n\n`type` 支持 `solid`、`dashed`、`dotted`。\n\n```vue preview src=\"./demos/Type.vue\"\n```\n\n## Align\n\n水平分隔且带标签时,可用 `align` 控制标签位置。\n\n```vue preview src=\"./demos/Align.vue\"\n```\n\n## Title placement\n\n`titlePlacement` 是 `align` 的别名。\n\n```vue preview src=\"./demos/TitlePlacement.vue\"\n```\n\n## Layout\n\n`layout` 控制水平 / 垂直;`orientation` 为别名。\n\n```vue preview src=\"./demos/Layout.vue\"\n```\n\n## Plain\n\n`plain` 让标签使用正文样式(默认偏标题字重)。\n\n```vue preview src=\"./demos/Plain.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | 布局方向。 |\n| `orientation` | `'horizontal' \\| 'vertical'` | — | `layout` 的别名。 |\n| `type` | `'solid' \\| 'dashed' \\| 'dotted'` | `'solid'` | 线条样式(含虚线 / 点线)。 |\n| `align` | `'left' \\| 'center' \\| 'right'` | `'center'` | 水平分隔带标签时的标签对齐。 |\n| `titlePlacement` | `'left' \\| 'center' \\| 'right'` | — | `align` 的别名;传入时优先。 |\n| `plain` | `boolean` | `false` | 标签使用正文样式。 |\n| `size` | `'small' \\| 'medium' \\| 'large'` | — | 水平分隔的上下间距(`--m-space-*`)。 |\n| `label` | `string` | — | 中间标签文案。存在默认插槽时以插槽为准。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 标签内容,优先于 `label`。 |\n\n## Events\n\n无自定义事件。\n"
7439
7660
  },
7440
7661
  "en-US": {
7441
7662
  "title": "Divider",
@@ -7484,7 +7705,7 @@
7484
7705
  {
7485
7706
  "id": "props",
7486
7707
  "title": "Props",
7487
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | Layout direction. |\n| `orientation` | `'horizontal' \\| 'vertical'` | 鈥?| Alias of `layout`. |\n| `type` | `'solid' \\| 'dashed' \\| 'dotted'` | `'solid'` | Line style (solid / dashed / dotted). |\n| `align` | `'left' \\| 'center' \\| 'right'` | `'center'` | Label alignment for a horizontal divider with a label. |\n| `titlePlacement` | `'left' \\| 'center' \\| 'right'` | 鈥?| Alias of `align`; takes precedence when set. |\n| `plain` | `boolean` | `false` | Use body text style for the label. |\n| `size` | `'small' \\| 'medium' \\| 'large'` | 鈥?| Vertical margin for horizontal dividers (`--m-space-*`). |\n| `label` | `string` | 鈥?| Center label text. The default slot takes precedence when present. |"
7708
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | Layout direction. |\n| `orientation` | `'horizontal' \\| 'vertical'` | 鈥?| Alias of `layout`. |\n| `type` | `'solid' \\| 'dashed' \\| 'dotted'` | `'solid'` | Line style (solid / dashed / dotted). |\n| `align` | `'left' \\| 'center' \\| 'right'` | `'center'` | Label alignment for a horizontal divider with a label. |\n| `titlePlacement` | `'left' \\| 'center' \\| 'right'` | 鈥?| Alias of `align`; takes precedence when set. |\n| `plain` | `boolean` | `false` | Use body text style for the label. |\n| `size` | `'small' \\| 'medium' \\| 'large'` | 鈥?| Vertical margin for horizontal dividers (`--m-space-*`). |\n| `label` | `string` | 鈥?| Center label text. The default slot takes precedence when present. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |"
7488
7709
  },
7489
7710
  {
7490
7711
  "id": "slots",
@@ -7497,7 +7718,7 @@
7497
7718
  "body": "No custom events."
7498
7719
  }
7499
7720
  ],
7500
- "markdown": "---\ntitle: Divider\ncategory: 01 / BASIC\ndescription: Content divider.\n---\n\n# Divider\n\nContent divider, optionally with a label.\n\n## Import\n\n```ts\nimport { MDivider } from 'morya-ui'\n```\n\n## Basic\n\nDefault horizontal solid divider.\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Type\n\n`type` supports `solid`, `dashed`, and `dotted`.\n\n```vue preview src=\"./demos/Type.vue\"\n```\n\n## Align\n\nWhen the divider is horizontal and has a label, use `align` to control the label position.\n\n```vue preview src=\"./demos/Align.vue\"\n```\n\n## Title placement\n\n`titlePlacement` is an alias of `align`.\n\n```vue preview src=\"./demos/TitlePlacement.vue\"\n```\n\n## Layout\n\n`layout` controls horizontal / vertical; `orientation` is an alias.\n\n```vue preview src=\"./demos/Layout.vue\"\n```\n\n## Plain\n\n`plain` uses body text styling for the label (default is stronger heading weight).\n\n```vue preview src=\"./demos/Plain.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | Layout direction. |\n| `orientation` | `'horizontal' \\| 'vertical'` | 鈥?| Alias of `layout`. |\n| `type` | `'solid' \\| 'dashed' \\| 'dotted'` | `'solid'` | Line style (solid / dashed / dotted). |\n| `align` | `'left' \\| 'center' \\| 'right'` | `'center'` | Label alignment for a horizontal divider with a label. |\n| `titlePlacement` | `'left' \\| 'center' \\| 'right'` | 鈥?| Alias of `align`; takes precedence when set. |\n| `plain` | `boolean` | `false` | Use body text style for the label. |\n| `size` | `'small' \\| 'medium' \\| 'large'` | 鈥?| Vertical margin for horizontal dividers (`--m-space-*`). |\n| `label` | `string` | 鈥?| Center label text. The default slot takes precedence when present. |\n\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Label content, takes precedence over `label`. |\n\n## Events\n\nNo custom events.\n"
7721
+ "markdown": "---\ntitle: Divider\ncategory: 01 / BASIC\ndescription: Content divider.\n---\n\n# Divider\n\nContent divider, optionally with a label.\n\n## Import\n\n```ts\nimport { MDivider } from 'morya-ui'\n```\n\n## Basic\n\nDefault horizontal solid divider.\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Type\n\n`type` supports `solid`, `dashed`, and `dotted`.\n\n```vue preview src=\"./demos/Type.vue\"\n```\n\n## Align\n\nWhen the divider is horizontal and has a label, use `align` to control the label position.\n\n```vue preview src=\"./demos/Align.vue\"\n```\n\n## Title placement\n\n`titlePlacement` is an alias of `align`.\n\n```vue preview src=\"./demos/TitlePlacement.vue\"\n```\n\n## Layout\n\n`layout` controls horizontal / vertical; `orientation` is an alias.\n\n```vue preview src=\"./demos/Layout.vue\"\n```\n\n## Plain\n\n`plain` uses body text styling for the label (default is stronger heading weight).\n\n```vue preview src=\"./demos/Plain.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `layout` | `'horizontal' \\| 'vertical'` | `'horizontal'` | Layout direction. |\n| `orientation` | `'horizontal' \\| 'vertical'` | 鈥?| Alias of `layout`. |\n| `type` | `'solid' \\| 'dashed' \\| 'dotted'` | `'solid'` | Line style (solid / dashed / dotted). |\n| `align` | `'left' \\| 'center' \\| 'right'` | `'center'` | Label alignment for a horizontal divider with a label. |\n| `titlePlacement` | `'left' \\| 'center' \\| 'right'` | 鈥?| Alias of `align`; takes precedence when set. |\n| `plain` | `boolean` | `false` | Use body text style for the label. |\n| `size` | `'small' \\| 'medium' \\| 'large'` | 鈥?| Vertical margin for horizontal dividers (`--m-space-*`). |\n| `label` | `string` | 鈥?| Center label text. The default slot takes precedence when present. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |\n\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Label content, takes precedence over `label`. |\n\n## Events\n\nNo custom events.\n"
7501
7722
  }
7502
7723
  }
7503
7724
  },
@@ -7873,7 +8094,7 @@
7873
8094
  "sectionId": "position",
7874
8095
  "lang": "vue",
7875
8096
  "preview": true,
7876
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDrawer } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst position = ref<'left' | 'right' | 'top' | 'bottom'>('right')\n\nfunction openAt(next: 'left' | 'right' | 'top' | 'bottom') {\n position.value = next\n open.value = true\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Left\" size=\"small\" @click=\"openAt('left')\" />\n <MButton label=\"Right\" size=\"small\" severity=\"secondary\" @click=\"openAt('right')\" />\n <MButton label=\"Top\" size=\"small\" severity=\"secondary\" @click=\"openAt('top')\" />\n <MButton label=\"Bottom\" size=\"small\" severity=\"secondary\" @click=\"openAt('bottom')\" />\n <MDrawer v-model=\"open\" :header=\"`Position: ${position}`\" :position=\"position\">\n <p style=\"margin:0\">\n Use <code>dismissable</code> to control mask dismiss.\n </p>\n </MDrawer>\n </div>\n</template>",
8097
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDrawer } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst position = ref<'left' | 'right' | 'top' | 'bottom'>('right')\n\nfunction openAt(next: 'left' | 'right' | 'top' | 'bottom') {\n position.value = next\n open.value = true\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Left\" size=\"small\" @click=\"openAt('left')\" />\n <MButton label=\"Right\" size=\"small\" @click=\"openAt('right')\"/>\n <MButton label=\"Top\" size=\"small\" @click=\"openAt('top')\"/>\n <MButton label=\"Bottom\" size=\"small\" @click=\"openAt('bottom')\"/>\n <MDrawer v-model=\"open\" :header=\"`Position: ${position}`\" :position=\"position\">\n <p style=\"margin:0\">\n Use <code>dismissable</code> to control mask dismiss.\n </p>\n </MDrawer>\n </div>\n</template>",
7877
8098
  "locale": "zh-CN"
7878
8099
  },
7879
8100
  {
@@ -7882,7 +8103,7 @@
7882
8103
  "sectionId": "footer",
7883
8104
  "lang": "vue",
7884
8105
  "preview": true,
7885
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDrawer, MSpace } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"With Footer\" @click=\"open = true\" />\n <MDrawer v-model=\"open\" header=\"Edit details\" position=\"right\" :width=\"360\">\n <p style=\"margin:0\">\n Put primary and secondary actions in the footer slot so the body can scroll independently.\n </p>\n <template #footer>\n <MSpace style=\"justify-content: flex-end; width: 100%\">\n <MButton label=\"Cancel\" severity=\"secondary\" text @click=\"open = false\" />\n <MButton label=\"Save\" @click=\"open = false\" />\n </MSpace>\n </template>\n </MDrawer>\n </div>\n</template>",
8106
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDrawer, MSpace } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"With Footer\" @click=\"open = true\" />\n <MDrawer v-model=\"open\" header=\"Edit details\" position=\"right\" :width=\"360\">\n <p style=\"margin:0\">\n Put primary and secondary actions in the footer slot so the body can scroll independently.\n </p>\n <template #footer>\n <MSpace style=\"justify-content: flex-end; width: 100%\">\n <MButton label=\"Cancel\" @click=\"open = false\" type=\"text\"/>\n <MButton label=\"Save\" @click=\"open = false\" />\n </MSpace>\n </template>\n </MDrawer>\n </div>\n</template>",
7886
8107
  "locale": "zh-CN"
7887
8108
  },
7888
8109
  {
@@ -7909,7 +8130,7 @@
7909
8130
  "sectionId": "position",
7910
8131
  "lang": "vue",
7911
8132
  "preview": true,
7912
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDrawer } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst position = ref<'left' | 'right' | 'top' | 'bottom'>('right')\n\nfunction openAt(next: 'left' | 'right' | 'top' | 'bottom') {\n position.value = next\n open.value = true\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Left\" size=\"small\" @click=\"openAt('left')\" />\n <MButton label=\"Right\" size=\"small\" severity=\"secondary\" @click=\"openAt('right')\" />\n <MButton label=\"Top\" size=\"small\" severity=\"secondary\" @click=\"openAt('top')\" />\n <MButton label=\"Bottom\" size=\"small\" severity=\"secondary\" @click=\"openAt('bottom')\" />\n <MDrawer v-model=\"open\" :header=\"`Position: ${position}`\" :position=\"position\">\n <p style=\"margin:0\">\n Use <code>dismissable</code> to control mask dismiss.\n </p>\n </MDrawer>\n </div>\n</template>",
8133
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDrawer } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst position = ref<'left' | 'right' | 'top' | 'bottom'>('right')\n\nfunction openAt(next: 'left' | 'right' | 'top' | 'bottom') {\n position.value = next\n open.value = true\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Left\" size=\"small\" @click=\"openAt('left')\" />\n <MButton label=\"Right\" size=\"small\" @click=\"openAt('right')\"/>\n <MButton label=\"Top\" size=\"small\" @click=\"openAt('top')\"/>\n <MButton label=\"Bottom\" size=\"small\" @click=\"openAt('bottom')\"/>\n <MDrawer v-model=\"open\" :header=\"`Position: ${position}`\" :position=\"position\">\n <p style=\"margin:0\">\n Use <code>dismissable</code> to control mask dismiss.\n </p>\n </MDrawer>\n </div>\n</template>",
7913
8134
  "locale": "en-US"
7914
8135
  },
7915
8136
  {
@@ -7918,7 +8139,7 @@
7918
8139
  "sectionId": "footer",
7919
8140
  "lang": "vue",
7920
8141
  "preview": true,
7921
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDrawer, MSpace } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"With Footer\" @click=\"open = true\" />\n <MDrawer v-model=\"open\" header=\"Edit details\" position=\"right\" :width=\"360\">\n <p style=\"margin:0\">\n Put primary and secondary actions in the footer slot so the body can scroll independently.\n </p>\n <template #footer>\n <MSpace style=\"justify-content: flex-end; width: 100%\">\n <MButton label=\"Cancel\" severity=\"secondary\" text @click=\"open = false\" />\n <MButton label=\"Save\" @click=\"open = false\" />\n </MSpace>\n </template>\n </MDrawer>\n </div>\n</template>",
8142
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDrawer, MSpace } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div>\n <MButton label=\"With Footer\" @click=\"open = true\" />\n <MDrawer v-model=\"open\" header=\"Edit details\" position=\"right\" :width=\"360\">\n <p style=\"margin:0\">\n Put primary and secondary actions in the footer slot so the body can scroll independently.\n </p>\n <template #footer>\n <MSpace style=\"justify-content: flex-end; width: 100%\">\n <MButton label=\"Cancel\" @click=\"open = false\" type=\"text\"/>\n <MButton label=\"Save\" @click=\"open = false\" />\n </MSpace>\n </template>\n </MDrawer>\n </div>\n</template>",
7922
8143
  "locale": "en-US"
7923
8144
  }
7924
8145
  ],
@@ -8140,7 +8361,7 @@
8140
8361
  "sectionId": "基础用法",
8141
8362
  "lang": "vue",
8142
8363
  "preview": true,
8143
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDropdown } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst items = [\n { value: 'edit', label: 'Edit' },\n { value: 'duplicate', label: 'Duplicate' },\n { value: 'delete', label: 'Delete', disabled: true },\n]\n\nfunction onSelect(item: { value?: string; label?: string }) {\n open.value = false\n console.log(item.value)\n}\n</script>\n\n<template>\n <MDropdown v-model=\"open\" :items=\"items\" @select=\"onSelect\">\n <template #trigger>\n <MButton label=\"Actions\" icon=\"chevron-down\" icon-pos=\"right\" severity=\"secondary\" />\n </template>\n </MDropdown>\n</template>",
8364
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDropdown } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst items = [\n { value: 'edit', label: 'Edit' },\n { value: 'duplicate', label: 'Duplicate' },\n { value: 'delete', label: 'Delete', disabled: true },\n]\n\nfunction onSelect(item: { value?: string; label?: string }) {\n open.value = false\n console.log(item.value)\n}\n</script>\n\n<template>\n <MDropdown v-model=\"open\" :items=\"items\" @select=\"onSelect\">\n <template #trigger>\n <MButton label=\"Actions\" icon=\"chevron-down\" icon-placement=\"end\"/>\n </template>\n </MDropdown>\n</template>",
8144
8365
  "locale": "zh-CN"
8145
8366
  },
8146
8367
  {
@@ -8149,7 +8370,7 @@
8149
8370
  "sectionId": "nested-group-hover",
8150
8371
  "lang": "vue",
8151
8372
  "preview": true,
8152
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDropdown } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst items = [\n { type: 'group' as const, label: '编辑', items: [{ value: 'cut', label: '剪切' }, { value: 'copy', label: '复制' }] },\n { separator: true },\n { value: 'more', label: '更多', items: [{ value: 'deep', label: '深层操作' }] },\n]\n</script>\n\n<template>\n <MDropdown v-model=\"open\" :items=\"items\" trigger=\"hover\" :show-delay=\"0\" :hide-delay=\"200\">\n <template #trigger>\n <MButton label=\"悬停打开\" severity=\"secondary\" />\n </template>\n </MDropdown>\n</template>",
8373
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDropdown } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst items = [\n { type: 'group' as const, label: '编辑', items: [{ value: 'cut', label: '剪切' }, { value: 'copy', label: '复制' }] },\n { separator: true },\n { value: 'more', label: '更多', items: [{ value: 'deep', label: '深层操作' }] },\n]\n</script>\n\n<template>\n <MDropdown v-model=\"open\" :items=\"items\" trigger=\"hover\" :show-delay=\"0\" :hide-delay=\"200\">\n <template #trigger>\n <MButton label=\"悬停打开\"/>\n </template>\n </MDropdown>\n</template>",
8153
8374
  "locale": "zh-CN"
8154
8375
  },
8155
8376
  {
@@ -8176,7 +8397,7 @@
8176
8397
  "sectionId": "basic",
8177
8398
  "lang": "vue",
8178
8399
  "preview": true,
8179
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDropdown } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst items = [\n { value: 'edit', label: 'Edit' },\n { value: 'duplicate', label: 'Duplicate' },\n { value: 'delete', label: 'Delete', disabled: true },\n]\n\nfunction onSelect(item: { value?: string; label?: string }) {\n open.value = false\n console.log(item.value)\n}\n</script>\n\n<template>\n <MDropdown v-model=\"open\" :items=\"items\" @select=\"onSelect\">\n <template #trigger>\n <MButton label=\"Actions\" icon=\"chevron-down\" icon-pos=\"right\" severity=\"secondary\" />\n </template>\n </MDropdown>\n</template>",
8400
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDropdown } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst items = [\n { value: 'edit', label: 'Edit' },\n { value: 'duplicate', label: 'Duplicate' },\n { value: 'delete', label: 'Delete', disabled: true },\n]\n\nfunction onSelect(item: { value?: string; label?: string }) {\n open.value = false\n console.log(item.value)\n}\n</script>\n\n<template>\n <MDropdown v-model=\"open\" :items=\"items\" @select=\"onSelect\">\n <template #trigger>\n <MButton label=\"Actions\" icon=\"chevron-down\" icon-placement=\"end\"/>\n </template>\n </MDropdown>\n</template>",
8180
8401
  "locale": "en-US"
8181
8402
  },
8182
8403
  {
@@ -8185,7 +8406,7 @@
8185
8406
  "sectionId": "nested-group-hover",
8186
8407
  "lang": "vue",
8187
8408
  "preview": true,
8188
- "code": "<script setup lang=\"ts\">\nimport { MButton, MDropdown } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst items = [\n { type: 'group' as const, label: 'Edit', items: [{ value: 'cut', label: 'Cut' }, { value: 'copy', label: 'Copy' }] },\n { separator: true },\n { value: 'more', label: 'More', items: [{ value: 'deep', label: 'Deep action' }] },\n]\n</script>\n\n<template>\n <MDropdown v-model=\"open\" :items=\"items\" trigger=\"hover\" :show-delay=\"0\" :hide-delay=\"200\">\n <template #trigger>\n <MButton label=\"Hover to open\" severity=\"secondary\" />\n </template>\n </MDropdown>\n</template>",
8409
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MDropdown } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\nconst items = [\n { type: 'group' as const, label: 'Edit', items: [{ value: 'cut', label: 'Cut' }, { value: 'copy', label: 'Copy' }] },\n { separator: true },\n { value: 'more', label: 'More', items: [{ value: 'deep', label: 'Deep action' }] },\n]\n</script>\n\n<template>\n <MDropdown v-model=\"open\" :items=\"items\" trigger=\"hover\" :show-delay=\"0\" :hide-delay=\"200\">\n <template #trigger>\n <MButton label=\"Hover to open\"/>\n </template>\n </MDropdown>\n</template>",
8189
8410
  "locale": "en-US"
8190
8411
  },
8191
8412
  {
@@ -8424,7 +8645,7 @@
8424
8645
  "sectionId": "操作区",
8425
8646
  "lang": "vue",
8426
8647
  "preview": true,
8427
- "code": "<script setup lang=\"ts\">\nimport { MButton, MEmpty } from 'morya-ui'\n</script>\n\n<template>\n <MEmpty\n title=\"还没有课程\"\n description=\"创建第一门课程后,学员就能在目录里看到它。也可以稍后从模板导入。\"\n icon=\"book\"\n >\n <template #extra>\n <MButton label=\"创建第一门课程\" />\n <MButton label=\"从模板导入\" severity=\"secondary\" text />\n </template>\n </MEmpty>\n</template>",
8648
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MEmpty } from 'morya-ui'\n</script>\n\n<template>\n <MEmpty\n title=\"还没有课程\"\n description=\"创建第一门课程后,学员就能在目录里看到它。也可以稍后从模板导入。\"\n icon=\"book\"\n >\n <template #extra>\n <MButton label=\"创建第一门课程\" />\n <MButton label=\"从模板导入\" type=\"text\"/>\n </template>\n </MEmpty>\n</template>",
8428
8649
  "locale": "zh-CN"
8429
8650
  },
8430
8651
  {
@@ -8478,7 +8699,7 @@
8478
8699
  "sectionId": "actions",
8479
8700
  "lang": "vue",
8480
8701
  "preview": true,
8481
- "code": "<script setup lang=\"ts\">\nimport { MButton, MEmpty } from 'morya-ui'\n</script>\n\n<template>\n <MEmpty\n title=\"No courses yet\"\n description=\"Create your first course so learners can find it in the catalog. You can also import from a template later.\"\n icon=\"book\"\n >\n <template #extra>\n <MButton label=\"Create first course\" />\n <MButton label=\"Import from template\" severity=\"secondary\" text />\n </template>\n </MEmpty>\n</template>",
8702
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MEmpty } from 'morya-ui'\n</script>\n\n<template>\n <MEmpty\n title=\"No courses yet\"\n description=\"Create your first course so learners can find it in the catalog. You can also import from a template later.\"\n icon=\"book\"\n >\n <template #extra>\n <MButton label=\"Create first course\" />\n <MButton label=\"Import from template\" type=\"text\"/>\n </template>\n </MEmpty>\n</template>",
8482
8703
  "locale": "en-US"
8483
8704
  },
8484
8705
  {
@@ -9463,7 +9684,7 @@
9463
9684
  "sectionId": "基础用法",
9464
9685
  "lang": "vue",
9465
9686
  "preview": true,
9466
- "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex>\n <MButton label=\"一\" size=\"small\" />\n <MButton label=\"二\" size=\"small\" severity=\"secondary\" />\n <MButton label=\"三\" size=\"small\" severity=\"secondary\" />\n </MFlex>\n</template>",
9687
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex>\n <MButton label=\"一\" size=\"small\" />\n <MButton label=\"二\" size=\"small\"/>\n <MButton label=\"三\" size=\"small\"/>\n </MFlex>\n</template>",
9467
9688
  "locale": "zh-CN"
9468
9689
  },
9469
9690
  {
@@ -9472,7 +9693,7 @@
9472
9693
  "sectionId": "vertical",
9473
9694
  "lang": "vue",
9474
9695
  "preview": true,
9475
- "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex vertical>\n <MButton label=\"上\" size=\"small\" />\n <MButton label=\"中\" size=\"small\" severity=\"secondary\" />\n <MButton label=\"下\" size=\"small\" severity=\"secondary\" />\n </MFlex>\n</template>",
9696
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex vertical>\n <MButton label=\"上\" size=\"small\" />\n <MButton label=\"中\" size=\"small\"/>\n <MButton label=\"下\" size=\"small\"/>\n </MFlex>\n</template>",
9476
9697
  "locale": "zh-CN"
9477
9698
  },
9478
9699
  {
@@ -9499,7 +9720,7 @@
9499
9720
  "sectionId": "basic",
9500
9721
  "lang": "vue",
9501
9722
  "preview": true,
9502
- "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex>\n <MButton label=\"One\" size=\"small\" />\n <MButton label=\"Two\" size=\"small\" severity=\"secondary\" />\n <MButton label=\"Three\" size=\"small\" severity=\"secondary\" />\n </MFlex>\n</template>",
9723
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex>\n <MButton label=\"One\" size=\"small\" />\n <MButton label=\"Two\" size=\"small\"/>\n <MButton label=\"Three\" size=\"small\"/>\n </MFlex>\n</template>",
9503
9724
  "locale": "en-US"
9504
9725
  },
9505
9726
  {
@@ -9508,7 +9729,7 @@
9508
9729
  "sectionId": "vertical",
9509
9730
  "lang": "vue",
9510
9731
  "preview": true,
9511
- "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex vertical>\n <MButton label=\"Top\" size=\"small\" />\n <MButton label=\"Middle\" size=\"small\" severity=\"secondary\" />\n <MButton label=\"Bottom\" size=\"small\" severity=\"secondary\" />\n </MFlex>\n</template>",
9732
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MFlex } from 'morya-ui'\n</script>\n\n<template>\n <MFlex vertical>\n <MButton label=\"Top\" size=\"small\" />\n <MButton label=\"Middle\" size=\"small\"/>\n <MButton label=\"Bottom\" size=\"small\"/>\n </MFlex>\n</template>",
9512
9733
  "locale": "en-US"
9513
9734
  },
9514
9735
  {
@@ -10176,7 +10397,7 @@
10176
10397
  "sectionId": "声明式-rules",
10177
10398
  "lang": "vue",
10178
10399
  "preview": true,
10179
- "code": "<script setup lang=\"ts\">\nimport type { FormInstance, FormRules } from 'morya-ui'\nimport { MButton, MForm, MFormItem, MInput } from 'morya-ui'\nimport { reactive, ref } from 'vue'\n\nconst formRef = ref<FormInstance | null>(null)\nconst model = reactive({ name: '', email: '' })\nconst rules: FormRules = {\n name: { required: true, message: '请输入名称', trigger: ['blur', 'input'] },\n email: [\n { required: true, message: '请输入邮箱', trigger: 'blur' },\n { pattern: /.[^\\n\\r@\\u2028\\u2029]*@.+\\..+/, message: '邮箱格式不正确', trigger: 'blur' },\n ],\n}\n\nasync function onSubmit() {\n const { valid } = await formRef.value!.validate()\n if (!valid) return\n}\n</script>\n\n<template>\n <MForm\n ref=\"formRef\"\n :model=\"model\"\n :rules=\"rules\"\n label-position=\"top\"\n validate-on=\"submit\"\n style=\"max-width: 22rem\"\n @submit=\"onSubmit\"\n >\n <MFormItem label=\"名称\" name=\"name\">\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"model.name\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MFormItem label=\"邮箱\" name=\"email\" help=\"用于接收通知\">\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"model.email\" type=\"email\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MButton native-type=\"submit\" label=\"提交\" />\n </MForm>\n</template>",
10400
+ "code": "<script setup lang=\"ts\">\nimport type { FormInstance, FormRules } from 'morya-ui'\nimport { MButton, MForm, MFormItem, MInput } from 'morya-ui'\nimport { reactive, ref } from 'vue'\n\nconst formRef = ref<FormInstance | null>(null)\nconst model = reactive({ name: '', email: '' })\nconst rules: FormRules = {\n name: { required: true, message: '请输入名称', trigger: ['blur', 'input'] },\n email: [\n { required: true, message: '请输入邮箱', trigger: 'blur' },\n { pattern: /.[^\\n\\r@\\u2028\\u2029]*@.+\\..+/, message: '邮箱格式不正确', trigger: 'blur' },\n ],\n}\n\nasync function onSubmit() {\n const { valid } = await formRef.value!.validate()\n if (!valid) return\n}\n</script>\n\n<template>\n <MForm\n ref=\"formRef\"\n :model=\"model\"\n :rules=\"rules\"\n label-position=\"top\"\n validate-on=\"submit\"\n style=\"max-width: 22rem\"\n @submit=\"onSubmit\"\n >\n <MFormItem label=\"名称\" name=\"name\">\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"model.name\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MFormItem label=\"邮箱\" name=\"email\" help=\"用于接收通知\">\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"model.email\" type=\"email\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MButton html-type=\"submit\" label=\"提交\"/>\n </MForm>\n</template>",
10180
10401
  "locale": "zh-CN"
10181
10402
  },
10182
10403
  {
@@ -10203,7 +10424,7 @@
10203
10424
  "sectionId": "回调校验-兼容",
10204
10425
  "lang": "vue",
10205
10426
  "preview": true,
10206
- "code": "<script setup lang=\"ts\">\nimport { MButton, MForm, MFormItem, MInput } from 'morya-ui'\nimport { reactive } from 'vue'\n\nconst form = reactive({ name: '' })\n</script>\n\n<template>\n <MForm validate-on=\"submit\" style=\"max-width: 22rem\">\n <MFormItem\n label=\"名称\"\n name=\"name\"\n required\n :validate=\"() => (form.name.trim() ? undefined : '请输入名称')\"\n >\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"form.name\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MButton native-type=\"submit\" label=\"提交\" />\n </MForm>\n</template>",
10427
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MForm, MFormItem, MInput } from 'morya-ui'\nimport { reactive } from 'vue'\n\nconst form = reactive({ name: '' })\n</script>\n\n<template>\n <MForm validate-on=\"submit\" style=\"max-width: 22rem\">\n <MFormItem\n label=\"名称\"\n name=\"name\"\n required\n :validate=\"() => (form.name.trim() ? undefined : '请输入名称')\"\n >\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"form.name\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MButton html-type=\"submit\" label=\"提交\"/>\n </MForm>\n</template>",
10207
10428
  "locale": "zh-CN"
10208
10429
  },
10209
10430
  {
@@ -10239,7 +10460,7 @@
10239
10460
  "sectionId": "declarative-rules",
10240
10461
  "lang": "vue",
10241
10462
  "preview": true,
10242
- "code": "<script setup lang=\"ts\">\nimport type { FormInstance, FormRules } from 'morya-ui'\nimport { MButton, MForm, MFormItem, MInput } from 'morya-ui'\nimport { reactive, ref } from 'vue'\n\nconst formRef = ref<FormInstance | null>(null)\nconst model = reactive({ name: '', email: '' })\nconst rules: FormRules = {\n name: { required: true, message: 'Enter a name', trigger: ['blur', 'input'] },\n email: [\n { required: true, message: 'Enter an email', trigger: 'blur' },\n { pattern: /.[^\\n\\r@\\u2028\\u2029]*@.+\\..+/, message: 'Enter a valid email', trigger: 'blur' },\n ],\n}\n\nasync function onSubmit() {\n const { valid } = await formRef.value!.validate()\n if (!valid) return\n}\n</script>\n\n<template>\n <MForm\n ref=\"formRef\"\n :model=\"model\"\n :rules=\"rules\"\n label-position=\"top\"\n validate-on=\"submit\"\n style=\"max-width: 22rem\"\n @submit=\"onSubmit\"\n >\n <MFormItem label=\"Name\" name=\"name\">\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"model.name\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MFormItem label=\"Email\" name=\"email\" help=\"Used for notifications\">\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"model.email\" type=\"email\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MButton native-type=\"submit\" label=\"Submit\" />\n </MForm>\n</template>",
10463
+ "code": "<script setup lang=\"ts\">\nimport type { FormInstance, FormRules } from 'morya-ui'\nimport { MButton, MForm, MFormItem, MInput } from 'morya-ui'\nimport { reactive, ref } from 'vue'\n\nconst formRef = ref<FormInstance | null>(null)\nconst model = reactive({ name: '', email: '' })\nconst rules: FormRules = {\n name: { required: true, message: 'Enter a name', trigger: ['blur', 'input'] },\n email: [\n { required: true, message: 'Enter an email', trigger: 'blur' },\n { pattern: /.[^\\n\\r@\\u2028\\u2029]*@.+\\..+/, message: 'Enter a valid email', trigger: 'blur' },\n ],\n}\n\nasync function onSubmit() {\n const { valid } = await formRef.value!.validate()\n if (!valid) return\n}\n</script>\n\n<template>\n <MForm\n ref=\"formRef\"\n :model=\"model\"\n :rules=\"rules\"\n label-position=\"top\"\n validate-on=\"submit\"\n style=\"max-width: 22rem\"\n @submit=\"onSubmit\"\n >\n <MFormItem label=\"Name\" name=\"name\">\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"model.name\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MFormItem label=\"Email\" name=\"email\" help=\"Used for notifications\">\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"model.email\" type=\"email\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MButton html-type=\"submit\" label=\"Submit\"/>\n </MForm>\n</template>",
10243
10464
  "locale": "en-US"
10244
10465
  },
10245
10466
  {
@@ -10266,7 +10487,7 @@
10266
10487
  "sectionId": "callback-validation-compatible",
10267
10488
  "lang": "vue",
10268
10489
  "preview": true,
10269
- "code": "<script setup lang=\"ts\">\nimport { MButton, MForm, MFormItem, MInput } from 'morya-ui'\nimport { reactive } from 'vue'\n\nconst form = reactive({ name: '' })\n</script>\n\n<template>\n <MForm validate-on=\"submit\" style=\"max-width: 22rem\">\n <MFormItem\n label=\"Name\"\n name=\"name\"\n required\n :validate=\"() => (form.name.trim() ? undefined : 'Enter a name')\"\n >\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"form.name\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MButton native-type=\"submit\" label=\"Submit\" />\n </MForm>\n</template>",
10490
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MForm, MFormItem, MInput } from 'morya-ui'\nimport { reactive } from 'vue'\n\nconst form = reactive({ name: '' })\n</script>\n\n<template>\n <MForm validate-on=\"submit\" style=\"max-width: 22rem\">\n <MFormItem\n label=\"Name\"\n name=\"name\"\n required\n :validate=\"() => (form.name.trim() ? undefined : 'Enter a name')\"\n >\n <template #default=\"{ id, invalid }\">\n <MInput :id=\"id\" v-model=\"form.name\" fluid :invalid=\"invalid\" />\n </template>\n </MFormItem>\n <MButton html-type=\"submit\" label=\"Submit\"/>\n </MForm>\n</template>",
10270
10491
  "locale": "en-US"
10271
10492
  },
10272
10493
  {
@@ -15595,7 +15816,7 @@
15595
15816
  "sectionId": "服务式调用",
15596
15817
  "lang": "vue",
15597
15818
  "preview": true,
15598
- "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>",
15819
+ "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=\"区域加载\" @click=\"openRegion\"/>\n <MButton label=\"全屏加载\" @click=\"openFullscreen\" />\n </div>\n </div>\n</template>",
15599
15820
  "locale": "zh-CN"
15600
15821
  },
15601
15822
  {
@@ -15658,7 +15879,7 @@
15658
15879
  "sectionId": "service",
15659
15880
  "lang": "vue",
15660
15881
  "preview": true,
15661
- "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>",
15882
+ "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\" @click=\"openRegion\"/>\n <MButton label=\"Fullscreen\" @click=\"openFullscreen\" />\n </div>\n </div>\n</template>",
15662
15883
  "locale": "en-US"
15663
15884
  },
15664
15885
  {
@@ -17198,7 +17419,7 @@
17198
17419
  "sectionId": "api",
17199
17420
  "lang": "vue",
17200
17421
  "preview": true,
17201
- "code": "<script setup lang=\"ts\">\nimport { MButton, message } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Success\" severity=\"success\" @click=\"message.success('保存成功')\" />\n <MButton label=\"Info\" severity=\"info\" @click=\"message.info('这是一条提示')\" />\n <MButton label=\"Warn\" severity=\"warn\" @click=\"message.warn('请核对后再提交')\" />\n <MButton label=\"Error\" severity=\"danger\" @click=\"message.error('请求失败,请重试')\" />\n <MButton\n label=\"Closable\"\n @click=\"message.info({ content: '可手动关闭', closable: true, life: 0 })\"\n />\n </div>\n</template>",
17422
+ "code": "<script setup lang=\"ts\">\nimport { MButton, message } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Success\" @click=\"message.success('保存成功')\" color=\"success\" variant=\"solid\"/>\n <MButton label=\"Info\" @click=\"message.info('这是一条提示')\" color=\"info\" variant=\"solid\"/>\n <MButton label=\"Warn\" @click=\"message.warn('请核对后再提交')\" color=\"warning\" variant=\"solid\"/>\n <MButton label=\"Error\" @click=\"message.error('请求失败,请重试')\" danger type=\"primary\"/>\n <MButton\n label=\"Closable\"\n @click=\"message.info({ content: '可手动关闭', closable: true, life: 0 })\"\n />\n </div>\n</template>",
17202
17423
  "locale": "zh-CN"
17203
17424
  },
17204
17425
  {
@@ -17243,7 +17464,7 @@
17243
17464
  "sectionId": "api",
17244
17465
  "lang": "vue",
17245
17466
  "preview": true,
17246
- "code": "<script setup lang=\"ts\">\nimport { MButton, message } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Success\" severity=\"success\" @click=\"message.success('Saved')\" />\n <MButton label=\"Info\" severity=\"info\" @click=\"message.info('A short tip')\" />\n <MButton label=\"Warn\" severity=\"warn\" @click=\"message.warn('Please double-check')\" />\n <MButton label=\"Error\" severity=\"danger\" @click=\"message.error('Request failed')\" />\n <MButton\n label=\"Closable\"\n @click=\"message.info({ content: 'Dismiss manually', closable: true, life: 0 })\"\n />\n </div>\n</template>",
17467
+ "code": "<script setup lang=\"ts\">\nimport { MButton, message } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3\">\n <MButton label=\"Success\" @click=\"message.success('Saved')\" color=\"success\" variant=\"solid\"/>\n <MButton label=\"Info\" @click=\"message.info('A short tip')\" color=\"info\" variant=\"solid\"/>\n <MButton label=\"Warn\" @click=\"message.warn('Please double-check')\" color=\"warning\" variant=\"solid\"/>\n <MButton label=\"Error\" @click=\"message.error('Request failed')\" danger type=\"primary\"/>\n <MButton\n label=\"Closable\"\n @click=\"message.info({ content: 'Dismiss manually', closable: true, life: 0 })\"\n />\n </div>\n</template>",
17247
17468
  "locale": "en-US"
17248
17469
  },
17249
17470
  {
@@ -17940,7 +18161,7 @@
17940
18161
  "sectionId": "列表页组合",
17941
18162
  "lang": "vue",
17942
18163
  "preview": true,
17943
- "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MInput,\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPageToolbar,\n MSpace,\n} from 'morya-ui'\nimport { ref } from 'vue'\n\nconst keyword = ref('')\n</script>\n\n<template>\n <div\n class=\"doc-demo-frame\"\n style=\"border:1px solid var(--m-color-border);border-radius:var(--m-radius-md);overflow:visible;background:var(--m-color-surface)\"\n >\n <MPageContent>\n <MPageHeader title=\"用户管理\" description=\"维护账号与角色。\">\n <template #actions>\n <MButton severity=\"primary\">\n 新建\n </MButton>\n </template>\n </MPageHeader>\n <MPageFilters aria-label=\"筛选\" variant=\"filled\">\n <MSpace wrap>\n <MInput v-model=\"keyword\" placeholder=\"搜索\" clearable class=\"w-48\" />\n </MSpace>\n <template #actions>\n <MButton severity=\"secondary\">\n 查询\n </MButton>\n </template>\n </MPageFilters>\n <MPageToolbar>\n <span style=\"color:var(--m-color-text-muted);font-size:var(--m-font-size-sm)\">已选 0 项</span>\n <template #actions>\n <MButton severity=\"secondary\" text>\n 导出\n </MButton>\n <MButton severity=\"danger\" text>\n 删除\n </MButton>\n </template>\n </MPageToolbar>\n </MPageContent>\n </div>\n</template>",
18164
+ "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MInput,\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPageToolbar,\n MSpace,\n} from 'morya-ui'\nimport { ref } from 'vue'\n\nconst keyword = ref('')\n</script>\n\n<template>\n <div\n class=\"doc-demo-frame\"\n style=\"border:1px solid var(--m-color-border);border-radius:var(--m-radius-md);overflow:visible;background:var(--m-color-surface)\"\n >\n <MPageContent>\n <MPageHeader title=\"用户管理\" description=\"维护账号与角色。\">\n <template #actions>\n <MButton type=\"primary\">\n 新建\n </MButton>\n </template>\n </MPageHeader>\n <MPageFilters aria-label=\"筛选\" variant=\"filled\">\n <MSpace wrap>\n <MInput v-model=\"keyword\" placeholder=\"搜索\" clearable class=\"w-48\" />\n </MSpace>\n <template #actions>\n <MButton>\n 查询\n </MButton>\n </template>\n </MPageFilters>\n <MPageToolbar>\n <span style=\"color:var(--m-color-text-muted);font-size:var(--m-font-size-sm)\">已选 0 项</span>\n <template #actions>\n <MButton type=\"text\">\n 导出\n </MButton>\n <MButton type=\"text\" danger>\n 删除\n </MButton>\n </template>\n </MPageToolbar>\n </MPageContent>\n </div>\n</template>",
17944
18165
  "locale": "zh-CN"
17945
18166
  },
17946
18167
  {
@@ -17949,7 +18170,7 @@
17949
18170
  "sectionId": "列表页组合",
17950
18171
  "lang": "vue",
17951
18172
  "preview": true,
17952
- "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MInput,\n MPageContent,\n MPageFilterChips,\n MPageFilters,\n MPageHeader,\n MSelect,\n MSpace,\n MTag,\n} from 'morya-ui'\nimport { computed, ref } from 'vue'\n\nconst keyword = ref('')\nconst status = ref<string | null>('active')\nconst filtersExpanded = ref(false)\nconst department = ref<string | null>(null)\n\nconst activeFilters = computed(() => {\n const items: Array<{ key: string; label: string }> = []\n if (keyword.value.trim()) {\n items.push({ key: 'keyword', label: `关键词:${keyword.value.trim()}` })\n }\n if (status.value && status.value !== 'all') {\n items.push({ key: 'status', label: `状态:${status.value === 'active' ? '启用' : '停用'}` })\n }\n if (department.value) {\n items.push({ key: 'department', label: `部门:${department.value}` })\n }\n return items\n})\n\nfunction clearFilter(key: string) {\n if (key === 'keyword') keyword.value = ''\n if (key === 'status') status.value = 'all'\n if (key === 'department') department.value = null\n}\n\nfunction resetAll() {\n keyword.value = ''\n status.value = 'all'\n department.value = null\n}\n</script>\n\n<template>\n <div\n class=\"doc-demo-frame\"\n style=\"border:1px solid var(--m-color-border);border-radius:var(--m-radius-md);overflow:visible;background:var(--m-color-surface)\"\n >\n <MPageContent>\n <MPageHeader title=\"用户管理\" description=\"折叠高级筛选(chevron + 收起),查询/重置放 #actions。\">\n <template #actions>\n <MButton severity=\"primary\">\n 新建\n </MButton>\n </template>\n </MPageHeader>\n <MPageFilters\n v-model:expanded=\"filtersExpanded\"\n aria-label=\"筛选\"\n variant=\"filled\"\n collapsible\n >\n <MSpace wrap>\n <MInput v-model=\"keyword\" placeholder=\"搜索名称\" clearable style=\"width: 14rem\" />\n <MSelect\n v-model=\"status\"\n :options=\"[\n { label: '全部', value: 'all' },\n { label: '启用', value: 'active' },\n { label: '停用', value: 'inactive' },\n ]\"\n placeholder=\"状态\"\n style=\"width: 10rem\"\n />\n </MSpace>\n <template #actions>\n <MButton severity=\"secondary\">\n 查询\n </MButton>\n <MButton severity=\"secondary\" text @click=\"resetAll\">\n 重置\n </MButton>\n </template>\n <template #advanced>\n <MSpace wrap>\n <MSelect\n v-model=\"department\"\n :options=\"[\n { label: '研发', value: '研发' },\n { label: '运营', value: '运营' },\n ]\"\n placeholder=\"部门\"\n clearable\n style=\"width: 10rem\"\n />\n </MSpace>\n </template>\n </MPageFilters>\n <MPageFilterChips v-if=\"activeFilters.length\" label=\"已选\" aria-label=\"已选筛选\">\n <MTag\n v-for=\"item in activeFilters\"\n :key=\"item.key\"\n :value=\"item.label\"\n size=\"small\"\n bordered\n closable\n @close=\"clearFilter(item.key)\"\n />\n </MPageFilterChips>\n </MPageContent>\n </div>\n</template>",
18173
+ "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MInput,\n MPageContent,\n MPageFilterChips,\n MPageFilters,\n MPageHeader,\n MSelect,\n MSpace,\n MTag,\n} from 'morya-ui'\nimport { computed, ref } from 'vue'\n\nconst keyword = ref('')\nconst status = ref<string | null>('active')\nconst filtersExpanded = ref(false)\nconst department = ref<string | null>(null)\n\nconst activeFilters = computed(() => {\n const items: Array<{ key: string; label: string }> = []\n if (keyword.value.trim()) {\n items.push({ key: 'keyword', label: `关键词:${keyword.value.trim()}` })\n }\n if (status.value && status.value !== 'all') {\n items.push({ key: 'status', label: `状态:${status.value === 'active' ? '启用' : '停用'}` })\n }\n if (department.value) {\n items.push({ key: 'department', label: `部门:${department.value}` })\n }\n return items\n})\n\nfunction clearFilter(key: string) {\n if (key === 'keyword') keyword.value = ''\n if (key === 'status') status.value = 'all'\n if (key === 'department') department.value = null\n}\n\nfunction resetAll() {\n keyword.value = ''\n status.value = 'all'\n department.value = null\n}\n</script>\n\n<template>\n <div\n class=\"doc-demo-frame\"\n style=\"border:1px solid var(--m-color-border);border-radius:var(--m-radius-md);overflow:visible;background:var(--m-color-surface)\"\n >\n <MPageContent>\n <MPageHeader title=\"用户管理\" description=\"折叠高级筛选(chevron + 收起),查询/重置放 #actions。\">\n <template #actions>\n <MButton type=\"primary\">\n 新建\n </MButton>\n </template>\n </MPageHeader>\n <MPageFilters\n v-model:expanded=\"filtersExpanded\"\n aria-label=\"筛选\"\n variant=\"filled\"\n collapsible\n >\n <MSpace wrap>\n <MInput v-model=\"keyword\" placeholder=\"搜索名称\" clearable style=\"width: 14rem\" />\n <MSelect\n v-model=\"status\"\n :options=\"[\n { label: '全部', value: 'all' },\n { label: '启用', value: 'active' },\n { label: '停用', value: 'inactive' },\n ]\"\n placeholder=\"状态\"\n style=\"width: 10rem\"\n />\n </MSpace>\n <template #actions>\n <MButton>\n 查询\n </MButton>\n <MButton @click=\"resetAll\" type=\"text\">\n 重置\n </MButton>\n </template>\n <template #advanced>\n <MSpace wrap>\n <MSelect\n v-model=\"department\"\n :options=\"[\n { label: '研发', value: '研发' },\n { label: '运营', value: '运营' },\n ]\"\n placeholder=\"部门\"\n clearable\n style=\"width: 10rem\"\n />\n </MSpace>\n </template>\n </MPageFilters>\n <MPageFilterChips v-if=\"activeFilters.length\" label=\"已选\" aria-label=\"已选筛选\">\n <MTag\n v-for=\"item in activeFilters\"\n :key=\"item.key\"\n :value=\"item.label\"\n size=\"small\"\n bordered\n closable\n @close=\"clearFilter(item.key)\"\n />\n </MPageFilterChips>\n </MPageContent>\n </div>\n</template>",
17953
18174
  "locale": "zh-CN"
17954
18175
  },
17955
18176
  {
@@ -17958,7 +18179,7 @@
17958
18179
  "sectionId": "表单页组合",
17959
18180
  "lang": "vue",
17960
18181
  "preview": true,
17961
- "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MForm,\n MFormItem,\n MInput,\n MPageContent,\n MPageHeader,\n MPageSection,\n MSpace,\n} from 'morya-ui'\nimport { ref } from 'vue'\n\nconst name = ref('')\n</script>\n\n<template>\n <div\n class=\"doc-demo-frame\"\n style=\"border:1px solid var(--m-color-border);border-radius:var(--m-radius-md);overflow:hidden;background:var(--m-color-surface)\"\n >\n <MPageContent width=\"narrow\">\n <MPageHeader title=\"新建用户\" description=\"填写基本信息。\" />\n <MPageSection variant=\"form\">\n <MForm @submit.prevent>\n <MFormItem label=\"姓名\" name=\"name\">\n <MInput v-model=\"name\" fluid />\n </MFormItem>\n <MPageSection variant=\"actions\">\n <MSpace>\n <MButton native-type=\"submit\" severity=\"primary\">\n 保存\n </MButton>\n <MButton severity=\"secondary\">\n 取消\n </MButton>\n </MSpace>\n </MPageSection>\n </MForm>\n </MPageSection>\n </MPageContent>\n </div>\n</template>",
18182
+ "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MForm,\n MFormItem,\n MInput,\n MPageContent,\n MPageHeader,\n MPageSection,\n MSpace,\n} from 'morya-ui'\nimport { ref } from 'vue'\n\nconst name = ref('')\n</script>\n\n<template>\n <div\n class=\"doc-demo-frame\"\n style=\"border:1px solid var(--m-color-border);border-radius:var(--m-radius-md);overflow:hidden;background:var(--m-color-surface)\"\n >\n <MPageContent width=\"narrow\">\n <MPageHeader title=\"新建用户\" description=\"填写基本信息。\" />\n <MPageSection variant=\"form\">\n <MForm @submit.prevent>\n <MFormItem label=\"姓名\" name=\"name\">\n <MInput v-model=\"name\" fluid />\n </MFormItem>\n <MPageSection variant=\"actions\">\n <MSpace>\n <MButton html-type=\"submit\">\n 保存\n </MButton>\n <MButton>\n 取消\n </MButton>\n </MSpace>\n </MPageSection>\n </MForm>\n </MPageSection>\n </MPageContent>\n </div>\n</template>",
17962
18183
  "locale": "zh-CN"
17963
18184
  },
17964
18185
  {
@@ -17994,7 +18215,7 @@
17994
18215
  "sectionId": "list-page-stack",
17995
18216
  "lang": "vue",
17996
18217
  "preview": true,
17997
- "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MInput,\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPageToolbar,\n MSpace,\n} from 'morya-ui'\nimport { ref } from 'vue'\n\nconst keyword = ref('')\n</script>\n\n<template>\n <div\n class=\"doc-demo-frame\"\n style=\"border:1px solid var(--m-color-border);border-radius:var(--m-radius-md);overflow:visible;background:var(--m-color-surface)\"\n >\n <MPageContent>\n <MPageHeader title=\"Users\" description=\"Manage accounts and roles.\">\n <template #actions>\n <MButton severity=\"primary\">\n Create\n </MButton>\n </template>\n </MPageHeader>\n <MPageFilters aria-label=\"Filters\" variant=\"filled\">\n <MSpace wrap>\n <MInput v-model=\"keyword\" placeholder=\"Search\" clearable class=\"w-48\" />\n </MSpace>\n <template #actions>\n <MButton severity=\"secondary\">\n Search\n </MButton>\n </template>\n </MPageFilters>\n <MPageToolbar>\n <span style=\"color:var(--m-color-text-muted);font-size:var(--m-font-size-sm)\">0 selected</span>\n <template #actions>\n <MButton severity=\"secondary\" text>\n Export\n </MButton>\n <MButton severity=\"danger\" text>\n Delete\n </MButton>\n </template>\n </MPageToolbar>\n </MPageContent>\n </div>\n</template>",
18218
+ "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MInput,\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPageToolbar,\n MSpace,\n} from 'morya-ui'\nimport { ref } from 'vue'\n\nconst keyword = ref('')\n</script>\n\n<template>\n <div\n class=\"doc-demo-frame\"\n style=\"border:1px solid var(--m-color-border);border-radius:var(--m-radius-md);overflow:visible;background:var(--m-color-surface)\"\n >\n <MPageContent>\n <MPageHeader title=\"Users\" description=\"Manage accounts and roles.\">\n <template #actions>\n <MButton type=\"primary\">\n Create\n </MButton>\n </template>\n </MPageHeader>\n <MPageFilters aria-label=\"Filters\" variant=\"filled\">\n <MSpace wrap>\n <MInput v-model=\"keyword\" placeholder=\"Search\" clearable class=\"w-48\" />\n </MSpace>\n <template #actions>\n <MButton>\n Search\n </MButton>\n </template>\n </MPageFilters>\n <MPageToolbar>\n <span style=\"color:var(--m-color-text-muted);font-size:var(--m-font-size-sm)\">0 selected</span>\n <template #actions>\n <MButton type=\"text\">\n Export\n </MButton>\n <MButton type=\"text\" danger>\n Delete\n </MButton>\n </template>\n </MPageToolbar>\n </MPageContent>\n </div>\n</template>",
17998
18219
  "locale": "en-US"
17999
18220
  },
18000
18221
  {
@@ -18003,7 +18224,7 @@
18003
18224
  "sectionId": "list-page-stack",
18004
18225
  "lang": "vue",
18005
18226
  "preview": true,
18006
- "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MInput,\n MPageContent,\n MPageFilterChips,\n MPageFilters,\n MPageHeader,\n MSelect,\n MSpace,\n MTag,\n} from 'morya-ui'\nimport { computed, ref } from 'vue'\n\nconst keyword = ref('')\nconst status = ref<string | null>('active')\nconst filtersExpanded = ref(false)\nconst department = ref<string | null>(null)\n\nconst activeFilters = computed(() => {\n const items: Array<{ key: string; label: string }> = []\n if (keyword.value.trim()) {\n items.push({ key: 'keyword', label: `Keyword: ${keyword.value.trim()}` })\n }\n if (status.value && status.value !== 'all') {\n items.push({\n key: 'status',\n label: `Status: ${status.value === 'active' ? 'Active' : 'Inactive'}`,\n })\n }\n if (department.value) {\n items.push({ key: 'department', label: `Department: ${department.value}` })\n }\n return items\n})\n\nfunction clearFilter(key: string) {\n if (key === 'keyword') keyword.value = ''\n if (key === 'status') status.value = 'all'\n if (key === 'department') department.value = null\n}\n\nfunction resetAll() {\n keyword.value = ''\n status.value = 'all'\n department.value = null\n}\n</script>\n\n<template>\n <div\n class=\"doc-demo-frame\"\n style=\"border:1px solid var(--m-color-border);border-radius:var(--m-radius-md);overflow:visible;background:var(--m-color-surface)\"\n >\n <MPageContent>\n <MPageHeader title=\"Users\" description=\"Collapsible advanced filters (chevron + Collapse); query/reset in #actions.\">\n <template #actions>\n <MButton severity=\"primary\">\n Create\n </MButton>\n </template>\n </MPageHeader>\n <MPageFilters\n v-model:expanded=\"filtersExpanded\"\n aria-label=\"Filters\"\n variant=\"filled\"\n collapsible\n >\n <MSpace wrap>\n <MInput v-model=\"keyword\" placeholder=\"Search name\" clearable style=\"width: 14rem\" />\n <MSelect\n v-model=\"status\"\n :options=\"[\n { label: 'All', value: 'all' },\n { label: 'Active', value: 'active' },\n { label: 'Inactive', value: 'inactive' },\n ]\"\n placeholder=\"Status\"\n style=\"width: 10rem\"\n />\n </MSpace>\n <template #actions>\n <MButton severity=\"secondary\">\n Search\n </MButton>\n <MButton severity=\"secondary\" text @click=\"resetAll\">\n Reset\n </MButton>\n </template>\n <template #advanced>\n <MSpace wrap>\n <MSelect\n v-model=\"department\"\n :options=\"[\n { label: 'Engineering', value: 'Engineering' },\n { label: 'Operations', value: 'Operations' },\n ]\"\n placeholder=\"Department\"\n clearable\n style=\"width: 10rem\"\n />\n </MSpace>\n </template>\n </MPageFilters>\n <MPageFilterChips v-if=\"activeFilters.length\" label=\"Active\" aria-label=\"Active filters\">\n <MTag\n v-for=\"item in activeFilters\"\n :key=\"item.key\"\n :value=\"item.label\"\n size=\"small\"\n bordered\n closable\n @close=\"clearFilter(item.key)\"\n />\n </MPageFilterChips>\n </MPageContent>\n </div>\n</template>",
18227
+ "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MInput,\n MPageContent,\n MPageFilterChips,\n MPageFilters,\n MPageHeader,\n MSelect,\n MSpace,\n MTag,\n} from 'morya-ui'\nimport { computed, ref } from 'vue'\n\nconst keyword = ref('')\nconst status = ref<string | null>('active')\nconst filtersExpanded = ref(false)\nconst department = ref<string | null>(null)\n\nconst activeFilters = computed(() => {\n const items: Array<{ key: string; label: string }> = []\n if (keyword.value.trim()) {\n items.push({ key: 'keyword', label: `Keyword: ${keyword.value.trim()}` })\n }\n if (status.value && status.value !== 'all') {\n items.push({\n key: 'status',\n label: `Status: ${status.value === 'active' ? 'Active' : 'Inactive'}`,\n })\n }\n if (department.value) {\n items.push({ key: 'department', label: `Department: ${department.value}` })\n }\n return items\n})\n\nfunction clearFilter(key: string) {\n if (key === 'keyword') keyword.value = ''\n if (key === 'status') status.value = 'all'\n if (key === 'department') department.value = null\n}\n\nfunction resetAll() {\n keyword.value = ''\n status.value = 'all'\n department.value = null\n}\n</script>\n\n<template>\n <div\n class=\"doc-demo-frame\"\n style=\"border:1px solid var(--m-color-border);border-radius:var(--m-radius-md);overflow:visible;background:var(--m-color-surface)\"\n >\n <MPageContent>\n <MPageHeader title=\"Users\" description=\"Collapsible advanced filters (chevron + Collapse); query/reset in #actions.\">\n <template #actions>\n <MButton type=\"primary\">\n Create\n </MButton>\n </template>\n </MPageHeader>\n <MPageFilters\n v-model:expanded=\"filtersExpanded\"\n aria-label=\"Filters\"\n variant=\"filled\"\n collapsible\n >\n <MSpace wrap>\n <MInput v-model=\"keyword\" placeholder=\"Search name\" clearable style=\"width: 14rem\" />\n <MSelect\n v-model=\"status\"\n :options=\"[\n { label: 'All', value: 'all' },\n { label: 'Active', value: 'active' },\n { label: 'Inactive', value: 'inactive' },\n ]\"\n placeholder=\"Status\"\n style=\"width: 10rem\"\n />\n </MSpace>\n <template #actions>\n <MButton>\n Search\n </MButton>\n <MButton @click=\"resetAll\" type=\"text\">\n Reset\n </MButton>\n </template>\n <template #advanced>\n <MSpace wrap>\n <MSelect\n v-model=\"department\"\n :options=\"[\n { label: 'Engineering', value: 'Engineering' },\n { label: 'Operations', value: 'Operations' },\n ]\"\n placeholder=\"Department\"\n clearable\n style=\"width: 10rem\"\n />\n </MSpace>\n </template>\n </MPageFilters>\n <MPageFilterChips v-if=\"activeFilters.length\" label=\"Active\" aria-label=\"Active filters\">\n <MTag\n v-for=\"item in activeFilters\"\n :key=\"item.key\"\n :value=\"item.label\"\n size=\"small\"\n bordered\n closable\n @close=\"clearFilter(item.key)\"\n />\n </MPageFilterChips>\n </MPageContent>\n </div>\n</template>",
18007
18228
  "locale": "en-US"
18008
18229
  },
18009
18230
  {
@@ -18973,7 +19194,7 @@
18973
19194
  "sectionId": "placement",
18974
19195
  "lang": "vue",
18975
19196
  "preview": true,
18976
- "code": "<script setup lang=\"ts\">\nimport { MButton, MPopover } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div style=\"display:flex;justify-content:center;padding:2rem\">\n <MPopover v-model=\"open\" placement=\"bottom-start\">\n <MButton label=\"bottom-start\" severity=\"secondary\" @click=\"open = !open\" />\n <template #content>\n <p style=\"margin:0\">\n Aligned to the start of the trigger.\n </p>\n </template>\n </MPopover>\n </div>\n</template>",
19197
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MPopover } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div style=\"display:flex;justify-content:center;padding:2rem\">\n <MPopover v-model=\"open\" placement=\"bottom-start\">\n <MButton label=\"bottom-start\" @click=\"open = !open\"/>\n <template #content>\n <p style=\"margin:0\">\n Aligned to the start of the trigger.\n </p>\n </template>\n </MPopover>\n </div>\n</template>",
18977
19198
  "locale": "zh-CN"
18978
19199
  },
18979
19200
  {
@@ -18982,7 +19203,7 @@
18982
19203
  "sectionId": "hover",
18983
19204
  "lang": "vue",
18984
19205
  "preview": true,
18985
- "code": "<script setup lang=\"ts\">\nimport { MButton, MPopover } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <MPopover v-model=\"open\" trigger=\"hover\" :show-delay=\"80\" :hide-delay=\"120\">\n <MButton label=\"Hover me\" severity=\"secondary\" />\n <template #content>\n <p style=\"margin:0\">\n Opens on hover.\n </p>\n </template>\n </MPopover>\n</template>",
19206
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MPopover } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <MPopover v-model=\"open\" trigger=\"hover\" :show-delay=\"80\" :hide-delay=\"120\">\n <MButton label=\"Hover me\"/>\n <template #content>\n <p style=\"margin:0\">\n Opens on hover.\n </p>\n </template>\n </MPopover>\n</template>",
18986
19207
  "locale": "zh-CN"
18987
19208
  },
18988
19209
  {
@@ -19009,7 +19230,7 @@
19009
19230
  "sectionId": "placement",
19010
19231
  "lang": "vue",
19011
19232
  "preview": true,
19012
- "code": "<script setup lang=\"ts\">\nimport { MButton, MPopover } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div style=\"display:flex;justify-content:center;padding:2rem\">\n <MPopover v-model=\"open\" placement=\"bottom-start\">\n <MButton label=\"bottom-start\" severity=\"secondary\" @click=\"open = !open\" />\n <template #content>\n <p style=\"margin:0\">\n Aligned to the start of the trigger.\n </p>\n </template>\n </MPopover>\n </div>\n</template>",
19233
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MPopover } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <div style=\"display:flex;justify-content:center;padding:2rem\">\n <MPopover v-model=\"open\" placement=\"bottom-start\">\n <MButton label=\"bottom-start\" @click=\"open = !open\"/>\n <template #content>\n <p style=\"margin:0\">\n Aligned to the start of the trigger.\n </p>\n </template>\n </MPopover>\n </div>\n</template>",
19013
19234
  "locale": "en-US"
19014
19235
  },
19015
19236
  {
@@ -19018,7 +19239,7 @@
19018
19239
  "sectionId": "hover",
19019
19240
  "lang": "vue",
19020
19241
  "preview": true,
19021
- "code": "<script setup lang=\"ts\">\nimport { MButton, MPopover } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <MPopover v-model=\"open\" trigger=\"hover\" :show-delay=\"80\" :hide-delay=\"120\">\n <MButton label=\"Hover me\" severity=\"secondary\" />\n <template #content>\n <p style=\"margin:0\">\n Opens on hover.\n </p>\n </template>\n </MPopover>\n</template>",
19242
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MPopover } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst open = ref(false)\n</script>\n\n<template>\n <MPopover v-model=\"open\" trigger=\"hover\" :show-delay=\"80\" :hide-delay=\"120\">\n <MButton label=\"Hover me\"/>\n <template #content>\n <p style=\"margin:0\">\n Opens on hover.\n </p>\n </template>\n </MPopover>\n</template>",
19022
19243
  "locale": "en-US"
19023
19244
  }
19024
19245
  ],
@@ -19173,6 +19394,12 @@
19173
19394
  "type": "string",
19174
19395
  "default": "—",
19175
19396
  "description": "自定义填充色。"
19397
+ },
19398
+ {
19399
+ "name": "pt",
19400
+ "type": "[RootPassThrough](/docs/types#RootPassThrough) `{ root? }",
19401
+ "default": "—",
19402
+ "description": "DOM 透传,见 [样式与 attrs](/docs/attrs)."
19176
19403
  }
19177
19404
  ],
19178
19405
  "events": [],
@@ -19262,7 +19489,7 @@
19262
19489
  {
19263
19490
  "id": "props",
19264
19491
  "title": "Props",
19265
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `number` | `0` | 进度 0–100(determinate)。 |\n| `mode` | `'determinate' \\| 'indeterminate'` | `'determinate'` | 确定 / 不确定模式。 |\n| `showValue` | `boolean` | `true` | 是否显示百分比文案。 |\n| `type` | `'line' \\| 'circle'` | `'line'` | 线形或环形。 |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'danger' \\| 'exception' \\| 'active' \\| 'normal' \\| …` | — | 语义色。`exception`→danger;`active`→线形条纹动效;`normal`→主色。 |\n| `color` | `string` | — | 自定义填充色。 |"
19492
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `number` | `0` | 进度 0–100(determinate)。 |\n| `mode` | `'determinate' \\| 'indeterminate'` | `'determinate'` | 确定 / 不确定模式。 |\n| `showValue` | `boolean` | `true` | 是否显示百分比文案。 |\n| `type` | `'line' \\| 'circle'` | `'line'` | 线形或环形。 |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'danger' \\| 'exception' \\| 'active' \\| 'normal' \\| …` | — | 语义色。`exception`→danger;`active`→线形条纹动效;`normal`→主色。 |\n| `color` | `string` | — | 自定义填充色。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
19266
19493
  },
19267
19494
  {
19268
19495
  "id": "events",
@@ -19275,7 +19502,7 @@
19275
19502
  "body": "无插槽。"
19276
19503
  }
19277
19504
  ],
19278
- "markdown": "---\ntitle: ProgressBar\ncategory: 03 / DATA\ndescription: 进度条用于展示确定或不确定进度。\n---\n\n# ProgressBar\n\n进度条用于展示任务完成比例,或不确定加载态。\n\n## 引入\n\n```ts\nimport { MProgressBar } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Circle & status\n\n```vue preview src=\"./demos/CircleAndStatus.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `number` | `0` | 进度 0–100(determinate)。 |\n| `mode` | `'determinate' \\| 'indeterminate'` | `'determinate'` | 确定 / 不确定模式。 |\n| `showValue` | `boolean` | `true` | 是否显示百分比文案。 |\n| `type` | `'line' \\| 'circle'` | `'line'` | 线形或环形。 |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'danger' \\| 'exception' \\| 'active' \\| 'normal' \\| …` | — | 语义色。`exception`→danger;`active`→线形条纹动效;`normal`→主色。 |\n| `color` | `string` | — | 自定义填充色。 |\n\n## Events\n\n无自定义事件。\n\n## Slots\n\n无插槽。\n"
19505
+ "markdown": "---\ntitle: ProgressBar\ncategory: 03 / DATA\ndescription: 进度条用于展示确定或不确定进度。\n---\n\n# ProgressBar\n\n进度条用于展示任务完成比例,或不确定加载态。\n\n## 引入\n\n```ts\nimport { MProgressBar } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Circle & status\n\n```vue preview src=\"./demos/CircleAndStatus.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `number` | `0` | 进度 0–100(determinate)。 |\n| `mode` | `'determinate' \\| 'indeterminate'` | `'determinate'` | 确定 / 不确定模式。 |\n| `showValue` | `boolean` | `true` | 是否显示百分比文案。 |\n| `type` | `'line' \\| 'circle'` | `'line'` | 线形或环形。 |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'danger' \\| 'exception' \\| 'active' \\| 'normal' \\| …` | — | 语义色。`exception`→danger;`active`→线形条纹动效;`normal`→主色。 |\n| `color` | `string` | — | 自定义填充色。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n## Events\n\n无自定义事件。\n\n## Slots\n\n无插槽。\n"
19279
19506
  },
19280
19507
  "en-US": {
19281
19508
  "title": "ProgressBar",
@@ -19304,7 +19531,7 @@
19304
19531
  {
19305
19532
  "id": "props",
19306
19533
  "title": "Props",
19307
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `number` | `0` | Progress 0鈥?00 (determinate). |\n| `mode` | `'determinate' \\| 'indeterminate'` | `'determinate'` | Determinate / indeterminate mode. |\n| `showValue` | `boolean` | `true` | Whether to show the percentage label. |\n| `type` | `'line' \\| 'circle'` | `'line'` | Line or circle. |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'danger' \\| 'exception' \\| 'active' \\| 'normal' \\| 鈥 | 鈥?| Semantic fill. `exception`鈫抎anger; `active`鈫抣ine stripe; `normal`鈫抪rimary. |\n| `color` | `string` | 鈥?| Custom fill color. |"
19534
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `number` | `0` | Progress 0鈥?00 (determinate). |\n| `mode` | `'determinate' \\| 'indeterminate'` | `'determinate'` | Determinate / indeterminate mode. |\n| `showValue` | `boolean` | `true` | Whether to show the percentage label. |\n| `type` | `'line' \\| 'circle'` | `'line'` | Line or circle. |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'danger' \\| 'exception' \\| 'active' \\| 'normal' \\| 鈥 | 鈥?| Semantic fill. `exception`鈫抎anger; `active`鈫抣ine stripe; `normal`鈫抪rimary. |\n| `color` | `string` | 鈥?| Custom fill color. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |"
19308
19535
  },
19309
19536
  {
19310
19537
  "id": "events",
@@ -19317,7 +19544,7 @@
19317
19544
  "body": "No slots."
19318
19545
  }
19319
19546
  ],
19320
- "markdown": "---\ntitle: ProgressBar\ncategory: 03 / DATA\ndescription: Progress bar for determinate or indeterminate progress.\n---\n\n# ProgressBar\n\nShows task completion, or an indeterminate loading state.\n\n## Import\n\n```ts\nimport { MProgressBar } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Circle & status\n\n```vue preview src=\"./demos/CircleAndStatus.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `number` | `0` | Progress 0鈥?00 (determinate). |\n| `mode` | `'determinate' \\| 'indeterminate'` | `'determinate'` | Determinate / indeterminate mode. |\n| `showValue` | `boolean` | `true` | Whether to show the percentage label. |\n| `type` | `'line' \\| 'circle'` | `'line'` | Line or circle. |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'danger' \\| 'exception' \\| 'active' \\| 'normal' \\| 鈥 | 鈥?| Semantic fill. `exception`鈫抎anger; `active`鈫抣ine stripe; `normal`鈫抪rimary. |\n| `color` | `string` | 鈥?| Custom fill color. |\n\n## Events\n\nNo custom events.\n\n## Slots\n\nNo slots.\n"
19547
+ "markdown": "---\ntitle: ProgressBar\ncategory: 03 / DATA\ndescription: Progress bar for determinate or indeterminate progress.\n---\n\n# ProgressBar\n\nShows task completion, or an indeterminate loading state.\n\n## Import\n\n```ts\nimport { MProgressBar } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Circle & status\n\n```vue preview src=\"./demos/CircleAndStatus.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `number` | `0` | Progress 0鈥?00 (determinate). |\n| `mode` | `'determinate' \\| 'indeterminate'` | `'determinate'` | Determinate / indeterminate mode. |\n| `showValue` | `boolean` | `true` | Whether to show the percentage label. |\n| `type` | `'line' \\| 'circle'` | `'line'` | Line or circle. |\n| `status` | `'success' \\| 'info' \\| 'warning' \\| 'danger' \\| 'exception' \\| 'active' \\| 'normal' \\| 鈥 | 鈥?| Semantic fill. `exception`鈫抎anger; `active`鈫抣ine stripe; `normal`鈫抪rimary. |\n| `color` | `string` | 鈥?| Custom fill color. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |\n\n## Events\n\nNo custom events.\n\n## Slots\n\nNo slots.\n"
19321
19548
  }
19322
19549
  }
19323
19550
  },
@@ -20404,7 +20631,7 @@
20404
20631
  "sectionId": "操作区",
20405
20632
  "lang": "vue",
20406
20633
  "preview": true,
20407
- "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>",
20634
+ "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=\"返回首页\" type=\"text\"/>\n </template>\n </MResult>\n <MResult status=\"error\" description=\"请检查网络后重试,或联系管理员。\">\n <template #footer>\n <MButton label=\"重试\" />\n </template>\n </MResult>\n </div>\n</template>",
20408
20635
  "locale": "zh-CN"
20409
20636
  },
20410
20637
  {
@@ -20413,7 +20640,7 @@
20413
20640
  "sectionId": "http-类状态",
20414
20641
  "lang": "vue",
20415
20642
  "preview": true,
20416
- "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>",
20643
+ "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=\"返回\"/>\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>",
20417
20644
  "locale": "zh-CN"
20418
20645
  },
20419
20646
  {
@@ -20422,7 +20649,7 @@
20422
20649
  "sectionId": "尺寸",
20423
20650
  "lang": "vue",
20424
20651
  "preview": true,
20425
- "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>",
20652
+ "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 label=\"知道了\" size=\"small\"/>\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>",
20426
20653
  "locale": "zh-CN"
20427
20654
  },
20428
20655
  {
@@ -20449,7 +20676,7 @@
20449
20676
  "sectionId": "actions",
20450
20677
  "lang": "vue",
20451
20678
  "preview": true,
20452
- "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>",
20679
+ "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\" type=\"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>",
20453
20680
  "locale": "en-US"
20454
20681
  },
20455
20682
  {
@@ -20458,7 +20685,7 @@
20458
20685
  "sectionId": "http-statuses",
20459
20686
  "lang": "vue",
20460
20687
  "preview": true,
20461
- "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>",
20688
+ "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\"/>\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>",
20462
20689
  "locale": "en-US"
20463
20690
  },
20464
20691
  {
@@ -20467,7 +20694,7 @@
20467
20694
  "sectionId": "size",
20468
20695
  "lang": "vue",
20469
20696
  "preview": true,
20470
- "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>",
20697
+ "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 label=\"OK\" size=\"small\"/>\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>",
20471
20698
  "locale": "en-US"
20472
20699
  }
20473
20700
  ],
@@ -20815,7 +21042,7 @@
20815
21042
  "sectionId": "max-height",
20816
21043
  "lang": "vue",
20817
21044
  "preview": true,
20818
- "code": "<script setup lang=\"ts\">\nimport { MButton, MScrollbar } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst count = ref(3)\n</script>\n\n<template>\n <div class=\"grid gap-3\">\n <div style=\"display:flex;gap:0.5rem\">\n <MButton label=\"Add\" size=\"small\" @click=\"count++\" />\n <MButton label=\"Remove\" severity=\"secondary\" size=\"small\" @click=\"count = Math.max(0, count - 1)\" />\n </div>\n <MScrollbar max-height=\"220px\" always class=\"w-full\">\n <p\n v-for=\"item in count\"\n :key=\"item\"\n style=\"\n display:flex;align-items:center;justify-content:center;\n height:48px;margin:8px;border-radius:6px;\n background:color-mix(in srgb, var(--m-color-info) 12%, transparent);\n color:var(--m-color-info);\n \"\n >\n Item {{ item }}\n </p>\n </MScrollbar>\n </div>\n</template>",
21045
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MScrollbar } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst count = ref(3)\n</script>\n\n<template>\n <div class=\"grid gap-3\">\n <div style=\"display:flex;gap:0.5rem\">\n <MButton label=\"Add\" size=\"small\" @click=\"count++\" />\n <MButton label=\"Remove\" size=\"small\" @click=\"count = Math.max(0, count - 1)\"/>\n </div>\n <MScrollbar max-height=\"220px\" always class=\"w-full\">\n <p\n v-for=\"item in count\"\n :key=\"item\"\n style=\"\n display:flex;align-items:center;justify-content:center;\n height:48px;margin:8px;border-radius:6px;\n background:color-mix(in srgb, var(--m-color-info) 12%, transparent);\n color:var(--m-color-info);\n \"\n >\n Item {{ item }}\n </p>\n </MScrollbar>\n </div>\n</template>",
20819
21046
  "locale": "zh-CN"
20820
21047
  },
20821
21048
  {
@@ -20842,7 +21069,7 @@
20842
21069
  "sectionId": "manual-scroll",
20843
21070
  "lang": "vue",
20844
21071
  "preview": true,
20845
- "code": "<script setup lang=\"ts\">\nimport type { ScrollbarInstance } from 'morya-ui'\nimport { MButton, MScrollbar } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst scrollbarRef = ref<ScrollbarInstance>()\nconst scrollTop = ref(0)\n\nfunction jump(top: number) {\n scrollbarRef.value?.setScrollTop(top)\n}\n\nfunction onScroll(payload: { scrollTop: number }) {\n scrollTop.value = Math.round(payload.scrollTop)\n}\n</script>\n\n<template>\n <div class=\"grid gap-3\">\n <div style=\"display:flex;flex-wrap:wrap;gap:0.5rem;align-items:center\">\n <MButton label=\"Top\" size=\"small\" @click=\"jump(0)\" />\n <MButton label=\"Mid\" size=\"small\" severity=\"secondary\" @click=\"jump(200)\" />\n <MButton label=\"Bottom\" size=\"small\" severity=\"secondary\" @click=\"jump(9999)\" />\n <span style=\"color:var(--m-color-text-muted);font-size:0.875rem\">scrollTop: {{ scrollTop }}</span>\n </div>\n <MScrollbar ref=\"scrollbarRef\" height=\"200px\" style=\"width: 200px\" always @scroll=\"onScroll\">\n <p\n v-for=\"item in 24\"\n :key=\"item\"\n style=\"\n display:flex;align-items:center;justify-content:center;\n height:48px;margin:8px;border-radius:6px;\n background:color-mix(in srgb, var(--m-color-success) 12%, transparent);\n color:var(--m-color-success);\n \"\n >\n {{ item }}\n </p>\n </MScrollbar>\n </div>\n</template>",
21072
+ "code": "<script setup lang=\"ts\">\nimport type { ScrollbarInstance } from 'morya-ui'\nimport { MButton, MScrollbar } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst scrollbarRef = ref<ScrollbarInstance>()\nconst scrollTop = ref(0)\n\nfunction jump(top: number) {\n scrollbarRef.value?.setScrollTop(top)\n}\n\nfunction onScroll(payload: { scrollTop: number }) {\n scrollTop.value = Math.round(payload.scrollTop)\n}\n</script>\n\n<template>\n <div class=\"grid gap-3\">\n <div style=\"display:flex;flex-wrap:wrap;gap:0.5rem;align-items:center\">\n <MButton label=\"Top\" size=\"small\" @click=\"jump(0)\" />\n <MButton label=\"Mid\" size=\"small\" @click=\"jump(200)\"/>\n <MButton label=\"Bottom\" size=\"small\" @click=\"jump(9999)\"/>\n <span style=\"color:var(--m-color-text-muted);font-size:0.875rem\">scrollTop: {{ scrollTop }}</span>\n </div>\n <MScrollbar ref=\"scrollbarRef\" height=\"200px\" style=\"width: 200px\" always @scroll=\"onScroll\">\n <p\n v-for=\"item in 24\"\n :key=\"item\"\n style=\"\n display:flex;align-items:center;justify-content:center;\n height:48px;margin:8px;border-radius:6px;\n background:color-mix(in srgb, var(--m-color-success) 12%, transparent);\n color:var(--m-color-success);\n \"\n >\n {{ item }}\n </p>\n </MScrollbar>\n </div>\n</template>",
20846
21073
  "locale": "zh-CN"
20847
21074
  },
20848
21075
  {
@@ -20896,7 +21123,7 @@
20896
21123
  "sectionId": "max-height",
20897
21124
  "lang": "vue",
20898
21125
  "preview": true,
20899
- "code": "<script setup lang=\"ts\">\nimport { MButton, MScrollbar } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst count = ref(3)\n</script>\n\n<template>\n <div class=\"grid gap-3\">\n <div style=\"display:flex;gap:0.5rem\">\n <MButton label=\"Add\" size=\"small\" @click=\"count++\" />\n <MButton label=\"Remove\" severity=\"secondary\" size=\"small\" @click=\"count = Math.max(0, count - 1)\" />\n </div>\n <MScrollbar max-height=\"220px\" always class=\"w-full\">\n <p\n v-for=\"item in count\"\n :key=\"item\"\n style=\"\n display:flex;align-items:center;justify-content:center;\n height:48px;margin:8px;border-radius:6px;\n background:color-mix(in srgb, var(--m-color-info) 12%, transparent);\n color:var(--m-color-info);\n \"\n >\n Item {{ item }}\n </p>\n </MScrollbar>\n </div>\n</template>",
21126
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MScrollbar } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst count = ref(3)\n</script>\n\n<template>\n <div class=\"grid gap-3\">\n <div style=\"display:flex;gap:0.5rem\">\n <MButton label=\"Add\" size=\"small\" @click=\"count++\" />\n <MButton label=\"Remove\" size=\"small\" @click=\"count = Math.max(0, count - 1)\"/>\n </div>\n <MScrollbar max-height=\"220px\" always class=\"w-full\">\n <p\n v-for=\"item in count\"\n :key=\"item\"\n style=\"\n display:flex;align-items:center;justify-content:center;\n height:48px;margin:8px;border-radius:6px;\n background:color-mix(in srgb, var(--m-color-info) 12%, transparent);\n color:var(--m-color-info);\n \"\n >\n Item {{ item }}\n </p>\n </MScrollbar>\n </div>\n</template>",
20900
21127
  "locale": "en-US"
20901
21128
  },
20902
21129
  {
@@ -20923,7 +21150,7 @@
20923
21150
  "sectionId": "manual-scroll",
20924
21151
  "lang": "vue",
20925
21152
  "preview": true,
20926
- "code": "<script setup lang=\"ts\">\nimport type { ScrollbarInstance } from 'morya-ui'\nimport { MButton, MScrollbar } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst scrollbarRef = ref<ScrollbarInstance>()\nconst scrollTop = ref(0)\n\nfunction jump(top: number) {\n scrollbarRef.value?.setScrollTop(top)\n}\n\nfunction onScroll(payload: { scrollTop: number }) {\n scrollTop.value = Math.round(payload.scrollTop)\n}\n</script>\n\n<template>\n <div class=\"grid gap-3\">\n <div style=\"display:flex;flex-wrap:wrap;gap:0.5rem;align-items:center\">\n <MButton label=\"Top\" size=\"small\" @click=\"jump(0)\" />\n <MButton label=\"Mid\" size=\"small\" severity=\"secondary\" @click=\"jump(200)\" />\n <MButton label=\"Bottom\" size=\"small\" severity=\"secondary\" @click=\"jump(9999)\" />\n <span style=\"color:var(--m-color-text-muted);font-size:0.875rem\">scrollTop: {{ scrollTop }}</span>\n </div>\n <MScrollbar ref=\"scrollbarRef\" height=\"200px\" always style=\"width: 200px\" @scroll=\"onScroll\">\n <p\n v-for=\"item in 24\"\n :key=\"item\"\n style=\"\n display:flex;align-items:center;justify-content:center;\n height:48px;margin:8px;border-radius:6px;\n background:color-mix(in srgb, var(--m-color-success) 12%, transparent);\n color:var(--m-color-success);\n \"\n >\n {{ item }}\n </p>\n </MScrollbar>\n </div>\n</template>",
21153
+ "code": "<script setup lang=\"ts\">\nimport type { ScrollbarInstance } from 'morya-ui'\nimport { MButton, MScrollbar } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst scrollbarRef = ref<ScrollbarInstance>()\nconst scrollTop = ref(0)\n\nfunction jump(top: number) {\n scrollbarRef.value?.setScrollTop(top)\n}\n\nfunction onScroll(payload: { scrollTop: number }) {\n scrollTop.value = Math.round(payload.scrollTop)\n}\n</script>\n\n<template>\n <div class=\"grid gap-3\">\n <div style=\"display:flex;flex-wrap:wrap;gap:0.5rem;align-items:center\">\n <MButton label=\"Top\" size=\"small\" @click=\"jump(0)\" />\n <MButton label=\"Mid\" size=\"small\" @click=\"jump(200)\"/>\n <MButton label=\"Bottom\" size=\"small\" @click=\"jump(9999)\"/>\n <span style=\"color:var(--m-color-text-muted);font-size:0.875rem\">scrollTop: {{ scrollTop }}</span>\n </div>\n <MScrollbar ref=\"scrollbarRef\" height=\"200px\" always style=\"width: 200px\" @scroll=\"onScroll\">\n <p\n v-for=\"item in 24\"\n :key=\"item\"\n style=\"\n display:flex;align-items:center;justify-content:center;\n height:48px;margin:8px;border-radius:6px;\n background:color-mix(in srgb, var(--m-color-success) 12%, transparent);\n color:var(--m-color-success);\n \"\n >\n {{ item }}\n </p>\n </MScrollbar>\n </div>\n</template>",
20927
21154
  "locale": "en-US"
20928
21155
  },
20929
21156
  {
@@ -21902,7 +22129,7 @@
21902
22129
  "sectionId": "自定义选项渲染",
21903
22130
  "lang": "vue",
21904
22131
  "preview": true,
21905
- "code": "<script setup lang=\"ts\">\nimport { MButton, MSelect } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst value = ref<string | number | undefined>()\nconst options = [\n { label: 'Design', value: 'design' },\n { label: 'Development', value: 'dev' },\n { label: 'Marketing', value: 'mkt' },\n]\n</script>\n\n<template>\n <MSelect v-model=\"value\" label=\"Team\" :options=\"options\" placeholder=\"Choose a team\">\n <template #header>\n <span style=\"color: var(--m-color-text-muted); font-size: var(--m-font-size-xs)\">\n Teams you belong to\n </span>\n </template>\n <template #footer>\n <MButton label=\"Manage teams\" variant=\"text\" size=\"sm\" />\n </template>\n </MSelect>\n</template>",
22132
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MSelect } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst value = ref<string | number | undefined>()\nconst options = [\n { label: 'Design', value: 'design' },\n { label: 'Development', value: 'dev' },\n { label: 'Marketing', value: 'mkt' },\n]\n</script>\n\n<template>\n <MSelect v-model=\"value\" label=\"Team\" :options=\"options\" placeholder=\"Choose a team\">\n <template #header>\n <span style=\"color: var(--m-color-text-muted); font-size: var(--m-font-size-xs)\">\n Teams you belong to\n </span>\n </template>\n <template #footer>\n <MButton label=\"Manage teams\" variant=\"text\" size=\"sm\"/>\n </template>\n </MSelect>\n</template>",
21906
22133
  "locale": "zh-CN"
21907
22134
  },
21908
22135
  {
@@ -22064,7 +22291,7 @@
22064
22291
  "sectionId": "custom-option-rendering",
22065
22292
  "lang": "vue",
22066
22293
  "preview": true,
22067
- "code": "<script setup lang=\"ts\">\nimport { MButton, MSelect } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst value = ref<string | number | undefined>()\nconst options = [\n { label: 'Design', value: 'design' },\n { label: 'Development', value: 'dev' },\n { label: 'Marketing', value: 'mkt' },\n]\n</script>\n\n<template>\n <MSelect v-model=\"value\" label=\"Team\" :options=\"options\" placeholder=\"Choose a team\">\n <template #header>\n <span style=\"color: var(--m-color-text-muted); font-size: var(--m-font-size-xs)\">\n Teams you belong to\n </span>\n </template>\n <template #footer>\n <MButton label=\"Manage teams\" variant=\"text\" size=\"sm\" />\n </template>\n </MSelect>\n</template>",
22294
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MSelect } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst value = ref<string | number | undefined>()\nconst options = [\n { label: 'Design', value: 'design' },\n { label: 'Development', value: 'dev' },\n { label: 'Marketing', value: 'mkt' },\n]\n</script>\n\n<template>\n <MSelect v-model=\"value\" label=\"Team\" :options=\"options\" placeholder=\"Choose a team\">\n <template #header>\n <span style=\"color: var(--m-color-text-muted); font-size: var(--m-font-size-xs)\">\n Teams you belong to\n </span>\n </template>\n <template #footer>\n <MButton label=\"Manage teams\" variant=\"text\" size=\"sm\"/>\n </template>\n </MSelect>\n</template>",
22068
22295
  "locale": "en-US"
22069
22296
  },
22070
22297
  {
@@ -23366,7 +23593,7 @@
23366
23593
  "sectionId": "基础用法",
23367
23594
  "lang": "vue",
23368
23595
  "preview": true,
23369
- "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <MSpace>\n <MButton label=\"保存\" size=\"small\" />\n <MButton label=\"取消\" size=\"small\" severity=\"secondary\" />\n <MButton label=\"重置\" size=\"small\" severity=\"secondary\" />\n </MSpace>\n</template>",
23596
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <MSpace>\n <MButton label=\"保存\" size=\"small\" />\n <MButton label=\"取消\" size=\"small\"/>\n <MButton label=\"重置\" size=\"small\"/>\n </MSpace>\n</template>",
23370
23597
  "locale": "zh-CN"
23371
23598
  },
23372
23599
  {
@@ -23384,7 +23611,7 @@
23384
23611
  "sectionId": "size",
23385
23612
  "lang": "vue",
23386
23613
  "preview": true,
23387
- "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-4\">\n <MSpace size=\"small\">\n <MButton label=\"small\" size=\"small\" />\n <MButton label=\"small\" size=\"small\" severity=\"secondary\" />\n </MSpace>\n <MSpace size=\"medium\">\n <MButton label=\"medium\" size=\"small\" />\n <MButton label=\"medium\" size=\"small\" severity=\"secondary\" />\n </MSpace>\n <MSpace size=\"large\">\n <MButton label=\"large\" size=\"small\" />\n <MButton label=\"large\" size=\"small\" severity=\"secondary\" />\n </MSpace>\n <MSpace :size=\"20\">\n <MButton label=\"20px\" size=\"small\" />\n <MButton label=\"20px\" size=\"small\" severity=\"secondary\" />\n </MSpace>\n </div>\n</template>",
23614
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-4\">\n <MSpace size=\"small\">\n <MButton label=\"small\" size=\"small\" />\n <MButton label=\"small\" size=\"small\"/>\n </MSpace>\n <MSpace size=\"medium\">\n <MButton label=\"medium\" size=\"small\" />\n <MButton label=\"medium\" size=\"small\"/>\n </MSpace>\n <MSpace size=\"large\">\n <MButton label=\"large\" size=\"small\" />\n <MButton label=\"large\" size=\"small\"/>\n </MSpace>\n <MSpace :size=\"20\">\n <MButton label=\"20px\" size=\"small\" />\n <MButton label=\"20px\" size=\"small\"/>\n </MSpace>\n </div>\n</template>",
23388
23615
  "locale": "zh-CN"
23389
23616
  },
23390
23617
  {
@@ -23411,7 +23638,7 @@
23411
23638
  "sectionId": "basic",
23412
23639
  "lang": "vue",
23413
23640
  "preview": true,
23414
- "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <MSpace>\n <MButton label=\"Save\" size=\"small\" />\n <MButton label=\"Cancel\" size=\"small\" severity=\"secondary\" />\n <MButton label=\"Reset\" size=\"small\" severity=\"secondary\" />\n </MSpace>\n</template>",
23641
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <MSpace>\n <MButton label=\"Save\" size=\"small\" />\n <MButton label=\"Cancel\" size=\"small\"/>\n <MButton label=\"Reset\" size=\"small\"/>\n </MSpace>\n</template>",
23415
23642
  "locale": "en-US"
23416
23643
  },
23417
23644
  {
@@ -23429,7 +23656,7 @@
23429
23656
  "sectionId": "size",
23430
23657
  "lang": "vue",
23431
23658
  "preview": true,
23432
- "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-4\">\n <MSpace size=\"small\">\n <MButton label=\"small\" size=\"small\" />\n <MButton label=\"small\" size=\"small\" severity=\"secondary\" />\n </MSpace>\n <MSpace size=\"medium\">\n <MButton label=\"medium\" size=\"small\" />\n <MButton label=\"medium\" size=\"small\" severity=\"secondary\" />\n </MSpace>\n <MSpace size=\"large\">\n <MButton label=\"large\" size=\"small\" />\n <MButton label=\"large\" size=\"small\" severity=\"secondary\" />\n </MSpace>\n <MSpace :size=\"20\">\n <MButton label=\"20px\" size=\"small\" />\n <MButton label=\"20px\" size=\"small\" severity=\"secondary\" />\n </MSpace>\n </div>\n</template>",
23659
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MSpace } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"grid gap-4\">\n <MSpace size=\"small\">\n <MButton label=\"small\" size=\"small\" />\n <MButton label=\"small\" size=\"small\"/>\n </MSpace>\n <MSpace size=\"medium\">\n <MButton label=\"medium\" size=\"small\" />\n <MButton label=\"medium\" size=\"small\"/>\n </MSpace>\n <MSpace size=\"large\">\n <MButton label=\"large\" size=\"small\" />\n <MButton label=\"large\" size=\"small\"/>\n </MSpace>\n <MSpace :size=\"20\">\n <MButton label=\"20px\" size=\"small\" />\n <MButton label=\"20px\" size=\"small\"/>\n </MSpace>\n </div>\n</template>",
23433
23660
  "locale": "en-US"
23434
23661
  },
23435
23662
  {
@@ -23853,13 +24080,13 @@
23853
24080
  "description": "菜单项。"
23854
24081
  },
23855
24082
  {
23856
- "name": "severity",
24083
+ "name": "color",
23857
24084
  "type": "—",
23858
24085
  "default": "—",
23859
24086
  "description": "视觉变体。"
23860
24087
  },
23861
24088
  {
23862
- "name": "outlined",
24089
+ "name": "variant",
23863
24090
  "type": "—",
23864
24091
  "default": "—",
23865
24092
  "description": "视觉变体。"
@@ -23981,7 +24208,7 @@
23981
24208
  {
23982
24209
  "id": "props",
23983
24210
  "title": "Props",
23984
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 主按钮文案。 |\n| `icon` | `string` | — | 可选图标字符。 |\n| `model` | `{ label, command?, disabled? }[]` | `[]` | 菜单项。 |\n| `severity` / `outlined` / `size` | — | — | 视觉变体。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `teleport` | `boolean` | `true` | 是否将菜单 Teleport 出去。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | 挂载目标;`'self'` 表示就地渲染。 |\n| `transition` | `string \\| false` | `'scale-fade'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
24211
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 主按钮文案。 |\n| `icon` | `string` | — | 可选图标字符。 |\n| `model` | `{ label, command?, disabled? }[]` | `[]` | 菜单项。 |\n| `color` / `variant` / `size` | — | — | 视觉变体。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `teleport` | `boolean` | `true` | 是否将菜单 Teleport 出去。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | 挂载目标;`'self'` 表示就地渲染。 |\n| `transition` | `string \\| false` | `'scale-fade'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
23985
24212
  },
23986
24213
  {
23987
24214
  "id": "events",
@@ -23994,7 +24221,7 @@
23994
24221
  "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 主按钮内容。 |"
23995
24222
  }
23996
24223
  ],
23997
- "markdown": "---\ntitle: SplitButton\ncategory: 01 / BASIC\ndescription: 主操作按钮附带下拉菜单项。\n---\n\n# SplitButton\n\n左侧主按钮触发 `click`,右侧展开菜单项触发 `command`。\n\n## 引入\n\n```ts\nimport { MSplitButton } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 主按钮文案。 |\n| `icon` | `string` | — | 可选图标字符。 |\n| `model` | `{ label, command?, disabled? }[]` | `[]` | 菜单项。 |\n| `severity` / `outlined` / `size` | — | — | 视觉变体。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `teleport` | `boolean` | `true` | 是否将菜单 Teleport 出去。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | 挂载目标;`'self'` 表示就地渲染。 |\n| `transition` | `string \\| false` | `'scale-fade'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `click` | `MouseEvent` | 主按钮点击。 |\n| `command` | `item` | 菜单项激活。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 主按钮内容。 |\n"
24224
+ "markdown": "---\ntitle: SplitButton\ncategory: 01 / BASIC\ndescription: 主操作按钮附带下拉菜单项。\n---\n\n# SplitButton\n\n左侧主按钮触发 `click`,右侧展开菜单项触发 `command`。\n\n## 引入\n\n```ts\nimport { MSplitButton } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 主按钮文案。 |\n| `icon` | `string` | — | 可选图标字符。 |\n| `model` | `{ label, command?, disabled? }[]` | `[]` | 菜单项。 |\n| `color` / `variant` / `size` | — | — | 视觉变体。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `teleport` | `boolean` | `true` | 是否将菜单 Teleport 出去。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | 挂载目标;`'self'` 表示就地渲染。 |\n| `transition` | `string \\| false` | `'scale-fade'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `click` | `MouseEvent` | 主按钮点击。 |\n| `command` | `item` | 菜单项激活。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 主按钮内容。 |\n"
23998
24225
  },
23999
24226
  "en-US": {
24000
24227
  "title": "SplitButton",
@@ -24018,7 +24245,7 @@
24018
24245
  {
24019
24246
  "id": "props",
24020
24247
  "title": "Props",
24021
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `label` | `string` | — | Primary button label. |\n| `icon` | `string` | — | Optional icon character. |\n| `model` | `{ label, command?, disabled? }[]` | `[]` | Menu items. |\n| `severity` / `outlined` / `size` | — | — | Visual variants. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `teleport` | `boolean` | `true` | Whether to Teleport the menu. |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | Mount target; `'self'` keeps it in place. |\n| `transition` | `string \\| false` | `'scale-fade'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
24248
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `label` | `string` | — | Primary button label. |\n| `icon` | `string` | — | Optional icon character. |\n| `model` | `{ label, command?, disabled? }[]` | `[]` | Menu items. |\n| `color` / `variant` / `size` | — | — | Visual variants. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `teleport` | `boolean` | `true` | Whether to Teleport the menu. |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | Mount target; `'self'` keeps it in place. |\n| `transition` | `string \\| false` | `'scale-fade'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
24022
24249
  },
24023
24250
  {
24024
24251
  "id": "events",
@@ -24031,7 +24258,7 @@
24031
24258
  "body": "| Slot | Description |\n| --- | --- |\n| `default` | Main button content. |"
24032
24259
  }
24033
24260
  ],
24034
- "markdown": "---\ntitle: SplitButton\ncategory: 01 / BASIC\ndescription: A primary action button with extra dropdown items.\n---\n\n# SplitButton\n\nThe left primary button emits `click`; items in the right-side menu emit `command`.\n\n## Import\n\n```ts\nimport { MSplitButton } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `label` | `string` | — | Primary button label. |\n| `icon` | `string` | — | Optional icon character. |\n| `model` | `{ label, command?, disabled? }[]` | `[]` | Menu items. |\n| `severity` / `outlined` / `size` | — | — | Visual variants. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `teleport` | `boolean` | `true` | Whether to Teleport the menu. |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | Mount target; `'self'` keeps it in place. |\n| `transition` | `string \\| false` | `'scale-fade'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\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| `click` | `MouseEvent` | Primary button click. |\n| `command` | `item` | Menu item activated. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Main button content. |\n"
24261
+ "markdown": "---\ntitle: SplitButton\ncategory: 01 / BASIC\ndescription: A primary action button with extra dropdown items.\n---\n\n# SplitButton\n\nThe left primary button emits `click`; items in the right-side menu emit `command`.\n\n## Import\n\n```ts\nimport { MSplitButton } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `label` | `string` | — | Primary button label. |\n| `icon` | `string` | — | Optional icon character. |\n| `model` | `{ label, command?, disabled? }[]` | `[]` | Menu items. |\n| `color` / `variant` / `size` | — | — | Visual variants. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `teleport` | `boolean` | `true` | Whether to Teleport the menu. |\n| `appendTo` | `string \\| HTMLElement \\| 'self'` | `'body'` | Mount target; `'self'` keeps it in place. |\n| `transition` | `string \\| false` | `'scale-fade'` | Enter/exit motion preset; `false` / `'none'` disables. See [Motion](/docs/motion). |\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| `click` | `MouseEvent` | Primary button click. |\n| `command` | `item` | Menu item activated. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Main button content. |\n"
24035
24262
  }
24036
24263
  }
24037
24264
  },
@@ -26926,7 +27153,7 @@
26926
27153
  "sectionId": "card-closable-extra",
26927
27154
  "lang": "vue",
26928
27155
  "preview": true,
26929
- "code": "<script setup lang=\"ts\">\nimport { MButton, MTabs } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst active = ref('a')\nconst tabs = ref([\n { label: '设计', value: 'a' },\n { label: '数据', value: 'b' },\n { label: '发布', value: 'c' },\n])\n\nfunction onClose(value: string) {\n tabs.value = tabs.value.filter((tab) => tab.value !== value)\n}\n\nfunction onAdd() {\n const value = `tab-${tabs.value.length + 1}`\n tabs.value = [...tabs.value, { label: `Tab ${tabs.value.length + 1}`, value }]\n active.value = value\n}\n</script>\n\n<template>\n <MTabs\n v-model=\"active\"\n type=\"card\"\n closable\n addable\n :tabs=\"tabs\"\n @close=\"onClose\"\n @add=\"onAdd\"\n >\n <template #extra>\n <MButton label=\"操作\" size=\"small\" severity=\"secondary\" />\n </template>\n <template #default=\"{ activeValue }\">\n <p style=\"margin:0\">\n {{ activeValue }}\n </p>\n </template>\n </MTabs>\n</template>",
27156
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MTabs } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst active = ref('a')\nconst tabs = ref([\n { label: '设计', value: 'a' },\n { label: '数据', value: 'b' },\n { label: '发布', value: 'c' },\n])\n\nfunction onClose(value: string) {\n tabs.value = tabs.value.filter((tab) => tab.value !== value)\n}\n\nfunction onAdd() {\n const value = `tab-${tabs.value.length + 1}`\n tabs.value = [...tabs.value, { label: `Tab ${tabs.value.length + 1}`, value }]\n active.value = value\n}\n</script>\n\n<template>\n <MTabs\n v-model=\"active\"\n type=\"card\"\n closable\n addable\n :tabs=\"tabs\"\n @close=\"onClose\"\n @add=\"onAdd\"\n >\n <template #extra>\n <MButton label=\"操作\" size=\"small\"/>\n </template>\n <template #default=\"{ activeValue }\">\n <p style=\"margin:0\">\n {{ activeValue }}\n </p>\n </template>\n </MTabs>\n</template>",
26930
27157
  "locale": "zh-CN"
26931
27158
  },
26932
27159
  {
@@ -26962,7 +27189,7 @@
26962
27189
  "sectionId": "card-closable-extra",
26963
27190
  "lang": "vue",
26964
27191
  "preview": true,
26965
- "code": "<script setup lang=\"ts\">\nimport { MButton, MTabs } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst active = ref('a')\nconst tabs = ref([\n { label: 'Design', value: 'a' },\n { label: 'Data', value: 'b' },\n { label: 'Ship', value: 'c' },\n])\n\nfunction onClose(value: string) {\n tabs.value = tabs.value.filter((tab) => tab.value !== value)\n}\n\nfunction onAdd() {\n const value = `tab-${tabs.value.length + 1}`\n tabs.value = [...tabs.value, { label: `Tab ${tabs.value.length + 1}`, value }]\n active.value = value\n}\n</script>\n\n<template>\n <MTabs\n v-model=\"active\"\n type=\"card\"\n closable\n addable\n :tabs=\"tabs\"\n @close=\"onClose\"\n @add=\"onAdd\"\n >\n <template #extra>\n <MButton label=\"Action\" size=\"small\" severity=\"secondary\" />\n </template>\n <template #default=\"{ activeValue }\">\n <p style=\"margin:0\">\n {{ activeValue }}\n </p>\n </template>\n </MTabs>\n</template>",
27192
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MTabs } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst active = ref('a')\nconst tabs = ref([\n { label: 'Design', value: 'a' },\n { label: 'Data', value: 'b' },\n { label: 'Ship', value: 'c' },\n])\n\nfunction onClose(value: string) {\n tabs.value = tabs.value.filter((tab) => tab.value !== value)\n}\n\nfunction onAdd() {\n const value = `tab-${tabs.value.length + 1}`\n tabs.value = [...tabs.value, { label: `Tab ${tabs.value.length + 1}`, value }]\n active.value = value\n}\n</script>\n\n<template>\n <MTabs\n v-model=\"active\"\n type=\"card\"\n closable\n addable\n :tabs=\"tabs\"\n @close=\"onClose\"\n @add=\"onAdd\"\n >\n <template #extra>\n <MButton label=\"Action\" size=\"small\"/>\n </template>\n <template #default=\"{ activeValue }\">\n <p style=\"margin:0\">\n {{ activeValue }}\n </p>\n </template>\n </MTabs>\n</template>",
26966
27193
  "locale": "en-US"
26967
27194
  },
26968
27195
  {
@@ -27146,6 +27373,12 @@
27146
27373
  "type": "boolean",
27147
27374
  "default": "false",
27148
27375
  "description": "选中态;配合 `v-model:checked`。"
27376
+ },
27377
+ {
27378
+ "name": "pt",
27379
+ "type": "[RootPassThrough](/docs/types#RootPassThrough) `{ root? }",
27380
+ "default": "—",
27381
+ "description": "DOM 透传,见 [样式与 attrs](/docs/attrs)."
27149
27382
  }
27150
27383
  ],
27151
27384
  "events": [
@@ -27348,7 +27581,7 @@
27348
27581
  {
27349
27582
  "id": "props",
27350
27583
  "title": "Props",
27351
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `string` | — | 标签文案。存在默认插槽内容时以插槽为准。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | 语义色。`warning` 为兼容别名,映射为 `warn`。 |\n| `rounded` | `boolean` | `false` | 全圆角。 |\n| `icon` | [IconName](/docs/types#IconName) | — | `MIcon` 图标名称。 |\n| `closable` | `boolean` | `false` | 显示关闭按钮(`checkable` 时忽略)。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n| `bordered` | `boolean` | `false` | 描边。 |\n| `color` | `string` | — | 自定义颜色。 |\n| `disabled` | `boolean` | `false` | 禁用交互。 |\n| `checkable` | `boolean` | `false` | 可切换选中。 |\n| `checked` | `boolean` | `false` | 选中态;配合 `v-model:checked`。 |"
27584
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `string` | — | 标签文案。存在默认插槽内容时以插槽为准。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | 语义色。`warning` 为兼容别名,映射为 `warn`。 |\n| `rounded` | `boolean` | `false` | 全圆角。 |\n| `icon` | [IconName](/docs/types#IconName) | — | `MIcon` 图标名称。 |\n| `closable` | `boolean` | `false` | 显示关闭按钮(`checkable` 时忽略)。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n| `bordered` | `boolean` | `false` | 描边。 |\n| `color` | `string` | — | 自定义颜色。 |\n| `disabled` | `boolean` | `false` | 禁用交互。 |\n| `checkable` | `boolean` | `false` | 可切换选中。 |\n| `checked` | `boolean` | `false` | 选中态;配合 `v-model:checked`。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
27352
27585
  },
27353
27586
  {
27354
27587
  "id": "events",
@@ -27361,7 +27594,7 @@
27361
27594
  "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 标签内容,优先于 `value`。 |"
27362
27595
  }
27363
27596
  ],
27364
- "markdown": "---\ntitle: Tag\ncategory: 01 / BASIC\ndescription: 标签用于展示状态或分类。\n---\n\n# Tag\n\n标签用于展示状态或分类。\n\n## 引入\n\n```ts\nimport { MTag } from 'morya-ui'\n```\n\n## 基础用法\n\n通过 `value` 或默认插槽展示文案。\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\n使用 `severity` 定义语义色;省略时为 primary。兼容旧值 `warning`(映射为 `warn`)。\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Icons\n\n`icon` 传入 `MIcon` 的图标名称。\n\n```vue preview src=\"./demos/Icons.vue\"\n```\n\n## Bordered\n\n`bordered` 使用色调描边。默认无描边、填充色调背景。\n\n```vue preview src=\"./demos/Bordered.vue\"\n```\n\n## Closable\n\n```vue preview src=\"./demos/Closable.vue\"\n```\n\n## Checkable\n\n`checkable` + `v-model:checked` 可切换选中。与 `closable` 同时设置时关闭按钮不显示。\n\n```vue preview src=\"./demos/Checkable.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `string` | — | 标签文案。存在默认插槽内容时以插槽为准。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | 语义色。`warning` 为兼容别名,映射为 `warn`。 |\n| `rounded` | `boolean` | `false` | 全圆角。 |\n| `icon` | [IconName](/docs/types#IconName) | — | `MIcon` 图标名称。 |\n| `closable` | `boolean` | `false` | 显示关闭按钮(`checkable` 时忽略)。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n| `bordered` | `boolean` | `false` | 描边。 |\n| `color` | `string` | — | 自定义颜色。 |\n| `disabled` | `boolean` | `false` | 禁用交互。 |\n| `checkable` | `boolean` | `false` | 可切换选中。 |\n| `checked` | `boolean` | `false` | 选中态;配合 `v-model:checked`。 |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `close` | `MouseEvent` | 点击关闭。 |\n| `update:checked` | `boolean` | 选中态变更(`v-model:checked`)。 |\n| `change` | `boolean` | 选中态变更。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 标签内容,优先于 `value`。 |\n"
27597
+ "markdown": "---\ntitle: Tag\ncategory: 01 / BASIC\ndescription: 标签用于展示状态或分类。\n---\n\n# Tag\n\n标签用于展示状态或分类。\n\n## 引入\n\n```ts\nimport { MTag } from 'morya-ui'\n```\n\n## 基础用法\n\n通过 `value` 或默认插槽展示文案。\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\n使用 `severity` 定义语义色;省略时为 primary。兼容旧值 `warning`(映射为 `warn`)。\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Icons\n\n`icon` 传入 `MIcon` 的图标名称。\n\n```vue preview src=\"./demos/Icons.vue\"\n```\n\n## Bordered\n\n`bordered` 使用色调描边。默认无描边、填充色调背景。\n\n```vue preview src=\"./demos/Bordered.vue\"\n```\n\n## Closable\n\n```vue preview src=\"./demos/Closable.vue\"\n```\n\n## Checkable\n\n`checkable` + `v-model:checked` 可切换选中。与 `closable` 同时设置时关闭按钮不显示。\n\n```vue preview src=\"./demos/Checkable.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `value` | `string` | — | 标签文案。存在默认插槽内容时以插槽为准。 |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | 语义色。`warning` 为兼容别名,映射为 `warn`。 |\n| `rounded` | `boolean` | `false` | 全圆角。 |\n| `icon` | [IconName](/docs/types#IconName) | — | `MIcon` 图标名称。 |\n| `closable` | `boolean` | `false` | 显示关闭按钮(`checkable` 时忽略)。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。 |\n| `bordered` | `boolean` | `false` | 描边。 |\n| `color` | `string` | — | 自定义颜色。 |\n| `disabled` | `boolean` | `false` | 禁用交互。 |\n| `checkable` | `boolean` | `false` | 可切换选中。 |\n| `checked` | `boolean` | `false` | 选中态;配合 `v-model:checked`。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `close` | `MouseEvent` | 点击关闭。 |\n| `update:checked` | `boolean` | 选中态变更(`v-model:checked`)。 |\n| `change` | `boolean` | 选中态变更。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 标签内容,优先于 `value`。 |\n"
27365
27598
  },
27366
27599
  "en-US": {
27367
27600
  "title": "Tag",
@@ -27410,7 +27643,7 @@
27410
27643
  {
27411
27644
  "id": "props",
27412
27645
  "title": "Props",
27413
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `string` | 鈥?| Tag text. The default slot takes precedence when present. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | Semantic color. `warning` is a compatibility alias mapped to `warn`. |\n| `rounded` | `boolean` | `false` | Fully rounded. |\n| `icon` | [IconName](/docs/types#IconName) | 鈥?| `MIcon` icon name. |\n| `closable` | `boolean` | `false` | Show a close control (ignored when `checkable`). |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size. |\n| `bordered` | `boolean` | `false` | Draw a border. |\n| `color` | `string` | 鈥?| Custom color. |\n| `disabled` | `boolean` | `false` | Disable interaction. |\n| `checkable` | `boolean` | `false` | Toggleable selection. |\n| `checked` | `boolean` | `false` | Checked state; use with `v-model:checked`. |"
27646
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `string` | 鈥?| Tag text. The default slot takes precedence when present. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | Semantic color. `warning` is a compatibility alias mapped to `warn`. |\n| `rounded` | `boolean` | `false` | Fully rounded. |\n| `icon` | [IconName](/docs/types#IconName) | 鈥?| `MIcon` icon name. |\n| `closable` | `boolean` | `false` | Show a close control (ignored when `checkable`). |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size. |\n| `bordered` | `boolean` | `false` | Draw a border. |\n| `color` | `string` | 鈥?| Custom color. |\n| `disabled` | `boolean` | `false` | Disable interaction. |\n| `checkable` | `boolean` | `false` | Toggleable selection. |\n| `checked` | `boolean` | `false` | Checked state; use with `v-model:checked`. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |"
27414
27647
  },
27415
27648
  {
27416
27649
  "id": "events",
@@ -27423,7 +27656,7 @@
27423
27656
  "body": "| Slot | Description |\n| --- | --- |\n| `default` | Tag content; takes precedence over `value`. |"
27424
27657
  }
27425
27658
  ],
27426
- "markdown": "---\ntitle: Tag\ncategory: 01 / BASIC\ndescription: Tag for status or category.\n---\n\n# Tag\n\nTags display status or category.\n\n## Import\n\n```ts\nimport { MTag } from 'morya-ui'\n```\n\n## Basic\n\nShow text via `value` or the default slot.\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\nUse `severity` for semantic color; defaults to primary when omitted. The legacy value `warning` is mapped to `warn`.\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Icons\n\nPass a `MIcon` icon name to `icon`.\n\n```vue preview src=\"./demos/Icons.vue\"\n```\n\n## Bordered\n\n`bordered` draws a tone-colored outline. Default is borderless with a filled tone background.\n\n```vue preview src=\"./demos/Bordered.vue\"\n```\n\n## Closable\n\n```vue preview src=\"./demos/Closable.vue\"\n```\n\n## Checkable\n\n`checkable` + `v-model:checked` toggles selection. When combined with `closable`, the close control is hidden.\n\n```vue preview src=\"./demos/Checkable.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `string` | 鈥?| Tag text. The default slot takes precedence when present. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | Semantic color. `warning` is a compatibility alias mapped to `warn`. |\n| `rounded` | `boolean` | `false` | Fully rounded. |\n| `icon` | [IconName](/docs/types#IconName) | 鈥?| `MIcon` icon name. |\n| `closable` | `boolean` | `false` | Show a close control (ignored when `checkable`). |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size. |\n| `bordered` | `boolean` | `false` | Draw a border. |\n| `color` | `string` | 鈥?| Custom color. |\n| `disabled` | `boolean` | `false` | Disable interaction. |\n| `checkable` | `boolean` | `false` | Toggleable selection. |\n| `checked` | `boolean` | `false` | Checked state; use with `v-model:checked`. |\n\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `close` | `MouseEvent` | Fired when close is clicked. |\n| `update:checked` | `boolean` | Checked state change (`v-model:checked`). |\n| `change` | `boolean` | Checked state change. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Tag content; takes precedence over `value`. |\n"
27659
+ "markdown": "---\ntitle: Tag\ncategory: 01 / BASIC\ndescription: Tag for status or category.\n---\n\n# Tag\n\nTags display status or category.\n\n## Import\n\n```ts\nimport { MTag } from 'morya-ui'\n```\n\n## Basic\n\nShow text via `value` or the default slot.\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\nUse `severity` for semantic color; defaults to primary when omitted. The legacy value `warning` is mapped to `warn`.\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Icons\n\nPass a `MIcon` icon name to `icon`.\n\n```vue preview src=\"./demos/Icons.vue\"\n```\n\n## Bordered\n\n`bordered` draws a tone-colored outline. Default is borderless with a filled tone background.\n\n```vue preview src=\"./demos/Bordered.vue\"\n```\n\n## Closable\n\n```vue preview src=\"./demos/Closable.vue\"\n```\n\n## Checkable\n\n`checkable` + `v-model:checked` toggles selection. When combined with `closable`, the close control is hidden.\n\n```vue preview src=\"./demos/Checkable.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `value` | `string` | 鈥?| Tag text. The default slot takes precedence when present. |\n| `severity` | `'primary' \\| 'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast' \\| 'warning'` | `'primary'` | Semantic color. `warning` is a compatibility alias mapped to `warn`. |\n| `rounded` | `boolean` | `false` | Fully rounded. |\n| `icon` | [IconName](/docs/types#IconName) | 鈥?| `MIcon` icon name. |\n| `closable` | `boolean` | `false` | Show a close control (ignored when `checkable`). |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | 鈥?| Size. |\n| `bordered` | `boolean` | `false` | Draw a border. |\n| `color` | `string` | 鈥?| Custom color. |\n| `disabled` | `boolean` | `false` | Disable interaction. |\n| `checkable` | `boolean` | `false` | Toggleable selection. |\n| `checked` | `boolean` | `false` | Checked state; use with `v-model:checked`. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `close` | `MouseEvent` | Fired when close is clicked. |\n| `update:checked` | `boolean` | Checked state change (`v-model:checked`). |\n| `change` | `boolean` | Checked state change. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Tag content; takes precedence over `value`. |\n"
27427
27660
  }
27428
27661
  }
27429
27662
  },
@@ -28932,7 +29165,7 @@
28932
29165
  "sectionId": "api",
28933
29166
  "lang": "vue",
28934
29167
  "preview": true,
28935
- "code": "<script setup lang=\"ts\">\nimport { MButton, toast } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton\n label=\"Success\"\n severity=\"success\"\n @click=\"toast.success({ summary: '已保存', detail: '变更已生效。' })\"\n />\n <MButton\n label=\"Info\"\n severity=\"info\"\n @click=\"toast.info({ summary: '提示', detail: '可以继续操作。' })\"\n />\n <MButton\n label=\"Warn\"\n severity=\"warn\"\n @click=\"toast.warn({ summary: '注意', detail: '请再核对一次。' })\"\n />\n <MButton\n label=\"Error\"\n severity=\"danger\"\n @click=\"toast.error({ summary: '失败', detail: '请稍后重试。' })\"\n />\n </div>\n</template>",
29168
+ "code": "<script setup lang=\"ts\">\nimport { MButton, toast } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Success\" @click=\"toast.success({ summary: '已保存', detail: '变更已生效。' })\" color=\"success\" variant=\"solid\"/>\n <MButton label=\"Info\" @click=\"toast.info({ summary: '提示', detail: '可以继续操作。' })\" color=\"info\" variant=\"solid\"/>\n <MButton label=\"Warn\" @click=\"toast.warn({ summary: '注意', detail: '请再核对一次。' })\" color=\"warning\" variant=\"solid\"/>\n <MButton label=\"Error\" @click=\"toast.error({ summary: '失败', detail: '请稍后重试。' })\" danger type=\"primary\"/>\n </div>\n</template>",
28936
29169
  "locale": "zh-CN"
28937
29170
  },
28938
29171
  {
@@ -28950,7 +29183,7 @@
28950
29183
  "sectionId": "controlled",
28951
29184
  "lang": "vue",
28952
29185
  "preview": true,
28953
- "code": "<script setup lang=\"ts\">\nimport type { ToastMessage } from 'morya-ui'\nimport { MButton, MToast } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst messages = ref<ToastMessage[]>([])\nlet seq = 0\n\nfunction push(severity: ToastMessage['severity'], summary: string, detail?: string) {\n messages.value = [\n ...messages.value,\n { id: `toast-${++seq}`, summary, detail, severity, life: 0 },\n ]\n}\n\nfunction onClose(message: ToastMessage) {\n messages.value = messages.value.filter((item) => item.id !== message.id)\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Success\" severity=\"success\" @click=\"push('success', 'Saved', 'Your changes are live.')\" />\n <MButton label=\"Info\" severity=\"info\" @click=\"push('info', 'Tip', 'Something to know.')\" />\n </div>\n <MToast :messages=\"messages\" position=\"top-right\" @close=\"onClose\" />\n</template>",
29186
+ "code": "<script setup lang=\"ts\">\nimport type { ToastMessage } from 'morya-ui'\nimport { MButton, MToast } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst messages = ref<ToastMessage[]>([])\nlet seq = 0\n\nfunction push(severity: ToastMessage['severity'], summary: string, detail?: string) {\n messages.value = [\n ...messages.value,\n { id: `toast-${++seq}`, summary, detail, severity, life: 0 },\n ]\n}\n\nfunction onClose(message: ToastMessage) {\n messages.value = messages.value.filter((item) => item.id !== message.id)\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Success\" @click=\"push('success', 'Saved', 'Your changes are live.')\" color=\"success\" variant=\"solid\"/>\n <MButton label=\"Info\" @click=\"push('info', 'Tip', 'Something to know.')\" color=\"info\" variant=\"solid\"/>\n </div>\n <MToast :messages=\"messages\" position=\"top-right\" @close=\"onClose\" />\n</template>",
28954
29187
  "locale": "zh-CN"
28955
29188
  },
28956
29189
  {
@@ -28986,7 +29219,7 @@
28986
29219
  "sectionId": "api",
28987
29220
  "lang": "vue",
28988
29221
  "preview": true,
28989
- "code": "<script setup lang=\"ts\">\nimport { MButton, toast } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton\n label=\"Success\"\n severity=\"success\"\n @click=\"toast.success({ summary: 'Saved', detail: 'Your changes are live.' })\"\n />\n <MButton\n label=\"Info\"\n severity=\"info\"\n @click=\"toast.info({ summary: 'Tip', detail: 'You can continue.' })\"\n />\n <MButton\n label=\"Warn\"\n severity=\"warn\"\n @click=\"toast.warn({ summary: 'Caution', detail: 'Please double-check.' })\"\n />\n <MButton\n label=\"Error\"\n severity=\"danger\"\n @click=\"toast.error({ summary: 'Failed', detail: 'Try again later.' })\"\n />\n </div>\n</template>",
29222
+ "code": "<script setup lang=\"ts\">\nimport { MButton, toast } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Success\" @click=\"toast.success({ summary: 'Saved', detail: 'Your changes are live.' })\" color=\"success\" variant=\"solid\"/>\n <MButton label=\"Info\" @click=\"toast.info({ summary: 'Tip', detail: 'You can continue.' })\" color=\"info\" variant=\"solid\"/>\n <MButton label=\"Warn\" @click=\"toast.warn({ summary: 'Caution', detail: 'Please double-check.' })\" color=\"warning\" variant=\"solid\"/>\n <MButton label=\"Error\" @click=\"toast.error({ summary: 'Failed', detail: 'Try again later.' })\" danger type=\"primary\"/>\n </div>\n</template>",
28990
29223
  "locale": "en-US"
28991
29224
  },
28992
29225
  {
@@ -29004,7 +29237,7 @@
29004
29237
  "sectionId": "controlled",
29005
29238
  "lang": "vue",
29006
29239
  "preview": true,
29007
- "code": "<script setup lang=\"ts\">\nimport type { ToastMessage } from 'morya-ui'\nimport { MButton, MToast } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst messages = ref<ToastMessage[]>([])\nlet seq = 0\n\nfunction push(severity: ToastMessage['severity'], summary: string, detail?: string) {\n messages.value = [\n ...messages.value,\n { id: `toast-${++seq}`, summary, detail, severity, life: 0 },\n ]\n}\n\nfunction onClose(message: ToastMessage) {\n messages.value = messages.value.filter((item) => item.id !== message.id)\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Success\" severity=\"success\" @click=\"push('success', 'Saved', 'Your changes are live.')\" />\n <MButton label=\"Info\" severity=\"info\" @click=\"push('info', 'Tip', 'Something to know.')\" />\n </div>\n <MToast :messages=\"messages\" position=\"top-right\" @close=\"onClose\" />\n</template>",
29240
+ "code": "<script setup lang=\"ts\">\nimport type { ToastMessage } from 'morya-ui'\nimport { MButton, MToast } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst messages = ref<ToastMessage[]>([])\nlet seq = 0\n\nfunction push(severity: ToastMessage['severity'], summary: string, detail?: string) {\n messages.value = [\n ...messages.value,\n { id: `toast-${++seq}`, summary, detail, severity, life: 0 },\n ]\n}\n\nfunction onClose(message: ToastMessage) {\n messages.value = messages.value.filter((item) => item.id !== message.id)\n}\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-3 items-center\">\n <MButton label=\"Success\" @click=\"push('success', 'Saved', 'Your changes are live.')\" color=\"success\" variant=\"solid\"/>\n <MButton label=\"Info\" @click=\"push('info', 'Tip', 'Something to know.')\" color=\"info\" variant=\"solid\"/>\n </div>\n <MToast :messages=\"messages\" position=\"top-right\" @close=\"onClose\" />\n</template>",
29008
29241
  "locale": "en-US"
29009
29242
  },
29010
29243
  {
@@ -29416,7 +29649,7 @@
29416
29649
  "sectionId": "基础用法",
29417
29650
  "lang": "vue",
29418
29651
  "preview": true,
29419
- "code": "<script setup lang=\"ts\">\nimport { MButton, MToolbar } from 'morya-ui'\n</script>\n\n<template>\n <MToolbar>\n <template #start>\n <MButton label=\"新建\" size=\"small\" />\n </template>\n <template #center>\n <span>工具栏</span>\n </template>\n <template #end>\n <MButton label=\"导出\" severity=\"secondary\" size=\"small\" />\n </template>\n </MToolbar>\n</template>",
29652
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MToolbar } from 'morya-ui'\n</script>\n\n<template>\n <MToolbar>\n <template #start>\n <MButton label=\"新建\" size=\"small\" />\n </template>\n <template #center>\n <span>工具栏</span>\n </template>\n <template #end>\n <MButton label=\"导出\" size=\"small\"/>\n </template>\n </MToolbar>\n</template>",
29420
29653
  "locale": "zh-CN"
29421
29654
  },
29422
29655
  {
@@ -29434,7 +29667,7 @@
29434
29667
  "sectionId": "basic",
29435
29668
  "lang": "vue",
29436
29669
  "preview": true,
29437
- "code": "<script setup lang=\"ts\">\nimport { MButton, MToolbar } from 'morya-ui'\n</script>\n\n<template>\n <MToolbar>\n <template #start>\n <MButton label=\"New\" size=\"small\" />\n </template>\n <template #center>\n <span>Toolbar</span>\n </template>\n <template #end>\n <MButton label=\"Export\" severity=\"secondary\" size=\"small\" />\n </template>\n </MToolbar>\n</template>",
29670
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MToolbar } from 'morya-ui'\n</script>\n\n<template>\n <MToolbar>\n <template #start>\n <MButton label=\"New\" size=\"small\" />\n </template>\n <template #center>\n <span>Toolbar</span>\n </template>\n <template #end>\n <MButton label=\"Export\" size=\"small\"/>\n </template>\n </MToolbar>\n</template>",
29438
29671
  "locale": "en-US"
29439
29672
  }
29440
29673
  ],
@@ -29603,7 +29836,7 @@
29603
29836
  "sectionId": "基础用法",
29604
29837
  "lang": "vue",
29605
29838
  "preview": true,
29606
- "code": "<script setup lang=\"ts\">\nimport { MButton, MTooltip } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MTooltip content=\"Save changes\" placement=\"top\">\n <MButton icon=\"check\" icon-only aria-label=\"Save\" />\n </MTooltip>\n <MTooltip content=\"Delete item\" placement=\"bottom\" :show-delay=\"200\" :hide-delay=\"120\" :max-width=\"160\">\n <MButton icon=\"trash\" icon-only severity=\"danger\" outlined aria-label=\"Delete\" />\n </MTooltip>\n </div>\n</template>",
29839
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MTooltip } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MTooltip content=\"Save changes\" placement=\"top\">\n <MButton icon=\"check\" icon-only aria-label=\"Save\" />\n </MTooltip>\n <MTooltip content=\"Delete item\" placement=\"bottom\" :show-delay=\"200\" :hide-delay=\"120\" :max-width=\"160\">\n <MButton icon=\"trash\" icon-only aria-label=\"Delete\" danger/>\n </MTooltip>\n </div>\n</template>",
29607
29840
  "locale": "zh-CN"
29608
29841
  },
29609
29842
  {
@@ -29621,7 +29854,7 @@
29621
29854
  "sectionId": "basic",
29622
29855
  "lang": "vue",
29623
29856
  "preview": true,
29624
- "code": "<script setup lang=\"ts\">\nimport { MButton, MTooltip } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MTooltip content=\"Save changes\" placement=\"top\">\n <MButton icon=\"check\" icon-only aria-label=\"Save\" />\n </MTooltip>\n <MTooltip content=\"Delete item\" placement=\"bottom\" :show-delay=\"200\" :hide-delay=\"120\" :max-width=\"160\">\n <MButton icon=\"trash\" icon-only severity=\"danger\" outlined aria-label=\"Delete\" />\n </MTooltip>\n </div>\n</template>",
29857
+ "code": "<script setup lang=\"ts\">\nimport { MButton, MTooltip } from 'morya-ui'\n</script>\n\n<template>\n <div class=\"flex flex-wrap gap-4 items-center\">\n <MTooltip content=\"Save changes\" placement=\"top\">\n <MButton icon=\"check\" icon-only aria-label=\"Save\" />\n </MTooltip>\n <MTooltip content=\"Delete item\" placement=\"bottom\" :show-delay=\"200\" :hide-delay=\"120\" :max-width=\"160\">\n <MButton icon=\"trash\" icon-only aria-label=\"Delete\" danger/>\n </MTooltip>\n </div>\n</template>",
29625
29858
  "locale": "en-US"
29626
29859
  }
29627
29860
  ],
@@ -29821,7 +30054,7 @@
29821
30054
  "sectionId": "基础用法",
29822
30055
  "lang": "vue",
29823
30056
  "preview": true,
29824
- "code": "<script setup lang=\"ts\">\nimport type { TourStep } from '../../types'\nimport { computed, ref } from 'vue'\nimport { MButton, MSpace, MTour } from 'morya-ui'\n\nconst open = ref(false)\nconst current = ref(0)\nconst firstEl = ref<HTMLElement | null>(null)\nconst secondEl = ref<HTMLElement | null>(null)\n\nfunction resolveEl(el: HTMLElement | { $el?: HTMLElement } | null) {\n if (!el) return null\n if (el instanceof HTMLElement) return el\n return el.$el ?? null\n}\n\nconst steps = computed((): TourStep[] => [\n {\n title: 'Primary action',\n description: 'This button starts the guided tour.',\n target: () => resolveEl(firstEl.value),\n },\n {\n title: 'Secondary',\n description: 'You can attach steps to any element.',\n target: () => resolveEl(secondEl.value),\n placement: 'bottom-start',\n },\n])\n</script>\n\n<template>\n <MSpace vertical>\n <MSpace>\n <span ref=\"firstEl\">\n <MButton\n severity=\"primary\"\n @click=\"open = true\"\n >\n Start tour\n </MButton>\n </span>\n <span ref=\"secondEl\">\n <MButton>\n Another control\n </MButton>\n </span>\n </MSpace>\n\n <MTour\n v-model:open=\"open\"\n v-model:current=\"current\"\n :steps=\"steps\"\n />\n </MSpace>\n</template>",
30057
+ "code": "<script setup lang=\"ts\">\nimport type { TourStep } from '../../types'\nimport { computed, ref } from 'vue'\nimport { MButton, MSpace, MTour } from 'morya-ui'\n\nconst open = ref(false)\nconst current = ref(0)\nconst firstEl = ref<HTMLElement | null>(null)\nconst secondEl = ref<HTMLElement | null>(null)\n\nfunction resolveEl(el: HTMLElement | { $el?: HTMLElement } | null) {\n if (!el) return null\n if (el instanceof HTMLElement) return el\n return el.$el ?? null\n}\n\nconst steps = computed((): TourStep[] => [\n {\n title: 'Primary action',\n description: 'This button starts the guided tour.',\n target: () => resolveEl(firstEl.value),\n },\n {\n title: 'Secondary',\n description: 'You can attach steps to any element.',\n target: () => resolveEl(secondEl.value),\n placement: 'bottom-start',\n },\n])\n</script>\n\n<template>\n <MSpace vertical>\n <MSpace>\n <span ref=\"firstEl\">\n <MButton @click=\"open = true\" type=\"primary\">\n Start tour\n </MButton>\n </span>\n <span ref=\"secondEl\">\n <MButton>\n Another control\n </MButton>\n </span>\n </MSpace>\n\n <MTour\n v-model:open=\"open\"\n v-model:current=\"current\"\n :steps=\"steps\"\n />\n </MSpace>\n</template>",
29825
30058
  "locale": "zh-CN"
29826
30059
  },
29827
30060
  {
@@ -29839,7 +30072,7 @@
29839
30072
  "sectionId": "basic",
29840
30073
  "lang": "vue",
29841
30074
  "preview": true,
29842
- "code": "<script setup lang=\"ts\">\nimport type { TourStep } from '../../types'\nimport { computed, ref } from 'vue'\nimport { MButton, MSpace, MTour } from 'morya-ui'\n\nconst open = ref(false)\nconst current = ref(0)\nconst firstEl = ref<HTMLElement | null>(null)\nconst secondEl = ref<HTMLElement | null>(null)\n\nfunction resolveEl(el: HTMLElement | { $el?: HTMLElement } | null) {\n if (!el) return null\n if (el instanceof HTMLElement) return el\n return el.$el ?? null\n}\n\nconst steps = computed((): TourStep[] => [\n {\n title: 'Primary action',\n description: 'This button starts the guided tour.',\n target: () => resolveEl(firstEl.value),\n },\n {\n title: 'Secondary',\n description: 'You can attach steps to any element.',\n target: () => resolveEl(secondEl.value),\n placement: 'bottom-start',\n },\n])\n</script>\n\n<template>\n <MSpace vertical>\n <MSpace>\n <span ref=\"firstEl\">\n <MButton\n severity=\"primary\"\n @click=\"open = true\"\n >\n Start tour\n </MButton>\n </span>\n <span ref=\"secondEl\">\n <MButton>\n Another control\n </MButton>\n </span>\n </MSpace>\n\n <MTour\n v-model:open=\"open\"\n v-model:current=\"current\"\n :steps=\"steps\"\n />\n </MSpace>\n</template>",
30075
+ "code": "<script setup lang=\"ts\">\nimport type { TourStep } from '../../types'\nimport { computed, ref } from 'vue'\nimport { MButton, MSpace, MTour } from 'morya-ui'\n\nconst open = ref(false)\nconst current = ref(0)\nconst firstEl = ref<HTMLElement | null>(null)\nconst secondEl = ref<HTMLElement | null>(null)\n\nfunction resolveEl(el: HTMLElement | { $el?: HTMLElement } | null) {\n if (!el) return null\n if (el instanceof HTMLElement) return el\n return el.$el ?? null\n}\n\nconst steps = computed((): TourStep[] => [\n {\n title: 'Primary action',\n description: 'This button starts the guided tour.',\n target: () => resolveEl(firstEl.value),\n },\n {\n title: 'Secondary',\n description: 'You can attach steps to any element.',\n target: () => resolveEl(secondEl.value),\n placement: 'bottom-start',\n },\n])\n</script>\n\n<template>\n <MSpace vertical>\n <MSpace>\n <span ref=\"firstEl\">\n <MButton @click=\"open = true\" type=\"primary\">\n Start tour\n </MButton>\n </span>\n <span ref=\"secondEl\">\n <MButton>\n Another control\n </MButton>\n </span>\n </MSpace>\n\n <MTour\n v-model:open=\"open\"\n v-model:current=\"current\"\n :steps=\"steps\"\n />\n </MSpace>\n</template>",
29843
30076
  "locale": "en-US"
29844
30077
  }
29845
30078
  ],
@@ -31874,7 +32107,7 @@
31874
32107
  "zh-CN": {
31875
32108
  "title": "设计语言",
31876
32109
  "description": "Morya 设计原则与 Design Spec 章节入口。",
31877
- "markdown": "---\ntitle: 设计语言\norder: 4.5\ndescription: Morya 设计原则与 Design Spec 章节入口。\n---\n\n# 设计语言\n\nMorya UI 是一套**令牌驱动**的 Vue 3 组件库:颜色、间距、圆角、字号与动效统一走 `--m-*`,交互词表用 `severity` / `variant` / `size`,全局行为由 `MConfigProvider`、`useTheme`、`useDensity`、`useMotion` 协同。\n\n本文是 Design Spec 总览。原则摘要来自仓库 [`design-kit/DESIGN.md`](https://github.com/morya-space/morya-ui/blob/main/design-kit/DESIGN.md);完整变量目录见 [设计令牌](/docs/design-tokens)。\n\n## 原则\n\n1. **组件优先**:交互与布局优先用库内 `M*`,避免手写等价 DOM。\n2. **令牌优先**:页面与业务样式只消费 `--m-*`;禁止在业务代码写裸 `#hex` / `rgb()`(换品牌改主题入口)。\n3. **语义一致**:主操作为默认 primary;破坏性操作用 `severity=\"danger\"` 或确认流。\n4. **可访问**:控件有可访问名称;纯图标按钮提供 `aria-label`;浮层可键盘关闭。\n5. **单一事实源**:API 以组件文档 / MCP 为准,勿臆造 prop。\n\n## 章节\n\n| 章节 | 内容 |\n| ------------------------------------- | ------------------------------------------ |\n| [色彩](/docs/design-color) | 品牌色、语义色、中性面、对比与覆盖 |\n| [字体与排版](/docs/design-typography) | 字号阶梯、字重、控件字号 |\n| [间距](/docs/design-spacing) | `--m-space-*` 节奏与密度缩放 |\n| [布局](/docs/design-layout) | `MLayout` / `MPage*` / `MSpace` 与页面框架 |\n| [动效](/docs/motion) | 设计原则、时长、缓动、减弱与 API |\n| [反馈](/docs/design-feedback) | Message / Toast / Dialog / Alert 层级 |\n\n工程接入另见 [主题](/docs/theme)、[全局配置](/docs/config)、[约定](/docs/conventions)、[Common Props](/docs/common-props)。\n\n## 主题编辑器\n\n在线调色、密度与动效预览:[主题编辑器](/theme-editor)(独立交互路由)。编程侧用 `createTheme` / `useTheme`,见 [主题](/docs/theme)。\n",
32110
+ "markdown": "---\ntitle: 设计语言\norder: 4.5\ndescription: Morya 设计原则与 Design Spec 章节入口。\n---\n\n# 设计语言\n\nMorya UI 是一套**令牌驱动**的 Vue 3 组件库:颜色、间距、圆角、字号与动效统一走 `--m-*`,交互词表用 `severity` / `variant` / `size`,全局行为由 `MConfigProvider`、`useTheme`、`useDensity`、`useMotion` 协同。\n\n本文是 Design Spec 总览。原则摘要来自仓库 [`design-kit/DESIGN.md`](https://github.com/morya-space/morya-ui/blob/main/design-kit/DESIGN.md);完整变量目录见 [设计令牌](/docs/design-tokens)。\n\n## 原则\n\n1. **组件优先**:交互与布局优先用库内 `M*`,避免手写等价 DOM。\n2. **令牌优先**:页面与业务样式只消费 `--m-*`;禁止在业务代码写裸 `#hex` / `rgb()`(换品牌改主题入口)。\n3. **语义一致**:主操作用 `type=\"primary\"`;破坏性操作用 `danger` / `color=\"danger\"` 或确认流。\n4. **可访问**:控件有可访问名称;纯图标按钮提供 `aria-label`;浮层可键盘关闭。\n5. **单一事实源**:API 以组件文档 / MCP 为准,勿臆造 prop。\n\n## 章节\n\n| 章节 | 内容 |\n| ------------------------------------- | ------------------------------------------ |\n| [色彩](/docs/design-color) | 品牌色、语义色、中性面、对比与覆盖 |\n| [字体与排版](/docs/design-typography) | 字号阶梯、字重、控件字号 |\n| [间距](/docs/design-spacing) | `--m-space-*` 节奏与密度缩放 |\n| [布局](/docs/design-layout) | `MLayout` / `MPage*` / `MSpace` 与页面框架 |\n| [动效](/docs/motion) | 设计原则、时长、缓动、减弱与 API |\n| [反馈](/docs/design-feedback) | Message / Toast / Dialog / Alert 层级 |\n\n工程接入另见 [主题](/docs/theme)、[全局配置](/docs/config)、[约定](/docs/conventions)、[Common Props](/docs/common-props)。\n\n## 主题编辑器\n\n在线调色、密度与动效预览:[主题编辑器](/theme-editor)(独立交互路由)。编程侧用 `createTheme` / `useTheme`,见 [主题](/docs/theme)。\n",
31878
32111
  "sections": [
31879
32112
  {
31880
32113
  "title": "",
@@ -31884,7 +32117,7 @@
31884
32117
  {
31885
32118
  "title": "原则",
31886
32119
  "id": "原则",
31887
- "body": "1. **组件优先**:交互与布局优先用库内 `M*`,避免手写等价 DOM。\n2. **令牌优先**:页面与业务样式只消费 `--m-*`;禁止在业务代码写裸 `#hex` / `rgb()`(换品牌改主题入口)。\n3. **语义一致**:主操作为默认 primary;破坏性操作用 `severity=\"danger\"` 或确认流。\n4. **可访问**:控件有可访问名称;纯图标按钮提供 `aria-label`;浮层可键盘关闭。\n5. **单一事实源**:API 以组件文档 / MCP 为准,勿臆造 prop。"
32120
+ "body": "1. **组件优先**:交互与布局优先用库内 `M*`,避免手写等价 DOM。\n2. **令牌优先**:页面与业务样式只消费 `--m-*`;禁止在业务代码写裸 `#hex` / `rgb()`(换品牌改主题入口)。\n3. **语义一致**:主操作用 `type=\"primary\"`;破坏性操作用 `danger` / `color=\"danger\"` 或确认流。\n4. **可访问**:控件有可访问名称;纯图标按钮提供 `aria-label`;浮层可键盘关闭。\n5. **单一事实源**:API 以组件文档 / MCP 为准,勿臆造 prop。"
31888
32121
  },
31889
32122
  {
31890
32123
  "title": "章节",
@@ -31901,7 +32134,7 @@
31901
32134
  "en-US": {
31902
32135
  "title": "Design language",
31903
32136
  "description": "Entry to Morya design principles and Design Spec chapters.",
31904
- "markdown": "---\ntitle: Design language\norder: 4.5\ndescription: Entry to Morya design principles and Design Spec chapters.\n---\n\n# Design language\n\nMorya UI is a **token-driven** Vue 3 library: color, spacing, radius, type, and motion share `--m-*` variables; interaction vocabulary uses `severity` / `variant` / `size`; global behavior is coordinated by `MConfigProvider`, `useTheme`, `useDensity`, and `useMotion`.\n\nThis page is the Design Spec hub. Principles come from [`design-kit/DESIGN.md`](https://github.com/morya-space/morya-ui/blob/main/design-kit/DESIGN.md); the full variable catalog is in [Design tokens](/docs/design-tokens).\n\n## Principles\n\n1. **Components first**: Prefer library `M*` controls over hand-rolled DOM equivalents.\n2. **Tokens first**: App styles consume `--m-*` only; no raw `#hex` / `rgb()` in product CSS (change brand at the theme entry).\n3. **Semantic consistency**: Primary actions default to primary; destructive work uses `severity=\"danger\"` or a confirm flow.\n4. **Accessibility**: Controls need accessible names; icon-only buttons need `aria-label`; overlays dismiss via keyboard.\n5. **Single source of truth**: Trust component docs / MCP for APIs; do not invent props.\n\n## Chapters\n\n| Chapter | Focus |\n| ------------------------------------- | ------------------------------------------------------------- |\n| [Color](/docs/design-color) | Brand, severity, neutrals, contrast, overrides |\n| [Typography](/docs/design-typography) | Type ramp, weights, control fonts |\n| [Spacing](/docs/design-spacing) | `--m-space-*` rhythm and density scaling |\n| [Layout](/docs/design-layout) | `MLayout` / `MPage*` / `MSpace` and app chrome |\n| [Motion](/docs/motion) | Design principles, duration, easing, reduced motion, and APIs |\n| [Feedback](/docs/design-feedback) | Message / Toast / Dialog / Alert hierarchy |\n\nEngineering guides: [Theme](/docs/theme), [Configuration](/docs/config), [Conventions](/docs/conventions), [Common Props](/docs/common-props).\n\n## Theme editor\n\nLive accent, density, and motion preview: [Theme editor](/theme-editor) (interactive route). Programmatic APIs: `createTheme` / `useTheme` — see [Theme](/docs/theme).\n",
32137
+ "markdown": "---\ntitle: Design language\norder: 4.5\ndescription: Entry to Morya design principles and Design Spec chapters.\n---\n\n# Design language\n\nMorya UI is a **token-driven** Vue 3 library: color, spacing, radius, type, and motion share `--m-*` variables; interaction vocabulary uses `severity` / `variant` / `size`; global behavior is coordinated by `MConfigProvider`, `useTheme`, `useDensity`, and `useMotion`.\n\nThis page is the Design Spec hub. Principles come from [`design-kit/DESIGN.md`](https://github.com/morya-space/morya-ui/blob/main/design-kit/DESIGN.md); the full variable catalog is in [Design tokens](/docs/design-tokens).\n\n## Principles\n\n1. **Components first**: Prefer library `M*` controls over hand-rolled DOM equivalents.\n2. **Tokens first**: App styles consume `--m-*` only; no raw `#hex` / `rgb()` in product CSS (change brand at the theme entry).\n3. **Semantic consistency**: Primary actions use `type=\"primary\"`; destructive work uses `danger` / `color=\"danger\"` or a confirm flow.\n4. **Accessibility**: Controls need accessible names; icon-only buttons need `aria-label`; overlays dismiss via keyboard.\n5. **Single source of truth**: Trust component docs / MCP for APIs; do not invent props.\n\n## Chapters\n\n| Chapter | Focus |\n| ------------------------------------- | ------------------------------------------------------------- |\n| [Color](/docs/design-color) | Brand, severity, neutrals, contrast, overrides |\n| [Typography](/docs/design-typography) | Type ramp, weights, control fonts |\n| [Spacing](/docs/design-spacing) | `--m-space-*` rhythm and density scaling |\n| [Layout](/docs/design-layout) | `MLayout` / `MPage*` / `MSpace` and app chrome |\n| [Motion](/docs/motion) | Design principles, duration, easing, reduced motion, and APIs |\n| [Feedback](/docs/design-feedback) | Message / Toast / Dialog / Alert hierarchy |\n\nEngineering guides: [Theme](/docs/theme), [Configuration](/docs/config), [Conventions](/docs/conventions), [Common Props](/docs/common-props).\n\n## Theme editor\n\nLive accent, density, and motion preview: [Theme editor](/theme-editor) (interactive route). Programmatic APIs: `createTheme` / `useTheme` — see [Theme](/docs/theme).\n",
31905
32138
  "sections": [
31906
32139
  {
31907
32140
  "title": "",
@@ -31911,7 +32144,7 @@
31911
32144
  {
31912
32145
  "title": "Principles",
31913
32146
  "id": "principles",
31914
- "body": "1. **Components first**: Prefer library `M*` controls over hand-rolled DOM equivalents.\n2. **Tokens first**: App styles consume `--m-*` only; no raw `#hex` / `rgb()` in product CSS (change brand at the theme entry).\n3. **Semantic consistency**: Primary actions default to primary; destructive work uses `severity=\"danger\"` or a confirm flow.\n4. **Accessibility**: Controls need accessible names; icon-only buttons need `aria-label`; overlays dismiss via keyboard.\n5. **Single source of truth**: Trust component docs / MCP for APIs; do not invent props."
32147
+ "body": "1. **Components first**: Prefer library `M*` controls over hand-rolled DOM equivalents.\n2. **Tokens first**: App styles consume `--m-*` only; no raw `#hex` / `rgb()` in product CSS (change brand at the theme entry).\n3. **Semantic consistency**: Primary actions use `type=\"primary\"`; destructive work uses `danger` / `color=\"danger\"` or a confirm flow.\n4. **Accessibility**: Controls need accessible names; icon-only buttons need `aria-label`; overlays dismiss via keyboard.\n5. **Single source of truth**: Trust component docs / MCP for APIs; do not invent props."
31915
32148
  },
31916
32149
  {
31917
32150
  "title": "Chapters",
@@ -31938,7 +32171,7 @@
31938
32171
  "zh-CN": {
31939
32172
  "title": "色彩",
31940
32173
  "description": "品牌色、语义色、中性色与对比度约定。",
31941
- "markdown": "---\ntitle: 色彩\norder: 4.51\ndescription: 品牌色、语义色、中性色与对比度约定。\n---\n\n# 色彩\n\n组件只消费语义化 `--m-*` 颜色变量,不维护第二套业务色板。亮 / 暗色由 `document.documentElement` 的 `data-theme` 切换(`useTheme`)。\n\n## 原则\n\n- **换品牌改令牌**:在主题入口覆盖 `--m-color-primary`(及派生 hover / active / bg),页面仍写 `var(--m-*)`。\n- **语义先于色相**:按钮、Tag、Alert 用 `severity`,不要用裸色冒充状态。\n- **暗色必须可跟随**:业务 CSS 勿写死浅色专用 hex;依赖 `[data-theme=\"dark\"]` 覆盖。\n- **不只靠颜色传达**:错误 / 成功同时给文案或图标(见 [无障碍](/docs/accessibility))。\n\n## 核心令牌\n\n| Token | 默认(亮色) | 用途 |\n| --- | --- | --- |\n| `--m-color-primary` | `#1677ff` | 品牌主色、链接、默认主按钮 |\n| `--m-color-primary-hover` | `#4096ff` | 主色悬浮 |\n| `--m-color-surface` | `#ffffff` | 容器 / 卡片底 |\n| `--m-color-text` | `rgba(0,0,0,0.88)` | 正文 |\n| `--m-color-text-muted` | `rgba(0,0,0,0.45)` | 次要说明 |\n| `--m-color-border` | `#d9d9d9` | 描边 |\n| `--m-color-split` | `#f0f0f0` | 弱分割(弱于 border) |\n| `--m-color-success` | `#52c41a` | 成功 |\n| `--m-color-info` | `#1677ff` | 信息 |\n| `--m-color-warning` / `--m-color-warn` | `#faad14` | 警告(`warn` 为别名) |\n| `--m-color-danger` | `#ff4d4f` | 危险 / 错误 |\n| `--m-color-help` | `#9333ea` | 帮助提示 |\n| `--m-color-on-emphasis` | `#ffffff` | 实心强调面上的前景 |\n| `--m-color-focus-ring` | 跟主色 | 聚焦相关 |\n| `--m-opacity-disabled` | `0.55` | 禁用透明度 |\n\n暗色示例:`--m-color-surface: #141414`,正文 `rgba(255,255,255,0.85)`。完整表见 [设计令牌](/docs/design-tokens)。\n\n## severity 映射\n\n| `severity` | 对应色 |\n| --- | --- |\n| (省略 / primary) | `--m-color-primary` |\n| `secondary` | 中性次要外观 |\n| `success` | `--m-color-success` |\n| `info` | `--m-color-info` |\n| `warning` / `warn` | `--m-color-warning` |\n| `help` | `--m-color-help` |\n| `danger` | `--m-color-danger` |\n| `contrast` | `--m-color-contrast` 系 |\n\n破坏性操作:按钮 / 确认用 `severity=\"danger\"`,不要用主色冒充删除。\n\n## 覆盖方式\n\n```css\n:root {\n --m-color-primary: #0b6e4f;\n}\n[data-theme=\"dark\"] {\n --m-color-primary: #3ecf8e;\n}\n```\n\n也可用 `createTheme({ seed: { colorPrimary: '…' } })` 派生 hover / bg 等(见 [主题](/docs/theme))。在线预览:[主题编辑器](/theme-editor)。\n\n## 建议与避免\n\n| 建议 | 避免 |\n| --- | --- |\n| 主操作默认 primary,次要用 `secondary` / `outlined` | 一屏多个同等实心主按钮 |\n| 错误态用 `danger` + 文案 | 只用红色边框表达错误 |\n| 弱分隔用 `--m-color-split` | 到处加粗边框抢层级 |\n| 聚焦用 `--m-focus-shadow` | 手写外扩 outline 与主题脱节 |\n\n下一章:[字体与排版](/docs/design-typography)。\n",
32174
+ "markdown": "---\ntitle: 色彩\norder: 4.51\ndescription: 品牌色、语义色、中性色与对比度约定。\n---\n\n# 色彩\n\n组件只消费语义化 `--m-*` 颜色变量,不维护第二套业务色板。亮 / 暗色由 `document.documentElement` 的 `data-theme` 切换(`useTheme`)。\n\n## 原则\n\n- **换品牌改令牌**:在主题入口覆盖 `--m-color-primary`(及派生 hover / active / bg),页面仍写 `var(--m-*)`。\n- **语义先于色相**:按钮、Tag、Alert 用 `severity`,不要用裸色冒充状态。\n- **暗色必须可跟随**:业务 CSS 勿写死浅色专用 hex;依赖 `[data-theme=\"dark\"]` 覆盖。\n- **不只靠颜色传达**:错误 / 成功同时给文案或图标(见 [无障碍](/docs/accessibility))。\n\n## 核心令牌\n\n| Token | 默认(亮色) | 用途 |\n| --- | --- | --- |\n| `--m-color-primary` | `#1677ff` | 品牌主色、链接、默认主按钮 |\n| `--m-color-primary-hover` | `#4096ff` | 主色悬浮 |\n| `--m-color-surface` | `#ffffff` | 容器 / 卡片底 |\n| `--m-color-text` | `rgba(0,0,0,0.88)` | 正文 |\n| `--m-color-text-muted` | `rgba(0,0,0,0.45)` | 次要说明 |\n| `--m-color-border` | `#d9d9d9` | 描边 |\n| `--m-color-split` | `#f0f0f0` | 弱分割(弱于 border) |\n| `--m-color-success` | `#52c41a` | 成功 |\n| `--m-color-info` | `#1677ff` | 信息 |\n| `--m-color-warning` / `--m-color-warn` | `#faad14` | 警告(`warn` 为别名) |\n| `--m-color-danger` | `#ff4d4f` | 危险 / 错误 |\n| `--m-color-help` | `#9333ea` | 帮助提示 |\n| `--m-color-on-emphasis` | `#ffffff` | 实心强调面上的前景 |\n| `--m-color-focus-ring` | 跟主色 | 聚焦相关 |\n| `--m-opacity-disabled` | `0.55` | 禁用透明度 |\n\n暗色示例:`--m-color-surface: #141414`,正文 `rgba(255,255,255,0.85)`。完整表见 [设计令牌](/docs/design-tokens)。\n\n## severity 映射\n\n| `severity` | 对应色 |\n| --- | --- |\n| (省略 / primary) | `--m-color-primary` |\n| `secondary` | 中性次要外观 |\n| `success` | `--m-color-success` |\n| `info` | `--m-color-info` |\n| `warning` / `warn` | `--m-color-warning` |\n| `help` | `--m-color-help` |\n| `danger` | `--m-color-danger` |\n| `contrast` | `--m-color-contrast` 系 |\n\n破坏性操作:按钮 / 确认用 `danger` 或 `color=\"danger\"`,不要用主色冒充删除。\n\n## 覆盖方式\n\n```css\n:root {\n --m-color-primary: #0b6e4f;\n}\n[data-theme=\"dark\"] {\n --m-color-primary: #3ecf8e;\n}\n```\n\n也可用 `createTheme({ seed: { colorPrimary: '…' } })` 派生 hover / bg 等(见 [主题](/docs/theme))。在线预览:[主题编辑器](/theme-editor)。\n\n## 建议与避免\n\n| 建议 | 避免 |\n| --- | --- |\n| 主操作默认 primary,次要用 `secondary` / `outlined` | 一屏多个同等实心主按钮 |\n| 错误态用 `danger` + 文案 | 只用红色边框表达错误 |\n| 弱分隔用 `--m-color-split` | 到处加粗边框抢层级 |\n| 聚焦用 `--m-focus-shadow` | 手写外扩 outline 与主题脱节 |\n\n下一章:[字体与排版](/docs/design-typography)。\n",
31942
32175
  "sections": [
31943
32176
  {
31944
32177
  "title": "",
@@ -31958,7 +32191,7 @@
31958
32191
  {
31959
32192
  "title": "severity 映射",
31960
32193
  "id": "severity-映射",
31961
- "body": "| `severity` | 对应色 |\n| --- | --- |\n| (省略 / primary) | `--m-color-primary` |\n| `secondary` | 中性次要外观 |\n| `success` | `--m-color-success` |\n| `info` | `--m-color-info` |\n| `warning` / `warn` | `--m-color-warning` |\n| `help` | `--m-color-help` |\n| `danger` | `--m-color-danger` |\n| `contrast` | `--m-color-contrast` 系 |\n\n破坏性操作:按钮 / 确认用 `severity=\"danger\"`,不要用主色冒充删除。"
32194
+ "body": "| `severity` | 对应色 |\n| --- | --- |\n| (省略 / primary) | `--m-color-primary` |\n| `secondary` | 中性次要外观 |\n| `success` | `--m-color-success` |\n| `info` | `--m-color-info` |\n| `warning` / `warn` | `--m-color-warning` |\n| `help` | `--m-color-help` |\n| `danger` | `--m-color-danger` |\n| `contrast` | `--m-color-contrast` 系 |\n\n破坏性操作:按钮 / 确认用 `danger` 或 `color=\"danger\"`,不要用主色冒充删除。"
31962
32195
  },
31963
32196
  {
31964
32197
  "title": "覆盖方式",
@@ -31975,7 +32208,7 @@
31975
32208
  "en-US": {
31976
32209
  "title": "Color",
31977
32210
  "description": "Brand, severity, neutrals, and contrast conventions.",
31978
- "markdown": "---\ntitle: Color\norder: 4.51\ndescription: Brand, severity, neutrals, and contrast conventions.\n---\n\n# Color\n\nComponents consume semantic `--m-*` color variables only—there is no second product palette. Light / dark follows `data-theme` on `document.documentElement` via `useTheme`.\n\n## Principles\n\n- **Brand at the theme entry**: Override `--m-color-primary` (and derived hover / active / bg); pages keep `var(--m-*)`.\n- **Semantics over hue**: Buttons, tags, and alerts use `severity`—do not fake status with raw colors.\n- **Dark must follow**: Avoid light-only hex in app CSS; rely on `[data-theme=\"dark\"]` overrides.\n- **Never color alone**: Pair error / success with copy or icons (see [Accessibility](/docs/accessibility)).\n\n## Core tokens\n\n| Token | Default (light) | Role |\n| --- | --- | --- |\n| `--m-color-primary` | `#1677ff` | Brand, links, default primary button |\n| `--m-color-primary-hover` | `#4096ff` | Primary hover |\n| `--m-color-surface` | `#ffffff` | Container / card surface |\n| `--m-color-text` | `rgba(0,0,0,0.88)` | Body text |\n| `--m-color-text-muted` | `rgba(0,0,0,0.45)` | Secondary copy |\n| `--m-color-border` | `#d9d9d9` | Borders |\n| `--m-color-split` | `#f0f0f0` | Weaker dividers |\n| `--m-color-success` | `#52c41a` | Success |\n| `--m-color-info` | `#1677ff` | Info |\n| `--m-color-warning` / `--m-color-warn` | `#faad14` | Warning (`warn` alias) |\n| `--m-color-danger` | `#ff4d4f` | Danger / error |\n| `--m-color-help` | `#9333ea` | Help accent |\n| `--m-color-on-emphasis` | `#ffffff` | Foreground on solid emphasis |\n| `--m-color-focus-ring` | Tracks primary | Focus-related |\n| `--m-opacity-disabled` | `0.55` | Disabled opacity |\n\nDark example: `--m-color-surface: #141414`, body `rgba(255,255,255,0.85)`. Full catalog: [Design tokens](/docs/design-tokens).\n\n## Severity mapping\n\n| `severity` | Maps to |\n| --- | --- |\n| (omit / primary) | `--m-color-primary` |\n| `secondary` | Neutral secondary treatment |\n| `success` | `--m-color-success` |\n| `info` | `--m-color-info` |\n| `warning` / `warn` | `--m-color-warning` |\n| `help` | `--m-color-help` |\n| `danger` | `--m-color-danger` |\n| `contrast` | `--m-color-contrast` family |\n\nDestructive actions: use `severity=\"danger\"` on buttons / confirms—do not paint delete as primary.\n\n## Overrides\n\n```css\n:root {\n --m-color-primary: #0b6e4f;\n}\n[data-theme=\"dark\"] {\n --m-color-primary: #3ecf8e;\n}\n```\n\nOr derive with `createTheme({ seed: { colorPrimary: '…' } })` (see [Theme](/docs/theme)). Live preview: [Theme editor](/theme-editor).\n\n## Do / Don't\n\n| Do | Don't |\n| --- | --- |\n| One clear primary action; secondary via `secondary` / `outlined` | Several equally solid primary buttons |\n| Errors: `danger` + message | Red border alone for validation |\n| Weak rules with `--m-color-split` | Heavy borders everywhere |\n| Focus with `--m-focus-shadow` | Ad-hoc outline rings that ignore theme |\n\nNext: [Typography](/docs/design-typography).\n",
32211
+ "markdown": "---\ntitle: Color\norder: 4.51\ndescription: Brand, severity, neutrals, and contrast conventions.\n---\n\n# Color\n\nComponents consume semantic `--m-*` color variables only—there is no second product palette. Light / dark follows `data-theme` on `document.documentElement` via `useTheme`.\n\n## Principles\n\n- **Brand at the theme entry**: Override `--m-color-primary` (and derived hover / active / bg); pages keep `var(--m-*)`.\n- **Semantics over hue**: Buttons, tags, and alerts use `severity`—do not fake status with raw colors.\n- **Dark must follow**: Avoid light-only hex in app CSS; rely on `[data-theme=\"dark\"]` overrides.\n- **Never color alone**: Pair error / success with copy or icons (see [Accessibility](/docs/accessibility)).\n\n## Core tokens\n\n| Token | Default (light) | Role |\n| --- | --- | --- |\n| `--m-color-primary` | `#1677ff` | Brand, links, default primary button |\n| `--m-color-primary-hover` | `#4096ff` | Primary hover |\n| `--m-color-surface` | `#ffffff` | Container / card surface |\n| `--m-color-text` | `rgba(0,0,0,0.88)` | Body text |\n| `--m-color-text-muted` | `rgba(0,0,0,0.45)` | Secondary copy |\n| `--m-color-border` | `#d9d9d9` | Borders |\n| `--m-color-split` | `#f0f0f0` | Weaker dividers |\n| `--m-color-success` | `#52c41a` | Success |\n| `--m-color-info` | `#1677ff` | Info |\n| `--m-color-warning` / `--m-color-warn` | `#faad14` | Warning (`warn` alias) |\n| `--m-color-danger` | `#ff4d4f` | Danger / error |\n| `--m-color-help` | `#9333ea` | Help accent |\n| `--m-color-on-emphasis` | `#ffffff` | Foreground on solid emphasis |\n| `--m-color-focus-ring` | Tracks primary | Focus-related |\n| `--m-opacity-disabled` | `0.55` | Disabled opacity |\n\nDark example: `--m-color-surface: #141414`, body `rgba(255,255,255,0.85)`. Full catalog: [Design tokens](/docs/design-tokens).\n\n## Severity mapping\n\n| `severity` | Maps to |\n| --- | --- |\n| (omit / primary) | `--m-color-primary` |\n| `secondary` | Neutral secondary treatment |\n| `success` | `--m-color-success` |\n| `info` | `--m-color-info` |\n| `warning` / `warn` | `--m-color-warning` |\n| `help` | `--m-color-help` |\n| `danger` | `--m-color-danger` |\n| `contrast` | `--m-color-contrast` family |\n\nDestructive actions: use `danger` or `color=\"danger\"` on buttons / confirms—do not paint delete as primary.\n\n## Overrides\n\n```css\n:root {\n --m-color-primary: #0b6e4f;\n}\n[data-theme=\"dark\"] {\n --m-color-primary: #3ecf8e;\n}\n```\n\nOr derive with `createTheme({ seed: { colorPrimary: '…' } })` (see [Theme](/docs/theme)). Live preview: [Theme editor](/theme-editor).\n\n## Do / Don't\n\n| Do | Don't |\n| --- | --- |\n| One clear primary action; secondary via `secondary` / `outlined` | Several equally solid primary buttons |\n| Errors: `danger` + message | Red border alone for validation |\n| Weak rules with `--m-color-split` | Heavy borders everywhere |\n| Focus with `--m-focus-shadow` | Ad-hoc outline rings that ignore theme |\n\nNext: [Typography](/docs/design-typography).\n",
31979
32212
  "sections": [
31980
32213
  {
31981
32214
  "title": "",
@@ -31995,7 +32228,7 @@
31995
32228
  {
31996
32229
  "title": "Severity mapping",
31997
32230
  "id": "severity-mapping",
31998
- "body": "| `severity` | Maps to |\n| --- | --- |\n| (omit / primary) | `--m-color-primary` |\n| `secondary` | Neutral secondary treatment |\n| `success` | `--m-color-success` |\n| `info` | `--m-color-info` |\n| `warning` / `warn` | `--m-color-warning` |\n| `help` | `--m-color-help` |\n| `danger` | `--m-color-danger` |\n| `contrast` | `--m-color-contrast` family |\n\nDestructive actions: use `severity=\"danger\"` on buttons / confirms—do not paint delete as primary."
32231
+ "body": "| `severity` | Maps to |\n| --- | --- |\n| (omit / primary) | `--m-color-primary` |\n| `secondary` | Neutral secondary treatment |\n| `success` | `--m-color-success` |\n| `info` | `--m-color-info` |\n| `warning` / `warn` | `--m-color-warning` |\n| `help` | `--m-color-help` |\n| `danger` | `--m-color-danger` |\n| `contrast` | `--m-color-contrast` family |\n\nDestructive actions: use `danger` or `color=\"danger\"` on buttons / confirms—do not paint delete as primary."
31999
32232
  },
32000
32233
  {
32001
32234
  "title": "Overrides",
@@ -32640,7 +32873,7 @@
32640
32873
  "zh-CN": {
32641
32874
  "title": "Common Props",
32642
32875
  "description": "跨组件公共 props、Semantic DOM 与 pt 约定。",
32643
- "markdown": "---\ntitle: Common Props\norder: 7.5\ndescription: 跨组件公共 props、Semantic DOM 与 pt 约定。\n---\n\n# Common Props\n\n多数 Morya 组件共享同一套交互词表与样式落点,本页说明 morya 自己的命名与语义。细节交叉阅读:[约定](/docs/conventions)、[样式与 attrs](/docs/attrs)、[API 类型](/docs/types)、[设计令牌](/docs/design-tokens)。\n\n## 语义与外观\n\n| Prop | 含义 | 常见取值 |\n| -------------------- | ------------ | ------------------------------------------------------------------------------------------------------------- |\n| `severity` | 语义色 | `primary`(常可省略)/ `secondary` / `success` / `info` / `warning`(`warn`)/ `help` / `danger` / `contrast` |\n| `variant` | 外观快捷方式 | 随组件:`outlined` / `dashed` / `text` / `link` / `ghost` / `quaternary` / 输入框 `filled` 等 |\n| `size` | 控件尺寸 | `small` / `medium` / `large`(兼容 `sm` / `md` / `lg`);未传常继承 Config |\n| `disabled` | 禁用 | 交互与点击关闭;视觉用 `--m-opacity-disabled` 等 |\n| `loading` | 加载中 | 常见于 Button;阻止重复提交 |\n| `fluid` | 通栏 | 宽度撑满父级 |\n| `status` / `invalid` | 表单校验态 | 如 `error` / `warning`;配合 `error-message` |\n\n布尔形态(`outlined`、`text`、`link`…)与 `variant` 等价时可择一;**severity 管色,variant 管形**,可组合(如 `severity=\"danger\"` + `outlined`)。\n\n## 样式落点:class / style / 事件\n\n复合组件不是「根 = 原生控件」。attrs 三类落点:\n\n| 类型 | 例子 | `class` / `style` / 多数 attrs | 事件 `@xxx` |\n| ---------- | ---------------- | -------------------------------- | ----------------- |\n| 字段 | Input、Select | 外层 field 根 | 内层 input / 控件 |\n| Label 控件 | Checkbox、Switch | 可见 `<label>` | hidden `<input>` |\n| 容器 | Card、Tabs | 对外根(Dialog 的 class 在遮罩) | 同层 |\n| 叶子 | Button、Tag | 交互元素本身 | 同元素 |\n\n完整规则与演示:[样式与 attrs](/docs/attrs)。\n\n## Semantic DOM 与 `pt`\n\n**Semantic DOM**:文档里用稳定的结构名描述可定制节点(如 Button 的 root / icon / label),方便主题与测试定位。\n\n**`pt`(pass-through)**:按分段把 `class` / `style` / 原生属性合并到内层 DOM,键名即分段名。\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 }\"\n/>\n```\n\n常见键:\n\n| 形态 | `pt` 键 |\n| ----------- | ------------------------------------------------------------------------- |\n| 字段 | `root`、`label`、`input` / `control`,部分有 `prefix` / `suffix` / `help` |\n| Checkbox 等 | `root`、`input` |\n| 单根容器 | `root` |\n| 复杂组件 | 额外键见该组件文档(如 Splitter 的 `gutter`) |\n\n类型:`PassThroughPart`、`FieldPassThrough`、`RootPassThrough` 等见 [API 类型](/docs/types)。同名 `class` / `style` 与已有绑定**合并**,非整段覆盖。\n\n叶子组件(如 `MButton`)通常直接把 `class` 绑在 `<button>` 上;`MButtonGroup` 等仍可用 `pt.root`。结构说明写在各组件 **Semantic DOM** 小节(示范:[Button](/components/Button))。\n\n## 全局默认\n\n`MConfigProvider` / `createMoryaUI` 可下发默认 `size`、`density`、`inputVariant`、`appendTo`、`zIndex`、`locale`、`componentDefaults`、`motion` 等——见 [全局配置](/docs/config)。视觉层仍用 [主题](/docs/theme) 的 `useTheme` / 令牌覆盖。\n\n## 建议与避免\n\n| 建议 | 避免 |\n| ----------------------------------------------------- | ------------------------------------- |\n| 跨组件统一 `severity` 词表 | 同一产品里混用 `type=\"danger\"` 等异名 |\n| 布局 class 加在字段根 | 指望 `class` 自动落到内层 input |\n| 用 `pt` 改前缀 / 控件细节 | 为改一处 class 去 fork 组件 |\n| Semantic DOM 名称与 BEM(`.m-button__label`)对齐记忆 | 臆造未文档化的 `pt` 键 |\n",
32876
+ "markdown": "---\ntitle: Common Props\norder: 7.5\ndescription: 跨组件公共 props、Semantic DOM 与 pt 约定。\n---\n\n# Common Props\n\n多数 Morya 组件共享同一套交互词表与样式落点,本页说明 morya 自己的命名与语义。细节交叉阅读:[约定](/docs/conventions)、[样式与 attrs](/docs/attrs)、[API 类型](/docs/types)、[设计令牌](/docs/design-tokens)。\n\n## 语义与外观\n\n| Prop | 含义 | 常见取值 |\n| -------------------- | ------------ | ------------------------------------------------------------------------------------------------------------- |\n| `severity` | 语义色 | Badge / Tag / Alert / Message 等:`primary` / `secondary` / `success` / `info` / `warning`(`warn`)/ `danger` / `contrast` |\n| `type` / `color` / `variant` | Button 外观 | Button 用 `type`(糖)+ `color` + `variant`(`solid` / `outlined` / `dashed` / `filled` / `text` / `link`);默认 `color=default` + `variant=outlined`;主实心用 `type=\"primary\"` |\n| `size` | 控件尺寸 | `small` / `medium` / `large`(兼容 `sm` / `md` / `lg`);未传常继承 Config |\n| `disabled` | 禁用 | 交互与点击关闭;视觉用 `--m-opacity-disabled` 等 |\n| `loading` | 加载中 | 常见于 Button;阻止重复提交 |\n| `fluid` / `block` | 通栏 | 多数字段用 `fluid`;Button / ButtonGroup 用 `block` |\n| `status` / `invalid` | 表单校验态 | 如 `error` / `warning`;配合 `error-message` |\n\n**Badge / Tag / Alert 等**:`severity` 管色。**Button**:`type` / `color` / `variant` 管色与形(如 `type=\"primary\"`,或 `color=\"danger\"` + `variant=\"outlined\"`);危险实心可用 `type=\"primary\" danger`。\n\n## 样式落点:class / style / 事件\n\n复合组件不是「根 = 原生控件」。attrs 三类落点:\n\n| 类型 | 例子 | `class` / `style` / 多数 attrs | 事件 `@xxx` |\n| ---------- | ---------------- | -------------------------------- | ----------------- |\n| 字段 | Input、Select | 外层 field 根 | 内层 input / 控件 |\n| Label 控件 | Checkbox、Switch | 可见 `<label>` | hidden `<input>` |\n| 容器 | Card、Tabs | 对外根(Dialog 的 class 在遮罩) | 同层 |\n| 叶子 | Button、Tag | 交互元素本身 | 同元素 |\n\n完整规则与演示:[样式与 attrs](/docs/attrs)。\n\n## Semantic DOM 与 `pt`\n\n**Semantic DOM**:文档里用稳定的结构名描述可定制节点(如 Button 的 root / icon / label),方便主题与测试定位。\n\n**`pt`(pass-through)**:按分段把 `class` / `style` / 原生属性合并到内层 DOM,键名即分段名。\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 }\"\n/>\n```\n\n常见键:\n\n| 形态 | `pt` 键 |\n| ----------- | ------------------------------------------------------------------------- |\n| 字段 | `root`、`label`、`input` / `control`,部分有 `prefix` / `suffix` / `help` |\n| Checkbox 等 | `root`、`input` |\n| 单根容器 | `root` |\n| 复杂组件 | 额外键见该组件文档(如 Splitter 的 `gutter`) |\n\n类型:`PassThroughPart`、`FieldPassThrough`、`RootPassThrough` 等见 [API 类型](/docs/types)。同名 `class` / `style` 与已有绑定**合并**,非整段覆盖。\n\n叶子组件(如 `MButton`)通常直接把 `class` 绑在 `<button>` 上;`MButtonGroup` 等仍可用 `pt.root`。结构说明写在各组件 **Semantic DOM** 小节(示范:[Button](/components/Button))。\n\n## 全局默认\n\n`MConfigProvider` / `createMoryaUI` 可下发默认 `size`、`density`、`inputVariant`、`appendTo`、`zIndex`、`locale`、`componentDefaults`、`motion` 等——见 [全局配置](/docs/config)。视觉层仍用 [主题](/docs/theme) 的 `useTheme` / 令牌覆盖。\n\n## 建议与避免\n\n| 建议 | 避免 |\n| ----------------------------------------------------- | ------------------------------------- |\n| Badge / Tag / Alert 用 `severity`;Button 用 `type` / `color` / `variant` | 在 Button 上继续写已移除的 `severity` / `fluid` / `outlined` 布尔 |\n| 布局 class 加在字段根 | 指望 `class` 自动落到内层 input |\n| 用 `pt` 改前缀 / 控件细节 | 为改一处 class 去 fork 组件 |\n| Semantic DOM 名称与 BEM(`.m-button__label`)对齐记忆 | 臆造未文档化的 `pt` 键 |\n",
32644
32877
  "sections": [
32645
32878
  {
32646
32879
  "title": "",
@@ -32650,7 +32883,7 @@
32650
32883
  {
32651
32884
  "title": "语义与外观",
32652
32885
  "id": "语义与外观",
32653
- "body": "| Prop | 含义 | 常见取值 |\n| -------------------- | ------------ | ------------------------------------------------------------------------------------------------------------- |\n| `severity` | 语义色 | `primary`(常可省略)/ `secondary` / `success` / `info` / `warning`(`warn`)/ `help` / `danger` / `contrast` |\n| `variant` | 外观快捷方式 | 随组件:`outlined` / `dashed` / `text` / `link` / `ghost` / `quaternary` / 输入框 `filled` 等 |\n| `size` | 控件尺寸 | `small` / `medium` / `large`(兼容 `sm` / `md` / `lg`);未传常继承 Config |\n| `disabled` | 禁用 | 交互与点击关闭;视觉用 `--m-opacity-disabled` 等 |\n| `loading` | 加载中 | 常见于 Button;阻止重复提交 |\n| `fluid` | 通栏 | 宽度撑满父级 |\n| `status` / `invalid` | 表单校验态 | 如 `error` / `warning`;配合 `error-message` |\n\n布尔形态(`outlined`、`text`、`link`…)与 `variant` 等价时可择一;**severity 管色,variant 管形**,可组合(如 `severity=\"danger\"` + `outlined`)。"
32886
+ "body": "| Prop | 含义 | 常见取值 |\n| -------------------- | ------------ | ------------------------------------------------------------------------------------------------------------- |\n| `severity` | 语义色 | Badge / Tag / Alert / Message 等:`primary` / `secondary` / `success` / `info` / `warning`(`warn`)/ `danger` / `contrast` |\n| `type` / `color` / `variant` | Button 外观 | Button 用 `type`(糖)+ `color` + `variant`(`solid` / `outlined` / `dashed` / `filled` / `text` / `link`);默认 `color=default` + `variant=outlined`;主实心用 `type=\"primary\"` |\n| `size` | 控件尺寸 | `small` / `medium` / `large`(兼容 `sm` / `md` / `lg`);未传常继承 Config |\n| `disabled` | 禁用 | 交互与点击关闭;视觉用 `--m-opacity-disabled` 等 |\n| `loading` | 加载中 | 常见于 Button;阻止重复提交 |\n| `fluid` / `block` | 通栏 | 多数字段用 `fluid`;Button / ButtonGroup 用 `block` |\n| `status` / `invalid` | 表单校验态 | 如 `error` / `warning`;配合 `error-message` |\n\n**Badge / Tag / Alert 等**:`severity` 管色。**Button**:`type` / `color` / `variant` 管色与形(如 `type=\"primary\"`,或 `color=\"danger\"` + `variant=\"outlined\"`);危险实心可用 `type=\"primary\" danger`。"
32654
32887
  },
32655
32888
  {
32656
32889
  "title": "样式落点:class / style / 事件",
@@ -32670,14 +32903,14 @@
32670
32903
  {
32671
32904
  "title": "建议与避免",
32672
32905
  "id": "建议与避免",
32673
- "body": "| 建议 | 避免 |\n| ----------------------------------------------------- | ------------------------------------- |\n| 跨组件统一 `severity` 词表 | 同一产品里混用 `type=\"danger\"` 等异名 |\n| 布局 class 加在字段根 | 指望 `class` 自动落到内层 input |\n| 用 `pt` 改前缀 / 控件细节 | 为改一处 class 去 fork 组件 |\n| Semantic DOM 名称与 BEM(`.m-button__label`)对齐记忆 | 臆造未文档化的 `pt` 键 |"
32906
+ "body": "| 建议 | 避免 |\n| ----------------------------------------------------- | ------------------------------------- |\n| Badge / Tag / Alert 用 `severity`;Button 用 `type` / `color` / `variant` | 在 Button 上继续写已移除的 `severity` / `fluid` / `outlined` 布尔 |\n| 布局 class 加在字段根 | 指望 `class` 自动落到内层 input |\n| 用 `pt` 改前缀 / 控件细节 | 为改一处 class 去 fork 组件 |\n| Semantic DOM 名称与 BEM(`.m-button__label`)对齐记忆 | 臆造未文档化的 `pt` 键 |"
32674
32907
  }
32675
32908
  ]
32676
32909
  },
32677
32910
  "en-US": {
32678
32911
  "title": "Common Props",
32679
32912
  "description": "Shared props, Semantic DOM, and pt conventions across components.",
32680
- "markdown": "---\ntitle: Common Props\norder: 7.5\ndescription: Shared props, Semantic DOM, and pt conventions across components.\n---\n\n# Common Props\n\nMost Morya components share one interaction vocabulary and style targeting model. This page documents morya's own names and semantics. Cross-links: [Conventions](/docs/conventions), [Attrs](/docs/attrs), [API types](/docs/types), [Design tokens](/docs/design-tokens).\n\n## Semantics and appearance\n\n| Prop | Meaning | Common values |\n| -------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------ |\n| `severity` | Semantic color | `primary` (often omitted) / `secondary` / `success` / `info` / `warning` (`warn`) / `help` / `danger` / `contrast` |\n| `variant` | Appearance shortcut | Per component: `outlined` / `dashed` / `text` / `link` / `ghost` / `quaternary` / input `filled`, etc. |\n| `size` | Control size | `small` / `medium` / `large` (`sm` / `md` / `lg` aliases); often inherits Config when omitted |\n| `disabled` | Disabled | Blocks interaction; visuals use `--m-opacity-disabled` and related tokens |\n| `loading` | Busy | Common on Button; prevents double submit |\n| `fluid` | Full width | Stretch to parent width |\n| `status` / `invalid` | Form validation | e.g. `error` / `warning`; pair with `error-message` |\n\nBoolean mirrors (`outlined`, `text`, `link`, …) may equal `variant`—pick one. **`severity` colors; `variant` shapes**; they compose (e.g. `severity=\"danger\"` + `outlined`).\n\n## Where class / style / events land\n\nComposite components are not “root = native control”. Three targeting patterns:\n\n| Kind | Examples | `class` / `style` / most attrs | Events `@xxx` |\n| ------------- | ---------------- | ------------------------------------- | --------------------- |\n| Field | Input, Select | Outer field root | Inner input / control |\n| Label control | Checkbox, Switch | Visible `<label>` | Hidden `<input>` |\n| Container | Card, Tabs | Public root (Dialog `class` on scrim) | Same layer |\n| Leaf | Button, Tag | Interactive element itself | Same element |\n\nFull rules and demos: [Attrs](/docs/attrs).\n\n## Semantic DOM and `pt`\n\n**Semantic DOM**: stable structural names in docs for customizable nodes (e.g. Button root / icon / label)—handy for theming and tests.\n\n**`pt` (pass-through)**: merge `class` / `style` / native attrs onto inner DOM by segment key.\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 }\"\n/>\n```\n\nCommon keys:\n\n| Shape | `pt` keys |\n| --------------------- | ---------------------------------------------------------------------------- |\n| Field | `root`, `label`, `input` / `control`; sometimes `prefix` / `suffix` / `help` |\n| Checkbox-like | `root`, `input` |\n| Single-root container | `root` |\n| Complex | Extra keys in that component’s docs (e.g. Splitter `gutter`) |\n\nTypes: `PassThroughPart`, `FieldPassThrough`, `RootPassThrough`, … in [API types](/docs/types). Same-named `class` / `style` **merge** with existing bindings rather than replace wholesale.\n\nLeaf components such as `MButton` bind `class` on the `<button>` directly; groups like `MButtonGroup` still accept `pt.root`. Structure notes live under each component’s **Semantic DOM** section (example: [Button](/components/Button)).\n\n## Global defaults\n\n`MConfigProvider` / `createMoryaUI` can supply default `size`, `density`, `inputVariant`, `appendTo`, `zIndex`, `locale`, `componentDefaults`, `motion`, and more — see [Configuration](/docs/config). Visual layer remains [Theme](/docs/theme) via `useTheme` / token overrides.\n\n## Do / Don't\n\n| Do | Don't |\n| ------------------------------------------------------ | ---------------------------------------------------------- |\n| Keep one `severity` vocabulary across components | Mix foreign names like `type=\"danger\"` in the same product |\n| Put layout `class` on the field root | Expect `class` to fall through onto the inner input |\n| Use `pt` for prefix / inner tweaks | Fork a component to change one class |\n| Align Semantic DOM names with BEM (`.m-button__label`) | Invent undocumented `pt` keys |\n",
32913
+ "markdown": "---\ntitle: Common Props\norder: 7.5\ndescription: Shared props, Semantic DOM, and pt conventions across components.\n---\n\n# Common Props\n\nMost Morya components share one interaction vocabulary and style targeting model. This page documents morya's own names and semantics. Cross-links: [Conventions](/docs/conventions), [Attrs](/docs/attrs), [API types](/docs/types), [Design tokens](/docs/design-tokens).\n\n## Semantics and appearance\n\n| Prop | Meaning | Common values |\n| -------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------ |\n| `severity` | Semantic color | Badge / Tag / Alert / Message: `primary` / `secondary` / `success` / `info` / `warning` (`warn`) / `danger` / `contrast` |\n| `type` / `color` / `variant` | Button appearance | Button uses `type` (sugar) + `color` + `variant` (`solid` / `outlined` / `dashed` / `filled` / `text` / `link`); default is `color=default` + `variant=outlined`; solid primary needs `type=\"primary\"` |\n| `size` | Control size | `small` / `medium` / `large` (`sm` / `md` / `lg` aliases); often inherits Config when omitted |\n| `disabled` | Disabled | Blocks interaction; visuals use `--m-opacity-disabled` and related tokens |\n| `loading` | Busy | Common on Button; prevents double submit |\n| `fluid` / `block` | Full width | Most fields use `fluid`; Button / ButtonGroup use `block` |\n| `status` / `invalid` | Form validation | e.g. `error` / `warning`; pair with `error-message` |\n\n**Badge / Tag / Alert**: `severity` sets tone. **Button**: `type` / `color` / `variant` set tone and shape (e.g. `type=\"primary\"`, or `color=\"danger\"` + `variant=\"outlined\"`); solid danger can be `type=\"primary\" danger`.\n\n## Where class / style / events land\n\nComposite components are not “root = native control”. Three targeting patterns:\n\n| Kind | Examples | `class` / `style` / most attrs | Events `@xxx` |\n| ------------- | ---------------- | ------------------------------------- | --------------------- |\n| Field | Input, Select | Outer field root | Inner input / control |\n| Label control | Checkbox, Switch | Visible `<label>` | Hidden `<input>` |\n| Container | Card, Tabs | Public root (Dialog `class` on scrim) | Same layer |\n| Leaf | Button, Tag | Interactive element itself | Same element |\n\nFull rules and demos: [Attrs](/docs/attrs).\n\n## Semantic DOM and `pt`\n\n**Semantic DOM**: stable structural names in docs for customizable nodes (e.g. Button root / icon / label)—handy for theming and tests.\n\n**`pt` (pass-through)**: merge `class` / `style` / native attrs onto inner DOM by segment key.\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 }\"\n/>\n```\n\nCommon keys:\n\n| Shape | `pt` keys |\n| --------------------- | ---------------------------------------------------------------------------- |\n| Field | `root`, `label`, `input` / `control`; sometimes `prefix` / `suffix` / `help` |\n| Checkbox-like | `root`, `input` |\n| Single-root container | `root` |\n| Complex | Extra keys in that component’s docs (e.g. Splitter `gutter`) |\n\nTypes: `PassThroughPart`, `FieldPassThrough`, `RootPassThrough`, … in [API types](/docs/types). Same-named `class` / `style` **merge** with existing bindings rather than replace wholesale.\n\nLeaf components such as `MButton` bind `class` on the `<button>` directly; groups like `MButtonGroup` still accept `pt.root`. Structure notes live under each component’s **Semantic DOM** section (example: [Button](/components/Button)).\n\n## Global defaults\n\n`MConfigProvider` / `createMoryaUI` can supply default `size`, `density`, `inputVariant`, `appendTo`, `zIndex`, `locale`, `componentDefaults`, `motion`, and more — see [Configuration](/docs/config). Visual layer remains [Theme](/docs/theme) via `useTheme` / token overrides.\n\n## Do / Don't\n\n| Do | Don't |\n| ------------------------------------------------------ | ---------------------------------------------------------- |\n| Use `severity` on Badge / Tag / Alert; `type` / `color` / `variant` on Button | Keep removed Button props (`severity` / `fluid` / boolean `outlined`) |\n| Put layout `class` on the field root | Expect `class` to fall through onto the inner input |\n| Use `pt` for prefix / inner tweaks | Fork a component to change one class |\n| Align Semantic DOM names with BEM (`.m-button__label`) | Invent undocumented `pt` keys |\n",
32681
32914
  "sections": [
32682
32915
  {
32683
32916
  "title": "",
@@ -32687,7 +32920,7 @@
32687
32920
  {
32688
32921
  "title": "Semantics and appearance",
32689
32922
  "id": "semantics-and-appearance",
32690
- "body": "| Prop | Meaning | Common values |\n| -------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------ |\n| `severity` | Semantic color | `primary` (often omitted) / `secondary` / `success` / `info` / `warning` (`warn`) / `help` / `danger` / `contrast` |\n| `variant` | Appearance shortcut | Per component: `outlined` / `dashed` / `text` / `link` / `ghost` / `quaternary` / input `filled`, etc. |\n| `size` | Control size | `small` / `medium` / `large` (`sm` / `md` / `lg` aliases); often inherits Config when omitted |\n| `disabled` | Disabled | Blocks interaction; visuals use `--m-opacity-disabled` and related tokens |\n| `loading` | Busy | Common on Button; prevents double submit |\n| `fluid` | Full width | Stretch to parent width |\n| `status` / `invalid` | Form validation | e.g. `error` / `warning`; pair with `error-message` |\n\nBoolean mirrors (`outlined`, `text`, `link`, …) may equal `variant`—pick one. **`severity` colors; `variant` shapes**; they compose (e.g. `severity=\"danger\"` + `outlined`)."
32923
+ "body": "| Prop | Meaning | Common values |\n| -------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------ |\n| `severity` | Semantic color | Badge / Tag / Alert / Message: `primary` / `secondary` / `success` / `info` / `warning` (`warn`) / `danger` / `contrast` |\n| `type` / `color` / `variant` | Button appearance | Button uses `type` (sugar) + `color` + `variant` (`solid` / `outlined` / `dashed` / `filled` / `text` / `link`); default is `color=default` + `variant=outlined`; solid primary needs `type=\"primary\"` |\n| `size` | Control size | `small` / `medium` / `large` (`sm` / `md` / `lg` aliases); often inherits Config when omitted |\n| `disabled` | Disabled | Blocks interaction; visuals use `--m-opacity-disabled` and related tokens |\n| `loading` | Busy | Common on Button; prevents double submit |\n| `fluid` / `block` | Full width | Most fields use `fluid`; Button / ButtonGroup use `block` |\n| `status` / `invalid` | Form validation | e.g. `error` / `warning`; pair with `error-message` |\n\n**Badge / Tag / Alert**: `severity` sets tone. **Button**: `type` / `color` / `variant` set tone and shape (e.g. `type=\"primary\"`, or `color=\"danger\"` + `variant=\"outlined\"`); solid danger can be `type=\"primary\" danger`."
32691
32924
  },
32692
32925
  {
32693
32926
  "title": "Where class / style / events land",
@@ -32707,7 +32940,7 @@
32707
32940
  {
32708
32941
  "title": "Do / Don't",
32709
32942
  "id": "do-don-t",
32710
- "body": "| Do | Don't |\n| ------------------------------------------------------ | ---------------------------------------------------------- |\n| Keep one `severity` vocabulary across components | Mix foreign names like `type=\"danger\"` in the same product |\n| Put layout `class` on the field root | Expect `class` to fall through onto the inner input |\n| Use `pt` for prefix / inner tweaks | Fork a component to change one class |\n| Align Semantic DOM names with BEM (`.m-button__label`) | Invent undocumented `pt` keys |"
32943
+ "body": "| Do | Don't |\n| ------------------------------------------------------ | ---------------------------------------------------------- |\n| Use `severity` on Badge / Tag / Alert; `type` / `color` / `variant` on Button | Keep removed Button props (`severity` / `fluid` / boolean `outlined`) |\n| Put layout `class` on the field root | Expect `class` to fall through onto the inner input |\n| Use `pt` for prefix / inner tweaks | Fork a component to change one class |\n| Align Semantic DOM names with BEM (`.m-button__label`) | Invent undocumented `pt` keys |"
32711
32944
  }
32712
32945
  ]
32713
32946
  }
@@ -32724,24 +32957,24 @@
32724
32957
  "zh-CN": {
32725
32958
  "title": "API 类型",
32726
32959
  "description": "文档 Props 里常见类型名的结构与含义。",
32727
- "markdown": "---\ntitle: API 类型\norder: 8\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=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) 在 `RootPassThrough` 上增加分隔条与面板:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\n分隔条外观也可用 `resizeTriggerClass` / `resizeTriggerStyle`,内容用 `#resize-trigger`(别名 `#gutter`)。\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=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) 选项分组(混入 `options` 渲染分组标题行):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\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",
32960
+ "markdown": "---\ntitle: API 类型\norder: 8\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=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) 在 `RootPassThrough` 上增加分隔条与面板:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\n分隔条外观也可用 `resizeTriggerClass` / `resizeTriggerStyle`,内容用 `#resize-trigger`(别名 `#gutter`)。\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=\"ButtonType\">ButtonType</h3>\n\n按钮类型糖([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\n按钮颜色轴(Button、ConfirmDialog `acceptColor`、Dialog `positiveColor` 等):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\n按钮变体轴:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\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=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) 选项分组(混入 `options` 渲染分组标题行):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\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",
32728
32961
  "sections": [
32729
32962
  {
32730
32963
  "title": "",
32731
32964
  "id": "overview",
32732
- "body": "# 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=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) 在 `RootPassThrough` 上增加分隔条与面板:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\n分隔条外观也可用 `resizeTriggerClass` / `resizeTriggerStyle`,内容用 `#resize-trigger`(别名 `#gutter`)。\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=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) 选项分组(混入 `options` 渲染分组标题行):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\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`)写在对应组件页 **类型** 小节;这里只列跨组件复用的名字。"
32965
+ "body": "# 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=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) 在 `RootPassThrough` 上增加分隔条与面板:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\n分隔条外观也可用 `resizeTriggerClass` / `resizeTriggerStyle`,内容用 `#resize-trigger`(别名 `#gutter`)。\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=\"ButtonType\">ButtonType</h3>\n\n按钮类型糖([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\n按钮颜色轴(Button、ConfirmDialog `acceptColor`、Dialog `positiveColor` 等):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\n按钮变体轴:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\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=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) 选项分组(混入 `options` 渲染分组标题行):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\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`)写在对应组件页 **类型** 小节;这里只列跨组件复用的名字。"
32733
32966
  }
32734
32967
  ]
32735
32968
  },
32736
32969
  "en-US": {
32737
32970
  "title": "API types",
32738
32971
  "description": "Shapes behind type names in component Props tables.",
32739
- "markdown": "---\ntitle: API types\norder: 8\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=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) extends `RootPassThrough` with gutter and panes:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\nGutter look can also use `resizeTriggerClass` / `resizeTriggerStyle`; content goes in `#resize-trigger` (alias `#gutter`).\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=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) option group (mix into `options` to render a group header row):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\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",
32972
+ "markdown": "---\ntitle: API types\norder: 8\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=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) extends `RootPassThrough` with gutter and panes:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\nGutter look can also use `resizeTriggerClass` / `resizeTriggerStyle`; content goes in `#resize-trigger` (alias `#gutter`).\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=\"ButtonType\">ButtonType</h3>\n\nButton type sugar ([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\nButton color axis (Button, ConfirmDialog `acceptColor`, Dialog `positiveColor`, …):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\nButton variant axis:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\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=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) option group (mix into `options` to render a group header row):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\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",
32740
32973
  "sections": [
32741
32974
  {
32742
32975
  "title": "",
32743
32976
  "id": "overview",
32744
- "body": "# 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=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) extends `RootPassThrough` with gutter and panes:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\nGutter look can also use `resizeTriggerClass` / `resizeTriggerStyle`; content goes in `#resize-trigger` (alias `#gutter`).\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=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) option group (mix into `options` to render a group header row):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\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."
32977
+ "body": "# 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=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) extends `RootPassThrough` with gutter and panes:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\nGutter look can also use `resizeTriggerClass` / `resizeTriggerStyle`; content goes in `#resize-trigger` (alias `#gutter`).\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=\"ButtonType\">ButtonType</h3>\n\nButton type sugar ([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\nButton color axis (Button, ConfirmDialog `acceptColor`, Dialog `positiveColor`, …):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\nButton variant axis:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\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=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) option group (mix into `options` to render a group header row):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\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."
32745
32978
  }
32746
32979
  ]
32747
32980
  }
@@ -33342,7 +33575,7 @@
33342
33575
  "zh-CN": {
33343
33576
  "title": "Agent MCP",
33344
33577
  "description": "可选的 MCP 服务,供支持 Model Context Protocol 的 AI 客户端检索本库文档。",
33345
- "markdown": "---\ntitle: Agent MCP\norder: 14\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、规则与多编辑器 MCP 一起装好,见 [一键接入](/docs/setup)(默认写入 Cursor / VS Code / Zed 与 `.mcp.json`);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 配置;setup 会写入):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**VS Code**(工作区 `.vscode/mcp.json`;setup 会写入):\n\n```json\n{\n \"servers\": {\n \"morya-ui\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**便携**(项目根 `.mcp.json`;setup 会写入,供 Agent Host / 跨工具发现):\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` 等;需手写,setup 不自动写):\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**(项目 `.zed/settings.json` → `context_servers`;setup 会合并写入):\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 源码(含 settings / wizard / result / detail / form-in-dialog 等;`includeScaffold` 有样例时返回样例源码) |\n| `list_page_snippets` | 列出可复用的页面区块 snippet |\n| `get_page_snippet` | 读取局部区块 snippet(筛选区、工具栏等) |\n| `validate_page` | 校验页面组合、间距、双边框,以及 rows / message / MStatus 等契约 |\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_usage`** → `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` → 阅读某一指南\n- 传 `query` → 根据问题推荐组件\n\n当前指南包括:`form-surface-choice`、`overlay-choice`、`data-display-choice`、`selection-choice`(含 Select / TreeSelect / CascadeSelect / Listbox / SelectButton / Radio / AutoComplete)、`status-label-choice`、`empty-result-choice`、`action-menu-choice`、`loading-choice`、`page-scroll-choice`、`surface-choice`、`page-section-choice`、`layout-spacing-choice`、`surface-nesting-choice`。\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 与多编辑器 MCP\n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 何时用、表面地图\n- [快速上手](/docs/quick-start):在应用中安装并使用组件\n- [组件](/components):浏览全部组件与交互示例\n",
33578
+ "markdown": "---\ntitle: Agent MCP\norder: 14\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、规则与多编辑器 MCP 一起装好,见 [一键接入](/docs/setup)(默认写入 Cursor / VS Code / Zed 与 `.mcp.json`);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 配置;setup 会写入):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**VS Code**(工作区 `.vscode/mcp.json`;setup 会写入):\n\n```json\n{\n \"servers\": {\n \"morya-ui\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**便携**(项目根 `.mcp.json`;setup 会写入,供 Agent Host / 跨工具发现):\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` 等;需手写,setup 不自动写):\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**(项目 `.zed/settings.json` → `context_servers`;setup 会合并写入):\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 源码(含 settings / wizard / result / detail / form-in-dialog 等;`includeScaffold` 有样例时返回样例源码) |\n| `list_page_snippets` | 列出可复用的页面区块 snippet |\n| `get_page_snippet` | 读取局部区块 snippet(筛选区、工具栏等) |\n| `validate_page` | 校验页面组合、间距、双边框,以及 rows / message / MStatus 等契约 |\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_usage`** → `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` → 阅读某一指南\n- 传 `query` → 根据问题推荐组件\n\n当前指南包括:`form-surface-choice`、`overlay-choice`、`data-display-choice`、`selection-choice`(含 Select / TreeSelect / CascadeSelect / Listbox / SelectButton / Radio / AutoComplete)、`status-label-choice`、`empty-result-choice`、`action-menu-choice`、`loading-choice`、`page-scroll-choice`、`surface-choice`、`page-section-choice`、`layout-spacing-choice`、`surface-nesting-choice`。\n\n## 对话示例\n\n接入后,可直接让助手调用本服务,例如:\n\n> 用 morya-ui 的 MCP 查一下 Dialog 的 props,并给一个带确认 / 取消按钮的示例。\n\n> 搜索和「日期」相关的组件,选一个适合表单的,按文档写出最小用法。\n\n> 根据 MCP 里 Button 的文档,写一个 `type=\"primary\" 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=\"删除\" danger type=\"primary\"/>\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 与多编辑器 MCP\n- [Agent Skill](/docs/agent-skill):`morya-ui-pages` 何时用、表面地图\n- [快速上手](/docs/quick-start):在应用中安装并使用组件\n- [组件](/components):浏览全部组件与交互示例\n",
33346
33579
  "sections": [
33347
33580
  {
33348
33581
  "title": "",
@@ -33362,7 +33595,7 @@
33362
33595
  {
33363
33596
  "title": "对话示例",
33364
33597
  "id": "对话示例",
33365
- "body": "接入后,可直接让助手调用本服务,例如:\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```"
33598
+ "body": "接入后,可直接让助手调用本服务,例如:\n\n> 用 morya-ui 的 MCP 查一下 Dialog 的 props,并给一个带确认 / 取消按钮的示例。\n\n> 搜索和「日期」相关的组件,选一个适合表单的,按文档写出最小用法。\n\n> 根据 MCP 里 Button 的文档,写一个 `type=\"primary\" 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=\"删除\" danger type=\"primary\"/>\n</template>\n```"
33366
33599
  },
33367
33600
  {
33368
33601
  "title": "与文档站的关系",
@@ -33379,7 +33612,7 @@
33379
33612
  "en-US": {
33380
33613
  "title": "Agent MCP",
33381
33614
  "description": "Optional MCP server for AI clients that support the Model Context Protocol.",
33382
- "markdown": "---\ntitle: Agent MCP\norder: 14\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, rules, and multi-editor MCP in one step, see [One-shot setup](/docs/setup) (writes Cursor / VS Code / Zed plus `.mcp.json` by default). 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; written by setup):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**VS Code** (workspace `.vscode/mcp.json`; written by setup):\n\n```json\n{\n \"servers\": {\n \"morya-ui\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Portable** (project-root `.mcp.json`; written by setup for Agent Host / cross-tool discovery):\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.; configure manually — setup does not write these):\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** (project `.zed/settings.json` → `context_servers`; merged by setup):\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 MPage* composition rules |\n| `recommend_component` | List, read, or recommend component selection guides |\n| `list_golden_pages` | List golden page samples |\n| `get_golden_page` | Read a golden page Vue source (`list-page` … `settings-page`, `wizard-form`, …) |\n| `list_page_snippets` | List reusable page section snippets |\n| `get_page_snippet` | Read a local section snippet (filters, toolbar, …) |\n| `validate_page` | Check page composition, spacing, double-border, and contract hints (`rows`, message, MStatus) |\n\nMost tools accept `mode`: `zh` (default) or `en`.\n\nComponent lookup accepts common aliases such as `DataTable`, `数据表格`, `Pager`, and `确认弹窗`.\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_golden_page` → `get_pattern` → `get_design_rules` → `get_component` / `get_example` → **`validate_usage`** → `validate_page`. Use `recommend_component` when choosing between similar components.\n\n**Edit one section:** `list_page_snippets` → `get_page_snippet` → `get_component` / `get_example` → `validate_usage` → `validate_page`\n\nPass `includeScaffold: true` to `recommend_page` for starter Vue code (returns the golden page source when one exists):\n\n```json\n{\n \"intent\": \"Oil well management list\",\n \"pageType\": \"list\",\n \"features\": [\"filters\", \"create\", \"pagination\"],\n \"mode\": \"en\",\n \"includeScaffold\": true\n}\n```\n\n`recommend_component` modes:\n\n- omit `query` and `decision` → list decision guides\n- `decision` only → read one guide\n- `query` → recommend a component for a UI question\n\nCurrent guides include `form-surface-choice`, `overlay-choice`, `data-display-choice`, `selection-choice` (Select / TreeSelect / CascadeSelect / Listbox / SelectButton / Radio / AutoComplete), `status-label-choice`, `empty-result-choice`, `action-menu-choice`, `loading-choice`, `page-scroll-choice`, `surface-choice`, `page-section-choice`, `layout-spacing-choice`, and `surface-nesting-choice`.\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",
33615
+ "markdown": "---\ntitle: Agent MCP\norder: 14\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, rules, and multi-editor MCP in one step, see [One-shot setup](/docs/setup) (writes Cursor / VS Code / Zed plus `.mcp.json` by default). 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; written by setup):\n\n```json\n{\n \"mcpServers\": {\n \"morya-ui\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**VS Code** (workspace `.vscode/mcp.json`; written by setup):\n\n```json\n{\n \"servers\": {\n \"morya-ui\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@morya-ui/mcp\"]\n }\n }\n}\n```\n\n**Portable** (project-root `.mcp.json`; written by setup for Agent Host / cross-tool discovery):\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.; configure manually — setup does not write these):\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** (project `.zed/settings.json` → `context_servers`; merged by setup):\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 MPage* composition rules |\n| `recommend_component` | List, read, or recommend component selection guides |\n| `list_golden_pages` | List golden page samples |\n| `get_golden_page` | Read a golden page Vue source (`list-page` … `settings-page`, `wizard-form`, …) |\n| `list_page_snippets` | List reusable page section snippets |\n| `get_page_snippet` | Read a local section snippet (filters, toolbar, …) |\n| `validate_page` | Check page composition, spacing, double-border, and contract hints (`rows`, message, MStatus) |\n\nMost tools accept `mode`: `zh` (default) or `en`.\n\nComponent lookup accepts common aliases such as `DataTable`, `数据表格`, `Pager`, and `确认弹窗`.\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_golden_page` → `get_pattern` → `get_design_rules` → `get_component` / `get_example` → **`validate_usage`** → `validate_page`. Use `recommend_component` when choosing between similar components.\n\n**Edit one section:** `list_page_snippets` → `get_page_snippet` → `get_component` / `get_example` → `validate_usage` → `validate_page`\n\nPass `includeScaffold: true` to `recommend_page` for starter Vue code (returns the golden page source when one exists):\n\n```json\n{\n \"intent\": \"Oil well management list\",\n \"pageType\": \"list\",\n \"features\": [\"filters\", \"create\", \"pagination\"],\n \"mode\": \"en\",\n \"includeScaffold\": true\n}\n```\n\n`recommend_component` modes:\n\n- omit `query` and `decision` → list decision guides\n- `decision` only → read one guide\n- `query` → recommend a component for a UI question\n\nCurrent guides include `form-surface-choice`, `overlay-choice`, `data-display-choice`, `selection-choice` (Select / TreeSelect / CascadeSelect / Listbox / SelectButton / Radio / AutoComplete), `status-label-choice`, `empty-result-choice`, `action-menu-choice`, `loading-choice`, `page-scroll-choice`, `surface-choice`, `page-section-choice`, `layout-spacing-choice`, and `surface-nesting-choice`.\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 `type=\"primary\" 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\" danger type=\"primary\"/>\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",
33383
33616
  "sections": [
33384
33617
  {
33385
33618
  "title": "",
@@ -33399,7 +33632,7 @@
33399
33632
  {
33400
33633
  "title": "Prompt examples",
33401
33634
  "id": "prompt-examples",
33402
- "body": "After 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```"
33635
+ "body": "After 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 `type=\"primary\" 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\" danger type=\"primary\"/>\n</template>\n```"
33403
33636
  },
33404
33637
  {
33405
33638
  "title": "Relation to this site",
@@ -33426,7 +33659,7 @@
33426
33659
  "zh-CN": {
33427
33660
  "title": "登录表单",
33428
33661
  "description": "用 MForm + FormRules 做邮箱/密码登录校验。",
33429
- "markdown": "---\ntitle: 登录表单\norder: 20\ndescription: 用 MForm + FormRules 做邮箱/密码登录校验。\n---\n\n# 登录表单\n\n把邮箱、密码和提交按钮组合成可直接复制的登录表单:声明式 `rules` 校验,提交时统一跑一遍。\n\n## 目标\n\n- 邮箱必填 + 格式校验\n- 密码必填 + 最短长度\n- 提交时 `validate()`,失败只展示字段错误,成功再继续业务逻辑\n\n## 何时使用\n\n- 登录 / 注册页、账号切换弹窗等短表单\n- 需要字段级错误文案,而不是一次弹全局 Toast\n\n## 步骤\n\n1. 安装并引入样式:`pnpm add morya-ui`,入口加 `import 'morya-ui/styles.css'`(按需导入可跳过全量样式)。\n2. 用 `reactive` 建 `model`,用 `FormRules` 按字段名写规则。\n3. `MForm` 绑定 `model` / `rules`,`validate-on=\"submit\"`;字段放在 `MFormItem` 里,并通过默认插槽拿到 `id` / `invalid`。\n4. 密码用 `MInputPassword`;邮箱用 `MInput type=\"email\"`。\n5. 在 `@submit` 里 `await formRef.validate()`,检查 `valid` 后再请求接口。\n\n`validate()` **始终 resolve**,不会 reject;失败时看 `{ valid, errors }`。\n\n## 预览\n\n```vue preview src=\"./demos/recipes/FormLogin.zh.vue\"\n```\n\n## 检查清单\n\n- [ ] `name` 与 `rules` 键一致(`email` / `password`)\n- [ ] 控件收到 `id` 与 `invalid`,错误能关联到 label\n- [ ] 密码使用 `MInputPassword`(不要用明文 `type=\"password\"` 凑合,除非刻意简化)\n- [ ] 提交按钮 `native-type=\"submit\"`,避免只绑 `@click` 漏掉原生提交\n- [ ] 已引入 `morya-ui` 与样式\n\n## 相关\n\n- [Form](/components/Form):声明式 rules、`useForm`\n- [Input](/components/Input) / [InputPassword](/components/InputPassword)\n- [Button](/components/Button)\n- [快速上手](/docs/quick-start)\n",
33662
+ "markdown": "---\ntitle: 登录表单\norder: 20\ndescription: 用 MForm + FormRules 做邮箱/密码登录校验。\n---\n\n# 登录表单\n\n把邮箱、密码和提交按钮组合成可直接复制的登录表单:声明式 `rules` 校验,提交时统一跑一遍。\n\n## 目标\n\n- 邮箱必填 + 格式校验\n- 密码必填 + 最短长度\n- 提交时 `validate()`,失败只展示字段错误,成功再继续业务逻辑\n\n## 何时使用\n\n- 登录 / 注册页、账号切换弹窗等短表单\n- 需要字段级错误文案,而不是一次弹全局 Toast\n\n## 步骤\n\n1. 安装并引入样式:`pnpm add morya-ui`,入口加 `import 'morya-ui/styles.css'`(按需导入可跳过全量样式)。\n2. 用 `reactive` 建 `model`,用 `FormRules` 按字段名写规则。\n3. `MForm` 绑定 `model` / `rules`,`validate-on=\"submit\"`;字段放在 `MFormItem` 里,并通过默认插槽拿到 `id` / `invalid`。\n4. 密码用 `MInputPassword`;邮箱用 `MInput type=\"email\"`。\n5. 在 `@submit` 里 `await formRef.validate()`,检查 `valid` 后再请求接口。\n\n`validate()` **始终 resolve**,不会 reject;失败时看 `{ valid, errors }`。\n\n## 预览\n\n```vue preview src=\"./demos/recipes/FormLogin.zh.vue\"\n```\n\n## 检查清单\n\n- [ ] `name` 与 `rules` 键一致(`email` / `password`)\n- [ ] 控件收到 `id` 与 `invalid`,错误能关联到 label\n- [ ] 密码使用 `MInputPassword`(不要用明文 `type=\"password\"` 凑合,除非刻意简化)\n- [ ] 提交按钮 `html-type=\"submit\"`,避免只绑 `@click` 漏掉原生提交\n- [ ] 已引入 `morya-ui` 与样式\n\n## 相关\n\n- [Form](/components/Form):声明式 rules、`useForm`\n- [Input](/components/Input) / [InputPassword](/components/InputPassword)\n- [Button](/components/Button)\n- [快速上手](/docs/quick-start)\n",
33430
33663
  "sections": [
33431
33664
  {
33432
33665
  "title": "",
@@ -33456,7 +33689,7 @@
33456
33689
  {
33457
33690
  "title": "检查清单",
33458
33691
  "id": "检查清单",
33459
- "body": "- [ ] `name` 与 `rules` 键一致(`email` / `password`)\n- [ ] 控件收到 `id` 与 `invalid`,错误能关联到 label\n- [ ] 密码使用 `MInputPassword`(不要用明文 `type=\"password\"` 凑合,除非刻意简化)\n- [ ] 提交按钮 `native-type=\"submit\"`,避免只绑 `@click` 漏掉原生提交\n- [ ] 已引入 `morya-ui` 与样式"
33692
+ "body": "- [ ] `name` 与 `rules` 键一致(`email` / `password`)\n- [ ] 控件收到 `id` 与 `invalid`,错误能关联到 label\n- [ ] 密码使用 `MInputPassword`(不要用明文 `type=\"password\"` 凑合,除非刻意简化)\n- [ ] 提交按钮 `html-type=\"submit\"`,避免只绑 `@click` 漏掉原生提交\n- [ ] 已引入 `morya-ui` 与样式"
33460
33693
  },
33461
33694
  {
33462
33695
  "title": "相关",
@@ -33468,7 +33701,7 @@
33468
33701
  "en-US": {
33469
33702
  "title": "Login form",
33470
33703
  "description": "Build an email/password login form with MForm and FormRules.",
33471
- "markdown": "---\ntitle: Login form\norder: 20\ndescription: Build an email/password login form with MForm and FormRules.\n---\n\n# Login form\n\nA copy-paste login form with declarative `rules`: email + password, validate on submit.\n\n## Goal\n\n- Required email with format check\n- Required password with a minimum length\n- Call `validate()` on submit; show field errors first, then run your business logic\n\n## When to use\n\n- Sign-in / sign-up pages and short account dialogs\n- Field-level error copy instead of a single global toast\n\n## Steps\n\n1. Install and load styles: `pnpm add morya-ui`, then `import 'morya-ui/styles.css'` at the app entry (skip full CSS when using subpath imports).\n2. Keep values in a `reactive` `model` and declare `FormRules` keyed by field name.\n3. Bind `model` / `rules` on `MForm` with `validate-on=\"submit\"`. Wrap fields in `MFormItem` and pass `id` / `invalid` from the default slot.\n4. Use `MInputPassword` for the password and `MInput type=\"email\"` for the email.\n5. In `@submit`, `await formRef.validate()` and check `valid` before calling your API.\n\n`validate()` **always resolves** — it does not reject. On failure, inspect `{ valid, errors }`.\n\n## Preview\n\n```vue preview src=\"./demos/recipes/FormLogin.en.vue\"\n```\n\n## Checklist\n\n- [ ] `name` matches the `rules` keys (`email` / `password`)\n- [ ] Controls receive `id` and `invalid` so errors link to labels\n- [ ] Password uses `MInputPassword` (avoid a plain `type=\"password\"` unless you intentionally simplify)\n- [ ] Submit button uses `native-type=\"submit\"` so native form submit is not skipped\n- [ ] `morya-ui` and styles are imported\n\n## Related\n\n- [Form](/components/Form): declarative rules, `useForm`\n- [Input](/components/Input) / [InputPassword](/components/InputPassword)\n- [Button](/components/Button)\n- [Quick start](/docs/quick-start)\n",
33704
+ "markdown": "---\ntitle: Login form\norder: 20\ndescription: Build an email/password login form with MForm and FormRules.\n---\n\n# Login form\n\nA copy-paste login form with declarative `rules`: email + password, validate on submit.\n\n## Goal\n\n- Required email with format check\n- Required password with a minimum length\n- Call `validate()` on submit; show field errors first, then run your business logic\n\n## When to use\n\n- Sign-in / sign-up pages and short account dialogs\n- Field-level error copy instead of a single global toast\n\n## Steps\n\n1. Install and load styles: `pnpm add morya-ui`, then `import 'morya-ui/styles.css'` at the app entry (skip full CSS when using subpath imports).\n2. Keep values in a `reactive` `model` and declare `FormRules` keyed by field name.\n3. Bind `model` / `rules` on `MForm` with `validate-on=\"submit\"`. Wrap fields in `MFormItem` and pass `id` / `invalid` from the default slot.\n4. Use `MInputPassword` for the password and `MInput type=\"email\"` for the email.\n5. In `@submit`, `await formRef.validate()` and check `valid` before calling your API.\n\n`validate()` **always resolves** — it does not reject. On failure, inspect `{ valid, errors }`.\n\n## Preview\n\n```vue preview src=\"./demos/recipes/FormLogin.en.vue\"\n```\n\n## Checklist\n\n- [ ] `name` matches the `rules` keys (`email` / `password`)\n- [ ] Controls receive `id` and `invalid` so errors link to labels\n- [ ] Password uses `MInputPassword` (avoid a plain `type=\"password\"` unless you intentionally simplify)\n- [ ] Submit button uses `html-type=\"submit\"` so native form submit is not skipped\n- [ ] `morya-ui` and styles are imported\n\n## Related\n\n- [Form](/components/Form): declarative rules, `useForm`\n- [Input](/components/Input) / [InputPassword](/components/InputPassword)\n- [Button](/components/Button)\n- [Quick start](/docs/quick-start)\n",
33472
33705
  "sections": [
33473
33706
  {
33474
33707
  "title": "",
@@ -33498,7 +33731,7 @@
33498
33731
  {
33499
33732
  "title": "Checklist",
33500
33733
  "id": "checklist",
33501
- "body": "- [ ] `name` matches the `rules` keys (`email` / `password`)\n- [ ] Controls receive `id` and `invalid` so errors link to labels\n- [ ] Password uses `MInputPassword` (avoid a plain `type=\"password\"` unless you intentionally simplify)\n- [ ] Submit button uses `native-type=\"submit\"` so native form submit is not skipped\n- [ ] `morya-ui` and styles are imported"
33734
+ "body": "- [ ] `name` matches the `rules` keys (`email` / `password`)\n- [ ] Controls receive `id` and `invalid` so errors link to labels\n- [ ] Password uses `MInputPassword` (avoid a plain `type=\"password\"` unless you intentionally simplify)\n- [ ] Submit button uses `html-type=\"submit\"` so native form submit is not skipped\n- [ ] `morya-ui` and styles are imported"
33502
33735
  },
33503
33736
  {
33504
33737
  "title": "Related",
@@ -33614,7 +33847,7 @@
33614
33847
  "zh-CN": {
33615
33848
  "title": "确认流程",
33616
33849
  "description": "声明式 MConfirmDialog 与命令式 useConfirm 两种确认交互。",
33617
- "markdown": "---\ntitle: 确认流程\norder: 22\ndescription: 声明式 MConfirmDialog 与命令式 useConfirm 两种确认交互。\n---\n\n# 确认流程\n\n删除、停用、覆盖写入等不可轻易撤销的操作,先让用户点一次确认。Morya 提供模板声明式与 `useConfirm().require()` 命令式两条路。\n\n## 目标\n\n- 模板里用 `MConfirmDialog` + `v-model` 控制显隐\n- 脚本里用 `useConfirm().require(...)`,得到 `Promise<boolean>`\n- 危险操作用 `accept-severity=\"danger\"`(可选 `type=\"warning\"`)\n\n## 何时使用\n\n| 方式 | 适合 |\n| --- | --- |\n| 声明式 `MConfirmDialog` | 文案/插槽固定、需要和页面状态绑定、要自定义 footer |\n| 命令式 `useConfirm` | 工具函数、表格行操作、不想为每个入口挂一个 Dialog |\n| Dialog `modal.confirm` | 需要完整 Dialog 能力(异步 `onOk`、自定义内容)。见 [Dialog](/components/Dialog) |\n\n## 步骤\n\n1. **声明式**:`visible` 驱动 `v-model`;按钮打开对话框;监听 `@accept` / `@reject`。\n2. **命令式**:`const confirm = useConfirm()`,`await confirm.require({ header, message, ... })`;`true` 表示确认,`false` 表示取消或关闭。\n3. 确认按钮语义色用 `acceptSeverity: 'danger'`;需要状态图标时加 `type: 'warning'`。\n4. 真正删数据放在确认之后;若删除是异步的,可在声明式路径用 `beforeAccept`,或命令式路径里先 `await` 再反馈结果。\n\n## 预览\n\n```vue preview src=\"./demos/recipes/ConfirmFlow.zh.vue\"\n```\n\n## 检查清单\n\n- [ ] 危险操作文案写清楚不可撤销后果\n- [ ] 声明式路径绑定了 `@accept` / `@reject`(或等价业务回调)\n- [ ] 命令式路径处理了 `false`(取消 / Esc / 点遮罩)\n- [ ] 不要把确认框当成普通通知(短反馈用 `message` / `toast`)\n- [ ] 已引入 `morya-ui` 与样式\n\n## 相关\n\n- [ConfirmDialog](/components/ConfirmDialog):`MConfirmDialog`、`useConfirm`\n- [Dialog](/components/Dialog):`useModal` / `modal.confirm`\n- [约定](/docs/conventions):反馈选型\n- [快速上手](/docs/quick-start)\n",
33850
+ "markdown": "---\ntitle: 确认流程\norder: 22\ndescription: 声明式 MConfirmDialog 与命令式 useConfirm 两种确认交互。\n---\n\n# 确认流程\n\n删除、停用、覆盖写入等不可轻易撤销的操作,先让用户点一次确认。Morya 提供模板声明式与 `useConfirm().require()` 命令式两条路。\n\n## 目标\n\n- 模板里用 `MConfirmDialog` + `v-model` 控制显隐\n- 脚本里用 `useConfirm().require(...)`,得到 `Promise<boolean>`\n- 危险操作用 `accept-color=\"danger\"`(可选 `type=\"warning\"`)\n\n## 何时使用\n\n| 方式 | 适合 |\n| --- | --- |\n| 声明式 `MConfirmDialog` | 文案/插槽固定、需要和页面状态绑定、要自定义 footer |\n| 命令式 `useConfirm` | 工具函数、表格行操作、不想为每个入口挂一个 Dialog |\n| Dialog `modal.confirm` | 需要完整 Dialog 能力(异步 `onOk`、自定义内容)。见 [Dialog](/components/Dialog) |\n\n## 步骤\n\n1. **声明式**:`visible` 驱动 `v-model`;按钮打开对话框;监听 `@accept` / `@reject`。\n2. **命令式**:`const confirm = useConfirm()`,`await confirm.require({ header, message, ... })`;`true` 表示确认,`false` 表示取消或关闭。\n3. 确认按钮颜色用 `acceptColor: 'danger'`;需要状态图标时加 `type: 'warning'`。\n4. 真正删数据放在确认之后;若删除是异步的,可在声明式路径用 `beforeAccept`,或命令式路径里先 `await` 再反馈结果。\n\n## 预览\n\n```vue preview src=\"./demos/recipes/ConfirmFlow.zh.vue\"\n```\n\n## 检查清单\n\n- [ ] 危险操作文案写清楚不可撤销后果\n- [ ] 声明式路径绑定了 `@accept` / `@reject`(或等价业务回调)\n- [ ] 命令式路径处理了 `false`(取消 / Esc / 点遮罩)\n- [ ] 不要把确认框当成普通通知(短反馈用 `message` / `toast`)\n- [ ] 已引入 `morya-ui` 与样式\n\n## 相关\n\n- [ConfirmDialog](/components/ConfirmDialog):`MConfirmDialog`、`useConfirm`\n- [Dialog](/components/Dialog):`useModal` / `modal.confirm`\n- [约定](/docs/conventions):反馈选型\n- [快速上手](/docs/quick-start)\n",
33618
33851
  "sections": [
33619
33852
  {
33620
33853
  "title": "",
@@ -33624,7 +33857,7 @@
33624
33857
  {
33625
33858
  "title": "目标",
33626
33859
  "id": "目标",
33627
- "body": "- 模板里用 `MConfirmDialog` + `v-model` 控制显隐\n- 脚本里用 `useConfirm().require(...)`,得到 `Promise<boolean>`\n- 危险操作用 `accept-severity=\"danger\"`(可选 `type=\"warning\"`)"
33860
+ "body": "- 模板里用 `MConfirmDialog` + `v-model` 控制显隐\n- 脚本里用 `useConfirm().require(...)`,得到 `Promise<boolean>`\n- 危险操作用 `accept-color=\"danger\"`(可选 `type=\"warning\"`)"
33628
33861
  },
33629
33862
  {
33630
33863
  "title": "何时使用",
@@ -33634,7 +33867,7 @@
33634
33867
  {
33635
33868
  "title": "步骤",
33636
33869
  "id": "步骤",
33637
- "body": "1. **声明式**:`visible` 驱动 `v-model`;按钮打开对话框;监听 `@accept` / `@reject`。\n2. **命令式**:`const confirm = useConfirm()`,`await confirm.require({ header, message, ... })`;`true` 表示确认,`false` 表示取消或关闭。\n3. 确认按钮语义色用 `acceptSeverity: 'danger'`;需要状态图标时加 `type: 'warning'`。\n4. 真正删数据放在确认之后;若删除是异步的,可在声明式路径用 `beforeAccept`,或命令式路径里先 `await` 再反馈结果。"
33870
+ "body": "1. **声明式**:`visible` 驱动 `v-model`;按钮打开对话框;监听 `@accept` / `@reject`。\n2. **命令式**:`const confirm = useConfirm()`,`await confirm.require({ header, message, ... })`;`true` 表示确认,`false` 表示取消或关闭。\n3. 确认按钮颜色用 `acceptColor: 'danger'`;需要状态图标时加 `type: 'warning'`。\n4. 真正删数据放在确认之后;若删除是异步的,可在声明式路径用 `beforeAccept`,或命令式路径里先 `await` 再反馈结果。"
33638
33871
  },
33639
33872
  {
33640
33873
  "title": "预览",
@@ -33656,7 +33889,7 @@
33656
33889
  "en-US": {
33657
33890
  "title": "Confirm flow",
33658
33891
  "description": "Declarative MConfirmDialog and imperative useConfirm for destructive actions.",
33659
- "markdown": "---\ntitle: Confirm flow\norder: 22\ndescription: Declarative MConfirmDialog and imperative useConfirm for destructive actions.\n---\n\n# Confirm flow\n\nFor deletes, disables, and other hard-to-undo actions, ask once before running them. Morya covers both a template-driven dialog and `useConfirm().require()`.\n\n## Goal\n\n- Control `MConfirmDialog` with `v-model` in the template\n- Call `useConfirm().require(...)` from script and await a `Promise<boolean>`\n- Mark destructive accepts with `accept-severity=\"danger\"` (optional `type=\"warning\"`)\n\n## When to use\n\n| Approach | Best for |\n| --- | --- |\n| Declarative `MConfirmDialog` | Fixed copy/slots, state bound to the page, custom footer |\n| Imperative `useConfirm` | Helpers, per-row table actions, avoiding one Dialog per entry |\n| Dialog `modal.confirm` | Full Dialog features (async `onOk`, custom content). See [Dialog](/components/Dialog) |\n\n## Steps\n\n1. **Declarative**: drive visibility with `v-model`; open from a button; handle `@accept` / `@reject`.\n2. **Imperative**: `const confirm = useConfirm()`, then `await confirm.require({ header, message, ... })`. `true` means accepted; `false` means cancelled or dismissed.\n3. Set `acceptSeverity: 'danger'` for destructive confirms; add `type: 'warning'` when you want a status icon.\n4. Run the real side effect after confirm. For async deletes, use `beforeAccept` on the declarative path, or `await` your API after `require()` resolves `true`.\n\n## Preview\n\n```vue preview src=\"./demos/recipes/ConfirmFlow.en.vue\"\n```\n\n## Checklist\n\n- [ ] Copy spells out the irreversible consequence\n- [ ] Declarative path wires `@accept` / `@reject` (or equivalent handlers)\n- [ ] Imperative path handles `false` (cancel / Esc / outside click)\n- [ ] Do not misuse confirms as toasts (short feedback belongs to `message` / `toast`)\n- [ ] `morya-ui` and styles are imported\n\n## Related\n\n- [ConfirmDialog](/components/ConfirmDialog): `MConfirmDialog`, `useConfirm`\n- [Dialog](/components/Dialog): `useModal` / `modal.confirm`\n- [Conventions](/docs/conventions): feedback selection\n- [Quick start](/docs/quick-start)\n",
33892
+ "markdown": "---\ntitle: Confirm flow\norder: 22\ndescription: Declarative MConfirmDialog and imperative useConfirm for destructive actions.\n---\n\n# Confirm flow\n\nFor deletes, disables, and other hard-to-undo actions, ask once before running them. Morya covers both a template-driven dialog and `useConfirm().require()`.\n\n## Goal\n\n- Control `MConfirmDialog` with `v-model` in the template\n- Call `useConfirm().require(...)` from script and await a `Promise<boolean>`\n- Mark destructive accepts with `accept-color=\"danger\"` (optional `type=\"warning\"`)\n\n## When to use\n\n| Approach | Best for |\n| --- | --- |\n| Declarative `MConfirmDialog` | Fixed copy/slots, state bound to the page, custom footer |\n| Imperative `useConfirm` | Helpers, per-row table actions, avoiding one Dialog per entry |\n| Dialog `modal.confirm` | Full Dialog features (async `onOk`, custom content). See [Dialog](/components/Dialog) |\n\n## Steps\n\n1. **Declarative**: drive visibility with `v-model`; open from a button; handle `@accept` / `@reject`.\n2. **Imperative**: `const confirm = useConfirm()`, then `await confirm.require({ header, message, ... })`. `true` means accepted; `false` means cancelled or dismissed.\n3. Set `acceptColor: 'danger'` for destructive confirms; add `type: 'warning'` when you want a status icon.\n4. Run the real side effect after confirm. For async deletes, use `beforeAccept` on the declarative path, or `await` your API after `require()` resolves `true`.\n\n## Preview\n\n```vue preview src=\"./demos/recipes/ConfirmFlow.en.vue\"\n```\n\n## Checklist\n\n- [ ] Copy spells out the irreversible consequence\n- [ ] Declarative path wires `@accept` / `@reject` (or equivalent handlers)\n- [ ] Imperative path handles `false` (cancel / Esc / outside click)\n- [ ] Do not misuse confirms as toasts (short feedback belongs to `message` / `toast`)\n- [ ] `morya-ui` and styles are imported\n\n## Related\n\n- [ConfirmDialog](/components/ConfirmDialog): `MConfirmDialog`, `useConfirm`\n- [Dialog](/components/Dialog): `useModal` / `modal.confirm`\n- [Conventions](/docs/conventions): feedback selection\n- [Quick start](/docs/quick-start)\n",
33660
33893
  "sections": [
33661
33894
  {
33662
33895
  "title": "",
@@ -33666,7 +33899,7 @@
33666
33899
  {
33667
33900
  "title": "Goal",
33668
33901
  "id": "goal",
33669
- "body": "- Control `MConfirmDialog` with `v-model` in the template\n- Call `useConfirm().require(...)` from script and await a `Promise<boolean>`\n- Mark destructive accepts with `accept-severity=\"danger\"` (optional `type=\"warning\"`)"
33902
+ "body": "- Control `MConfirmDialog` with `v-model` in the template\n- Call `useConfirm().require(...)` from script and await a `Promise<boolean>`\n- Mark destructive accepts with `accept-color=\"danger\"` (optional `type=\"warning\"`)"
33670
33903
  },
33671
33904
  {
33672
33905
  "title": "When to use",
@@ -33676,7 +33909,7 @@
33676
33909
  {
33677
33910
  "title": "Steps",
33678
33911
  "id": "steps",
33679
- "body": "1. **Declarative**: drive visibility with `v-model`; open from a button; handle `@accept` / `@reject`.\n2. **Imperative**: `const confirm = useConfirm()`, then `await confirm.require({ header, message, ... })`. `true` means accepted; `false` means cancelled or dismissed.\n3. Set `acceptSeverity: 'danger'` for destructive confirms; add `type: 'warning'` when you want a status icon.\n4. Run the real side effect after confirm. For async deletes, use `beforeAccept` on the declarative path, or `await` your API after `require()` resolves `true`."
33912
+ "body": "1. **Declarative**: drive visibility with `v-model`; open from a button; handle `@accept` / `@reject`.\n2. **Imperative**: `const confirm = useConfirm()`, then `await confirm.require({ header, message, ... })`. `true` means accepted; `false` means cancelled or dismissed.\n3. Set `acceptColor: 'danger'` for destructive confirms; add `type: 'warning'` when you want a status icon.\n4. Run the real side effect after confirm. For async deletes, use `beforeAccept` on the declarative path, or `await` your API after `require()` resolves `true`."
33680
33913
  },
33681
33914
  {
33682
33915
  "title": "Preview",
@@ -33980,12 +34213,12 @@
33980
34213
  "zh-CN": {
33981
34214
  "title": "约定",
33982
34215
  "description": "morya-ui 的命名、语义色、尺寸与主题约定。",
33983
- "markdown": "---\ntitle: 约定\norder: 35\ndescription: morya-ui 的命名、语义色、尺寸与主题约定。\n---\n\n# 约定\n\nMorya UI 用自己的词表描述界面:组件前缀 `M*`、语义色 `severity`、外观 `variant`、设计令牌 `--m-*`。写业务页时直接跟这套约定走。\n\n## 组件与令牌\n\n| 约定 | 说明 |\n| --- | --- |\n| 组件名 | 一律 `M` 前缀:`MButton`、`MDialog`、`MTable` |\n| 主题 | `MConfigProvider` + `useTheme` / `useDensity` / `useMotion` |\n| 颜色与几何 | 只用 `--m-*`,品牌色改 `--m-color-primary` |\n| 控件高度 | 默认 medium `32px`,圆角 `--m-control-radius` |\n| 字重 | 控件文案默认 400 |\n\n完整变量见 [设计令牌](/docs/design-tokens),覆盖方式见 [主题](/docs/theme)。\n\n## 语义与外观\n\n| 词 | 用在 |\n| --- | --- |\n| `severity` | 语义色:`primary` / `secondary` / `success` / `info` / `warning` / `danger` |\n| `variant` | 外观:`outlined` / `dashed` / `text` / `link` / `ghost` 等 |\n| `fluid` | 通栏(占满父级宽度) |\n| `size` | `small` / `medium` / `large`(部分控件仍接受 `sm` / `md` / `lg`) |\n| `status` | 表单控件校验态:`error` / `warning` |\n\n按钮默认就是主色实心;次要操作用 `severity=\"secondary\"`,危险操作用 `severity=\"danger\"`。\n\n## 反馈\n\n| 场景 | 用法 |\n| --- | --- |\n| 短操作结果 | `message` / `MMessage` |\n| 摘要 + 详情、异步过程 | `toast` / `MToast` |\n| 需要确认 | `MConfirmDialog` / `MConfirmPopup` / `useConfirm` |\n| 页面内常驻说明 | `MAlert` |\n| 阻塞等待 | `MLoading`(细环可用 `MProgressSpinner`) |\n| 进度 | `MProgressBar` |\n| 空态 / 结果页 | `MEmpty` / `MResult` |\n\n## 布局与页面\n\n后台骨架用 `MLayout` 系列;列表/筛选/统计块用 `MPage*`。间距容器是 `MSpace` / `MFlex` / `MGrid`,相邻按钮拼组用 `MButtonGroup`。\n\n## 本库特有的能力\n\nDock、Terminal、Knob、Page 套件、以及 MCP / Agent Skill 是同一套令牌上的产品面。选型看 [组件文档](/components/Button) 和仓库 `DESIGN.md`。\n",
34216
+ "markdown": "---\ntitle: 约定\norder: 35\ndescription: morya-ui 的命名、语义色、尺寸与主题约定。\n---\n\n# 约定\n\nMorya UI 用自己的词表描述界面:组件前缀 `M*`、语义色 `severity`(Badge / Tag / Alert 等)、Button 的 `type` / `color` / `variant`、设计令牌 `--m-*`。写业务页时直接跟这套约定走。\n\n## 组件与令牌\n\n| 约定 | 说明 |\n| --- | --- |\n| 组件名 | 一律 `M` 前缀:`MButton`、`MDialog`、`MTable` |\n| 主题 | `MConfigProvider` + `useTheme` / `useDensity` / `useMotion` |\n| 颜色与几何 | 只用 `--m-*`,品牌色改 `--m-color-primary` |\n| 控件高度 | 默认 medium `32px`,圆角 `--m-control-radius` |\n| 字重 | 控件文案默认 400 |\n\n完整变量见 [设计令牌](/docs/design-tokens),覆盖方式见 [主题](/docs/theme)。\n\n## 语义与外观\n\n| 词 | 用在 |\n| --- | --- |\n| `severity` | Badge / Tag / Alert 等语义色:`primary` / `secondary` / `success` / `info` / `warning` / `danger` |\n| `type` / `color` / `variant` | Button:`type` 糖(`primary` / `dashed` / `text` / `link`…)+ `color` + `variant`(`solid` / `outlined` / `filled`…) |\n| `fluid` / `block` | 通栏;字段多用 `fluid`,Button / ButtonGroup 用 `block` |\n| `size` | `small` / `medium` / `large`(部分控件仍接受 `sm` / `md` / `lg`) |\n| `status` | 表单控件校验态:`error` / `warning` |\n\n按钮默认是灰色描边(`default` + `outlined`);主实心用 `type=\"primary\"`,次要动作保持默认或 `type=\"text\"`,危险操作用 `danger` / `color=\"danger\"`。\n\n## 反馈\n\n| 场景 | 用法 |\n| --- | --- |\n| 短操作结果 | `message` / `MMessage` |\n| 摘要 + 详情、异步过程 | `toast` / `MToast` |\n| 需要确认 | `MConfirmDialog` / `MConfirmPopup` / `useConfirm` |\n| 页面内常驻说明 | `MAlert` |\n| 阻塞等待 | `MLoading`(细环可用 `MProgressSpinner`) |\n| 进度 | `MProgressBar` |\n| 空态 / 结果页 | `MEmpty` / `MResult` |\n\n## 布局与页面\n\n后台骨架用 `MLayout` 系列;列表/筛选/统计块用 `MPage*`。间距容器是 `MSpace` / `MFlex` / `MGrid`,相邻按钮拼组用 `MButtonGroup`。\n\n## 本库特有的能力\n\nDock、Terminal、Knob、Page 套件、以及 MCP / Agent Skill 是同一套令牌上的产品面。选型看 [组件文档](/components/Button) 和仓库 `DESIGN.md`。\n",
33984
34217
  "sections": [
33985
34218
  {
33986
34219
  "title": "",
33987
34220
  "id": "overview",
33988
- "body": "# 约定\n\nMorya UI 用自己的词表描述界面:组件前缀 `M*`、语义色 `severity`、外观 `variant`、设计令牌 `--m-*`。写业务页时直接跟这套约定走。"
34221
+ "body": "# 约定\n\nMorya UI 用自己的词表描述界面:组件前缀 `M*`、语义色 `severity`(Badge / Tag / Alert 等)、Button 的 `type` / `color` / `variant`、设计令牌 `--m-*`。写业务页时直接跟这套约定走。"
33989
34222
  },
33990
34223
  {
33991
34224
  "title": "组件与令牌",
@@ -33995,7 +34228,7 @@
33995
34228
  {
33996
34229
  "title": "语义与外观",
33997
34230
  "id": "语义与外观",
33998
- "body": "| 词 | 用在 |\n| --- | --- |\n| `severity` | 语义色:`primary` / `secondary` / `success` / `info` / `warning` / `danger` |\n| `variant` | 外观:`outlined` / `dashed` / `text` / `link` / `ghost` 等 |\n| `fluid` | 通栏(占满父级宽度) |\n| `size` | `small` / `medium` / `large`(部分控件仍接受 `sm` / `md` / `lg`) |\n| `status` | 表单控件校验态:`error` / `warning` |\n\n按钮默认就是主色实心;次要操作用 `severity=\"secondary\"`,危险操作用 `severity=\"danger\"`。"
34231
+ "body": "| 词 | 用在 |\n| --- | --- |\n| `severity` | Badge / Tag / Alert 等语义色:`primary` / `secondary` / `success` / `info` / `warning` / `danger` |\n| `type` / `color` / `variant` | Button:`type` 糖(`primary` / `dashed` / `text` / `link`…)+ `color` + `variant`(`solid` / `outlined` / `filled`…) |\n| `fluid` / `block` | 通栏;字段多用 `fluid`,Button / ButtonGroup 用 `block` |\n| `size` | `small` / `medium` / `large`(部分控件仍接受 `sm` / `md` / `lg`) |\n| `status` | 表单控件校验态:`error` / `warning` |\n\n按钮默认是灰色描边(`default` + `outlined`);主实心用 `type=\"primary\"`,次要动作保持默认或 `type=\"text\"`,危险操作用 `danger` / `color=\"danger\"`。"
33999
34232
  },
34000
34233
  {
34001
34234
  "title": "反馈",
@@ -34017,12 +34250,12 @@
34017
34250
  "en-US": {
34018
34251
  "title": "Conventions",
34019
34252
  "description": "Naming, severity, size, and theme conventions in morya-ui.",
34020
- "markdown": "---\ntitle: Conventions\norder: 35\ndescription: Naming, severity, size, and theme conventions in morya-ui.\n---\n\n# Conventions\n\nMorya UI has its own vocabulary: `M*` components, `severity` for tone, `variant` for appearance, and `--m-*` design tokens. Follow these conventions when you assemble product UI.\n\n## Components and tokens\n\n| Convention | Meaning |\n| --- | --- |\n| Names | Always `M` prefix: `MButton`, `MDialog`, `MTable` |\n| Theme | `MConfigProvider` plus `useTheme` / `useDensity` / `useMotion` |\n| Color and geometry | `--m-*` only; brand via `--m-color-primary` |\n| Control height | Medium default `32px`; radius `--m-control-radius` |\n| Type weight | Control copy defaults to 400 |\n\nSee [Design tokens](/docs/design-tokens) and [Theme](/docs/theme).\n\n## Tone and appearance\n\n| Word | Use |\n| --- | --- |\n| `severity` | Semantic color: `primary` / `secondary` / `success` / `info` / `warning` / `danger` |\n| `variant` | Appearance: `outlined` / `dashed` / `text` / `link` / `ghost`, etc. |\n| `fluid` | Full width of the parent |\n| `size` | `small` / `medium` / `large` (some controls still accept `sm` / `md` / `lg`) |\n| `status` | Field validation: `error` / `warning` |\n\nThe default button is a solid primary action. Use `severity=\"secondary\"` for quiet actions and `severity=\"danger\"` for destructive ones.\n\n## Feedback\n\n| Situation | Use |\n| --- | --- |\n| Short result | `message` / `MMessage` |\n| Summary + detail, or async work | `toast` / `MToast` |\n| Confirm | `MConfirmDialog` / `MConfirmPopup` / `useConfirm` |\n| Persistent in-page notice | `MAlert` |\n| Blocking wait | `MLoading` (`MProgressSpinner` for a thin ring) |\n| Progress | `MProgressBar` |\n| Empty / outcome | `MEmpty` / `MResult` |\n\n## Layout and pages\n\nAdmin chrome uses the `MLayout` family; list/filter/stat blocks use `MPage*`. Spacing containers are `MSpace` / `MFlex` / `MGrid`. Join adjacent buttons with `MButtonGroup`.\n\n## Distinctive surfaces\n\nDock, Terminal, Knob, the Page kit, and MCP / Agent Skill sit on the same token system. Prefer the [component docs](/components/Button) and repository `DESIGN.md` when choosing APIs.\n",
34253
+ "markdown": "---\ntitle: Conventions\norder: 35\ndescription: Naming, severity, size, and theme conventions in morya-ui.\n---\n\n# Conventions\n\nMorya UI has its own vocabulary: `M*` components, `severity` for tone on Badge / Tag / Alert, Button `type` / `color` / `variant`, and `--m-*` design tokens. Follow these conventions when you assemble product UI.\n\n## Components and tokens\n\n| Convention | Meaning |\n| --- | --- |\n| Names | Always `M` prefix: `MButton`, `MDialog`, `MTable` |\n| Theme | `MConfigProvider` plus `useTheme` / `useDensity` / `useMotion` |\n| Color and geometry | `--m-*` only; brand via `--m-color-primary` |\n| Control height | Medium default `32px`; radius `--m-control-radius` |\n| Type weight | Control copy defaults to 400 |\n\nSee [Design tokens](/docs/design-tokens) and [Theme](/docs/theme).\n\n## Tone and appearance\n\n| Word | Use |\n| --- | --- |\n| `severity` | Semantic color on Badge / Tag / Alert: `primary` / `secondary` / `success` / `info` / `warning` / `danger` |\n| `type` / `color` / `variant` | Button: `type` sugar (`primary` / `dashed` / `text` / `link`…) + `color` + `variant` (`solid` / `outlined` / `filled`…) |\n| `fluid` / `block` | Full width; fields mostly use `fluid`, Button / ButtonGroup use `block` |\n| `size` | `small` / `medium` / `large` (some controls still accept `sm` / `md` / `lg`) |\n| `status` | Field validation: `error` / `warning` |\n\nButtons default to gray outlined (`default` + `outlined`). Use `type=\"primary\"` for solid primary, keep the default or `type=\"text\"` for quiet actions, and `danger` / `color=\"danger\"` for destructive ones.\n\n## Feedback\n\n| Situation | Use |\n| --- | --- |\n| Short result | `message` / `MMessage` |\n| Summary + detail, or async work | `toast` / `MToast` |\n| Confirm | `MConfirmDialog` / `MConfirmPopup` / `useConfirm` |\n| Persistent in-page notice | `MAlert` |\n| Blocking wait | `MLoading` (`MProgressSpinner` for a thin ring) |\n| Progress | `MProgressBar` |\n| Empty / outcome | `MEmpty` / `MResult` |\n\n## Layout and pages\n\nAdmin chrome uses the `MLayout` family; list/filter/stat blocks use `MPage*`. Spacing containers are `MSpace` / `MFlex` / `MGrid`. Join adjacent buttons with `MButtonGroup`.\n\n## Distinctive surfaces\n\nDock, Terminal, Knob, the Page kit, and MCP / Agent Skill sit on the same token system. Prefer the [component docs](/components/Button) and repository `DESIGN.md` when choosing APIs.\n",
34021
34254
  "sections": [
34022
34255
  {
34023
34256
  "title": "",
34024
34257
  "id": "overview",
34025
- "body": "# Conventions\n\nMorya UI has its own vocabulary: `M*` components, `severity` for tone, `variant` for appearance, and `--m-*` design tokens. Follow these conventions when you assemble product UI."
34258
+ "body": "# Conventions\n\nMorya UI has its own vocabulary: `M*` components, `severity` for tone on Badge / Tag / Alert, Button `type` / `color` / `variant`, and `--m-*` design tokens. Follow these conventions when you assemble product UI."
34026
34259
  },
34027
34260
  {
34028
34261
  "title": "Components and tokens",
@@ -34032,7 +34265,7 @@
34032
34265
  {
34033
34266
  "title": "Tone and appearance",
34034
34267
  "id": "tone-and-appearance",
34035
- "body": "| Word | Use |\n| --- | --- |\n| `severity` | Semantic color: `primary` / `secondary` / `success` / `info` / `warning` / `danger` |\n| `variant` | Appearance: `outlined` / `dashed` / `text` / `link` / `ghost`, etc. |\n| `fluid` | Full width of the parent |\n| `size` | `small` / `medium` / `large` (some controls still accept `sm` / `md` / `lg`) |\n| `status` | Field validation: `error` / `warning` |\n\nThe default button is a solid primary action. Use `severity=\"secondary\"` for quiet actions and `severity=\"danger\"` for destructive ones."
34268
+ "body": "| Word | Use |\n| --- | --- |\n| `severity` | Semantic color on Badge / Tag / Alert: `primary` / `secondary` / `success` / `info` / `warning` / `danger` |\n| `type` / `color` / `variant` | Button: `type` sugar (`primary` / `dashed` / `text` / `link`…) + `color` + `variant` (`solid` / `outlined` / `filled`…) |\n| `fluid` / `block` | Full width; fields mostly use `fluid`, Button / ButtonGroup use `block` |\n| `size` | `small` / `medium` / `large` (some controls still accept `sm` / `md` / `lg`) |\n| `status` | Field validation: `error` / `warning` |\n\nButtons default to gray outlined (`default` + `outlined`). Use `type=\"primary\"` for solid primary, keep the default or `type=\"text\"` for quiet actions, and `danger` / `color=\"danger\"` for destructive ones."
34036
34269
  },
34037
34270
  {
34038
34271
  "title": "Feedback",