@morya-ui/mcp 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/data/catalog.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
- "generatedAt": "2026-09-23T09:00:38.573Z",
2
+ "generatedAt": "2026-09-24T08:45:45.036Z",
3
3
  "library": {
4
4
  "name": "morya-ui",
5
- "version": "0.3.1"
5
+ "version": "0.3.3"
6
6
  },
7
7
  "mcp": {
8
8
  "name": "@morya-ui/mcp",
9
- "version": "0.3.1"
9
+ "version": "0.3.3"
10
10
  },
11
11
  "components": [
12
12
  {
@@ -1406,12 +1406,36 @@
1406
1406
  "default": "false",
1407
1407
  "description": "强制方形纯图标按钮。"
1408
1408
  },
1409
+ {
1410
+ "name": "badge",
1411
+ "type": "string",
1412
+ "default": "—",
1413
+ "description": "徽标文本。"
1414
+ },
1415
+ {
1416
+ "name": "badgeSeverity",
1417
+ "type": "'secondary' | 'info' | 'success' | 'warn' | 'danger' | 'contrast' | null",
1418
+ "default": "null",
1419
+ "description": "徽标语义色。"
1420
+ },
1409
1421
  {
1410
1422
  "name": "severity",
1411
1423
  "type": "'secondary' | 'success' | 'info' | 'warn' | 'help' | 'danger' | 'contrast'",
1412
1424
  "default": "—",
1413
1425
  "description": "语义色。省略时为 primary。"
1414
1426
  },
1427
+ {
1428
+ "name": "color",
1429
+ "type": "string",
1430
+ "default": "—",
1431
+ "description": "自定义颜色,覆盖 `severity`。"
1432
+ },
1433
+ {
1434
+ "name": "size",
1435
+ "type": "'small' | 'large' | 'sm' | 'md' | 'lg'",
1436
+ "default": "—",
1437
+ "description": "尺寸。默认中等;兼容 `sm` / `lg`。"
1438
+ },
1415
1439
  {
1416
1440
  "name": "variant",
1417
1441
  "type": "'outlined' | 'text' | 'link' | 'ghost' | 'quaternary'",
@@ -1436,11 +1460,17 @@
1436
1460
  "default": "false",
1437
1461
  "description": "链接按钮。"
1438
1462
  },
1463
+ {
1464
+ "name": "underline",
1465
+ "type": "boolean",
1466
+ "default": "true",
1467
+ "description": "`link` 悬浮下划线。设为 `false` 可关闭。"
1468
+ },
1439
1469
  {
1440
1470
  "name": "ghost",
1441
1471
  "type": "boolean",
1442
1472
  "default": "false",
1443
- "description": "透明底按钮。"
1473
+ "description": "浅色填充,等同于 `text` 的悬浮态。"
1444
1474
  },
1445
1475
  {
1446
1476
  "name": "quaternary",
@@ -1449,10 +1479,10 @@
1449
1479
  "description": "极轻量文字按钮。"
1450
1480
  },
1451
1481
  {
1452
- "name": "color",
1453
- "type": "string",
1454
- "default": "—",
1455
- "description": "自定义颜色,覆盖 `severity`。"
1482
+ "name": "plain",
1483
+ "type": "boolean",
1484
+ "default": "false",
1485
+ "description": "浅色填充,等同于 `outlined` 的悬浮态;也可与 `text` / `outlined` 组合弱化。"
1456
1486
  },
1457
1487
  {
1458
1488
  "name": "raised",
@@ -1466,18 +1496,6 @@
1466
1496
  "default": "false",
1467
1497
  "description": "全圆角。"
1468
1498
  },
1469
- {
1470
- "name": "plain",
1471
- "type": "boolean",
1472
- "default": "false",
1473
- "description": "弱化色,常与 `text` / `outlined` 组合。"
1474
- },
1475
- {
1476
- "name": "size",
1477
- "type": "'small' | 'large' | 'sm' | 'md' | 'lg'",
1478
- "default": "—",
1479
- "description": "尺寸。默认中等;兼容 `sm` / `lg`。"
1480
- },
1481
1499
  {
1482
1500
  "name": "fluid",
1483
1501
  "type": "boolean",
@@ -1497,22 +1515,16 @@
1497
1515
  "description": "禁用。"
1498
1516
  },
1499
1517
  {
1500
- "name": "badge",
1501
- "type": "string",
1502
- "default": "—",
1503
- "description": "徽标文本。"
1504
- },
1505
- {
1506
- "name": "badgeSeverity",
1507
- "type": "'secondary' | 'info' | 'success' | 'warn' | 'danger' | 'contrast' | null",
1508
- "default": "null",
1509
- "description": "徽标语义色。"
1518
+ "name": "ripple",
1519
+ "type": "boolean",
1520
+ "default": "false",
1521
+ "description": "点击水波纹。设为 `true` 可开启。"
1510
1522
  },
1511
1523
  {
1512
- "name": "autofocus",
1524
+ "name": "press",
1513
1525
  "type": "boolean",
1514
1526
  "default": "false",
1515
- "description": "原生 autofocus。"
1527
+ "description": "按下时轻微缩放。设为 `true` 可开启。"
1516
1528
  },
1517
1529
  {
1518
1530
  "name": "nativeType",
@@ -1520,6 +1532,12 @@
1520
1532
  "default": "'button'",
1521
1533
  "description": "原生 button type。"
1522
1534
  },
1535
+ {
1536
+ "name": "autofocus",
1537
+ "type": "boolean",
1538
+ "default": "false",
1539
+ "description": "原生 autofocus。"
1540
+ },
1523
1541
  {
1524
1542
  "name": "ariaLabel",
1525
1543
  "type": "string",
@@ -1592,7 +1610,7 @@
1592
1610
  "sectionId": "styles",
1593
1611
  "lang": "vue",
1594
1612
  "preview": true,
1595
- "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 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>",
1613
+ "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>",
1596
1614
  "locale": "zh-CN"
1597
1615
  },
1598
1616
  {
@@ -1601,7 +1619,7 @@
1601
1619
  "sectionId": "text-link",
1602
1620
  "lang": "vue",
1603
1621
  "preview": true,
1604
- "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 Secondary\" link severity=\"secondary\" />\n </div>\n</template>",
1622
+ "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>",
1605
1623
  "locale": "zh-CN"
1606
1624
  },
1607
1625
  {
@@ -1682,7 +1700,7 @@
1682
1700
  "sectionId": "styles",
1683
1701
  "lang": "vue",
1684
1702
  "preview": true,
1685
- "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 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>",
1703
+ "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>",
1686
1704
  "locale": "en-US"
1687
1705
  },
1688
1706
  {
@@ -1691,7 +1709,7 @@
1691
1709
  "sectionId": "text-link",
1692
1710
  "lang": "vue",
1693
1711
  "preview": true,
1694
- "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 Secondary\" link severity=\"secondary\" />\n </div>\n</template>",
1712
+ "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>",
1695
1713
  "locale": "en-US"
1696
1714
  },
1697
1715
  {
@@ -1773,12 +1791,12 @@
1773
1791
  {
1774
1792
  "id": "text-link",
1775
1793
  "title": "Text & Link",
1776
- "body": "`text` 为轻量文字按钮;`link` 呈现为内联链接样式。二者均可与 `severity` 组合。\n\n```vue preview src=\"./demos/TextAndLink.vue\"\n```"
1794
+ "body": "`text` 为轻量文字按钮;`link` 呈现为无背景的内联链接样式,默认悬浮下划线,设 `:underline=\"false\"` 可关闭。二者均可与 `severity` 组合。\n\n```vue preview src=\"./demos/TextAndLink.vue\"\n```"
1777
1795
  },
1778
1796
  {
1779
1797
  "id": "ghost-quaternary",
1780
1798
  "title": "Ghost & Quaternary",
1781
- "body": "`ghost` 为透明底 + 描边色文字;`quaternary` 更克制,适合工具栏次要操作。也可通过 `variant` 指定。\n\n```vue preview src=\"./demos/GhostAndQuaternary.vue\"\n```"
1799
+ "body": "`ghost` 为浅色填充,等同于 `text` 的悬浮态;`quaternary` 更克制,适合工具栏次要操作。也可通过 `variant` 指定。\n\n```vue preview src=\"./demos/GhostAndQuaternary.vue\"\n```"
1782
1800
  },
1783
1801
  {
1784
1802
  "id": "button-group",
@@ -1803,7 +1821,7 @@
1803
1821
  {
1804
1822
  "id": "props",
1805
1823
  "title": "Props",
1806
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 按钮文案。存在默认插槽内容时以插槽为准。 |\n| `icon` | `IconName \\| Component` | — | 图标名称或自定义组件。 |\n| `iconPos` | `'left' \\| 'right' \\| 'top' \\| 'bottom'` | `'left'` | 图标相对标签的位置。 |\n| `iconOnly` | `boolean` | `false` | 强制方形纯图标按钮。 |\n| `severity` | `'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast'` | — | 语义色。省略时为 primary。 |\n| `variant` | `'outlined' \\| 'text' \\| 'link' \\| 'ghost' \\| 'quaternary'` | — | 样式变体快捷方式,等价于对应布尔 prop。 |\n| `outlined` | `boolean` | `false` | 描边按钮。 |\n| `text` | `boolean` | `false` | 文字按钮。 |\n| `link` | `boolean` | `false` | 链接按钮。 |\n| `ghost` | `boolean` | `false` | 透明底按钮。 |\n| `quaternary` | `boolean` | `false` | 极轻量文字按钮。 |\n| `color` | `string` | — | 自定义颜色,覆盖 `severity`。 |\n| `raised` | `boolean` | `false` | 浮起阴影。 |\n| `rounded` | `boolean` | `false` | 全圆角。 |\n| `plain` | `boolean` | `false` | 弱化色,常与 `text` / `outlined` 组合。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。默认中等;兼容 `sm` / `lg`。 |\n| `fluid` | `boolean` | `false` | 宽度撑满容器。 |\n| `loading` | `boolean` | `false` | 加载中,禁用点击并显示 spinner。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `badge` | `string` | — | 徽标文本。 |\n| `badgeSeverity` | `'secondary' \\| 'info' \\| 'success' \\| 'warn' \\| 'danger' \\| 'contrast' \\| null` | `null` | 徽标语义色。 |\n| `autofocus` | `boolean` | `false` | 原生 autofocus。 |\n| `nativeType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | 原生 button type。 |\n| `ariaLabel` | `string` | — | 可访问名称;图标按钮建议提供。 |"
1824
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\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' \\| 'text' \\| 'link' \\| 'ghost' \\| 'quaternary'` | — | 样式变体快捷方式,等价于对应布尔 prop。 |\n| `outlined` | `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` | 全圆角。 |\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` | — | 可访问名称;图标按钮建议提供。 |"
1807
1825
  },
1808
1826
  {
1809
1827
  "id": "events",
@@ -1826,7 +1844,7 @@
1826
1844
  "body": "- 渲染原生 `<button>`。\n- 纯图标按钮请设置 `ariaLabel`(或可访问的文本标签)。\n- `loading` 时设置 `aria-busy`,并禁用交互。"
1827
1845
  }
1828
1846
  ],
1829
- "markdown": "---\ntitle: Button\ncategory: 01 / BASIC\ndescription: 按钮用于触发即时动作。\n---\n\n# Button\n\n按钮用于触发即时动作。\n\n## 引入\n\n```ts\nimport { MButton } from 'morya-ui'\n```\n\n## 基础用法\n\n通过默认插槽或 `label` 展示按钮文案。\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\n使用 `severity` 定义按钮语义色;省略时为 primary。\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Styles\n\n`outlined`、`text`、`link`、`raised`、`rounded`、`plain` 可自由组合。\n\n```vue preview src=\"./demos/Styles.vue\"\n```\n\n## Text & Link\n\n`text` 为轻量文字按钮;`link` 呈现为内联链接样式。二者均可与 `severity` 组合。\n\n```vue preview src=\"./demos/TextAndLink.vue\"\n```\n\n## Ghost & Quaternary\n\n`ghost` 为透明底 + 描边色文字;`quaternary` 更克制,适合工具栏次要操作。也可通过 `variant` 指定。\n\n```vue preview src=\"./demos/GhostAndQuaternary.vue\"\n```\n\n## Button Group\n\n`MButtonGroup` 将相邻按钮拼成一组。\n\n```vue preview src=\"./demos/ButtonGroup.zh.vue\"\n```\n\n## Icons & Badge\n\n支持 `icon`、`iconPos`、`iconOnly`,以及 `badge` 徽标。\n\n```vue preview src=\"./demos/IconsAndBadge.vue\"\n```\n\n## Loading\n\n`loading` 状态下显示 spinner 并阻止点击。\n\n```vue preview src=\"./demos/Loading.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.vue\"\n```\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| `severity` | `'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast'` | — | 语义色。省略时为 primary。 |\n| `variant` | `'outlined' \\| 'text' \\| 'link' \\| 'ghost' \\| 'quaternary'` | — | 样式变体快捷方式,等价于对应布尔 prop。 |\n| `outlined` | `boolean` | `false` | 描边按钮。 |\n| `text` | `boolean` | `false` | 文字按钮。 |\n| `link` | `boolean` | `false` | 链接按钮。 |\n| `ghost` | `boolean` | `false` | 透明底按钮。 |\n| `quaternary` | `boolean` | `false` | 极轻量文字按钮。 |\n| `color` | `string` | — | 自定义颜色,覆盖 `severity`。 |\n| `raised` | `boolean` | `false` | 浮起阴影。 |\n| `rounded` | `boolean` | `false` | 全圆角。 |\n| `plain` | `boolean` | `false` | 弱化色,常与 `text` / `outlined` 组合。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 尺寸。默认中等;兼容 `sm` / `lg`。 |\n| `fluid` | `boolean` | `false` | 宽度撑满容器。 |\n| `loading` | `boolean` | `false` | 加载中,禁用点击并显示 spinner。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `badge` | `string` | — | 徽标文本。 |\n| `badgeSeverity` | `'secondary' \\| 'info' \\| 'success' \\| 'warn' \\| 'danger' \\| 'contrast' \\| null` | `null` | 徽标语义色。 |\n| `autofocus` | `boolean` | `false` | 原生 autofocus。 |\n| `nativeType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | 原生 button type。 |\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## 无障碍\n\n- 渲染原生 `<button>`。\n- 纯图标按钮请设置 `ariaLabel`(或可访问的文本标签)。\n- `loading` 时设置 `aria-busy`,并禁用交互。\n"
1847
+ "markdown": "---\ntitle: Button\ncategory: 01 / BASIC\ndescription: 按钮用于触发即时动作。\n---\n\n# Button\n\n按钮用于触发即时动作。\n\n## 引入\n\n```ts\nimport { MButton } from 'morya-ui'\n```\n\n## 基础用法\n\n通过默认插槽或 `label` 展示按钮文案。\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Severity\n\n使用 `severity` 定义按钮语义色;省略时为 primary。\n\n```vue preview src=\"./demos/Severity.vue\"\n```\n\n## Styles\n\n`outlined`、`text`、`link`、`raised`、`rounded`、`plain` 可自由组合。\n\n```vue preview src=\"./demos/Styles.vue\"\n```\n\n## Text & Link\n\n`text` 为轻量文字按钮;`link` 呈现为无背景的内联链接样式,默认悬浮下划线,设 `:underline=\"false\"` 可关闭。二者均可与 `severity` 组合。\n\n```vue preview src=\"./demos/TextAndLink.vue\"\n```\n\n## Ghost & Quaternary\n\n`ghost` 为浅色填充,等同于 `text` 的悬浮态;`quaternary` 更克制,适合工具栏次要操作。也可通过 `variant` 指定。\n\n```vue preview src=\"./demos/GhostAndQuaternary.vue\"\n```\n\n## Button Group\n\n`MButtonGroup` 将相邻按钮拼成一组。\n\n```vue preview src=\"./demos/ButtonGroup.zh.vue\"\n```\n\n## Icons & Badge\n\n支持 `icon`、`iconPos`、`iconOnly`,以及 `badge` 徽标。\n\n```vue preview src=\"./demos/IconsAndBadge.vue\"\n```\n\n## Loading\n\n`loading` 状态下显示 spinner 并阻止点击。\n\n```vue preview src=\"./demos/Loading.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.vue\"\n```\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' \\| 'text' \\| 'link' \\| 'ghost' \\| 'quaternary'` | — | 样式变体快捷方式,等价于对应布尔 prop。 |\n| `outlined` | `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` | 全圆角。 |\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## 无障碍\n\n- 渲染原生 `<button>`。\n- 纯图标按钮请设置 `ariaLabel`(或可访问的文本标签)。\n- `loading` 时设置 `aria-busy`,并禁用交互。\n"
1830
1848
  },
1831
1849
  "en-US": {
1832
1850
  "title": "Button",
@@ -1860,12 +1878,12 @@
1860
1878
  {
1861
1879
  "id": "text-link",
1862
1880
  "title": "Text & Link",
1863
- "body": "`text` is a lightweight text button; `link` renders as an inline link style. Both can be combined with `severity`.\n\n```vue preview src=\"./demos/TextAndLink.vue\"\n```"
1881
+ "body": "`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```"
1864
1882
  },
1865
1883
  {
1866
1884
  "id": "ghost-quaternary",
1867
1885
  "title": "Ghost & Quaternary",
1868
- "body": "`ghost` is a transparent fill with tinted text; `quaternary` is quieter for secondary toolbar actions. Both can be set via `variant`.\n\n```vue preview src=\"./demos/GhostAndQuaternary.vue\"\n```"
1886
+ "body": "`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```"
1869
1887
  },
1870
1888
  {
1871
1889
  "id": "button-group",
@@ -1890,7 +1908,7 @@
1890
1908
  {
1891
1909
  "id": "props",
1892
1910
  "title": "Props",
1893
- "body": "| 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| `severity` | `'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast'` | — | Semantic color. Defaults to primary when omitted. |\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| `ghost` | `boolean` | `false` | Transparent fill. |\n| `quaternary` | `boolean` | `false` | Extra-quiet text button. |\n| `color` | `string` | — | Custom color; overrides `severity`. |\n| `raised` | `boolean` | `false` | Raised shadow. |\n| `rounded` | `boolean` | `false` | Fully rounded. |\n| `plain` | `boolean` | `false` | Muted color; often combined with `text` / `outlined`. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Size. Medium by default; `sm` / `lg` aliases supported. |\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| `badge` | `string` | — | Badge text. |\n| `badgeSeverity` | `'secondary' \\| 'info' \\| 'success' \\| 'warn' \\| 'danger' \\| 'contrast' \\| null` | `null` | Badge semantic color. |\n| `autofocus` | `boolean` | `false` | Native autofocus. |\n| `nativeType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | Native button type. |\n| `ariaLabel` | `string` | — | Accessible name; recommended for icon-only buttons. |"
1911
+ "body": "| 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. |"
1894
1912
  },
1895
1913
  {
1896
1914
  "id": "events",
@@ -1913,7 +1931,7 @@
1913
1931
  "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."
1914
1932
  }
1915
1933
  ],
1916
- "markdown": "---\ntitle: Button\ncategory: 01 / BASIC\ndescription: Button triggers an immediate action.\n---\n\n# Button\n\nButton triggers an immediate action.\n\n## Import\n\n```ts\nimport { MButton } from 'morya-ui'\n```\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## Severity\n\nUse `severity` for semantic color; defaults to primary when omitted.\n\n```vue preview src=\"./demos/Severity.vue\"\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## Text & Link\n\n`text` is a lightweight text button; `link` renders as an inline link style. Both can be combined with `severity`.\n\n```vue preview src=\"./demos/TextAndLink.vue\"\n```\n\n## Ghost & Quaternary\n\n`ghost` is a transparent fill with tinted text; `quaternary` is quieter for secondary toolbar actions. Both can be set via `variant`.\n\n```vue preview src=\"./demos/GhostAndQuaternary.vue\"\n```\n\n## Button Group\n\n`MButtonGroup` joins adjacent buttons.\n\n```vue preview src=\"./demos/ButtonGroup.en.vue\"\n```\n\n## Icons & Badge\n\nSupports `icon`, `iconPos`, `iconOnly`, and a `badge`.\n\n```vue preview src=\"./demos/IconsAndBadge.vue\"\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## Disabled\n\n```vue preview src=\"./demos/Disabled.vue\"\n```\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| `severity` | `'secondary' \\| 'success' \\| 'info' \\| 'warn' \\| 'help' \\| 'danger' \\| 'contrast'` | — | Semantic color. Defaults to primary when omitted. |\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| `ghost` | `boolean` | `false` | Transparent fill. |\n| `quaternary` | `boolean` | `false` | Extra-quiet text button. |\n| `color` | `string` | — | Custom color; overrides `severity`. |\n| `raised` | `boolean` | `false` | Raised shadow. |\n| `rounded` | `boolean` | `false` | Fully rounded. |\n| `plain` | `boolean` | `false` | Muted color; often combined with `text` / `outlined`. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Size. Medium by default; `sm` / `lg` aliases supported. |\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| `badge` | `string` | — | Badge text. |\n| `badgeSeverity` | `'secondary' \\| 'info' \\| 'success' \\| 'warn' \\| 'danger' \\| 'contrast' \\| null` | `null` | Badge semantic color. |\n| `autofocus` | `boolean` | `false` | Native autofocus. |\n| `nativeType` | `'button' \\| 'submit' \\| 'reset'` | `'button'` | Native button type. |\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## 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"
1934
+ "markdown": "---\ntitle: Button\ncategory: 01 / BASIC\ndescription: Button triggers an immediate action.\n---\n\n# Button\n\nButton triggers an immediate action.\n\n## Import\n\n```ts\nimport { MButton } from 'morya-ui'\n```\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## Severity\n\nUse `severity` for semantic color; defaults to primary when omitted.\n\n```vue preview src=\"./demos/Severity.vue\"\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## 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## 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## Button Group\n\n`MButtonGroup` joins adjacent buttons.\n\n```vue preview src=\"./demos/ButtonGroup.en.vue\"\n```\n\n## Icons & Badge\n\nSupports `icon`, `iconPos`, `iconOnly`, and a `badge`.\n\n```vue preview src=\"./demos/IconsAndBadge.vue\"\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## Disabled\n\n```vue preview src=\"./demos/Disabled.vue\"\n```\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## 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"
1917
1935
  }
1918
1936
  }
1919
1937
  },
@@ -1957,10 +1975,10 @@
1957
1975
  "description": "是否描边。"
1958
1976
  },
1959
1977
  {
1960
- "name": "hoverable",
1961
- "type": "boolean",
1962
- "default": "false",
1963
- "description": "悬停抬起。"
1978
+ "name": "shadow",
1979
+ "type": "'never' | 'hover' | 'always'",
1980
+ "default": "'never'",
1981
+ "description": "阴影时机:`never` 无阴影;`hover` / `always` 均使用 `--m-card-shadow-rest`(`hover` 仅悬停时出现)。"
1964
1982
  },
1965
1983
  {
1966
1984
  "name": "headingLevel",
@@ -2029,7 +2047,16 @@
2029
2047
  "sectionId": "cover-hover",
2030
2048
  "lang": "vue",
2031
2049
  "preview": true,
2032
- "code": "<script setup lang=\"ts\">\nimport { MCard } from 'morya-ui'\n</script>\n\n<template>\n <MCard title=\"Cover card\" hoverable size=\"small\">\n <template #cover>\n <div style=\"height:6rem;background:color-mix(in srgb, var(--m-color-primary) 18%, transparent)\" />\n </template>\n Hover to lift. Set `bordered` to false for a borderless surface.\n </MCard>\n</template>",
2050
+ "code": "<script setup lang=\"ts\">\nimport { MCard } from 'morya-ui'\n</script>\n\n<template>\n <MCard title=\"Cover card\" shadow=\"hover\" size=\"small\">\n <template #cover>\n <div style=\"height:6rem;background:color-mix(in srgb, var(--m-color-primary) 18%, transparent)\" />\n </template>\n Hover for elevation (`shadow=\"hover\"`). Set `bordered` to false for a borderless surface.\n </MCard>\n</template>",
2051
+ "locale": "zh-CN"
2052
+ },
2053
+ {
2054
+ "id": "shadow-1",
2055
+ "section": "Shadow",
2056
+ "sectionId": "shadow",
2057
+ "lang": "vue",
2058
+ "preview": true,
2059
+ "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>",
2033
2060
  "locale": "zh-CN"
2034
2061
  },
2035
2062
  {
@@ -2065,7 +2092,16 @@
2065
2092
  "sectionId": "cover-hover",
2066
2093
  "lang": "vue",
2067
2094
  "preview": true,
2068
- "code": "<script setup lang=\"ts\">\nimport { MCard } from 'morya-ui'\n</script>\n\n<template>\n <MCard title=\"Cover card\" hoverable size=\"small\">\n <template #cover>\n <div style=\"height:6rem;background:color-mix(in srgb, var(--m-color-primary) 18%, transparent)\" />\n </template>\n Hover to lift. Set `bordered` to false for a borderless surface.\n </MCard>\n</template>",
2095
+ "code": "<script setup lang=\"ts\">\nimport { MCard } from 'morya-ui'\n</script>\n\n<template>\n <MCard title=\"Cover card\" shadow=\"hover\" size=\"small\">\n <template #cover>\n <div style=\"height:6rem;background:color-mix(in srgb, var(--m-color-primary) 18%, transparent)\" />\n </template>\n Hover for elevation (`shadow=\"hover\"`). Set `bordered` to false for a borderless surface.\n </MCard>\n</template>",
2096
+ "locale": "en-US"
2097
+ },
2098
+ {
2099
+ "id": "shadow-1",
2100
+ "section": "Shadow",
2101
+ "sectionId": "shadow",
2102
+ "lang": "vue",
2103
+ "preview": true,
2104
+ "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>",
2069
2105
  "locale": "en-US"
2070
2106
  }
2071
2107
  ],
@@ -2099,10 +2135,15 @@
2099
2135
  "title": "Cover & Hover",
2100
2136
  "body": "```vue preview src=\"./demos/CoverAndHover.vue\"\n```"
2101
2137
  },
2138
+ {
2139
+ "id": "shadow",
2140
+ "title": "Shadow",
2141
+ "body": "`shadow` 控制卡片**阴影**出现时机:`never` 平面、`hover` 悬停抬起、`always` 常驻抬起(均使用 `--m-card-shadow-rest`)。\n\n```vue preview src=\"./demos/Shadow.vue\"\n```"
2142
+ },
2102
2143
  {
2103
2144
  "id": "props",
2104
2145
  "title": "Props",
2105
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 标题。 |\n| `subtitle` | `string` | — | 副标题。 |\n| `ariaLabel` | `string` | — | 可访问名称;默认回退到 `title`。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 内边距尺寸。 |\n| `bordered` | `boolean` | `true` | 是否描边。 |\n| `hoverable` | `boolean` | `false` | 悬停抬起。 |\n| `headingLevel` | `1 \\| 2 \\| 3 \\| 4 \\| 5 \\| 6` | `2` | 标题 heading 级别。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | 根节点透传,键名 `root`。 |"
2146
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 标题。 |\n| `subtitle` | `string` | — | 副标题。 |\n| `ariaLabel` | `string` | — | 可访问名称;默认回退到 `title`。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 内边距尺寸。 |\n| `bordered` | `boolean` | `true` | 是否描边。 |\n| `shadow` | `'never' \\| 'hover' \\| 'always'` | `'never'` | 阴影时机:`never` 无阴影;`hover` / `always` 均使用 `--m-card-shadow-rest`(`hover` 仅悬停时出现)。 |\n| `headingLevel` | `1 \\| 2 \\| 3 \\| 4 \\| 5 \\| 6` | `2` | 标题 heading 级别。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | 根节点透传,键名 `root`。 |"
2106
2147
  },
2107
2148
  {
2108
2149
  "id": "slots",
@@ -2120,7 +2161,7 @@
2120
2161
  "body": "无自定义事件。"
2121
2162
  }
2122
2163
  ],
2123
- "markdown": "---\ntitle: Card\ncategory: 03 / DATA\ndescription: 内容容器。通过 title / subtitle 或 header / footer 插槽组织结构。\n---\n\n# Card\n\n内容容器,适合分组展示标题、正文与操作。Footer 仅通过插槽扩展(不提供 `footer` prop)。\n\n## 引入\n\n```ts\nimport { MButton, MCard } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Custom Header\n\n```vue preview src=\"./demos/CustomHeader.vue\"\n```\n\n## Cover & Hover\n\n```vue preview src=\"./demos/CoverAndHover.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 标题。 |\n| `subtitle` | `string` | — | 副标题。 |\n| `ariaLabel` | `string` | — | 可访问名称;默认回退到 `title`。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 内边距尺寸。 |\n| `bordered` | `boolean` | `true` | 是否描边。 |\n| `hoverable` | `boolean` | `false` | 悬停抬起。 |\n| `headingLevel` | `1 \\| 2 \\| 3 \\| 4 \\| 5 \\| 6` | `2` | 标题 heading 级别。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | 根节点透传,键名 `root`。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 正文。 |\n| `header` | 自定义头部(优先于 `title` / `subtitle`)。 |\n| `footer` | 底部区域(推荐用插槽,无 footer prop)。 |\n| `cover` | 封面,渲染在头部上方。 |\n\n## 无障碍\n\n- 有 `title` 时默认作为容器 `aria-label`;复杂头部请用 `#header` 并保证标题可读。\n- 底部操作按钮应使用语义清晰的 `label` 文本。\n\n## Events\n\n无自定义事件。\n"
2164
+ "markdown": "---\ntitle: Card\ncategory: 03 / DATA\ndescription: 内容容器。通过 title / subtitle 或 header / footer 插槽组织结构。\n---\n\n# Card\n\n内容容器,适合分组展示标题、正文与操作。Footer 仅通过插槽扩展(不提供 `footer` prop)。\n\n## 引入\n\n```ts\nimport { MButton, MCard } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Custom Header\n\n```vue preview src=\"./demos/CustomHeader.vue\"\n```\n\n## Cover & Hover\n\n```vue preview src=\"./demos/CoverAndHover.vue\"\n```\n\n## Shadow\n\n`shadow` 控制卡片**阴影**出现时机:`never` 平面、`hover` 悬停抬起、`always` 常驻抬起(均使用 `--m-card-shadow-rest`)。\n\n```vue preview src=\"./demos/Shadow.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 标题。 |\n| `subtitle` | `string` | — | 副标题。 |\n| `ariaLabel` | `string` | — | 可访问名称;默认回退到 `title`。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 内边距尺寸。 |\n| `bordered` | `boolean` | `true` | 是否描边。 |\n| `shadow` | `'never' \\| 'hover' \\| 'always'` | `'never'` | 阴影时机:`never` 无阴影;`hover` / `always` 均使用 `--m-card-shadow-rest`(`hover` 仅悬停时出现)。 |\n| `headingLevel` | `1 \\| 2 \\| 3 \\| 4 \\| 5 \\| 6` | `2` | 标题 heading 级别。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | 根节点透传,键名 `root`。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 正文。 |\n| `header` | 自定义头部(优先于 `title` / `subtitle`)。 |\n| `footer` | 底部区域(推荐用插槽,无 footer prop)。 |\n| `cover` | 封面,渲染在头部上方。 |\n\n## 无障碍\n\n- 有 `title` 时默认作为容器 `aria-label`;复杂头部请用 `#header` 并保证标题可读。\n- 底部操作按钮应使用语义清晰的 `label` 文本。\n\n## Events\n\n无自定义事件。\n"
2124
2165
  },
2125
2166
  "en-US": {
2126
2167
  "title": "Card",
@@ -2151,10 +2192,15 @@
2151
2192
  "title": "Cover & Hover",
2152
2193
  "body": "```vue preview src=\"./demos/CoverAndHover.vue\"\n```"
2153
2194
  },
2195
+ {
2196
+ "id": "shadow",
2197
+ "title": "Shadow",
2198
+ "body": "`shadow` controls **when** the elevation shadow appears: `never` (flat), `hover` (on pointer hover), or `always` (resting). `hover` and `always` share `--m-card-shadow-rest`.\n\n```vue preview src=\"./demos/Shadow.vue\"\n```"
2199
+ },
2154
2200
  {
2155
2201
  "id": "props",
2156
2202
  "title": "Props",
2157
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `title` | `string` | — | Title. |\n| `subtitle` | `string` | — | Subtitle. |\n| `ariaLabel` | `string` | — | Accessible name; falls back to `title` by default. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Padding size. |\n| `bordered` | `boolean` | `true` | Show a border. |\n| `hoverable` | `boolean` | `false` | Elevate on hover. |\n| `headingLevel` | `1 \\| 2 \\| 3 \\| 4 \\| 5 \\| 6` | `2` | Heading level for the title. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Root pass-through; key `root`. |"
2203
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `title` | `string` | — | Title. |\n| `subtitle` | `string` | — | Subtitle. |\n| `ariaLabel` | `string` | — | Accessible name; falls back to `title` by default. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Padding size. |\n| `bordered` | `boolean` | `true` | Show a border. |\n| `shadow` | `'never' \\| 'hover' \\| 'always'` | `'never'` | Shadow timing: `never`; `hover` and `always` share `--m-card-shadow-rest` (`hover` shows it only on hover). |\n| `headingLevel` | `1 \\| 2 \\| 3 \\| 4 \\| 5 \\| 6` | `2` | Heading level for the title. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Root pass-through; key `root`. |"
2158
2204
  },
2159
2205
  {
2160
2206
  "id": "slots",
@@ -2172,7 +2218,7 @@
2172
2218
  "body": "No custom events."
2173
2219
  }
2174
2220
  ],
2175
- "markdown": "---\ntitle: Card\ncategory: 03 / DATA\ndescription: Content container. Structure content with title / subtitle or header / footer slots.\n---\n\n# Card\n\nContent container for grouping title, body, and actions. Footer is extended via slot only (no `footer` prop).\n\n## Import\n\n```ts\nimport { MButton, MCard } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Custom Header\n\n```vue preview src=\"./demos/CustomHeader.vue\"\n```\n\n## Cover & Hover\n\n```vue preview src=\"./demos/CoverAndHover.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `title` | `string` | — | Title. |\n| `subtitle` | `string` | — | Subtitle. |\n| `ariaLabel` | `string` | — | Accessible name; falls back to `title` by default. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Padding size. |\n| `bordered` | `boolean` | `true` | Show a border. |\n| `hoverable` | `boolean` | `false` | Elevate on hover. |\n| `headingLevel` | `1 \\| 2 \\| 3 \\| 4 \\| 5 \\| 6` | `2` | Heading level for the title. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Root pass-through; key `root`. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Body. |\n| `header` | Custom header (takes precedence over `title` / `subtitle`). |\n| `footer` | Footer area (use the slot; there is no footer prop). |\n| `cover` | Cover above the header. |\n\n## Accessibility\n\n- When `title` is set it becomes the container `aria-label`; use `#header` for complex headers with readable titles.\n- Footer actions should use descriptive button labels.\n\n## Events\n\nNo custom events.\n"
2221
+ "markdown": "---\ntitle: Card\ncategory: 03 / DATA\ndescription: Content container. Structure content with title / subtitle or header / footer slots.\n---\n\n# Card\n\nContent container for grouping title, body, and actions. Footer is extended via slot only (no `footer` prop).\n\n## Import\n\n```ts\nimport { MButton, MCard } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Custom Header\n\n```vue preview src=\"./demos/CustomHeader.vue\"\n```\n\n## Cover & Hover\n\n```vue preview src=\"./demos/CoverAndHover.vue\"\n```\n\n## Shadow\n\n`shadow` controls **when** the elevation shadow appears: `never` (flat), `hover` (on pointer hover), or `always` (resting). `hover` and `always` share `--m-card-shadow-rest`.\n\n```vue preview src=\"./demos/Shadow.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `title` | `string` | — | Title. |\n| `subtitle` | `string` | — | Subtitle. |\n| `ariaLabel` | `string` | — | Accessible name; falls back to `title` by default. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Padding size. |\n| `bordered` | `boolean` | `true` | Show a border. |\n| `shadow` | `'never' \\| 'hover' \\| 'always'` | `'never'` | Shadow timing: `never`; `hover` and `always` share `--m-card-shadow-rest` (`hover` shows it only on hover). |\n| `headingLevel` | `1 \\| 2 \\| 3 \\| 4 \\| 5 \\| 6` | `2` | Heading level for the title. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Root pass-through; key `root`. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Body. |\n| `header` | Custom header (takes precedence over `title` / `subtitle`). |\n| `footer` | Footer area (use the slot; there is no footer prop). |\n| `cover` | Cover above the header. |\n\n## Accessibility\n\n- When `title` is set it becomes the container `aria-label`; use `#header` for complex headers with readable titles.\n- Footer actions should use descriptive button labels.\n\n## Events\n\nNo custom events.\n"
2176
2222
  }
2177
2223
  }
2178
2224
  },
@@ -3518,7 +3564,7 @@
3518
3564
  "name": "respectReducedMotion",
3519
3565
  "type": "boolean",
3520
3566
  "default": "true",
3521
- "description": "是否尊重系统 `prefers-reduced-motion`。"
3567
+ "description": "已废弃。组件动效不读取系统 `prefers-reduced-motion`。"
3522
3568
  },
3523
3569
  {
3524
3570
  "name": "globalDensity",
@@ -3682,7 +3728,7 @@
3682
3728
  {
3683
3729
  "id": "能力一览",
3684
3730
  "title": "能力一览",
3685
- "body": "| 能力 | 说明 |\n| --- | --- |\n| `appendTo` | 浮层默认 Teleport 目标,默认 `body` |\n| `size` | 表单控件默认尺寸 |\n| `density` | 全局内容密度 `compact` / `comfortable` / `spacious` |\n| `inputVariant` | 输入框默认 `outlined` / `filled` |\n| `zIndex` | 浮层基础层级 |\n| `locale` | 确认 / 空态 / 加载 / 占位等文案。可传入内置语言包 `zhCN` / `enUS` |\n| `componentDefaults` | 按组件覆盖默认 props(如 `Input.size`、`Space.size`、`Dialog.transition`)。局部 Props 优先 |\n| `motion` | 按角色覆盖进出场预设(`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) |\n| `respectReducedMotion` | 是否尊重系统 `prefers-reduced-motion`(默认 `true`) |"
3731
+ "body": "| 能力 | 说明 |\n| --- | --- |\n| `appendTo` | 浮层默认 Teleport 目标,默认 `body` |\n| `size` | 表单控件默认尺寸 |\n| `density` | 全局内容密度 `compact` / `comfortable` / `spacious` |\n| `inputVariant` | 输入框默认 `outlined` / `filled` |\n| `zIndex` | 浮层基础层级 |\n| `locale` | 确认 / 空态 / 加载 / 占位等文案。可传入内置语言包 `zhCN` / `enUS` |\n| `componentDefaults` | 按组件覆盖默认 props(如 `Input.size`、`Space.size`、`Dialog.transition`)。局部 Props 优先 |\n| `motion` | 按角色覆盖进出场预设(`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) |\n| `respectReducedMotion` | 已废弃。组件动效只跟 `useMotion` / `data-m-motion`,不读系统减少动态效果。 |"
3686
3732
  },
3687
3733
  {
3688
3734
  "id": "size",
@@ -3722,7 +3768,7 @@
3722
3768
  {
3723
3769
  "id": "props",
3724
3770
  "title": "Props",
3725
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `config` | `Partial<MGlobalConfig>` | — | 一次性传入完整配置(与下列 shorthand 等价)。 |\n| `appendTo` | `string \\| HTMLElement` | `'body'` | 浮层默认 Teleport 目标。 |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | 表单控件默认尺寸。 |\n| `inputVariant` | `'outlined' \\| 'filled'` | — | 输入框默认视觉变体。 |\n| `zIndex` | `number` | — | 浮层基础 z-index。 |\n| `density` | `'compact' \\| 'comfortable' \\| 'spacious'` | — | 全局内容密度。 |\n| `theme` | `'light' \\| 'dark' \\| 'system'` | — | 主题;`system` 跟随系统偏好。 |\n| `locale` | `MLocale` | — | 文案语言包(如 `zhCN` / `enUS`)。 |\n| `componentDefaults` | `Record<string, object>` | — | 按组件名覆盖默认 props(含 `transition`)。 |\n| `motion` | `{ transitions?: Partial<Record<role, string>> }` | — | 按浮层角色覆盖进出场预设。 |\n| `respectReducedMotion` | `boolean` | `true` | 是否尊重系统 `prefers-reduced-motion`。 |\n| `globalDensity` | `boolean` | `true` | 是否将 density / theme 写入 `documentElement`。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
3771
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `config` | `Partial<MGlobalConfig>` | — | 一次性传入完整配置(与下列 shorthand 等价)。 |\n| `appendTo` | `string \\| HTMLElement` | `'body'` | 浮层默认 Teleport 目标。 |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | 表单控件默认尺寸。 |\n| `inputVariant` | `'outlined' \\| 'filled'` | — | 输入框默认视觉变体。 |\n| `zIndex` | `number` | — | 浮层基础 z-index。 |\n| `density` | `'compact' \\| 'comfortable' \\| 'spacious'` | — | 全局内容密度。 |\n| `theme` | `'light' \\| 'dark' \\| 'system'` | — | 主题;`system` 跟随系统偏好。 |\n| `locale` | `MLocale` | — | 文案语言包(如 `zhCN` / `enUS`)。 |\n| `componentDefaults` | `Record<string, object>` | — | 按组件名覆盖默认 props(含 `transition`)。 |\n| `motion` | `{ transitions?: Partial<Record<role, string>> }` | — | 按浮层角色覆盖进出场预设。 |\n| `respectReducedMotion` | `boolean` | `true` | 已废弃。组件动效不读取系统 `prefers-reduced-motion`。 |\n| `globalDensity` | `boolean` | `true` | 是否将 density / theme 写入 `documentElement`。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
3726
3772
  },
3727
3773
  {
3728
3774
  "id": "events",
@@ -3735,7 +3781,7 @@
3735
3781
  "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 子组件树。 |"
3736
3782
  }
3737
3783
  ],
3738
- "markdown": "---\ntitle: ConfigProvider\ncategory: 00 / GUIDE\ndescription: 全局配置入口。统一浮层挂载、尺寸、密度、文案等应用级默认值。\n---\n\n# ConfigProvider\n\n通过 `MConfigProvider` 或 `createMoryaUI` 为整棵组件树提供全局默认值。局部 Props 优先级高于全局配置。\n\n## 能力一览\n\n| 能力 | 说明 |\n| --- | --- |\n| `appendTo` | 浮层默认 Teleport 目标,默认 `body` |\n| `size` | 表单控件默认尺寸 |\n| `density` | 全局内容密度 `compact` / `comfortable` / `spacious` |\n| `inputVariant` | 输入框默认 `outlined` / `filled` |\n| `zIndex` | 浮层基础层级 |\n| `locale` | 确认 / 空态 / 加载 / 占位等文案。可传入内置语言包 `zhCN` / `enUS` |\n| `componentDefaults` | 按组件覆盖默认 props(如 `Input.size`、`Space.size`、`Dialog.transition`)。局部 Props 优先 |\n| `motion` | 按角色覆盖进出场预设(`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) |\n| `respectReducedMotion` | 是否尊重系统 `prefers-reduced-motion`(默认 `true`) |\n\n## Size\n\n```vue preview src=\"./demos/Size.zh.vue\"\n```\n\n## Component Defaults\n\n按组件名覆盖默认 props。键名用无前缀名称(`Input`、`Space`)或 `M*` 别名均可。\n\n优先级:**组件 Props > `componentDefaults[组件]` > 全局 `size` / `inputVariant` > 内置默认值**。\n\n`Space` / `Flex` 的 `size` 是间距,**不会**继承全局控件 `size`。\n\n```vue preview src=\"./demos/ComponentDefaults.zh.vue\"\n```\n\n## Density\n\n```vue preview src=\"./demos/Density.vue\"\n```\n\n## Input Variant\n\n```vue preview src=\"./demos/InputVariant.zh.vue\"\n```\n\n## 应用级插件\n\n```ts\nimport MoryaUI, { createMoryaUI, enUS } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\n// 方式一:默认导出\ncreateApp(App).use(MoryaUI, { locale: enUS }).mount('#app')\n\n// 方式二:工厂函数\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n density: 'comfortable',\n zIndex: 1100,\n locale: enUS,\n motion: { transitions: { popup: 'slide-up', dialog: 'zoom' } },\n componentDefaults: {\n Space: { size: 'small' },\n Input: { clearable: true },\n Select: { transition: 'fade' },\n },\n }),\n )\n .mount('#app')\n```\n\n默认会**全局注册全部组件**(模板可直接用 `<MButton>`)。仅注入配置时传 `components: false`;也可传组件数组做部分注册。\n\n## 读取配置\n\n```ts\nimport { useMConfig } from 'morya-ui'\n\nconst config = useMConfig()\n```\n\n优先级:**组件 Props > `MConfigProvider` > `createMoryaUI()` > 内置默认值**。\n\n## 主题与动效\n\n主题强度与进出场预设是两层:\n\n- **强度**:`useMotion()` → `full` / `reduced` / `none`(写 `data-m-motion`)\n- **形态**:`motion.transitions[role]` / `componentDefaults.*.transition` / 组件 `transition` prop\n\n```ts\nimport { createMoryaUI, registerMotionPreset, useMotion, useTheme } from 'morya-ui'\n\nconst { setTheme, toggleTheme } = useTheme()\nconst { setMotion } = useMotion() // 'full' | 'reduced' | 'none'\n\napp.use(createMoryaUI({\n respectReducedMotion: false, // 演示站可忽略系统减弱动效\n motion: { transitions: { popup: 'slide-up' } },\n}))\n\nregisterMotionPreset('brand', { name: 'm-brand' })\n```\n\n完整预设列表与 demo 见 [动效](/docs/motion);亮暗与密度见 [主题](/docs/theme)。\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `config` | `Partial<MGlobalConfig>` | — | 一次性传入完整配置(与下列 shorthand 等价)。 |\n| `appendTo` | `string \\| HTMLElement` | `'body'` | 浮层默认 Teleport 目标。 |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | 表单控件默认尺寸。 |\n| `inputVariant` | `'outlined' \\| 'filled'` | — | 输入框默认视觉变体。 |\n| `zIndex` | `number` | — | 浮层基础 z-index。 |\n| `density` | `'compact' \\| 'comfortable' \\| 'spacious'` | — | 全局内容密度。 |\n| `theme` | `'light' \\| 'dark' \\| 'system'` | — | 主题;`system` 跟随系统偏好。 |\n| `locale` | `MLocale` | — | 文案语言包(如 `zhCN` / `enUS`)。 |\n| `componentDefaults` | `Record<string, object>` | — | 按组件名覆盖默认 props(含 `transition`)。 |\n| `motion` | `{ transitions?: Partial<Record<role, string>> }` | — | 按浮层角色覆盖进出场预设。 |\n| `respectReducedMotion` | `boolean` | `true` | 是否尊重系统 `prefers-reduced-motion`。 |\n| `globalDensity` | `boolean` | `true` | 是否将 density / theme 写入 `documentElement`。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n无自定义事件。\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 子组件树。 |\n"
3784
+ "markdown": "---\ntitle: ConfigProvider\ncategory: 00 / GUIDE\ndescription: 全局配置入口。统一浮层挂载、尺寸、密度、文案等应用级默认值。\n---\n\n# ConfigProvider\n\n通过 `MConfigProvider` 或 `createMoryaUI` 为整棵组件树提供全局默认值。局部 Props 优先级高于全局配置。\n\n## 能力一览\n\n| 能力 | 说明 |\n| --- | --- |\n| `appendTo` | 浮层默认 Teleport 目标,默认 `body` |\n| `size` | 表单控件默认尺寸 |\n| `density` | 全局内容密度 `compact` / `comfortable` / `spacious` |\n| `inputVariant` | 输入框默认 `outlined` / `filled` |\n| `zIndex` | 浮层基础层级 |\n| `locale` | 确认 / 空态 / 加载 / 占位等文案。可传入内置语言包 `zhCN` / `enUS` |\n| `componentDefaults` | 按组件覆盖默认 props(如 `Input.size`、`Space.size`、`Dialog.transition`)。局部 Props 优先 |\n| `motion` | 按角色覆盖进出场预设(`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) |\n| `respectReducedMotion` | 已废弃。组件动效只跟 `useMotion` / `data-m-motion`,不读系统减少动态效果。 |\n\n## Size\n\n```vue preview src=\"./demos/Size.zh.vue\"\n```\n\n## Component Defaults\n\n按组件名覆盖默认 props。键名用无前缀名称(`Input`、`Space`)或 `M*` 别名均可。\n\n优先级:**组件 Props > `componentDefaults[组件]` > 全局 `size` / `inputVariant` > 内置默认值**。\n\n`Space` / `Flex` 的 `size` 是间距,**不会**继承全局控件 `size`。\n\n```vue preview src=\"./demos/ComponentDefaults.zh.vue\"\n```\n\n## Density\n\n```vue preview src=\"./demos/Density.vue\"\n```\n\n## Input Variant\n\n```vue preview src=\"./demos/InputVariant.zh.vue\"\n```\n\n## 应用级插件\n\n```ts\nimport MoryaUI, { createMoryaUI, enUS } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\n// 方式一:默认导出\ncreateApp(App).use(MoryaUI, { locale: enUS }).mount('#app')\n\n// 方式二:工厂函数\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n density: 'comfortable',\n zIndex: 1100,\n locale: enUS,\n motion: { transitions: { popup: 'slide-up', dialog: 'zoom' } },\n componentDefaults: {\n Space: { size: 'small' },\n Input: { clearable: true },\n Select: { transition: 'fade' },\n },\n }),\n )\n .mount('#app')\n```\n\n默认会**全局注册全部组件**(模板可直接用 `<MButton>`)。仅注入配置时传 `components: false`;也可传组件数组做部分注册。\n\n## 读取配置\n\n```ts\nimport { useMConfig } from 'morya-ui'\n\nconst config = useMConfig()\n```\n\n优先级:**组件 Props > `MConfigProvider` > `createMoryaUI()` > 内置默认值**。\n\n## 主题与动效\n\n主题强度与进出场预设是两层:\n\n- **强度**:`useMotion()` → `full` / `reduced` / `none`(写 `data-m-motion`)\n- **形态**:`motion.transitions[role]` / `componentDefaults.*.transition` / 组件 `transition` prop\n\n```ts\nimport { createMoryaUI, registerMotionPreset, useMotion, useTheme } from 'morya-ui'\n\nconst { setTheme, toggleTheme } = useTheme()\nconst { setMotion } = useMotion() // 'full' | 'reduced' | 'none'\n\napp.use(createMoryaUI({\n respectReducedMotion: false, // 演示站可忽略系统减弱动效\n motion: { transitions: { popup: 'slide-up' } },\n}))\n\nregisterMotionPreset('brand', { name: 'm-brand' })\n```\n\n完整预设列表与 demo 见 [动效](/docs/motion);亮暗与密度见 [主题](/docs/theme)。\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `config` | `Partial<MGlobalConfig>` | — | 一次性传入完整配置(与下列 shorthand 等价)。 |\n| `appendTo` | `string \\| HTMLElement` | `'body'` | 浮层默认 Teleport 目标。 |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | 表单控件默认尺寸。 |\n| `inputVariant` | `'outlined' \\| 'filled'` | — | 输入框默认视觉变体。 |\n| `zIndex` | `number` | — | 浮层基础 z-index。 |\n| `density` | `'compact' \\| 'comfortable' \\| 'spacious'` | — | 全局内容密度。 |\n| `theme` | `'light' \\| 'dark' \\| 'system'` | — | 主题;`system` 跟随系统偏好。 |\n| `locale` | `MLocale` | — | 文案语言包(如 `zhCN` / `enUS`)。 |\n| `componentDefaults` | `Record<string, object>` | — | 按组件名覆盖默认 props(含 `transition`)。 |\n| `motion` | `{ transitions?: Partial<Record<role, string>> }` | — | 按浮层角色覆盖进出场预设。 |\n| `respectReducedMotion` | `boolean` | `true` | 已废弃。组件动效不读取系统 `prefers-reduced-motion`。 |\n| `globalDensity` | `boolean` | `true` | 是否将 density / theme 写入 `documentElement`。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n无自定义事件。\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 子组件树。 |\n"
3739
3785
  },
3740
3786
  "en-US": {
3741
3787
  "title": "ConfigProvider",
@@ -3749,7 +3795,7 @@
3749
3795
  {
3750
3796
  "id": "capabilities",
3751
3797
  "title": "Capabilities",
3752
- "body": "| Capability | Description |\n| --- | --- |\n| `appendTo` | Default Teleport target for overlays; defaults to `body` |\n| `size` | Default size for form controls |\n| `density` | Global content density: `compact` / `comfortable` / `spacious` |\n| `inputVariant` | Default input style: `outlined` / `filled` |\n| `zIndex` | Base overlay z-index |\n| `locale` | Strings for confirm / empty / loading / placeholder, etc. Pass built-in packs `zhCN` / `enUS` |\n| `componentDefaults` | Per-component default props (e.g. `Input.size`, `Dialog.transition`). Local props win |\n| `motion` | Enter/exit presets by overlay role (`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) |\n| `respectReducedMotion` | Honor OS `prefers-reduced-motion` (default `true`) |"
3798
+ "body": "| Capability | Description |\n| --- | --- |\n| `appendTo` | Default Teleport target for overlays; defaults to `body` |\n| `size` | Default size for form controls |\n| `density` | Global content density: `compact` / `comfortable` / `spacious` |\n| `inputVariant` | Default input style: `outlined` / `filled` |\n| `zIndex` | Base overlay z-index |\n| `locale` | Strings for confirm / empty / loading / placeholder, etc. Pass built-in packs `zhCN` / `enUS` |\n| `componentDefaults` | Per-component default props (e.g. `Input.size`, `Dialog.transition`). Local props win |\n| `motion` | Enter/exit presets by overlay role (`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) |\n| `respectReducedMotion` | Deprecated. Component motion follows `useMotion` / `data-m-motion` only. |"
3753
3799
  },
3754
3800
  {
3755
3801
  "id": "size",
@@ -3789,7 +3835,7 @@
3789
3835
  {
3790
3836
  "id": "props",
3791
3837
  "title": "Props",
3792
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `config` | `Partial<MGlobalConfig>` | — | Full config object (same as the shorthands below). |\n| `appendTo` | `string \\| HTMLElement` | `'body'` | Default Teleport target for overlays. |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | Default form control size. |\n| `inputVariant` | `'outlined' \\| 'filled'` | — | Default input surface. |\n| `zIndex` | `number` | — | Base overlay z-index. |\n| `density` | `'compact' \\| 'comfortable' \\| 'spacious'` | — | Global content density. |\n| `theme` | `'light' \\| 'dark' \\| 'system'` | — | Color theme; `system` follows OS. |\n| `locale` | `MLocale` | — | Copy pack (`zhCN` / `enUS`). |\n| `componentDefaults` | `Record<string, object>` | — | Per-component default props (including `transition`). |\n| `motion` | `{ transitions?: Partial<Record<role, string>> }` | — | Enter/exit presets by overlay role. |\n| `respectReducedMotion` | `boolean` | `true` | Honor OS `prefers-reduced-motion`. |\n| `globalDensity` | `boolean` | `true` | Also write density / theme to `documentElement`. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [Styling & attrs](/docs/attrs). |"
3838
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `config` | `Partial<MGlobalConfig>` | — | Full config object (same as the shorthands below). |\n| `appendTo` | `string \\| HTMLElement` | `'body'` | Default Teleport target for overlays. |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | Default form control size. |\n| `inputVariant` | `'outlined' \\| 'filled'` | — | Default input surface. |\n| `zIndex` | `number` | — | Base overlay z-index. |\n| `density` | `'compact' \\| 'comfortable' \\| 'spacious'` | — | Global content density. |\n| `theme` | `'light' \\| 'dark' \\| 'system'` | — | Color theme; `system` follows OS. |\n| `locale` | `MLocale` | — | Copy pack (`zhCN` / `enUS`). |\n| `componentDefaults` | `Record<string, object>` | — | Per-component default props (including `transition`). |\n| `motion` | `{ transitions?: Partial<Record<role, string>> }` | — | Enter/exit presets by overlay role. |\n| `respectReducedMotion` | `boolean` | `true` | Deprecated. Component motion does not read OS `prefers-reduced-motion`. |\n| `globalDensity` | `boolean` | `true` | Also write density / theme to `documentElement`. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [Styling & attrs](/docs/attrs). |"
3793
3839
  },
3794
3840
  {
3795
3841
  "id": "events",
@@ -3802,7 +3848,7 @@
3802
3848
  "body": "| Slot | Description |\n| --- | --- |\n| `default` | Child tree. |"
3803
3849
  }
3804
3850
  ],
3805
- "markdown": "---\ntitle: ConfigProvider\ncategory: 00 / GUIDE\ndescription: Global configuration entry. Unifies app-level defaults such as overlay mount, size, density, and locale strings.\n---\n\n# ConfigProvider\n\nProvide global defaults for the component tree via `MConfigProvider` or `createMoryaUI`. Local props take precedence over global config.\n\n## Capabilities\n\n| Capability | Description |\n| --- | --- |\n| `appendTo` | Default Teleport target for overlays; defaults to `body` |\n| `size` | Default size for form controls |\n| `density` | Global content density: `compact` / `comfortable` / `spacious` |\n| `inputVariant` | Default input style: `outlined` / `filled` |\n| `zIndex` | Base overlay z-index |\n| `locale` | Strings for confirm / empty / loading / placeholder, etc. Pass built-in packs `zhCN` / `enUS` |\n| `componentDefaults` | Per-component default props (e.g. `Input.size`, `Dialog.transition`). Local props win |\n| `motion` | Enter/exit presets by overlay role (`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) |\n| `respectReducedMotion` | Honor OS `prefers-reduced-motion` (default `true`) |\n\n## Size\n\n```vue preview src=\"./demos/Size.en.vue\"\n```\n\n## Component Defaults\n\nOverride default props per component. Keys may be unprefixed (`Input`, `Space`) or `M*` aliases.\n\nPrecedence: **component props > `componentDefaults[component]` > global `size` / `inputVariant` > built-in defaults**.\n\n`Space` / `Flex` `size` is gap and does **not** inherit the global control `size`.\n\n```vue preview src=\"./demos/ComponentDefaults.en.vue\"\n```\n\n## Density\n\n```vue preview src=\"./demos/Density.vue\"\n```\n\n## Input Variant\n\n```vue preview src=\"./demos/InputVariant.en.vue\"\n```\n\n## App-level plugin\n\n```ts\nimport MoryaUI, { createMoryaUI, enUS } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\n// Option A: default export\ncreateApp(App).use(MoryaUI, { locale: enUS }).mount('#app')\n\n// Option B: factory\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n density: 'comfortable',\n zIndex: 1100,\n locale: enUS,\n motion: { transitions: { popup: 'slide-up', dialog: 'zoom' } },\n componentDefaults: {\n Space: { size: 'small' },\n Input: { clearable: true },\n Select: { transition: 'fade' },\n },\n }),\n )\n .mount('#app')\n```\n\nBy default **all components are registered globally** (use `<MButton>` in templates). Pass `components: false` for config-only, or pass a component array for partial registration.\n\n## Reading config\n\n```ts\nimport { useMConfig } from 'morya-ui'\n\nconst config = useMConfig()\n```\n\nPrecedence: **component props > `MConfigProvider` > `createMoryaUI()` > built-in defaults**.\n\n## Theme and motion\n\nIntensity and enter/exit presets are separate layers:\n\n- **Intensity**: `useMotion()` → `full` / `reduced` / `none` (writes `data-m-motion`)\n- **Shape**: `motion.transitions[role]` / `componentDefaults.*.transition` / component `transition` prop\n\n```ts\nimport { createMoryaUI, registerMotionPreset, useMotion, useTheme } from 'morya-ui'\n\nconst { setTheme, toggleTheme } = useTheme()\nconst { setMotion } = useMotion() // 'full' | 'reduced' | 'none'\n\napp.use(createMoryaUI({\n respectReducedMotion: false, // docs demos may ignore OS reduced motion\n motion: { transitions: { popup: 'slide-up' } },\n}))\n\nregisterMotionPreset('brand', { name: 'm-brand' })\n```\n\nFull preset list and demos: [Motion](/docs/motion). Light/dark and density: [Theme](/docs/theme).\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `config` | `Partial<MGlobalConfig>` | — | Full config object (same as the shorthands below). |\n| `appendTo` | `string \\| HTMLElement` | `'body'` | Default Teleport target for overlays. |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | Default form control size. |\n| `inputVariant` | `'outlined' \\| 'filled'` | — | Default input surface. |\n| `zIndex` | `number` | — | Base overlay z-index. |\n| `density` | `'compact' \\| 'comfortable' \\| 'spacious'` | — | Global content density. |\n| `theme` | `'light' \\| 'dark' \\| 'system'` | — | Color theme; `system` follows OS. |\n| `locale` | `MLocale` | — | Copy pack (`zhCN` / `enUS`). |\n| `componentDefaults` | `Record<string, object>` | — | Per-component default props (including `transition`). |\n| `motion` | `{ transitions?: Partial<Record<role, string>> }` | — | Enter/exit presets by overlay role. |\n| `respectReducedMotion` | `boolean` | `true` | Honor OS `prefers-reduced-motion`. |\n| `globalDensity` | `boolean` | `true` | Also write density / theme to `documentElement`. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [Styling & attrs](/docs/attrs). |\n\n## Events\n\nNo custom events.\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Child tree. |\n"
3851
+ "markdown": "---\ntitle: ConfigProvider\ncategory: 00 / GUIDE\ndescription: Global configuration entry. Unifies app-level defaults such as overlay mount, size, density, and locale strings.\n---\n\n# ConfigProvider\n\nProvide global defaults for the component tree via `MConfigProvider` or `createMoryaUI`. Local props take precedence over global config.\n\n## Capabilities\n\n| Capability | Description |\n| --- | --- |\n| `appendTo` | Default Teleport target for overlays; defaults to `body` |\n| `size` | Default size for form controls |\n| `density` | Global content density: `compact` / `comfortable` / `spacious` |\n| `inputVariant` | Default input style: `outlined` / `filled` |\n| `zIndex` | Base overlay z-index |\n| `locale` | Strings for confirm / empty / loading / placeholder, etc. Pass built-in packs `zhCN` / `enUS` |\n| `componentDefaults` | Per-component default props (e.g. `Input.size`, `Dialog.transition`). Local props win |\n| `motion` | Enter/exit presets by overlay role (`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) |\n| `respectReducedMotion` | Deprecated. Component motion follows `useMotion` / `data-m-motion` only. |\n\n## Size\n\n```vue preview src=\"./demos/Size.en.vue\"\n```\n\n## Component Defaults\n\nOverride default props per component. Keys may be unprefixed (`Input`, `Space`) or `M*` aliases.\n\nPrecedence: **component props > `componentDefaults[component]` > global `size` / `inputVariant` > built-in defaults**.\n\n`Space` / `Flex` `size` is gap and does **not** inherit the global control `size`.\n\n```vue preview src=\"./demos/ComponentDefaults.en.vue\"\n```\n\n## Density\n\n```vue preview src=\"./demos/Density.vue\"\n```\n\n## Input Variant\n\n```vue preview src=\"./demos/InputVariant.en.vue\"\n```\n\n## App-level plugin\n\n```ts\nimport MoryaUI, { createMoryaUI, enUS } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\n// Option A: default export\ncreateApp(App).use(MoryaUI, { locale: enUS }).mount('#app')\n\n// Option B: factory\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n density: 'comfortable',\n zIndex: 1100,\n locale: enUS,\n motion: { transitions: { popup: 'slide-up', dialog: 'zoom' } },\n componentDefaults: {\n Space: { size: 'small' },\n Input: { clearable: true },\n Select: { transition: 'fade' },\n },\n }),\n )\n .mount('#app')\n```\n\nBy default **all components are registered globally** (use `<MButton>` in templates). Pass `components: false` for config-only, or pass a component array for partial registration.\n\n## Reading config\n\n```ts\nimport { useMConfig } from 'morya-ui'\n\nconst config = useMConfig()\n```\n\nPrecedence: **component props > `MConfigProvider` > `createMoryaUI()` > built-in defaults**.\n\n## Theme and motion\n\nIntensity and enter/exit presets are separate layers:\n\n- **Intensity**: `useMotion()` → `full` / `reduced` / `none` (writes `data-m-motion`)\n- **Shape**: `motion.transitions[role]` / `componentDefaults.*.transition` / component `transition` prop\n\n```ts\nimport { createMoryaUI, registerMotionPreset, useMotion, useTheme } from 'morya-ui'\n\nconst { setTheme, toggleTheme } = useTheme()\nconst { setMotion } = useMotion() // 'full' | 'reduced' | 'none'\n\napp.use(createMoryaUI({\n respectReducedMotion: false, // docs demos may ignore OS reduced motion\n motion: { transitions: { popup: 'slide-up' } },\n}))\n\nregisterMotionPreset('brand', { name: 'm-brand' })\n```\n\nFull preset list and demos: [Motion](/docs/motion). Light/dark and density: [Theme](/docs/theme).\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `config` | `Partial<MGlobalConfig>` | — | Full config object (same as the shorthands below). |\n| `appendTo` | `string \\| HTMLElement` | `'body'` | Default Teleport target for overlays. |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | Default form control size. |\n| `inputVariant` | `'outlined' \\| 'filled'` | — | Default input surface. |\n| `zIndex` | `number` | — | Base overlay z-index. |\n| `density` | `'compact' \\| 'comfortable' \\| 'spacious'` | — | Global content density. |\n| `theme` | `'light' \\| 'dark' \\| 'system'` | — | Color theme; `system` follows OS. |\n| `locale` | `MLocale` | — | Copy pack (`zhCN` / `enUS`). |\n| `componentDefaults` | `Record<string, object>` | — | Per-component default props (including `transition`). |\n| `motion` | `{ transitions?: Partial<Record<role, string>> }` | — | Enter/exit presets by overlay role. |\n| `respectReducedMotion` | `boolean` | `true` | Deprecated. Component motion does not read OS `prefers-reduced-motion`. |\n| `globalDensity` | `boolean` | `true` | Also write density / theme to `documentElement`. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM pass-through; see [Styling & attrs](/docs/attrs). |\n\n## Events\n\nNo custom events.\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Child tree. |\n"
3806
3852
  }
3807
3853
  }
3808
3854
  },
@@ -13482,7 +13528,7 @@
13482
13528
  {
13483
13529
  "id": "主题",
13484
13530
  "title": "主题",
13485
- "body": "指示器颜色走语义色:`--m-color-primary`、`--m-color-success`、`--m-color-warning`、`--m-color-danger`、`--m-color-text-muted`。遮罩默认是表面色的半透明混合,可用 `background` 或 `--m-loading-mask-bg` 覆盖。全屏层级是 `--m-loading-z-index`(默认 `--m-z-base + 200`)。\n\n`prefers-reduced-motion: reduce` 时循环动效关闭。"
13531
+ "body": "指示器颜色走语义色:`--m-color-primary`、`--m-color-success`、`--m-color-warning`、`--m-color-danger`、`--m-color-text-muted`。遮罩默认是表面色的半透明混合,可用 `background` 或 `--m-loading-mask-bg` 覆盖。全屏层级是 `--m-loading-z-index`(默认 `--m-z-base + 200`)。\n\n主题动效为 `reduced` 或 `none` 时循环动效关闭。"
13486
13532
  },
13487
13533
  {
13488
13534
  "id": "无障碍",
@@ -13490,7 +13536,7 @@
13490
13536
  "body": "- 指示器使用 `role=\"status\"`。\n- 遮罩区域设置 `aria-busy`,被盖住的内容设为 `inert`。\n- 不要只靠动画表示加载;需要说明时传入 `text`。"
13491
13537
  }
13492
13538
  ],
13493
- "markdown": "---\ntitle: Loading\ncategory: 05 / FEEDBACK\ndescription: 加载指示与遮罩:多种动效、区域加载、v-loading 指令和命令式 service。\n---\n\n# Loading\n\n用于区域或全屏的加载反馈。可以只渲染指示器,也可以盖住一块内容,或用指令和服务在任意节点上打开遮罩。\n\n内置圆环、极光环、弹跳球、波浪条、脉冲环和星尘。默认是圆环(`effect=\"circular\"`)。要改全局默认动效,设置 `componentDefaults.Loading.effect`。\n\n全屏遮罩会 Teleport 到 `body`,避免被父级 `overflow` / `transform` 裁切。同一时间只保留一个全屏实例。\n\n## 引入\n\n```ts\nimport { loading, MLoading, useLoading, vLoading } from 'morya-ui'\n```\n\n`app.use(MoryaUI)` 会注册 `v-loading`。按需引入时,在 `<script setup>` 里导入 `vLoading` 即可在模板中使用该指令。\n\n## 动效\n\n```vue preview src=\"./demos/Effects.vue\"\n```\n\n## 区域加载\n\n组件包住内容,或在元素上使用 `v-loading`。未传 `text` 时不显示文案,读屏仍使用 locale 的 `loading`。可用 `delay` 避免短请求闪一下。\n\n```vue preview src=\"./demos/Region.zh.vue\"\n```\n\n## 服务式调用\n\n不传 `target` 时遮罩铺满视口。`close()` 会先播放离场再卸载,`setText()` 改文案。也可用 `useLoading()`,在组件卸载时自动关闭。\n\n```vue preview src=\"./demos/Service.zh.vue\"\n```\n\n```ts\nconst instance = loading.service({\n text: '正在提交',\n effect: 'wave',\n lock: true,\n})\ninstance.setText('即将完成')\ninstance.close()\n```\n\n覆盖某个节点,或传入自定义指示器:\n\n```ts\nloading.service({\n target: '#panel',\n text: '加载中',\n})\n\nloading.service({\n spinner: () => h('span', '…'),\n text: '自定义',\n})\n```\n\n```ts\nconst { open, close } = useLoading({ effect: 'wave' })\nopen({ text: '保存中' })\nclose()\n```\n\n## 指令\n\n| 写法 | 说明 |\n| --- | --- |\n| `v-loading` | 布尔值,或带 `text` / `effect` / `background` / `lock` / `delay` / `spinner` 等字段的对象。 |\n| `v-loading.fullscreen` | 全屏遮罩。 |\n| `v-loading.lock` | 打开时锁定页面滚动。 |\n| `v-loading.body` | 遮罩挂到 `body`,并盖住当前元素(跟随尺寸变化)。 |\n| `m-loading-text` | 文案。 |\n| `m-loading-effect` | `circular` / `aurora` / `bounce` / `wave` / `pulse` / `stardust`。 |\n| `m-loading-background` | 遮罩背景色。 |\n| `m-loading-custom-class` | 加在遮罩上的类名。 |\n| `m-loading-delay` | 显示前延迟(ms)。 |\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `loading` | `boolean` | `true` | 包裹内容或 `fullscreen` 时是否显示遮罩。单独指示器始终显示。 |\n| `effect` | `'circular' \\| 'aurora' \\| 'bounce' \\| 'wave' \\| 'pulse' \\| 'stardust'` | `'circular'` | 动效。可用 `componentDefaults.Loading.effect` 改默认值。 |\n| `text` | `string` | — | 指示器下方文案。不传则不显示。 |\n| `ariaLabel` | `string` | locale `loading` | 无文案时的可访问名称。有文案时以文案为准。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 指示器缩放。 |\n| `background` | `string` | — | 遮罩背景,任意 CSS 颜色。 |\n| `customClass` | `string` | — | 加在遮罩上的类名。 |\n| `fullscreen` | `boolean` | `false` | 遮罩铺满视口(Teleport 到 `body`)。 |\n| `lock` | `boolean` | `false` | 显示时禁止页面滚动。 |\n| `delay` | `number` | `0` | 显示前延迟(ms)。 |\n| `transition` | `string \\| false` | `'loading'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs)。 |\n\n## Events\n\n无自定义事件。\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 被遮罩盖住的内容。 |\n| `indicator` | 替换遮罩中的指示器。仅在有默认插槽或 `fullscreen` 时生效。 |\n\n## 服务\n\n`loading.service(options)` 返回 `{ close, setText }`。`useLoading(defaults)` 返回 `{ open, close, setText }`。\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `target` | `string \\| HTMLElement` | — | 要盖住的元素或选择器。省略则为全屏。 |\n| `fullscreen` | `boolean` | 无 `target` 时为 `true` | 铺满视口。 |\n| `body` | `boolean` | `false` | 遮罩挂到 `body`,定位到 `target` 上。 |\n| `lock` | `boolean` | `false` | 锁定页面滚动。 |\n| `text` | `string` | — | 文案。 |\n| `effect` | 同组件 | `'circular'` | 动效。 |\n| `spinner` | `MRenderable` | — | 自定义指示器;设置后忽略内置 `effect`。 |\n| `background` | `string` | — | 遮罩背景。 |\n| `customClass` | `string` | — | 遮罩类名。 |\n| `size` | 同组件 | — | 指示器尺寸。 |\n| `delay` | `number` | — | 显示前延迟(ms)。 |\n\n## 主题\n\n指示器颜色走语义色:`--m-color-primary`、`--m-color-success`、`--m-color-warning`、`--m-color-danger`、`--m-color-text-muted`。遮罩默认是表面色的半透明混合,可用 `background` 或 `--m-loading-mask-bg` 覆盖。全屏层级是 `--m-loading-z-index`(默认 `--m-z-base + 200`)。\n\n`prefers-reduced-motion: reduce` 时循环动效关闭。\n\n## 无障碍\n\n- 指示器使用 `role=\"status\"`。\n- 遮罩区域设置 `aria-busy`,被盖住的内容设为 `inert`。\n- 不要只靠动画表示加载;需要说明时传入 `text`。\n"
13539
+ "markdown": "---\ntitle: Loading\ncategory: 05 / FEEDBACK\ndescription: 加载指示与遮罩:多种动效、区域加载、v-loading 指令和命令式 service。\n---\n\n# Loading\n\n用于区域或全屏的加载反馈。可以只渲染指示器,也可以盖住一块内容,或用指令和服务在任意节点上打开遮罩。\n\n内置圆环、极光环、弹跳球、波浪条、脉冲环和星尘。默认是圆环(`effect=\"circular\"`)。要改全局默认动效,设置 `componentDefaults.Loading.effect`。\n\n全屏遮罩会 Teleport 到 `body`,避免被父级 `overflow` / `transform` 裁切。同一时间只保留一个全屏实例。\n\n## 引入\n\n```ts\nimport { loading, MLoading, useLoading, vLoading } from 'morya-ui'\n```\n\n`app.use(MoryaUI)` 会注册 `v-loading`。按需引入时,在 `<script setup>` 里导入 `vLoading` 即可在模板中使用该指令。\n\n## 动效\n\n```vue preview src=\"./demos/Effects.vue\"\n```\n\n## 区域加载\n\n组件包住内容,或在元素上使用 `v-loading`。未传 `text` 时不显示文案,读屏仍使用 locale 的 `loading`。可用 `delay` 避免短请求闪一下。\n\n```vue preview src=\"./demos/Region.zh.vue\"\n```\n\n## 服务式调用\n\n不传 `target` 时遮罩铺满视口。`close()` 会先播放离场再卸载,`setText()` 改文案。也可用 `useLoading()`,在组件卸载时自动关闭。\n\n```vue preview src=\"./demos/Service.zh.vue\"\n```\n\n```ts\nconst instance = loading.service({\n text: '正在提交',\n effect: 'wave',\n lock: true,\n})\ninstance.setText('即将完成')\ninstance.close()\n```\n\n覆盖某个节点,或传入自定义指示器:\n\n```ts\nloading.service({\n target: '#panel',\n text: '加载中',\n})\n\nloading.service({\n spinner: () => h('span', '…'),\n text: '自定义',\n})\n```\n\n```ts\nconst { open, close } = useLoading({ effect: 'wave' })\nopen({ text: '保存中' })\nclose()\n```\n\n## 指令\n\n| 写法 | 说明 |\n| --- | --- |\n| `v-loading` | 布尔值,或带 `text` / `effect` / `background` / `lock` / `delay` / `spinner` 等字段的对象。 |\n| `v-loading.fullscreen` | 全屏遮罩。 |\n| `v-loading.lock` | 打开时锁定页面滚动。 |\n| `v-loading.body` | 遮罩挂到 `body`,并盖住当前元素(跟随尺寸变化)。 |\n| `m-loading-text` | 文案。 |\n| `m-loading-effect` | `circular` / `aurora` / `bounce` / `wave` / `pulse` / `stardust`。 |\n| `m-loading-background` | 遮罩背景色。 |\n| `m-loading-custom-class` | 加在遮罩上的类名。 |\n| `m-loading-delay` | 显示前延迟(ms)。 |\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `loading` | `boolean` | `true` | 包裹内容或 `fullscreen` 时是否显示遮罩。单独指示器始终显示。 |\n| `effect` | `'circular' \\| 'aurora' \\| 'bounce' \\| 'wave' \\| 'pulse' \\| 'stardust'` | `'circular'` | 动效。可用 `componentDefaults.Loading.effect` 改默认值。 |\n| `text` | `string` | — | 指示器下方文案。不传则不显示。 |\n| `ariaLabel` | `string` | locale `loading` | 无文案时的可访问名称。有文案时以文案为准。 |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 指示器缩放。 |\n| `background` | `string` | — | 遮罩背景,任意 CSS 颜色。 |\n| `customClass` | `string` | — | 加在遮罩上的类名。 |\n| `fullscreen` | `boolean` | `false` | 遮罩铺满视口(Teleport 到 `body`)。 |\n| `lock` | `boolean` | `false` | 显示时禁止页面滚动。 |\n| `delay` | `number` | `0` | 显示前延迟(ms)。 |\n| `transition` | `string \\| false` | `'loading'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs)。 |\n\n## Events\n\n无自定义事件。\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 被遮罩盖住的内容。 |\n| `indicator` | 替换遮罩中的指示器。仅在有默认插槽或 `fullscreen` 时生效。 |\n\n## 服务\n\n`loading.service(options)` 返回 `{ close, setText }`。`useLoading(defaults)` 返回 `{ open, close, setText }`。\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `target` | `string \\| HTMLElement` | — | 要盖住的元素或选择器。省略则为全屏。 |\n| `fullscreen` | `boolean` | 无 `target` 时为 `true` | 铺满视口。 |\n| `body` | `boolean` | `false` | 遮罩挂到 `body`,定位到 `target` 上。 |\n| `lock` | `boolean` | `false` | 锁定页面滚动。 |\n| `text` | `string` | — | 文案。 |\n| `effect` | 同组件 | `'circular'` | 动效。 |\n| `spinner` | `MRenderable` | — | 自定义指示器;设置后忽略内置 `effect`。 |\n| `background` | `string` | — | 遮罩背景。 |\n| `customClass` | `string` | — | 遮罩类名。 |\n| `size` | 同组件 | — | 指示器尺寸。 |\n| `delay` | `number` | — | 显示前延迟(ms)。 |\n\n## 主题\n\n指示器颜色走语义色:`--m-color-primary`、`--m-color-success`、`--m-color-warning`、`--m-color-danger`、`--m-color-text-muted`。遮罩默认是表面色的半透明混合,可用 `background` 或 `--m-loading-mask-bg` 覆盖。全屏层级是 `--m-loading-z-index`(默认 `--m-z-base + 200`)。\n\n主题动效为 `reduced` 或 `none` 时循环动效关闭。\n\n## 无障碍\n\n- 指示器使用 `role=\"status\"`。\n- 遮罩区域设置 `aria-busy`,被盖住的内容设为 `inert`。\n- 不要只靠动画表示加载;需要说明时传入 `text`。\n"
13494
13540
  },
13495
13541
  "en-US": {
13496
13542
  "title": "Loading",
@@ -13549,7 +13595,7 @@
13549
13595
  {
13550
13596
  "id": "theme",
13551
13597
  "title": "Theme",
13552
- "body": "Indicator colors use semantic tokens: `--m-color-primary`, `--m-color-success`, `--m-color-warning`, `--m-color-danger`, and `--m-color-text-muted`. The mask defaults to a translucent surface mix. Override it with `background` or `--m-loading-mask-bg`. Fullscreen stacking uses `--m-loading-z-index` (default `--m-z-base + 200`).\n\nLooping motion is disabled under `prefers-reduced-motion: reduce`."
13598
+ "body": "Indicator colors use semantic tokens: `--m-color-primary`, `--m-color-success`, `--m-color-warning`, `--m-color-danger`, and `--m-color-text-muted`. The mask defaults to a translucent surface mix. Override it with `background` or `--m-loading-mask-bg`. Fullscreen stacking uses `--m-loading-z-index` (default `--m-z-base + 200`).\n\nLooping motion stops when theme motion is `reduced` or `none`."
13553
13599
  },
13554
13600
  {
13555
13601
  "id": "accessibility",
@@ -13557,7 +13603,7 @@
13557
13603
  "body": "- The indicator uses `role=\"status\"`.\n- The masked region sets `aria-busy`, and covered content is `inert`.\n- Do not rely on motion alone; pass `text` when the wait needs an explanation."
13558
13604
  }
13559
13605
  ],
13560
- "markdown": "---\ntitle: Loading\ncategory: 05 / FEEDBACK\ndescription: Loading indicator and mask, with multiple effects, a region overlay, the v-loading directive, and an imperative service.\n---\n\n# Loading\n\nRegion or fullscreen loading feedback. Render an indicator on its own, cover a block of content, or open a mask on any node with the directive or service.\n\nBuilt-in graphics are a circular spinner, aurora ring, bouncing balls, wave bars, pulse rings, and stardust. The default is the circular spinner (`effect=\"circular\"`). Set `componentDefaults.Loading.effect` to change the global default.\n\nFullscreen masks teleport to `body` so parent `overflow` / `transform` cannot clip them. Only one fullscreen instance stays open at a time.\n\n## Import\n\n```ts\nimport { loading, MLoading, useLoading, vLoading } from 'morya-ui'\n```\n\n`app.use(MoryaUI)` registers `v-loading`. For on-demand usage, import `vLoading` in `<script setup>` and the template can use the directive.\n\n## Effects\n\n```vue preview src=\"./demos/Effects.vue\"\n```\n\n## Region\n\nWrap content with the component, or put `v-loading` on an element. Omit `text` to hide the caption; screen readers still get the locale `loading` string. Use `delay` to avoid a flash on short requests.\n\n```vue preview src=\"./demos/Region.en.vue\"\n```\n\n## Service\n\nWith no `target`, the mask covers the viewport. `close()` plays the leave transition before unmounting, and `setText()` changes the caption. `useLoading()` closes automatically when the caller unmounts.\n\n```vue preview src=\"./demos/Service.en.vue\"\n```\n\n```ts\nconst instance = loading.service({\n text: 'Submitting',\n effect: 'wave',\n lock: true,\n})\ninstance.setText('Almost done')\ninstance.close()\n```\n\nCover one node, or pass a custom indicator:\n\n```ts\nloading.service({\n target: '#panel',\n text: 'Loading',\n})\n\nloading.service({\n spinner: () => h('span', '…'),\n text: 'Custom',\n})\n```\n\n```ts\nconst { open, close } = useLoading({ effect: 'wave' })\nopen({ text: 'Saving' })\nclose()\n```\n\n## Directive\n\n| Form | Description |\n| --- | --- |\n| `v-loading` | A boolean, or an object with `text`, `effect`, `background`, `lock`, `delay`, `spinner`, and related fields. |\n| `v-loading.fullscreen` | Fullscreen mask. |\n| `v-loading.lock` | Lock page scrolling while open. |\n| `v-loading.body` | Mount the mask on `body`, positioned over the element (tracks size changes). |\n| `m-loading-text` | Caption. |\n| `m-loading-effect` | `circular` / `aurora` / `bounce` / `wave` / `pulse` / `stardust`. |\n| `m-loading-background` | Mask background. |\n| `m-loading-custom-class` | Extra class on the mask. |\n| `m-loading-delay` | Delay before showing (ms). |\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `loading` | `boolean` | `true` | Mask visibility when wrapping content or using `fullscreen`. A bare indicator is always shown. |\n| `effect` | `'circular' \\| 'aurora' \\| 'bounce' \\| 'wave' \\| 'pulse' \\| 'stardust'` | `'circular'` | Graphic. Override the default with `componentDefaults.Loading.effect`. |\n| `text` | `string` | — | Caption under the indicator. Hidden when omitted. |\n| `ariaLabel` | `string` | locale `loading` | Accessible name when there is no caption. A caption is used as the name when present. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Indicator scale. |\n| `background` | `string` | — | Mask background, any CSS color. |\n| `customClass` | `string` | — | Extra class on the mask. |\n| `fullscreen` | `boolean` | `false` | Cover the viewport (teleported to `body`). |\n| `lock` | `boolean` | `false` | Prevent page scrolling while visible. |\n| `delay` | `number` | `0` | Delay before showing (ms). |\n| `transition` | `string \\| false` | `'loading'` | 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## Events\n\nNo custom events.\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Content covered by the mask. |\n| `indicator` | Replaces the indicator inside the mask. Used when there is a default slot or `fullscreen`. |\n\n## Service\n\n`loading.service(options)` returns `{ close, setText }`. `useLoading(defaults)` returns `{ open, close, setText }`.\n\n| Option | Type | Default | Description |\n| --- | --- | --- | --- |\n| `target` | `string \\| HTMLElement` | — | Element or selector to cover. Omit for fullscreen. |\n| `fullscreen` | `boolean` | `true` when `target` is omitted | Cover the viewport. |\n| `body` | `boolean` | `false` | Mount the mask on `body`, positioned over `target`. |\n| `lock` | `boolean` | `false` | Lock page scrolling. |\n| `text` | `string` | — | Caption. |\n| `effect` | same as the component | `'circular'` | Graphic. |\n| `spinner` | `MRenderable` | — | Custom indicator; skips built-in effects when set. |\n| `background` | `string` | — | Mask background. |\n| `customClass` | `string` | — | Extra mask class. |\n| `size` | same as the component | — | Indicator size. |\n| `delay` | `number` | — | Delay before showing (ms). |\n\n## Theme\n\nIndicator colors use semantic tokens: `--m-color-primary`, `--m-color-success`, `--m-color-warning`, `--m-color-danger`, and `--m-color-text-muted`. The mask defaults to a translucent surface mix. Override it with `background` or `--m-loading-mask-bg`. Fullscreen stacking uses `--m-loading-z-index` (default `--m-z-base + 200`).\n\nLooping motion is disabled under `prefers-reduced-motion: reduce`.\n\n## Accessibility\n\n- The indicator uses `role=\"status\"`.\n- The masked region sets `aria-busy`, and covered content is `inert`.\n- Do not rely on motion alone; pass `text` when the wait needs an explanation.\n"
13606
+ "markdown": "---\ntitle: Loading\ncategory: 05 / FEEDBACK\ndescription: Loading indicator and mask, with multiple effects, a region overlay, the v-loading directive, and an imperative service.\n---\n\n# Loading\n\nRegion or fullscreen loading feedback. Render an indicator on its own, cover a block of content, or open a mask on any node with the directive or service.\n\nBuilt-in graphics are a circular spinner, aurora ring, bouncing balls, wave bars, pulse rings, and stardust. The default is the circular spinner (`effect=\"circular\"`). Set `componentDefaults.Loading.effect` to change the global default.\n\nFullscreen masks teleport to `body` so parent `overflow` / `transform` cannot clip them. Only one fullscreen instance stays open at a time.\n\n## Import\n\n```ts\nimport { loading, MLoading, useLoading, vLoading } from 'morya-ui'\n```\n\n`app.use(MoryaUI)` registers `v-loading`. For on-demand usage, import `vLoading` in `<script setup>` and the template can use the directive.\n\n## Effects\n\n```vue preview src=\"./demos/Effects.vue\"\n```\n\n## Region\n\nWrap content with the component, or put `v-loading` on an element. Omit `text` to hide the caption; screen readers still get the locale `loading` string. Use `delay` to avoid a flash on short requests.\n\n```vue preview src=\"./demos/Region.en.vue\"\n```\n\n## Service\n\nWith no `target`, the mask covers the viewport. `close()` plays the leave transition before unmounting, and `setText()` changes the caption. `useLoading()` closes automatically when the caller unmounts.\n\n```vue preview src=\"./demos/Service.en.vue\"\n```\n\n```ts\nconst instance = loading.service({\n text: 'Submitting',\n effect: 'wave',\n lock: true,\n})\ninstance.setText('Almost done')\ninstance.close()\n```\n\nCover one node, or pass a custom indicator:\n\n```ts\nloading.service({\n target: '#panel',\n text: 'Loading',\n})\n\nloading.service({\n spinner: () => h('span', '…'),\n text: 'Custom',\n})\n```\n\n```ts\nconst { open, close } = useLoading({ effect: 'wave' })\nopen({ text: 'Saving' })\nclose()\n```\n\n## Directive\n\n| Form | Description |\n| --- | --- |\n| `v-loading` | A boolean, or an object with `text`, `effect`, `background`, `lock`, `delay`, `spinner`, and related fields. |\n| `v-loading.fullscreen` | Fullscreen mask. |\n| `v-loading.lock` | Lock page scrolling while open. |\n| `v-loading.body` | Mount the mask on `body`, positioned over the element (tracks size changes). |\n| `m-loading-text` | Caption. |\n| `m-loading-effect` | `circular` / `aurora` / `bounce` / `wave` / `pulse` / `stardust`. |\n| `m-loading-background` | Mask background. |\n| `m-loading-custom-class` | Extra class on the mask. |\n| `m-loading-delay` | Delay before showing (ms). |\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `loading` | `boolean` | `true` | Mask visibility when wrapping content or using `fullscreen`. A bare indicator is always shown. |\n| `effect` | `'circular' \\| 'aurora' \\| 'bounce' \\| 'wave' \\| 'pulse' \\| 'stardust'` | `'circular'` | Graphic. Override the default with `componentDefaults.Loading.effect`. |\n| `text` | `string` | — | Caption under the indicator. Hidden when omitted. |\n| `ariaLabel` | `string` | locale `loading` | Accessible name when there is no caption. A caption is used as the name when present. |\n| `size` | `'small' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Indicator scale. |\n| `background` | `string` | — | Mask background, any CSS color. |\n| `customClass` | `string` | — | Extra class on the mask. |\n| `fullscreen` | `boolean` | `false` | Cover the viewport (teleported to `body`). |\n| `lock` | `boolean` | `false` | Prevent page scrolling while visible. |\n| `delay` | `number` | `0` | Delay before showing (ms). |\n| `transition` | `string \\| false` | `'loading'` | 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## Events\n\nNo custom events.\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Content covered by the mask. |\n| `indicator` | Replaces the indicator inside the mask. Used when there is a default slot or `fullscreen`. |\n\n## Service\n\n`loading.service(options)` returns `{ close, setText }`. `useLoading(defaults)` returns `{ open, close, setText }`.\n\n| Option | Type | Default | Description |\n| --- | --- | --- | --- |\n| `target` | `string \\| HTMLElement` | — | Element or selector to cover. Omit for fullscreen. |\n| `fullscreen` | `boolean` | `true` when `target` is omitted | Cover the viewport. |\n| `body` | `boolean` | `false` | Mount the mask on `body`, positioned over `target`. |\n| `lock` | `boolean` | `false` | Lock page scrolling. |\n| `text` | `string` | — | Caption. |\n| `effect` | same as the component | `'circular'` | Graphic. |\n| `spinner` | `MRenderable` | — | Custom indicator; skips built-in effects when set. |\n| `background` | `string` | — | Mask background. |\n| `customClass` | `string` | — | Extra mask class. |\n| `size` | same as the component | — | Indicator size. |\n| `delay` | `number` | — | Delay before showing (ms). |\n\n## Theme\n\nIndicator colors use semantic tokens: `--m-color-primary`, `--m-color-success`, `--m-color-warning`, `--m-color-danger`, and `--m-color-text-muted`. The mask defaults to a translucent surface mix. Override it with `background` or `--m-loading-mask-bg`. Fullscreen stacking uses `--m-loading-z-index` (default `--m-z-base + 200`).\n\nLooping motion stops when theme motion is `reduced` or `none`.\n\n## Accessibility\n\n- The indicator uses `role=\"status\"`.\n- The masked region sets `aria-busy`, and covered content is `inert`.\n- Do not rely on motion alone; pass `text` when the wait needs an explanation.\n"
13561
13607
  }
13562
13608
  }
13563
13609
  },
@@ -15199,19 +15245,54 @@
15199
15245
  "props": [
15200
15246
  {
15201
15247
  "name": "density",
15202
- "type": "'default' | 'compact' | 'spacious'",
15203
- "description": "子区块垂直间距。"
15248
+ "type": "'default' | 'compact'",
15249
+ "description": "`compact` 缩小主数值字号。"
15204
15250
  },
15205
15251
  {
15206
15252
  "name": "width",
15207
15253
  "type": "'full' | 'narrow'",
15208
15254
  "description": "`narrow` 约 42rem,适合表单页。"
15209
15255
  },
15256
+ {
15257
+ "name": "bands",
15258
+ "type": "'auto' | 'uniform'",
15259
+ "description": "`auto` 收紧 Header/筛选/Toolbar 与表格之间的 band;`uniform` 仅用 `gap`。"
15260
+ },
15210
15261
  {
15211
15262
  "name": "ariaLabel",
15212
15263
  "type": "string",
15213
15264
  "description": "无障碍标签。"
15214
15265
  },
15266
+ {
15267
+ "name": "variant",
15268
+ "type": "'default' | 'muted' | 'form' | 'actions'",
15269
+ "description": "视觉变体;`muted` 与 Table header 同色浅底;`form` 渲染为 `MCard` 表面。"
15270
+ },
15271
+ {
15272
+ "name": "collapsible",
15273
+ "type": "boolean",
15274
+ "description": "为 true 且提供 `#advanced` 时显示展开/收起。"
15275
+ },
15276
+ {
15277
+ "name": "expanded",
15278
+ "type": "boolean",
15279
+ "description": "高级区展开状态(`v-model:expanded`)。"
15280
+ },
15281
+ {
15282
+ "name": "expandLabel",
15283
+ "type": "string",
15284
+ "description": "覆盖默认展开/收起文案。"
15285
+ },
15286
+ {
15287
+ "name": "collapseLabel",
15288
+ "type": "string",
15289
+ "description": "覆盖默认展开/收起文案。"
15290
+ },
15291
+ {
15292
+ "name": "label",
15293
+ "type": "string",
15294
+ "description": "指标名称。"
15295
+ },
15215
15296
  {
15216
15297
  "name": "title",
15217
15298
  "type": "string",
@@ -15227,35 +15308,55 @@
15227
15308
  "type": "string",
15228
15309
  "description": "占位说明。"
15229
15310
  },
15230
- {
15231
- "name": "variant",
15232
- "type": "'default' | 'muted' | 'form' | 'actions'",
15233
- "description": "视觉变体。"
15234
- },
15235
- {
15236
- "name": "label",
15237
- "type": "string",
15238
- "description": "指标名称。"
15239
- },
15240
15311
  {
15241
15312
  "name": "value",
15242
15313
  "type": "string | number",
15243
- "description": "主数值。"
15314
+ "description": "主数值(等宽数字)。"
15244
15315
  },
15245
15316
  {
15246
15317
  "name": "trend",
15247
15318
  "type": "string",
15248
- "description": "变化量或说明。"
15319
+ "description": "变化量,渲染为与 `MStatus` 同色的文本。"
15249
15320
  },
15250
15321
  {
15251
15322
  "name": "trendSeverity",
15252
15323
  "type": "'primary' | 'success' | 'warn' | 'danger' | 'secondary'",
15253
15324
  "description": "趋势色。"
15254
15325
  },
15326
+ {
15327
+ "name": "trendDirection",
15328
+ "type": "'up' | 'down'",
15329
+ "description": "在趋势旁显示升/降箭头。"
15330
+ },
15331
+ {
15332
+ "name": "trendLabel",
15333
+ "type": "string",
15334
+ "description": "趋势后的弱说明,如「较上月」。"
15335
+ },
15255
15336
  {
15256
15337
  "name": "icon",
15257
15338
  "type": "string",
15258
- "description": "右侧图标名。"
15339
+ "description": "右侧弱化图标名。"
15340
+ },
15341
+ {
15342
+ "name": "loading",
15343
+ "type": "boolean",
15344
+ "description": "用骨架屏代替数值与趋势。"
15345
+ },
15346
+ {
15347
+ "name": "shadow",
15348
+ "type": "'never' | 'hover' | 'always'",
15349
+ "description": "透传 `MCard.shadow`(`layout=\"plain\"` 时无效)。"
15350
+ },
15351
+ {
15352
+ "name": "layout",
15353
+ "type": "'card' | 'plain'",
15354
+ "description": "`plain` 无 Card 壳,适合横排 KPI 条。"
15355
+ },
15356
+ {
15357
+ "name": "orientation",
15358
+ "type": "'stacked' | 'inline'",
15359
+ "description": "`inline` 标签与数值同一行。"
15259
15360
  },
15260
15361
  {
15261
15362
  "name": "minHeight",
@@ -15267,11 +15368,35 @@
15267
15368
  "slots": [
15268
15369
  {
15269
15370
  "name": "default",
15270
- "description": "无 `title` 时的左侧内容。"
15371
+ "description": "自定义说明内容。"
15372
+ },
15373
+ {
15374
+ "name": "advanced",
15375
+ "description": "折叠区(需 `collapsible`)。"
15376
+ },
15377
+ {
15378
+ "name": "active",
15379
+ "description": "可选;已选摘要(更常见是下方 `MPageFilterChips`)。"
15271
15380
  },
15272
15381
  {
15273
15382
  "name": "actions",
15274
- "description": "右侧操作。"
15383
+ "description": "标题行右侧操作区。"
15384
+ },
15385
+ {
15386
+ "name": "breadcrumb",
15387
+ "description": "标题上方的面包屑(放 `MBreadcrumb`)。"
15388
+ },
15389
+ {
15390
+ "name": "tags",
15391
+ "description": "标题右侧的状态/分类标记(放 `MTag` / `MStatus`)。"
15392
+ },
15393
+ {
15394
+ "name": "icon",
15395
+ "description": "自定义图标/插画。"
15396
+ },
15397
+ {
15398
+ "name": "extra",
15399
+ "description": "下一步操作区(如按钮)。"
15275
15400
  }
15276
15401
  ],
15277
15402
  "methods": [],
@@ -15282,7 +15407,7 @@
15282
15407
  "sectionId": "引入",
15283
15408
  "lang": "ts",
15284
15409
  "preview": false,
15285
- "code": "import {\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'",
15410
+ "code": "import {\n MPageContent,\n MPageFilterChips,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'",
15286
15411
  "locale": "zh-CN"
15287
15412
  },
15288
15413
  {
@@ -15291,7 +15416,16 @@
15291
15416
  "sectionId": "列表页组合",
15292
15417
  "lang": "vue",
15293
15418
  "preview": true,
15294
- "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MInput,\n MPageContent,\n MPageFilters,\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:hidden;background:var(--m-color-surface)\"\n >\n <MPageContent>\n <MPageFilters aria-label=\"筛选\">\n <MSpace wrap>\n <MInput v-model=\"keyword\" placeholder=\"搜索\" clearable class=\"w-48\" />\n <MButton severity=\"primary\">\n 查询\n </MButton>\n </MSpace>\n </MPageFilters>\n <MPageToolbar title=\"用户管理\">\n <template #actions>\n <MButton severity=\"primary\">\n 新建\n </MButton>\n </template>\n </MPageToolbar>\n </MPageContent>\n </div>\n</template>",
15419
+ "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 <MButton severity=\"secondary\">\n 查询\n </MButton>\n </MSpace>\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>",
15420
+ "locale": "zh-CN"
15421
+ },
15422
+ {
15423
+ "id": "列表页组合-2",
15424
+ "section": "列表页组合",
15425
+ "sectionId": "列表页组合",
15426
+ "lang": "vue",
15427
+ "preview": true,
15428
+ "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=\"折叠高级筛选,已选条件用 Tag 展示。\">\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 <MButton severity=\"secondary\">\n 查询\n </MButton>\n <MButton severity=\"secondary\" text @click=\"resetAll\">\n 重置\n </MButton>\n </MSpace>\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>",
15295
15429
  "locale": "zh-CN"
15296
15430
  },
15297
15431
  {
@@ -15309,7 +15443,16 @@
15309
15443
  "sectionId": "仪表盘-kpi",
15310
15444
  "lang": "vue",
15311
15445
  "preview": true,
15312
- "code": "<script setup lang=\"ts\">\nimport { MPageContent, MPageStat } from 'morya-ui'\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 density=\"compact\">\n <MPageStat label=\"总用户\" value=\"12,480\" trend=\"+8.2%\" icon=\"user\" />\n </MPageContent>\n </div>\n</template>",
15446
+ "code": "<script setup lang=\"ts\">\nimport { MPageContent, MPageStat } from 'morya-ui'\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 density=\"compact\">\n <MPageStat\n label=\"总用户\"\n value=\"12,480\"\n trend=\"+8.2%\"\n trend-direction=\"up\"\n trend-label=\"较上月\"\n trend-severity=\"success\"\n icon=\"user\"\n shadow=\"hover\"\n />\n <MPageStat\n label=\"待处理工单\"\n value=\"47\"\n trend=\"-12%\"\n loading\n icon=\"clipboard\"\n />\n </MPageContent>\n </div>\n</template>",
15447
+ "locale": "zh-CN"
15448
+ },
15449
+ {
15450
+ "id": "仪表盘-kpi-2",
15451
+ "section": "仪表盘 KPI",
15452
+ "sectionId": "仪表盘-kpi",
15453
+ "lang": "vue",
15454
+ "preview": true,
15455
+ "code": "<script setup lang=\"ts\">\nimport { MGrid, MGridItem, MPageContent, MPageStat } from 'morya-ui'\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 density=\"compact\">\n <MGrid :cols=\"2\" :x-gap=\"16\" :y-gap=\"12\" responsive=\"screen\">\n <MGridItem :span=\"1\">\n <MPageStat\n label=\"今日订单\"\n value=\"1,284\"\n trend=\"+6.1%\"\n trend-direction=\"up\"\n trend-severity=\"success\"\n layout=\"plain\"\n orientation=\"inline\"\n density=\"compact\"\n />\n </MGridItem>\n <MGridItem :span=\"1\">\n <MPageStat\n label=\"待处理\"\n value=\"47\"\n layout=\"plain\"\n orientation=\"inline\"\n density=\"compact\"\n />\n </MGridItem>\n <MGridItem :span=\"2\">\n <MPageStat\n label=\"总用户\"\n value=\"12,480\"\n trend=\"+8.2%\"\n trend-direction=\"up\"\n trend-label=\"较上月\"\n trend-severity=\"success\"\n icon=\"user\"\n shadow=\"hover\"\n />\n </MGridItem>\n </MGrid>\n </MPageContent>\n </div>\n</template>",
15313
15456
  "locale": "zh-CN"
15314
15457
  },
15315
15458
  {
@@ -15318,7 +15461,7 @@
15318
15461
  "sectionId": "import",
15319
15462
  "lang": "ts",
15320
15463
  "preview": false,
15321
- "code": "import {\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'",
15464
+ "code": "import {\n MPageContent,\n MPageFilterChips,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'",
15322
15465
  "locale": "en-US"
15323
15466
  },
15324
15467
  {
@@ -15327,7 +15470,25 @@
15327
15470
  "sectionId": "list-page-stack",
15328
15471
  "lang": "vue",
15329
15472
  "preview": true,
15330
- "code": "<script setup lang=\"ts\">\nimport {\n MButton,\n MInput,\n MPageContent,\n MPageFilters,\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:hidden;background:var(--m-color-surface)\"\n >\n <MPageContent>\n <MPageFilters aria-label=\"Filters\">\n <MSpace wrap>\n <MInput v-model=\"keyword\" placeholder=\"Search\" clearable class=\"w-48\" />\n <MButton severity=\"primary\">\n Search\n </MButton>\n </MSpace>\n </MPageFilters>\n <MPageToolbar title=\"Users\">\n <template #actions>\n <MButton severity=\"primary\">\n Create\n </MButton>\n </template>\n </MPageToolbar>\n </MPageContent>\n </div>\n</template>",
15473
+ "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 <MButton severity=\"secondary\">\n Search\n </MButton>\n </MSpace>\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>",
15474
+ "locale": "en-US"
15475
+ },
15476
+ {
15477
+ "id": "list-page-stack-2",
15478
+ "section": "List page stack",
15479
+ "sectionId": "list-page-stack",
15480
+ "lang": "vue",
15481
+ "preview": true,
15482
+ "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 and active tags.\">\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 <MButton severity=\"secondary\">\n Search\n </MButton>\n <MButton severity=\"secondary\" text @click=\"resetAll\">\n Reset\n </MButton>\n </MSpace>\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>",
15483
+ "locale": "en-US"
15484
+ },
15485
+ {
15486
+ "id": "dashboard-kpi-1",
15487
+ "section": "Dashboard KPI",
15488
+ "sectionId": "dashboard-kpi",
15489
+ "lang": "vue",
15490
+ "preview": true,
15491
+ "code": "<script setup lang=\"ts\">\nimport { MGrid, MGridItem, MPageContent, MPageStat } from 'morya-ui'\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 density=\"compact\">\n <MGrid :cols=\"2\" :x-gap=\"16\" :y-gap=\"12\" responsive=\"screen\">\n <MGridItem :span=\"1\">\n <MPageStat\n label=\"Orders today\"\n value=\"1,284\"\n trend=\"+6.1%\"\n trend-direction=\"up\"\n trend-severity=\"success\"\n layout=\"plain\"\n orientation=\"inline\"\n density=\"compact\"\n />\n </MGridItem>\n <MGridItem :span=\"1\">\n <MPageStat\n label=\"Pending\"\n value=\"47\"\n layout=\"plain\"\n orientation=\"inline\"\n density=\"compact\"\n />\n </MGridItem>\n <MGridItem :span=\"2\">\n <MPageStat\n label=\"Total users\"\n value=\"12,480\"\n trend=\"+8.2%\"\n trend-direction=\"up\"\n trend-label=\"vs last month\"\n trend-severity=\"success\"\n icon=\"user\"\n shadow=\"hover\"\n />\n </MGridItem>\n </MGrid>\n </MPageContent>\n </div>\n</template>",
15331
15492
  "locale": "en-US"
15332
15493
  }
15333
15494
  ],
@@ -15344,12 +15505,12 @@
15344
15505
  {
15345
15506
  "id": "引入",
15346
15507
  "title": "引入",
15347
- "body": "```ts\nimport {\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```"
15508
+ "body": "```ts\nimport {\n MPageContent,\n MPageFilterChips,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```"
15348
15509
  },
15349
15510
  {
15350
15511
  "id": "列表页组合",
15351
15512
  "title": "列表页组合",
15352
- "body": "`MPageContent` 负责内容区 **padding**(默认 `--m-space-6`)与子区块 **gap**(默认 `--m-space-4`),文档预览中外框仅模拟 `MLayoutContent` 边界。\n\n```vue preview src=\"./demos/ListPageStack.zh.vue\"\n```"
15513
+ "body": "`MPageContent` 负责内容区 **padding**(默认 `--m-space-6`)与子区块 **gap**(默认 `--m-space-4`),文档预览中外框仅模拟 `MLayoutContent` 边界。\n\n`MPageFilters` 默认是 **无框的控件行**(`variant=\"plain\"`);需要一条可辨识的工具带时再用 `variant=\"filled\"`(与 Table header 相同的 `--m-color-fill-light`,无圆角)。`MPageHeader` 是页面身份(约 `--m-font-size-xl`);`MPageToolbar` 是列表操作条(`--m-font-size-md`),不要当成第二页头。\n\n```vue preview src=\"./demos/ListPageStack.zh.vue\"\n```\n\n字段较多时:`MPageFilters collapsible` + `#advanced` 折叠高级项;已选条件用 `MPageFilterChips` 包一层 `MTag closable`(不要用自定义 dashed 壳)。\n\n```vue preview src=\"./demos/ListFiltersAdvanced.zh.vue\"\n```\n\n**面包屑**:路由级 trail 放在 `MLayoutHeader` 的 `MBreadcrumb`;若页内还需要上下文,用 `MPageHeader` 的 `#breadcrumb` 插槽——**不要**在 Layout 与 Page 各写一遍相同标题链。"
15353
15514
  },
15354
15515
  {
15355
15516
  "id": "表单页组合",
@@ -15359,20 +15520,20 @@
15359
15520
  {
15360
15521
  "id": "仪表盘-kpi",
15361
15522
  "title": "仪表盘 KPI",
15362
- "body": "```vue preview src=\"./demos/Kpi.vue\"\n```"
15523
+ "body": "默认 `MPageStat` 为 Card 表面;密集条带可用 `layout=\"plain\"` + `orientation=\"inline\"` + `density=\"compact\"`。\n\n```vue preview src=\"./demos/Kpi.vue\"\n```\n\n```vue preview src=\"./demos/StatVariants.zh.vue\"\n```"
15363
15524
  },
15364
15525
  {
15365
15526
  "id": "组合规则",
15366
15527
  "title": "组合规则",
15367
- "body": "| 场景 | 推荐组件 | 避免 |\n| --- | --- | --- |\n| 内容区垂直堆叠 | `MPageContent` | 手写 `gap` / `padding` |\n| 筛选区 | `MPageFilters` + `MSpace` / `MFlex` | 额外包一层 `MCard` |\n| 标题 + 主操作 | `MPageToolbar` | 裸 `div` + `justify-content` |\n| 页面说明 | `MPageHeader` | 无层级的裸 `h1` |\n| 表单主体 | `MPageSection variant=\"form\"` | 重复边框的 `MCard` 嵌套 |\n| 列表表格 | 直接放 `MTable` | `MCard` 再包 `MTable bordered` |\n| KPI | `MPageStat` | 每页自定义 stat CSS |\n| 图表占位 | `MPagePlaceholder` | dashed border 手写样式 |\n\n完整黄金样例用 MCP `get_golden_page`。**局部修改**时用 MCP `get_page_snippet`(如 `filters`、`toolbar`、`form-actions`)。"
15528
+ "body": "| 场景 | 推荐组件 | 避免 |\n| --- | --- | --- |\n| 内容区垂直堆叠 | `MPageContent` | 手写 `gap` / `padding` |\n| 筛选区 | `MPageFilters` + `MSpace` / `MFlex` | 额外包一层 `MCard` |\n| 页面身份 + 页级操作 | `MPageHeader` | 无层级的裸 `h1` |\n| 列表操作条 | `MPageToolbar` | 把 Toolbar 当成第二页头 |\n| 表单主体 | `MPageSection variant=\"form\"`(内部即 `MCard` 表面) | 再包一层 `MCard` |\n| 列表表格 | 直接放 `MTable` | `MCard` 再包 `MTable bordered` |\n| KPI | `MPageStat` | 每页自定义 stat CSS |\n| 图表占位 | `MPagePlaceholder` 或 `MCard` + `MEmpty` | 虚线框 / 光晕手写样式 |\n\n完整黄金样例用 MCP `get_golden_page`。**局部修改**时用 MCP `get_page_snippet`(如 `filters`、`toolbar`、`form-actions`)。"
15368
15529
  },
15369
15530
  {
15370
15531
  "id": "api",
15371
15532
  "title": "API",
15372
- "body": "### MPageContent\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `density` | `'default' \\| 'compact' \\| 'spacious'` | `'default'` | 子区块垂直间距。 |\n| `width` | `'full' \\| 'narrow'` | `'full'` | `narrow` 约 42rem,适合表单页。 |\n\n### MPageFilters\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `ariaLabel` | `string` | — | 筛选区无障碍名称。 |\n\n### MPageToolbar\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 无 `title` 时的左侧内容。 |\n| `actions` | 右侧操作区。 |\n\n### MPageHeader\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题。 |\n| `description` | `string` | — | 副标题/说明。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `actions` | 右侧操作。 |\n\n### MPageSection\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `variant` | `'default' \\| 'muted' \\| 'form' \\| 'actions'` | `'default'` | 视觉变体。 |\n| `title` | `string` | — | 可选分组标题。 |\n\n### MPageStat\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 指标名称。 |\n| `value` | `string \\| number` | — | 主数值。 |\n| `trend` | `string` | — | 变化量或说明。 |\n| `trendSeverity` | `'primary' \\| 'success' \\| 'warn' \\| 'danger' \\| 'secondary'` | `'primary'` | 趋势色。 |\n| `icon` | `string` | — | 右侧图标名。 |\n\n### MPagePlaceholder\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `description` | `string` | — | 占位说明。 |\n| `ariaLabel` | `string` | `'Placeholder'` | 无障碍标签。 |\n| `minHeight` | `number \\| string` | `'12rem'` | 最小高度。 |"
15533
+ "body": "### MPageContent\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `density` | `'default' \\| 'compact' \\| 'spacious'` | `'default'` | 子区块垂直间距。 |\n| `width` | `'full' \\| 'narrow'` | `'full'` | `narrow` 约 42rem,适合表单页。 |\n| `bands` | `'auto' \\| 'uniform'` | `'auto'` | `auto` 收紧 Header/筛选/Toolbar 与表格之间的 band;`uniform` 仅用 `gap`。 |\n\n`bands=\"auto\"` 时可通过 CSS 变量微调:`--m-page-content-body-lead`、`--m-page-content-tools-pull`(见 `styles.css`)。\n\n### MPageFilters\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `ariaLabel` | `string` | — | 筛选区无障碍名称。 |\n| `variant` | `'plain' \\| 'filled'` | `'plain'` | 表面处理;`filled` 与 Table header 同色浅底,无圆角。 |\n| `collapsible` | `boolean` | `false` | 为 true 且提供 `#advanced` 时显示展开/收起。 |\n| `expanded` | `boolean` | `false` | 高级区展开状态(`v-model:expanded`)。 |\n| `expandLabel` / `collapseLabel` | `string` | — | 覆盖默认展开/收起文案。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 常用筛选控件行。 |\n| `advanced` | 折叠区(需 `collapsible`)。 |\n| `active` | 可选;已选摘要(更常见是下方 `MPageFilterChips`)。 |\n\n### MPageFilterChips\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 弱前缀,如「已选」。 |\n| `ariaLabel` | `string` | — | 已选条件列表的无障碍名称。 |\n\n默认插槽放 `MTag closable` 或同类可移除标记。\n\n### MPageToolbar\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 操作条组名(`--m-font-size-md`),不是页面标题。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 无 `title` 时的左侧内容。 |\n| `actions` | 右侧操作区。 |\n\n### MPageHeader\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题(`--m-font-size-xl`)。 |\n| `description` | `string` | — | 副标题/说明。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `breadcrumb` | 标题上方的面包屑(放 `MBreadcrumb`)。 |\n| `tags` | 标题右侧的状态/分类标记(放 `MTag` / `MStatus`)。 |\n| `actions` | 右侧操作。 |\n\n### MPageSection\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `variant` | `'default' \\| 'muted' \\| 'form' \\| 'actions'` | `'default'` | 视觉变体;`muted` 与 Table header 同色浅底;`form` 渲染为 `MCard` 表面。 |\n| `title` | `string` | — | 可选分组标题。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `actions` | 标题行右侧操作区。 |\n\n### MPageStat\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 指标名称。 |\n| `value` | `string \\| number` | — | 主数值(等宽数字)。 |\n| `trend` | `string` | — | 变化量,渲染为与 `MStatus` 同色的文本。 |\n| `trendSeverity` | `'primary' \\| 'success' \\| 'warn' \\| 'danger' \\| 'secondary'` | `'primary'` | 趋势色。 |\n| `trendDirection` | `'up' \\| 'down'` | — | 在趋势旁显示升/降箭头。 |\n| `trendLabel` | `string` | — | 趋势后的弱说明,如「较上月」。 |\n| `icon` | `string` | — | 右侧弱化图标名。 |\n| `loading` | `boolean` | `false` | 用骨架屏代替数值与趋势。 |\n| `shadow` | `'never' \\| 'hover' \\| 'always'` | `'always'` | 透传 `MCard.shadow`(`layout=\"plain\"` 时无效)。 |\n| `layout` | `'card' \\| 'plain'` | `'card'` | `plain` 无 Card 壳,适合横排 KPI 条。 |\n| `density` | `'default' \\| 'compact'` | `'default'` | `compact` 缩小主数值字号。 |\n| `orientation` | `'stacked' \\| 'inline'` | `'stacked'` | `inline` 标签与数值同一行。 |\n\n### MPagePlaceholder\n\n内部组合 `MEmpty`:默认展示空态插画与说明,可通过默认插槽自定义内容、`#icon` 自定义图标、`#extra` 放置下一步操作。\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `description` | `string` | — | 占位说明。 |\n| `ariaLabel` | `string` | `'Placeholder'` | 无障碍标签。 |\n| `minHeight` | `number \\| string` | `'12rem'` | 最小高度。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 自定义说明内容。 |\n| `icon` | 自定义图标/插画。 |\n| `extra` | 下一步操作区(如按钮)。 |"
15373
15534
  }
15374
15535
  ],
15375
- "markdown": "---\ntitle: Page\ncategory: 06 / LAYOUT\ndescription: 业务页面组合区块,封装间距、边框与标题层级,少写或不写页面 CSS。\n---\n\n# Page\n\n业务页面组合组件。与 `MLayout` 搭配使用,把列表页筛选区、工具栏、表单分组、KPI 卡片等常见区块的间距和边框内聚到组件内,**优先用 Page 组件拼装页面,而不是每页手写 scoped CSS**。\n\n## 引入\n\n```ts\nimport {\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```\n\n## 列表页组合\n\n`MPageContent` 负责内容区 **padding**(默认 `--m-space-6`)与子区块 **gap**(默认 `--m-space-4`),文档预览中外框仅模拟 `MLayoutContent` 边界。\n\n```vue preview src=\"./demos/ListPageStack.zh.vue\"\n```\n\n## 表单页组合\n\n`MPageContent width=\"narrow\"` 限制表单宽度;`MPageSection variant=\"form\"` 提供表单表面;`variant=\"actions\"` 用于底栏操作。\n\n```vue preview src=\"./demos/Demo2.vue\"\n```\n\n## 仪表盘 KPI\n\n```vue preview src=\"./demos/Kpi.vue\"\n```\n\n## 组合规则\n\n| 场景 | 推荐组件 | 避免 |\n| --- | --- | --- |\n| 内容区垂直堆叠 | `MPageContent` | 手写 `gap` / `padding` |\n| 筛选区 | `MPageFilters` + `MSpace` / `MFlex` | 额外包一层 `MCard` |\n| 标题 + 主操作 | `MPageToolbar` | 裸 `div` + `justify-content` |\n| 页面说明 | `MPageHeader` | 无层级的裸 `h1` |\n| 表单主体 | `MPageSection variant=\"form\"` | 重复边框的 `MCard` 嵌套 |\n| 列表表格 | 直接放 `MTable` | `MCard` 再包 `MTable bordered` |\n| KPI | `MPageStat` | 每页自定义 stat CSS |\n| 图表占位 | `MPagePlaceholder` | dashed border 手写样式 |\n\n完整黄金样例用 MCP `get_golden_page`。**局部修改**时用 MCP `get_page_snippet`(如 `filters`、`toolbar`、`form-actions`)。\n\n## API\n\n### MPageContent\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `density` | `'default' \\| 'compact' \\| 'spacious'` | `'default'` | 子区块垂直间距。 |\n| `width` | `'full' \\| 'narrow'` | `'full'` | `narrow` 约 42rem,适合表单页。 |\n\n### MPageFilters\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `ariaLabel` | `string` | — | 筛选区无障碍名称。 |\n\n### MPageToolbar\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 无 `title` 时的左侧内容。 |\n| `actions` | 右侧操作区。 |\n\n### MPageHeader\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题。 |\n| `description` | `string` | — | 副标题/说明。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `actions` | 右侧操作。 |\n\n### MPageSection\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `variant` | `'default' \\| 'muted' \\| 'form' \\| 'actions'` | `'default'` | 视觉变体。 |\n| `title` | `string` | — | 可选分组标题。 |\n\n### MPageStat\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 指标名称。 |\n| `value` | `string \\| number` | — | 主数值。 |\n| `trend` | `string` | — | 变化量或说明。 |\n| `trendSeverity` | `'primary' \\| 'success' \\| 'warn' \\| 'danger' \\| 'secondary'` | `'primary'` | 趋势色。 |\n| `icon` | `string` | — | 右侧图标名。 |\n\n### MPagePlaceholder\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `description` | `string` | — | 占位说明。 |\n| `ariaLabel` | `string` | `'Placeholder'` | 无障碍标签。 |\n| `minHeight` | `number \\| string` | `'12rem'` | 最小高度。 |\n"
15536
+ "markdown": "---\ntitle: Page\ncategory: 06 / LAYOUT\ndescription: 业务页面组合区块,封装间距、边框与标题层级,少写或不写页面 CSS。\n---\n\n# Page\n\n业务页面组合组件。与 `MLayout` 搭配使用,把列表页筛选区、工具栏、表单分组、KPI 卡片等常见区块的间距和边框内聚到组件内,**优先用 Page 组件拼装页面,而不是每页手写 scoped CSS**。\n\n## 引入\n\n```ts\nimport {\n MPageContent,\n MPageFilterChips,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```\n\n## 列表页组合\n\n`MPageContent` 负责内容区 **padding**(默认 `--m-space-6`)与子区块 **gap**(默认 `--m-space-4`),文档预览中外框仅模拟 `MLayoutContent` 边界。\n\n`MPageFilters` 默认是 **无框的控件行**(`variant=\"plain\"`);需要一条可辨识的工具带时再用 `variant=\"filled\"`(与 Table header 相同的 `--m-color-fill-light`,无圆角)。`MPageHeader` 是页面身份(约 `--m-font-size-xl`);`MPageToolbar` 是列表操作条(`--m-font-size-md`),不要当成第二页头。\n\n```vue preview src=\"./demos/ListPageStack.zh.vue\"\n```\n\n字段较多时:`MPageFilters collapsible` + `#advanced` 折叠高级项;已选条件用 `MPageFilterChips` 包一层 `MTag closable`(不要用自定义 dashed 壳)。\n\n```vue preview src=\"./demos/ListFiltersAdvanced.zh.vue\"\n```\n\n**面包屑**:路由级 trail 放在 `MLayoutHeader` 的 `MBreadcrumb`;若页内还需要上下文,用 `MPageHeader` 的 `#breadcrumb` 插槽——**不要**在 Layout 与 Page 各写一遍相同标题链。\n\n## 表单页组合\n\n`MPageContent width=\"narrow\"` 限制表单宽度;`MPageSection variant=\"form\"` 提供表单表面;`variant=\"actions\"` 用于底栏操作。\n\n```vue preview src=\"./demos/Demo2.vue\"\n```\n\n## 仪表盘 KPI\n\n默认 `MPageStat` 为 Card 表面;密集条带可用 `layout=\"plain\"` + `orientation=\"inline\"` + `density=\"compact\"`。\n\n```vue preview src=\"./demos/Kpi.vue\"\n```\n\n```vue preview src=\"./demos/StatVariants.zh.vue\"\n```\n\n## 组合规则\n\n| 场景 | 推荐组件 | 避免 |\n| --- | --- | --- |\n| 内容区垂直堆叠 | `MPageContent` | 手写 `gap` / `padding` |\n| 筛选区 | `MPageFilters` + `MSpace` / `MFlex` | 额外包一层 `MCard` |\n| 页面身份 + 页级操作 | `MPageHeader` | 无层级的裸 `h1` |\n| 列表操作条 | `MPageToolbar` | 把 Toolbar 当成第二页头 |\n| 表单主体 | `MPageSection variant=\"form\"`(内部即 `MCard` 表面) | 再包一层 `MCard` |\n| 列表表格 | 直接放 `MTable` | `MCard` 再包 `MTable bordered` |\n| KPI | `MPageStat` | 每页自定义 stat CSS |\n| 图表占位 | `MPagePlaceholder` 或 `MCard` + `MEmpty` | 虚线框 / 光晕手写样式 |\n\n完整黄金样例用 MCP `get_golden_page`。**局部修改**时用 MCP `get_page_snippet`(如 `filters`、`toolbar`、`form-actions`)。\n\n## API\n\n### MPageContent\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `density` | `'default' \\| 'compact' \\| 'spacious'` | `'default'` | 子区块垂直间距。 |\n| `width` | `'full' \\| 'narrow'` | `'full'` | `narrow` 约 42rem,适合表单页。 |\n| `bands` | `'auto' \\| 'uniform'` | `'auto'` | `auto` 收紧 Header/筛选/Toolbar 与表格之间的 band;`uniform` 仅用 `gap`。 |\n\n`bands=\"auto\"` 时可通过 CSS 变量微调:`--m-page-content-body-lead`、`--m-page-content-tools-pull`(见 `styles.css`)。\n\n### MPageFilters\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `ariaLabel` | `string` | — | 筛选区无障碍名称。 |\n| `variant` | `'plain' \\| 'filled'` | `'plain'` | 表面处理;`filled` 与 Table header 同色浅底,无圆角。 |\n| `collapsible` | `boolean` | `false` | 为 true 且提供 `#advanced` 时显示展开/收起。 |\n| `expanded` | `boolean` | `false` | 高级区展开状态(`v-model:expanded`)。 |\n| `expandLabel` / `collapseLabel` | `string` | — | 覆盖默认展开/收起文案。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 常用筛选控件行。 |\n| `advanced` | 折叠区(需 `collapsible`)。 |\n| `active` | 可选;已选摘要(更常见是下方 `MPageFilterChips`)。 |\n\n### MPageFilterChips\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 弱前缀,如「已选」。 |\n| `ariaLabel` | `string` | — | 已选条件列表的无障碍名称。 |\n\n默认插槽放 `MTag closable` 或同类可移除标记。\n\n### MPageToolbar\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 操作条组名(`--m-font-size-md`),不是页面标题。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 无 `title` 时的左侧内容。 |\n| `actions` | 右侧操作区。 |\n\n### MPageHeader\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `title` | `string` | — | 页面标题(`--m-font-size-xl`)。 |\n| `description` | `string` | — | 副标题/说明。 |\n| `headingLevel` | `1–6` | `1` | 标题层级。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `breadcrumb` | 标题上方的面包屑(放 `MBreadcrumb`)。 |\n| `tags` | 标题右侧的状态/分类标记(放 `MTag` / `MStatus`)。 |\n| `actions` | 右侧操作。 |\n\n### MPageSection\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `variant` | `'default' \\| 'muted' \\| 'form' \\| 'actions'` | `'default'` | 视觉变体;`muted` 与 Table header 同色浅底;`form` 渲染为 `MCard` 表面。 |\n| `title` | `string` | — | 可选分组标题。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `actions` | 标题行右侧操作区。 |\n\n### MPageStat\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `label` | `string` | — | 指标名称。 |\n| `value` | `string \\| number` | — | 主数值(等宽数字)。 |\n| `trend` | `string` | — | 变化量,渲染为与 `MStatus` 同色的文本。 |\n| `trendSeverity` | `'primary' \\| 'success' \\| 'warn' \\| 'danger' \\| 'secondary'` | `'primary'` | 趋势色。 |\n| `trendDirection` | `'up' \\| 'down'` | — | 在趋势旁显示升/降箭头。 |\n| `trendLabel` | `string` | — | 趋势后的弱说明,如「较上月」。 |\n| `icon` | `string` | — | 右侧弱化图标名。 |\n| `loading` | `boolean` | `false` | 用骨架屏代替数值与趋势。 |\n| `shadow` | `'never' \\| 'hover' \\| 'always'` | `'always'` | 透传 `MCard.shadow`(`layout=\"plain\"` 时无效)。 |\n| `layout` | `'card' \\| 'plain'` | `'card'` | `plain` 无 Card 壳,适合横排 KPI 条。 |\n| `density` | `'default' \\| 'compact'` | `'default'` | `compact` 缩小主数值字号。 |\n| `orientation` | `'stacked' \\| 'inline'` | `'stacked'` | `inline` 标签与数值同一行。 |\n\n### MPagePlaceholder\n\n内部组合 `MEmpty`:默认展示空态插画与说明,可通过默认插槽自定义内容、`#icon` 自定义图标、`#extra` 放置下一步操作。\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `description` | `string` | — | 占位说明。 |\n| `ariaLabel` | `string` | `'Placeholder'` | 无障碍标签。 |\n| `minHeight` | `number \\| string` | `'12rem'` | 最小高度。 |\n\n| Slot | 说明 |\n| --- | --- |\n| `default` | 自定义说明内容。 |\n| `icon` | 自定义图标/插画。 |\n| `extra` | 下一步操作区(如按钮)。 |\n"
15376
15537
  },
15377
15538
  "en-US": {
15378
15539
  "title": "Page",
@@ -15386,12 +15547,17 @@
15386
15547
  {
15387
15548
  "id": "import",
15388
15549
  "title": "Import",
15389
- "body": "```ts\nimport {\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```"
15550
+ "body": "```ts\nimport {\n MPageContent,\n MPageFilterChips,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```"
15390
15551
  },
15391
15552
  {
15392
15553
  "id": "list-page-stack",
15393
15554
  "title": "List page stack",
15394
- "body": "`MPageContent` owns content **padding** (default `--m-space-6`) and section **gap** (default `--m-space-4`). The bordered frame in previews simulates `MLayoutContent` only.\n\n```vue preview src=\"./demos/ListPageStack.en.vue\"\n```"
15555
+ "body": "`MPageContent` owns content **padding** (default `--m-space-6`) and section **gap** (default `--m-space-4`). The bordered frame in previews simulates `MLayoutContent` only.\n\n`MPageFilters` defaults to a borderless control row (`variant=\"plain\"`); `variant=\"filled\"` uses the same `--m-color-fill-light` as the Table header, with no radius. `MPageHeader` is page identity (`--m-font-size-xl`); `MPageToolbar` is a list action row (`--m-font-size-md`), not a second page title. `MPageStat` supports `trendDirection`, `trendLabel`, `loading`, and `shadow` (defaults to `always`).\n\n```vue preview src=\"./demos/ListPageStack.en.vue\"\n```\n\nUse `MPageFilters collapsible` + `#advanced` for secondary fields; show active criteria with `MPageFilterChips` and closable `MTag`.\n\n```vue preview src=\"./demos/ListFiltersAdvanced.en.vue\"\n```\n\nPut the route trail in `MLayoutHeader` (`MBreadcrumb`) **or** in `MPageHeader` `#breadcrumb` — not both with duplicate titles."
15556
+ },
15557
+ {
15558
+ "id": "dashboard-kpi",
15559
+ "title": "Dashboard KPI",
15560
+ "body": "Default `MPageStat` uses a Card surface; dense strips can use `layout=\"plain\"`, `orientation=\"inline\"`, and `density=\"compact\"`.\n\n```vue preview src=\"./demos/StatVariants.en.vue\"\n```"
15395
15561
  },
15396
15562
  {
15397
15563
  "id": "form-page-stack",
@@ -15401,10 +15567,10 @@
15401
15567
  {
15402
15568
  "id": "composition-rules",
15403
15569
  "title": "Composition rules",
15404
- "body": "| Scenario | Use | Avoid |\n| --- | --- | --- |\n| Vertical page stack | `MPageContent` | Hand-written `gap` / `padding` |\n| Filters | `MPageFilters` | Extra bordered `MCard` wrapper |\n| Title + actions | `MPageToolbar` | Raw flex divs |\n| Form surface | `MPageSection variant=\"form\"` | Nested bordered cards |\n| Data table | `MTable` directly | `MCard` around bordered table |\n| KPI metric | `MPageStat` | Custom stat CSS per page |\n\nGolden references: MCP `get_golden_page`."
15570
+ "body": "| Scenario | Use | Avoid |\n| --- | --- | --- |\n| Vertical page stack | `MPageContent` | Hand-written `gap` / `padding` |\n| Filters | `MPageFilters` | Extra bordered `MCard` wrapper |\n| Page identity + page actions | `MPageHeader` | Raw `h1` with no hierarchy |\n| List action row | `MPageToolbar` | Using Toolbar as a second page title |\n| Form surface | `MPageSection variant=\"form\"` | Nested bordered cards |\n| Data table | `MTable` directly | `MCard` around bordered table |\n| KPI metric | `MPageStat` | Custom stat CSS per page |\n\nGolden references: MCP `get_golden_page`."
15405
15571
  }
15406
15572
  ],
15407
- "markdown": "---\ntitle: Page\ncategory: 06 / LAYOUT\ndescription: Composable page sections for spacing, borders, and headings with little or no custom CSS.\n---\n\n# Page\n\nPage composition components. Use them with `MLayout` to encode filter bars, toolbars, form surfaces, KPI cards, and other admin-page blocks **without rewriting scoped CSS on every page**.\n\n## Import\n\n```ts\nimport {\n MPageContent,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```\n\n## List page stack\n\n`MPageContent` owns content **padding** (default `--m-space-6`) and section **gap** (default `--m-space-4`). The bordered frame in previews simulates `MLayoutContent` only.\n\n```vue preview src=\"./demos/ListPageStack.en.vue\"\n```\n\n## Form page stack\n\nUse `MPageContent width=\"narrow\"`, `MPageSection variant=\"form\"`, and `variant=\"actions\"` for the footer.\n\n## Composition rules\n\n| Scenario | Use | Avoid |\n| --- | --- | --- |\n| Vertical page stack | `MPageContent` | Hand-written `gap` / `padding` |\n| Filters | `MPageFilters` | Extra bordered `MCard` wrapper |\n| Title + actions | `MPageToolbar` | Raw flex divs |\n| Form surface | `MPageSection variant=\"form\"` | Nested bordered cards |\n| Data table | `MTable` directly | `MCard` around bordered table |\n| KPI metric | `MPageStat` | Custom stat CSS per page |\n\nGolden references: MCP `get_golden_page`.\n"
15573
+ "markdown": "---\ntitle: Page\ncategory: 06 / LAYOUT\ndescription: Composable page sections for spacing, borders, and headings with little or no custom CSS.\n---\n\n# Page\n\nPage composition components. Use them with `MLayout` to encode filter bars, toolbars, form surfaces, KPI cards, and other admin-page blocks **without rewriting scoped CSS on every page**.\n\n## Import\n\n```ts\nimport {\n MPageContent,\n MPageFilterChips,\n MPageFilters,\n MPageHeader,\n MPagePlaceholder,\n MPageSection,\n MPageStat,\n MPageToolbar,\n} from 'morya-ui'\n```\n\n## List page stack\n\n`MPageContent` owns content **padding** (default `--m-space-6`) and section **gap** (default `--m-space-4`). The bordered frame in previews simulates `MLayoutContent` only.\n\n`MPageFilters` defaults to a borderless control row (`variant=\"plain\"`); `variant=\"filled\"` uses the same `--m-color-fill-light` as the Table header, with no radius. `MPageHeader` is page identity (`--m-font-size-xl`); `MPageToolbar` is a list action row (`--m-font-size-md`), not a second page title. `MPageStat` supports `trendDirection`, `trendLabel`, `loading`, and `shadow` (defaults to `always`).\n\n```vue preview src=\"./demos/ListPageStack.en.vue\"\n```\n\nUse `MPageFilters collapsible` + `#advanced` for secondary fields; show active criteria with `MPageFilterChips` and closable `MTag`.\n\n```vue preview src=\"./demos/ListFiltersAdvanced.en.vue\"\n```\n\nPut the route trail in `MLayoutHeader` (`MBreadcrumb`) **or** in `MPageHeader` `#breadcrumb` — not both with duplicate titles.\n\n## Dashboard KPI\n\nDefault `MPageStat` uses a Card surface; dense strips can use `layout=\"plain\"`, `orientation=\"inline\"`, and `density=\"compact\"`.\n\n```vue preview src=\"./demos/StatVariants.en.vue\"\n```\n\n## Form page stack\n\nUse `MPageContent width=\"narrow\"`, `MPageSection variant=\"form\"`, and `variant=\"actions\"` for the footer.\n\n## Composition rules\n\n| Scenario | Use | Avoid |\n| --- | --- | --- |\n| Vertical page stack | `MPageContent` | Hand-written `gap` / `padding` |\n| Filters | `MPageFilters` | Extra bordered `MCard` wrapper |\n| Page identity + page actions | `MPageHeader` | Raw `h1` with no hierarchy |\n| List action row | `MPageToolbar` | Using Toolbar as a second page title |\n| Form surface | `MPageSection variant=\"form\"` | Nested bordered cards |\n| Data table | `MTable` directly | `MCard` around bordered table |\n| KPI metric | `MPageStat` | Custom stat CSS per page |\n\nGolden references: MCP `get_golden_page`.\n"
15408
15574
  }
15409
15575
  }
15410
15576
  },
@@ -15463,7 +15629,7 @@
15463
15629
  "name": "showQuickJumper",
15464
15630
  "type": "boolean",
15465
15631
  "default": "false",
15466
- "description": "显示跳转到指定页。"
15632
+ "description": "显示跳转页码选择器。页数超过 10 时可在下拉中筛选。"
15467
15633
  },
15468
15634
  {
15469
15635
  "name": "simple",
@@ -15601,7 +15767,7 @@
15601
15767
  {
15602
15768
  "id": "props",
15603
15769
  "title": "Props",
15604
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | 当前页(从 1 开始)。 |\n| `totalRecords` | `number` | — | 总记录数。 |\n| `rows` | `number` | `10` | 每页条数。 |\n| `pageSize` | `number` | — | `rows` 的别名;两者同时传入时以 `pageSize` 为准。 |\n| `pageLinkSize` | `number` | `5` | 页码按钮数量。 |\n| `showSizePicker` | `boolean` | `false` | 显示每页条数选择器。 |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | `showSizePicker` 的选项。 |\n| `showQuickJumper` | `boolean` | `false` | 显示跳转到指定页。 |\n| `simple` | `boolean` | `false` | 精简为上一页 / 当前页 / 下一页。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
15770
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | 当前页(从 1 开始)。 |\n| `totalRecords` | `number` | — | 总记录数。 |\n| `rows` | `number` | `10` | 每页条数。 |\n| `pageSize` | `number` | — | `rows` 的别名;两者同时传入时以 `pageSize` 为准。 |\n| `pageLinkSize` | `number` | `5` | 页码按钮数量。 |\n| `showSizePicker` | `boolean` | `false` | 显示每页条数选择器。 |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | `showSizePicker` 的选项。 |\n| `showQuickJumper` | `boolean` | `false` | 显示跳转页码选择器。页数超过 10 时可在下拉中筛选。 |\n| `simple` | `boolean` | `false` | 精简为上一页 / 当前页 / 下一页。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
15605
15771
  },
15606
15772
  {
15607
15773
  "id": "events",
@@ -15619,7 +15785,7 @@
15619
15785
  "body": "无插槽。"
15620
15786
  }
15621
15787
  ],
15622
- "markdown": "---\ntitle: Pagination\ncategory: 03 / DATA\ndescription: 分页器,v-model 为页码;实例暴露 first(零基首条索引)。\n---\n\n# Pagination\n\n分页导航,`v-model` 使用 **1-based 页码**;实例属性 `first` 对应零基首条记录索引 `(page - 1) * rows`。\n\n`pageSize` 是 `rows` 的别名(同时传入时 `pageSize` 优先);另支持 `showSizePicker`、`showQuickJumper`、`simple`。\n\n## 引入\n\n```ts\nimport { MPagination } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Size picker / jumper / simple\n\n```vue preview src=\"./demos/SizePickerJumperSimple.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | 当前页(从 1 开始)。 |\n| `totalRecords` | `number` | — | 总记录数。 |\n| `rows` | `number` | `10` | 每页条数。 |\n| `pageSize` | `number` | — | `rows` 的别名;两者同时传入时以 `pageSize` 为准。 |\n| `pageLinkSize` | `number` | `5` | 页码按钮数量。 |\n| `showSizePicker` | `boolean` | `false` | 显示每页条数选择器。 |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | `showSizePicker` 的选项。 |\n| `showQuickJumper` | `boolean` | `false` | 显示跳转到指定页。 |\n| `simple` | `boolean` | `false` | 精简为上一页 / 当前页 / 下一页。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `number` | 页码变化。 |\n| `page` | `number` | 页码变化(同值)。 |\n| `update:rows` / `update:pageSize` | `number` | 每页条数变化(同值)。 |\n\n## Instance\n\n| 方法 / 属性 | 说明 |\n| --- | --- |\n| `first` | 当前页首条记录的零基索引:`(page - 1) * rows`。 |\n| `pageCount` | 总页数。 |\n\n## Slots\n\n无插槽。\n"
15788
+ "markdown": "---\ntitle: Pagination\ncategory: 03 / DATA\ndescription: 分页器,v-model 为页码;实例暴露 first(零基首条索引)。\n---\n\n# Pagination\n\n分页导航,`v-model` 使用 **1-based 页码**;实例属性 `first` 对应零基首条记录索引 `(page - 1) * rows`。\n\n`pageSize` 是 `rows` 的别名(同时传入时 `pageSize` 优先);另支持 `showSizePicker`、`showQuickJumper`、`simple`。\n\n## 引入\n\n```ts\nimport { MPagination } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Size picker / jumper / simple\n\n```vue preview src=\"./demos/SizePickerJumperSimple.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | 当前页(从 1 开始)。 |\n| `totalRecords` | `number` | — | 总记录数。 |\n| `rows` | `number` | `10` | 每页条数。 |\n| `pageSize` | `number` | — | `rows` 的别名;两者同时传入时以 `pageSize` 为准。 |\n| `pageLinkSize` | `number` | `5` | 页码按钮数量。 |\n| `showSizePicker` | `boolean` | `false` | 显示每页条数选择器。 |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | `showSizePicker` 的选项。 |\n| `showQuickJumper` | `boolean` | `false` | 显示跳转页码选择器。页数超过 10 时可在下拉中筛选。 |\n| `simple` | `boolean` | `false` | 精简为上一页 / 当前页 / 下一页。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `number` | 页码变化。 |\n| `page` | `number` | 页码变化(同值)。 |\n| `update:rows` / `update:pageSize` | `number` | 每页条数变化(同值)。 |\n\n## Instance\n\n| 方法 / 属性 | 说明 |\n| --- | --- |\n| `first` | 当前页首条记录的零基索引:`(page - 1) * rows`。 |\n| `pageCount` | 总页数。 |\n\n## Slots\n\n无插槽。\n"
15623
15789
  },
15624
15790
  "en-US": {
15625
15791
  "title": "Pagination",
@@ -15648,7 +15814,7 @@
15648
15814
  {
15649
15815
  "id": "props",
15650
15816
  "title": "Props",
15651
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | Current page (1-based). |\n| `totalRecords` | `number` | — | Total number of records. |\n| `rows` | `number` | `10` | Rows per page. |\n| `pageSize` | `number` | — | Alias of `rows`; `pageSize` wins when both are set. |\n| `pageLinkSize` | `number` | `5` | Number of page link buttons. |\n| `showSizePicker` | `boolean` | `false` | Show the page-size select. |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | Options for `showSizePicker`. |\n| `showQuickJumper` | `boolean` | `false` | Jump-to-page input. |\n| `simple` | `boolean` | `false` | Compact prev / current / next. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
15817
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | Current page (1-based). |\n| `totalRecords` | `number` | — | Total number of records. |\n| `rows` | `number` | `10` | Rows per page. |\n| `pageSize` | `number` | — | Alias of `rows`; `pageSize` wins when both are set. |\n| `pageLinkSize` | `number` | `5` | Number of page link buttons. |\n| `showSizePicker` | `boolean` | `false` | Show the page-size select. |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | Options for `showSizePicker`. |\n| `showQuickJumper` | `boolean` | `false` | Page select for jumping to a page. The menu can be filtered when there are more than 10 pages. |\n| `simple` | `boolean` | `false` | Compact prev / current / next. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
15652
15818
  },
15653
15819
  {
15654
15820
  "id": "events",
@@ -15666,7 +15832,7 @@
15666
15832
  "body": "No slots."
15667
15833
  }
15668
15834
  ],
15669
- "markdown": "---\ntitle: Pagination\ncategory: 03 / DATA\ndescription: Pagination. v-model is the page number. The instance exposes first (zero-based index of the first record).\n---\n\n# Pagination\n\nPagination. `v-model` uses a **1-based page number**. The instance property `first` is the zero-based index of the first record on the page: `(page - 1) * rows`.\n\n`pageSize` is an alias of `rows` (`pageSize` wins when both are set). Also supports `showSizePicker`, `showQuickJumper`, and `simple`.\n\n## Import\n\n```ts\nimport { MPagination } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Size picker / jumper / simple\n\n```vue preview src=\"./demos/SizePickerJumperSimple.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | Current page (1-based). |\n| `totalRecords` | `number` | — | Total number of records. |\n| `rows` | `number` | `10` | Rows per page. |\n| `pageSize` | `number` | — | Alias of `rows`; `pageSize` wins when both are set. |\n| `pageLinkSize` | `number` | `5` | Number of page link buttons. |\n| `showSizePicker` | `boolean` | `false` | Show the page-size select. |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | Options for `showSizePicker`. |\n| `showQuickJumper` | `boolean` | `false` | Jump-to-page input. |\n| `simple` | `boolean` | `false` | Compact prev / current / next. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `update:modelValue` | `number` | Emitted when the page changes. |\n| `page` | `number` | Emitted when the page changes (same value). |\n| `update:rows` / `update:pageSize` | `number` | Emitted when page size changes (same value). |\n\n## Instance\n\n| Method / Property | Description |\n| --- | --- |\n| `first` | Zero-based index of the first record on the current page: `(page - 1) * rows`. |\n| `pageCount` | Total number of pages. |\n\n## Slots\n\nNo slots.\n"
15835
+ "markdown": "---\ntitle: Pagination\ncategory: 03 / DATA\ndescription: Pagination. v-model is the page number. The instance exposes first (zero-based index of the first record).\n---\n\n# Pagination\n\nPagination. `v-model` uses a **1-based page number**. The instance property `first` is the zero-based index of the first record on the page: `(page - 1) * rows`.\n\n`pageSize` is an alias of `rows` (`pageSize` wins when both are set). Also supports `showSizePicker`, `showQuickJumper`, and `simple`.\n\n## Import\n\n```ts\nimport { MPagination } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Size picker / jumper / simple\n\n```vue preview src=\"./demos/SizePickerJumperSimple.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `number` | `1` | Current page (1-based). |\n| `totalRecords` | `number` | — | Total number of records. |\n| `rows` | `number` | `10` | Rows per page. |\n| `pageSize` | `number` | — | Alias of `rows`; `pageSize` wins when both are set. |\n| `pageLinkSize` | `number` | `5` | Number of page link buttons. |\n| `showSizePicker` | `boolean` | `false` | Show the page-size select. |\n| `pageSizes` | `number[]` | `[10, 20, 50, 100]` | Options for `showSizePicker`. |\n| `showQuickJumper` | `boolean` | `false` | Page select for jumping to a page. The menu can be filtered when there are more than 10 pages. |\n| `simple` | `boolean` | `false` | Compact prev / current / next. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Events\n\n| Event | Prop | Description |\n| --- | --- | --- |\n| `update:modelValue` | `number` | Emitted when the page changes. |\n| `page` | `number` | Emitted when the page changes (same value). |\n| `update:rows` / `update:pageSize` | `number` | Emitted when page size changes (same value). |\n\n## Instance\n\n| Method / Property | Description |\n| --- | --- |\n| `first` | Zero-based index of the first record on the current page: `(page - 1) * rows`. |\n| `pageCount` | Total number of pages. |\n\n## Slots\n\nNo slots.\n"
15670
15836
  }
15671
15837
  }
15672
15838
  },
@@ -15765,7 +15931,7 @@
15765
15931
  "sectionId": "基础用法",
15766
15932
  "lang": "vue",
15767
15933
  "preview": true,
15768
- "code": "<script setup lang=\"ts\">\nimport { MPanel } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst collapsed = ref(false)\n</script>\n\n<template>\n <MPanel v-model=\"collapsed\" header=\"Panel\" toggleable>\n <p style=\"margin:0\">\n 可折叠面板内容。\n </p>\n <template #footer>\n 操作区\n </template>\n </MPanel>\n</template>",
15934
+ "code": "<script setup lang=\"ts\">\nimport { MPanel } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst collapsed = ref(false)\n</script>\n\n<template>\n <MPanel v-model=\"collapsed\" header=\"Panel\" toggleable class=\"w-[300px]\">\n <p style=\"margin:0\">\n 可折叠面板内容。\n </p>\n <template #footer>\n 操作区\n </template>\n </MPanel>\n</template>",
15769
15935
  "locale": "zh-CN"
15770
15936
  },
15771
15937
  {
@@ -15792,7 +15958,7 @@
15792
15958
  "sectionId": "basic",
15793
15959
  "lang": "vue",
15794
15960
  "preview": true,
15795
- "code": "<script setup lang=\"ts\">\nimport { MPanel } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst collapsed = ref(false)\n</script>\n\n<template>\n <MPanel v-model=\"collapsed\" header=\"Panel\" toggleable>\n <p style=\"margin:0\">\n Collapsible panel content.\n </p>\n <template #footer>\n Actions\n </template>\n </MPanel>\n</template>",
15961
+ "code": "<script setup lang=\"ts\">\nimport { MPanel } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst collapsed = ref(false)\n</script>\n\n<template>\n <MPanel v-model=\"collapsed\" header=\"Panel\" toggleable class=\"w-[300px]\">\n <p style=\"margin:0\">\n Collapsible panel content.\n </p>\n <template #footer>\n Actions\n </template>\n </MPanel>\n</template>",
15796
15962
  "locale": "en-US"
15797
15963
  },
15798
15964
  {
@@ -16164,7 +16330,7 @@
16164
16330
  {
16165
16331
  "name": "transition",
16166
16332
  "type": "string | false",
16167
- "default": "'popover'",
16333
+ "default": "'scale-fade'",
16168
16334
  "description": "进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。"
16169
16335
  },
16170
16336
  {
@@ -16328,7 +16494,7 @@
16328
16494
  {
16329
16495
  "id": "props",
16330
16496
  "title": "Props",
16331
- "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 可见性。配合 `v-model` 使用。 |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'bottom-start' \\| 'bottom-end'` | `'bottom'` | 相对触发元素的位置。 |\n| `trigger` | `'manual' \\| 'click' \\| 'hover' \\| 'focus'` | `'manual'` | 打开方式。 |\n| `showDelay` / `hideDelay` | `number` | `0` / `200` | hover/focus 延迟(ms)。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `transition` | `string \\| false` | `'popover'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `disabled` | `boolean` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
16497
+ "body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 可见性。配合 `v-model` 使用。 |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'bottom-start' \\| 'bottom-end'` | `'bottom'` | 相对触发元素的位置。 |\n| `trigger` | `'manual' \\| 'click' \\| 'hover' \\| 'focus'` | `'manual'` | 打开方式。 |\n| `showDelay` / `hideDelay` | `number` | `0` / `200` | hover/focus 延迟(ms)。 |\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| `disabled` | `boolean` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
16332
16498
  },
16333
16499
  {
16334
16500
  "id": "events",
@@ -16346,7 +16512,7 @@
16346
16512
  "body": "| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 触发元素。 |\n| `content` | 浮层内容。 |"
16347
16513
  }
16348
16514
  ],
16349
- "markdown": "---\ntitle: Popover\ncategory: 05 / FEEDBACK\ndescription: 相对触发元素定位的浮层面板。支持 placement、Teleport;点击外部或 Esc 关闭。\n---\n\n# Popover\n\n相对触发元素显示的浮层,适合筛选、快捷操作或轻量表单。\n\n## 引入\n\n```ts\nimport { MButton, MPopover } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Placement\n\n```vue preview src=\"./demos/Placement.vue\"\n```\n\n## Hover\n\n`trigger` 默认 `manual`(仅 `v-model`)。设为 `hover` / `click` / `focus` 由组件自行开关。\n\n```vue preview src=\"./demos/Hover.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 可见性。配合 `v-model` 使用。 |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'bottom-start' \\| 'bottom-end'` | `'bottom'` | 相对触发元素的位置。 |\n| `trigger` | `'manual' \\| 'click' \\| 'hover' \\| 'focus'` | `'manual'` | 打开方式。 |\n| `showDelay` / `hideDelay` | `number` | `0` / `200` | hover/focus 延迟(ms)。 |\n| `teleport` | `boolean` | `true` | 浮层 Teleport;默认挂到 `body`。 |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | 挂载目标;`'self'` / `false` 就地渲染。 |\n| `transition` | `string \\| false` | `'popover'` | 进出场动效预设;`false` / `'none'` 关闭。见[动效](/docs/motion)。 |\n| `disabled` | `boolean` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `boolean` | 可见性变化。 |\n| `show` | — | 打开时触发。 |\n| `hide` | — | 关闭后触发。 |\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `show()` | 显示浮层。 |\n| `hide()` | 隐藏浮层。 |\n| `toggle()` | 切换显示状态。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 触发元素。 |\n| `content` | 浮层内容。 |\n"
16515
+ "markdown": "---\ntitle: Popover\ncategory: 05 / FEEDBACK\ndescription: 相对触发元素定位的浮层面板。支持 placement、Teleport;点击外部或 Esc 关闭。\n---\n\n# Popover\n\n相对触发元素显示的浮层,适合筛选、快捷操作或轻量表单。\n\n## 引入\n\n```ts\nimport { MButton, MPopover } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Placement\n\n```vue preview src=\"./demos/Placement.vue\"\n```\n\n## Hover\n\n`trigger` 默认 `manual`(仅 `v-model`)。设为 `hover` / `click` / `focus` 由组件自行开关。\n\n```vue preview src=\"./demos/Hover.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | 可见性。配合 `v-model` 使用。 |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'bottom-start' \\| 'bottom-end'` | `'bottom'` | 相对触发元素的位置。 |\n| `trigger` | `'manual' \\| 'click' \\| 'hover' \\| 'focus'` | `'manual'` | 打开方式。 |\n| `showDelay` / `hideDelay` | `number` | `0` / `200` | hover/focus 延迟(ms)。 |\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| `disabled` | `boolean` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `boolean` | 可见性变化。 |\n| `show` | — | 打开时触发。 |\n| `hide` | — | 关闭后触发。 |\n\n## Methods\n\n| 方法 | 说明 |\n| --- | --- |\n| `show()` | 显示浮层。 |\n| `hide()` | 隐藏浮层。 |\n| `toggle()` | 切换显示状态。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| `default` | 触发元素。 |\n| `content` | 浮层内容。 |\n"
16350
16516
  },
16351
16517
  "en-US": {
16352
16518
  "title": "Popover",
@@ -16380,7 +16546,7 @@
16380
16546
  {
16381
16547
  "id": "props",
16382
16548
  "title": "Props",
16383
- "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. Use with `v-model`. |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'bottom-start' \\| 'bottom-end'` | `'bottom'` | Position relative to the trigger. |\n| `trigger` | `'manual' \\| 'click' \\| 'hover' \\| 'focus'` | `'manual'` | How it opens. |\n| `showDelay` / `hideDelay` | `number` | `0` / `200` | Hover/focus delay in ms. |\n| `teleport` | `boolean` | `true` | Overlay Teleport. Mounts to `body` by default. |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target. `'self'` / `false` renders in place. |\n| `transition` | `string \\| false` | `'popover'` | 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). |"
16549
+ "body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. Use with `v-model`. |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'bottom-start' \\| 'bottom-end'` | `'bottom'` | Position relative to the trigger. |\n| `trigger` | `'manual' \\| 'click' \\| 'hover' \\| 'focus'` | `'manual'` | How it opens. |\n| `showDelay` / `hideDelay` | `number` | `0` / `200` | Hover/focus delay in ms. |\n| `teleport` | `boolean` | `true` | Overlay Teleport. Mounts to `body` by default. |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target. `'self'` / `false` renders 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). |"
16384
16550
  },
16385
16551
  {
16386
16552
  "id": "events",
@@ -16398,7 +16564,7 @@
16398
16564
  "body": "| Slot | Description |\n| --- | --- |\n| `default` | Trigger element. |\n| `content` | Overlay content. |"
16399
16565
  }
16400
16566
  ],
16401
- "markdown": "---\ntitle: Popover\ncategory: 05 / FEEDBACK\ndescription: Floating panel positioned relative to a trigger. Supports placement and Teleport. Closes on outside click or Esc.\n---\n\n# Popover\n\nOverlay positioned relative to a trigger. Use it for filters, quick actions, or lightweight forms.\n\n## Import\n\n```ts\nimport { MButton, MPopover } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Placement\n\n```vue preview src=\"./demos/Placement.vue\"\n```\n\n## Hover\n\n`trigger` defaults to `manual` (`v-model` only). Use `hover` / `click` / `focus` to let the component open itself.\n\n```vue preview src=\"./demos/Hover.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. Use with `v-model`. |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'bottom-start' \\| 'bottom-end'` | `'bottom'` | Position relative to the trigger. |\n| `trigger` | `'manual' \\| 'click' \\| 'hover' \\| 'focus'` | `'manual'` | How it opens. |\n| `showDelay` / `hideDelay` | `number` | `0` / `200` | Hover/focus delay in ms. |\n| `teleport` | `boolean` | `true` | Overlay Teleport. Mounts to `body` by default. |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target. `'self'` / `false` renders in place. |\n| `transition` | `string \\| false` | `'popover'` | 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` | Emitted when visibility changes. |\n| `show` | — | Emitted when opened. |\n| `hide` | — | Emitted after close. |\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `show()` | Show the popover. |\n| `hide()` | Hide the popover. |\n| `toggle()` | Toggle visibility. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Trigger element. |\n| `content` | Overlay content. |\n"
16567
+ "markdown": "---\ntitle: Popover\ncategory: 05 / FEEDBACK\ndescription: Floating panel positioned relative to a trigger. Supports placement and Teleport. Closes on outside click or Esc.\n---\n\n# Popover\n\nOverlay positioned relative to a trigger. Use it for filters, quick actions, or lightweight forms.\n\n## Import\n\n```ts\nimport { MButton, MPopover } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Placement\n\n```vue preview src=\"./demos/Placement.vue\"\n```\n\n## Hover\n\n`trigger` defaults to `manual` (`v-model` only). Use `hover` / `click` / `focus` to let the component open itself.\n\n```vue preview src=\"./demos/Hover.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `boolean` | `false` | Visibility. Use with `v-model`. |\n| `placement` | `'top' \\| 'bottom' \\| 'left' \\| 'right' \\| 'bottom-start' \\| 'bottom-end'` | `'bottom'` | Position relative to the trigger. |\n| `trigger` | `'manual' \\| 'click' \\| 'hover' \\| 'focus'` | `'manual'` | How it opens. |\n| `showDelay` / `hideDelay` | `number` | `0` / `200` | Hover/focus delay in ms. |\n| `teleport` | `boolean` | `true` | Overlay Teleport. Mounts to `body` by default. |\n| `appendTo` | `string \\| HTMLElement \\| 'self' \\| false` | `'body'` | Mount target. `'self'` / `false` renders 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| `update:modelValue` | `boolean` | Emitted when visibility changes. |\n| `show` | — | Emitted when opened. |\n| `hide` | — | Emitted after close. |\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `show()` | Show the popover. |\n| `hide()` | Hide the popover. |\n| `toggle()` | Toggle visibility. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `default` | Trigger element. |\n| `content` | Overlay content. |\n"
16402
16568
  }
16403
16569
  }
16404
16570
  },
@@ -26839,7 +27005,7 @@
26839
27005
  "zh-CN": {
26840
27006
  "title": "一键接入",
26841
27007
  "description": "用 @morya-ui/setup 安装组件库,并按需写入样式、Agent 配置与 MCP。",
26842
- "markdown": "---\ntitle: 一键接入\norder: 3\ndescription: 用 @morya-ui/setup 安装组件库,并按需写入样式、Agent 配置与 MCP。\n---\n\n# 一键接入\n\n[`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) 用于在业务 Vue 项目中接入 `morya-ui`:安装依赖、注入样式,并可一并写入 Agent Skill、Cursor 规则与 MCP。手写安装见 [快速上手](/docs/quick-start);AI 生成页面的约定见 [AI 接入](/docs/ai-setup)。\n\n## 命令\n\n在业务项目根目录执行:\n\n```bash\nnpx @morya-ui/setup\n```\n\n默认会:\n\n1. 安装 `morya-ui`(按锁文件选用 pnpm / yarn / npm)\n2. 复制 `DESIGN.md`、Agent Skill、Cursor rules 与检查脚本\n3. 合并 `.cursor/mcp.json`,接入 [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. 尝试在入口注入 `import 'morya-ui/styles.css'`\n5. 若缺失则追加 `check:colors` 脚本\n\n也可以按场景选用:\n\n```bash\n# 只安装组件库并注入样式\nnpx @morya-ui/setup app\n\n# 已装库时,只写入 AI 配置与 MCP\nnpx @morya-ui/setup ai\n\n# 非交互:默认 skill / 指定 / 全部\nnpx @morya-ui/setup ai --yes\nnpx @morya-ui/setup ai --skills=morya-ui-pages,frontend-design\nnpx @morya-ui/setup ai --skills=all\n```\n\n在 TTY 下,`full` / `ai` 会提示勾选可选 Agent Skill(必选 `morya-ui-pages` 始终写入)。完成后若写入了 MCP,请 **重启 Cursor**(或重载 MCP)。生成页面前让 Agent 先读 `DESIGN.md`。\n\n## 选项\n\n| Flag | 说明 |\n| --- | --- |\n| `--cwd <dir>` | 目标项目根(默认当前目录) |\n| `--pm pnpm\\|yarn\\|npm` | 指定包管理器 |\n| `--skills <list>` | 逗号分隔的 skill id,或 `all`(跳过交互提示) |\n| `--yes` / `-y` | 使用默认 skill,不提示 |\n| `--force` | 覆盖已有模板文件与 `morya-ui` MCP 条目 |\n| `--dry-run` | 只打印将要执行的操作 |\n| `--skip-install` | 不安装依赖 |\n| `--skip-template` | 不复制 skill / rules / docs |\n| `--skip-mcp` | 不写 MCP 配置 |\n| `--skip-styles` | 不注入样式 import |\n| `--skip-scripts` | 不改 `package.json` scripts |\n\n默认 **不覆盖** 已有文件;只有 `--force` 才会覆盖模板与 MCP 条目。\n\n### Skills\n\n| Id | 默认 | 作用 |\n| --- | --- | --- |\n| `morya-ui-pages` | 必选 | 用 `M*` + 黄金布局生成页面 |\n| `frontend-design` | 可选 | Express / 品牌向视觉味觉 |\n| `fixing-accessibility` | 可选 | 无障碍审计与定向修复 |\n\n目录:[`packages/setup/catalog/skills.json`](https://github.com/morya-space/morya-ui/blob/main/packages/setup/catalog/skills.json)。\n\n示例:只补 MCP:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```\n\n## 会落到项目里的内容\n\n| 路径 | 作用 |\n| --- | --- |\n| `DESIGN.md` | AI 设计第一信源(原则、应用根、令牌摘要、禁止项) |\n| `.agents/skills/morya-ui-pages/` | 页面生成 Agent Skill(见 [Agent Skill](/docs/agent-skill)) |\n| `.agents/skills/<optional>/` | 勾选时写入的 companion skill |\n| `.cursor/rules/` | Cursor 常驻规则 |\n| `scripts/check-raw-colors.mjs` | 裸色值扫描 |\n| `.cursor/mcp.json` | Cursor MCP(`npx -y @morya-ui/mcp`) |\n\n模板源在仓库 [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit)。CLI 不调用 `app.use(MoryaUI)`,也不改 `App.vue`。\n\n## 冲突策略\n\n- 模板文件与 `.cursor/rules/*`:目标已存在则跳过(除非 `--force`)\n- `.cursor/mcp.json`:合并其它 server;已有 `morya-ui` 条目则跳过(除非 `--force`)\n- `check:colors`:仅在缺失时追加(除非 `--force`)\n- 样式:找到入口且尚未引入时才注入\n\n## 下一步\n\n- [快速上手](/docs/quick-start):组件用法与最小示例 \n- [AI 接入](/docs/ai-setup):用 AI 生成业务页面时如何配合 Skill / MCP \n- [Agent Skill](/docs/agent-skill) · [Agent MCP](/docs/mcp) \n- [组件](/components):浏览 API 与预览\n",
27008
+ "markdown": "---\ntitle: 一键接入\norder: 3\ndescription: 用 @morya-ui/setup 安装组件库,并按需写入样式、Agent 配置与 MCP。\n---\n\n# 一键接入\n\n[`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) 用于在业务 Vue 项目中接入 `morya-ui`:安装依赖、注入样式,并可一并写入 Agent Skill、Cursor 规则与 MCP。手写安装见 [快速上手](/docs/quick-start);AI 生成页面的约定见 [AI 接入](/docs/ai-setup)。\n\n## 命令\n\n在业务项目根目录执行:\n\n```bash\nnpx @morya-ui/setup\n```\n\n默认会:\n\n1. 安装 `morya-ui`(按锁文件选用 pnpm / yarn / npm)\n2. 复制 `DESIGN.md`、Agent Skill、Cursor rules 与检查脚本\n3. 合并 `.cursor/mcp.json`,接入 [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. 尝试在入口注入 `import 'morya-ui/styles.css'`\n5. 若缺失则追加 `check:colors` 脚本\n\n也可以按场景选用:\n\n```bash\n# 只安装组件库并注入样式\nnpx @morya-ui/setup app\n\n# 已装库时,只写入 AI 配置与 MCP\nnpx @morya-ui/setup ai\n\n# 非交互:默认 skill / 指定 / 全部\nnpx @morya-ui/setup ai --yes\nnpx @morya-ui/setup ai --skills=morya-ui-pages,frontend-design,impeccable\nnpx @morya-ui/setup ai --skills=all\n```\n\n在 TTY 下,`full` / `ai` 会提示勾选可选 Agent Skill(必选 `morya-ui-pages` 始终写入)。可选 companion 通过 [skills CLI](https://skills.sh/) 安装**最新版**。完成后若写入了 MCP,请 **重启 Cursor**(或重载 MCP)。生成页面前让 Agent 先读 `DESIGN.md`。\n\n## 选项\n\n| Flag | 说明 |\n| --- | --- |\n| `--cwd <dir>` | 目标项目根(默认当前目录) |\n| `--pm pnpm\\|yarn\\|npm` | 指定包管理器 |\n| `--skills <list>` | 逗号分隔的 skill id,或 `all`(跳过交互提示) |\n| `--yes` / `-y` | 使用默认 skill,不提示 |\n| `--force` | 覆盖已有模板文件与 `morya-ui` MCP 条目 |\n| `--dry-run` | 只打印将要执行的操作 |\n| `--skip-install` | 不安装依赖 |\n| `--skip-template` | 不复制 skill / rules / docs(也不装 companion) |\n| `--skip-mcp` | 不写 MCP 配置 |\n| `--skip-styles` | 不注入样式 import |\n| `--skip-scripts` | 不改 `package.json` scripts |\n\n模板文件默认 **不覆盖**;只有 `--force` 才会覆盖模板与 MCP 条目。勾选的 companion skill 会始终拉取最新版。\n\n### Skills\n\n| Id | 默认 | 安装方式 | 作用 |\n| --- | --- | --- | --- |\n| `morya-ui-pages` | 必选 | 包内 template | 用 `M*` + 黄金布局生成页面 |\n| `frontend-design` | 可选 | skills CLI(`anthropics/skills` 最新) | Express / 品牌向视觉味觉 |\n| `fixing-accessibility` | 可选 | skills CLI(`ibelick/ui-skills` 最新) | 无障碍审计与定向修复 |\n| `impeccable` | 可选 | skills CLI(`pbakaus/impeccable` 最新) | 命名化 polish / 审计 / 改版 |\n\n目录:[`packages/setup/catalog/skills.json`](https://github.com/morya-space/morya-ui/blob/main/packages/setup/catalog/skills.json)。\n\n示例:只补 MCP:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```\n\n## 会落到项目里的内容\n\n| 路径 | 作用 |\n| --- | --- |\n| `DESIGN.md` | AI 设计第一信源(原则、应用根、令牌摘要、禁止项) |\n| `.agents/skills/morya-ui-pages/` | 页面生成 Agent Skill(见 [Agent Skill](/docs/agent-skill)) |\n| `.agents/skills/<optional>/` | 勾选时由 skills CLI 写入的最新 companion |\n| `.cursor/rules/` | Cursor 常驻规则 |\n| `scripts/check-raw-colors.mjs` | 裸色值扫描 |\n| `.cursor/mcp.json` | Cursor MCP(`npx -y @morya-ui/mcp`) |\n\n模板源在仓库 [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit)。CLI 不调用 `app.use(MoryaUI)`,也不改 `App.vue`。\n\n## 冲突策略\n\n- 模板文件与 `.cursor/rules/*`:目标已存在则跳过(除非 `--force`)\n- Companion skills(skills CLI):勾选时始终安装/更新为最新版\n- `.cursor/mcp.json`:合并其它 server;已有 `morya-ui` 条目则跳过(除非 `--force`)\n- `check:colors`:仅在缺失时追加(除非 `--force`)\n- 样式:找到入口且尚未引入时才注入\n\n## 下一步\n\n- [快速上手](/docs/quick-start):组件用法与最小示例 \n- [AI 接入](/docs/ai-setup):用 AI 生成业务页面时如何配合 Skill / MCP \n- [Agent Skill](/docs/agent-skill) · [Agent MCP](/docs/mcp) \n- [组件](/components):浏览 API 与预览\n",
26843
27009
  "sections": [
26844
27010
  {
26845
27011
  "title": "",
@@ -26849,22 +27015,22 @@
26849
27015
  {
26850
27016
  "title": "命令",
26851
27017
  "id": "命令",
26852
- "body": "在业务项目根目录执行:\n\n```bash\nnpx @morya-ui/setup\n```\n\n默认会:\n\n1. 安装 `morya-ui`(按锁文件选用 pnpm / yarn / npm)\n2. 复制 `DESIGN.md`、Agent Skill、Cursor rules 与检查脚本\n3. 合并 `.cursor/mcp.json`,接入 [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. 尝试在入口注入 `import 'morya-ui/styles.css'`\n5. 若缺失则追加 `check:colors` 脚本\n\n也可以按场景选用:\n\n```bash\n# 只安装组件库并注入样式\nnpx @morya-ui/setup app\n\n# 已装库时,只写入 AI 配置与 MCP\nnpx @morya-ui/setup ai\n\n# 非交互:默认 skill / 指定 / 全部\nnpx @morya-ui/setup ai --yes\nnpx @morya-ui/setup ai --skills=morya-ui-pages,frontend-design\nnpx @morya-ui/setup ai --skills=all\n```\n\n在 TTY 下,`full` / `ai` 会提示勾选可选 Agent Skill(必选 `morya-ui-pages` 始终写入)。完成后若写入了 MCP,请 **重启 Cursor**(或重载 MCP)。生成页面前让 Agent 先读 `DESIGN.md`。"
27018
+ "body": "在业务项目根目录执行:\n\n```bash\nnpx @morya-ui/setup\n```\n\n默认会:\n\n1. 安装 `morya-ui`(按锁文件选用 pnpm / yarn / npm)\n2. 复制 `DESIGN.md`、Agent Skill、Cursor rules 与检查脚本\n3. 合并 `.cursor/mcp.json`,接入 [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. 尝试在入口注入 `import 'morya-ui/styles.css'`\n5. 若缺失则追加 `check:colors` 脚本\n\n也可以按场景选用:\n\n```bash\n# 只安装组件库并注入样式\nnpx @morya-ui/setup app\n\n# 已装库时,只写入 AI 配置与 MCP\nnpx @morya-ui/setup ai\n\n# 非交互:默认 skill / 指定 / 全部\nnpx @morya-ui/setup ai --yes\nnpx @morya-ui/setup ai --skills=morya-ui-pages,frontend-design,impeccable\nnpx @morya-ui/setup ai --skills=all\n```\n\n在 TTY 下,`full` / `ai` 会提示勾选可选 Agent Skill(必选 `morya-ui-pages` 始终写入)。可选 companion 通过 [skills CLI](https://skills.sh/) 安装**最新版**。完成后若写入了 MCP,请 **重启 Cursor**(或重载 MCP)。生成页面前让 Agent 先读 `DESIGN.md`。"
26853
27019
  },
26854
27020
  {
26855
27021
  "title": "选项",
26856
27022
  "id": "选项",
26857
- "body": "| Flag | 说明 |\n| --- | --- |\n| `--cwd <dir>` | 目标项目根(默认当前目录) |\n| `--pm pnpm\\|yarn\\|npm` | 指定包管理器 |\n| `--skills <list>` | 逗号分隔的 skill id,或 `all`(跳过交互提示) |\n| `--yes` / `-y` | 使用默认 skill,不提示 |\n| `--force` | 覆盖已有模板文件与 `morya-ui` MCP 条目 |\n| `--dry-run` | 只打印将要执行的操作 |\n| `--skip-install` | 不安装依赖 |\n| `--skip-template` | 不复制 skill / rules / docs |\n| `--skip-mcp` | 不写 MCP 配置 |\n| `--skip-styles` | 不注入样式 import |\n| `--skip-scripts` | 不改 `package.json` scripts |\n\n默认 **不覆盖** 已有文件;只有 `--force` 才会覆盖模板与 MCP 条目。\n\n### Skills\n\n| Id | 默认 | 作用 |\n| --- | --- | --- |\n| `morya-ui-pages` | 必选 | 用 `M*` + 黄金布局生成页面 |\n| `frontend-design` | 可选 | Express / 品牌向视觉味觉 |\n| `fixing-accessibility` | 可选 | 无障碍审计与定向修复 |\n\n目录:[`packages/setup/catalog/skills.json`](https://github.com/morya-space/morya-ui/blob/main/packages/setup/catalog/skills.json)。\n\n示例:只补 MCP:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```"
27023
+ "body": "| Flag | 说明 |\n| --- | --- |\n| `--cwd <dir>` | 目标项目根(默认当前目录) |\n| `--pm pnpm\\|yarn\\|npm` | 指定包管理器 |\n| `--skills <list>` | 逗号分隔的 skill id,或 `all`(跳过交互提示) |\n| `--yes` / `-y` | 使用默认 skill,不提示 |\n| `--force` | 覆盖已有模板文件与 `morya-ui` MCP 条目 |\n| `--dry-run` | 只打印将要执行的操作 |\n| `--skip-install` | 不安装依赖 |\n| `--skip-template` | 不复制 skill / rules / docs(也不装 companion) |\n| `--skip-mcp` | 不写 MCP 配置 |\n| `--skip-styles` | 不注入样式 import |\n| `--skip-scripts` | 不改 `package.json` scripts |\n\n模板文件默认 **不覆盖**;只有 `--force` 才会覆盖模板与 MCP 条目。勾选的 companion skill 会始终拉取最新版。\n\n### Skills\n\n| Id | 默认 | 安装方式 | 作用 |\n| --- | --- | --- | --- |\n| `morya-ui-pages` | 必选 | 包内 template | 用 `M*` + 黄金布局生成页面 |\n| `frontend-design` | 可选 | skills CLI(`anthropics/skills` 最新) | Express / 品牌向视觉味觉 |\n| `fixing-accessibility` | 可选 | skills CLI(`ibelick/ui-skills` 最新) | 无障碍审计与定向修复 |\n| `impeccable` | 可选 | skills CLI(`pbakaus/impeccable` 最新) | 命名化 polish / 审计 / 改版 |\n\n目录:[`packages/setup/catalog/skills.json`](https://github.com/morya-space/morya-ui/blob/main/packages/setup/catalog/skills.json)。\n\n示例:只补 MCP:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```"
26858
27024
  },
26859
27025
  {
26860
27026
  "title": "会落到项目里的内容",
26861
27027
  "id": "会落到项目里的内容",
26862
- "body": "| 路径 | 作用 |\n| --- | --- |\n| `DESIGN.md` | AI 设计第一信源(原则、应用根、令牌摘要、禁止项) |\n| `.agents/skills/morya-ui-pages/` | 页面生成 Agent Skill(见 [Agent Skill](/docs/agent-skill)) |\n| `.agents/skills/<optional>/` | 勾选时写入的 companion skill |\n| `.cursor/rules/` | Cursor 常驻规则 |\n| `scripts/check-raw-colors.mjs` | 裸色值扫描 |\n| `.cursor/mcp.json` | Cursor MCP(`npx -y @morya-ui/mcp`) |\n\n模板源在仓库 [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit)。CLI 不调用 `app.use(MoryaUI)`,也不改 `App.vue`。"
27028
+ "body": "| 路径 | 作用 |\n| --- | --- |\n| `DESIGN.md` | AI 设计第一信源(原则、应用根、令牌摘要、禁止项) |\n| `.agents/skills/morya-ui-pages/` | 页面生成 Agent Skill(见 [Agent Skill](/docs/agent-skill)) |\n| `.agents/skills/<optional>/` | 勾选时由 skills CLI 写入的最新 companion |\n| `.cursor/rules/` | Cursor 常驻规则 |\n| `scripts/check-raw-colors.mjs` | 裸色值扫描 |\n| `.cursor/mcp.json` | Cursor MCP(`npx -y @morya-ui/mcp`) |\n\n模板源在仓库 [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit)。CLI 不调用 `app.use(MoryaUI)`,也不改 `App.vue`。"
26863
27029
  },
26864
27030
  {
26865
27031
  "title": "冲突策略",
26866
27032
  "id": "冲突策略",
26867
- "body": "- 模板文件与 `.cursor/rules/*`:目标已存在则跳过(除非 `--force`)\n- `.cursor/mcp.json`:合并其它 server;已有 `morya-ui` 条目则跳过(除非 `--force`)\n- `check:colors`:仅在缺失时追加(除非 `--force`)\n- 样式:找到入口且尚未引入时才注入"
27033
+ "body": "- 模板文件与 `.cursor/rules/*`:目标已存在则跳过(除非 `--force`)\n- Companion skills(skills CLI):勾选时始终安装/更新为最新版\n- `.cursor/mcp.json`:合并其它 server;已有 `morya-ui` 条目则跳过(除非 `--force`)\n- `check:colors`:仅在缺失时追加(除非 `--force`)\n- 样式:找到入口且尚未引入时才注入"
26868
27034
  },
26869
27035
  {
26870
27036
  "title": "下一步",
@@ -26876,7 +27042,7 @@
26876
27042
  "en-US": {
26877
27043
  "title": "One-shot setup",
26878
27044
  "description": "Use @morya-ui/setup to install the library and optionally write styles, Agent config, and MCP.",
26879
- "markdown": "---\ntitle: One-shot setup\norder: 3\ndescription: Use @morya-ui/setup to install the library and optionally write styles, Agent config, and MCP.\n---\n\n# One-shot setup\n\n[`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) onboards a consumer Vue app to `morya-ui`: install the dependency, inject styles, and optionally write the Agent skill, Cursor rules, and MCP. For manual install see [Quick start](/docs/quick-start). For AI page-generation workflow see [AI setup](/docs/ai-setup).\n\n## Commands\n\nFrom the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\nBy default this will:\n\n1. Install `morya-ui` (pnpm / yarn / npm from the lockfile)\n2. Copy `DESIGN.md`, Agent skill, Cursor rules, and check scripts\n3. Merge `.cursor/mcp.json` for [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. Try to inject `import 'morya-ui/styles.css'`\n5. Add a `check:colors` script when missing\n\nOther common commands:\n\n```bash\n# Library + styles only\nnpx @morya-ui/setup app\n\n# AI config + MCP only (library already installed)\nnpx @morya-ui/setup ai\n\n# Non-interactive skill selection\nnpx @morya-ui/setup ai --yes\nnpx @morya-ui/setup ai --skills=morya-ui-pages,frontend-design\nnpx @morya-ui/setup ai --skills=all\n```\n\nOn a TTY, `full` / `ai` prompts for optional Agent skills (required `morya-ui-pages` is always included). If MCP was written, **restart Cursor** (or reload MCP). Have the agent read `DESIGN.md` before generating pages.\n\n## Options\n\n| Flag | Meaning |\n| --- | --- |\n| `--cwd <dir>` | Target project root (default: cwd) |\n| `--pm pnpm\\|yarn\\|npm` | Package manager |\n| `--skills <list>` | Comma-separated skill ids, or `all` (skips the prompt) |\n| `--yes` / `-y` | Use default skills without prompting |\n| `--force` | Overwrite existing template files and the `morya-ui` MCP entry |\n| `--dry-run` | Print actions only |\n| `--skip-install` | Skip dependency install |\n| `--skip-template` | Skip copying skill / rules / docs |\n| `--skip-mcp` | Skip writing MCP config |\n| `--skip-styles` | Skip styles import injection |\n| `--skip-scripts` | Skip `package.json` scripts |\n\nBy default **existing files are not overwritten**; use `--force` to overwrite templates and the MCP entry.\n\n### Skills\n\n| Id | Default | Role |\n| --- | --- | --- |\n| `morya-ui-pages` | required | Page generation with `M*` + golden layouts |\n| `frontend-design` | optional | Express / brand visual taste |\n| `fixing-accessibility` | optional | A11y audit and targeted fixes |\n\nCatalog: [`packages/setup/catalog/skills.json`](https://github.com/morya-space/morya-ui/blob/main/packages/setup/catalog/skills.json).\n\nExample: MCP only:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```\n\n## What lands in the project\n\n| Path | Role |\n| --- | --- |\n| `DESIGN.md` | Primary design brief (principles, app root, token summary, bans) |\n| `.agents/skills/morya-ui-pages/` | Page-generation Agent skill (see [Agent Skill](/docs/agent-skill)) |\n| `.agents/skills/<optional>/` | Companion skills when selected |\n| `.cursor/rules/` | Cursor always-on rules |\n| `scripts/check-raw-colors.mjs` | Raw color scan |\n| `.cursor/mcp.json` | Cursor MCP (`npx -y @morya-ui/mcp`) |\n\nTemplate source: [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit). The CLI does not call `app.use(MoryaUI)` or edit `App.vue`.\n\n## Conflict policy\n\n- Template files and `.cursor/rules/*`: skip if the destination exists (unless `--force`)\n- `.cursor/mcp.json`: merge other servers; skip an existing `morya-ui` entry unless `--force`\n- `check:colors`: add only if missing (unless `--force`)\n- Styles: inject only when an entry is found and the import is not already present\n\n## Next steps\n\n- [Quick start](/docs/quick-start): component usage and a minimal example \n- [AI setup](/docs/ai-setup): how setup relates to Skill / MCP for AI page generation \n- [Agent Skill](/docs/agent-skill) · [Agent MCP](/docs/mcp) \n- [Components](/components): browse APIs and previews\n",
27045
+ "markdown": "---\ntitle: One-shot setup\norder: 3\ndescription: Use @morya-ui/setup to install the library and optionally write styles, Agent config, and MCP.\n---\n\n# One-shot setup\n\n[`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) onboards a consumer Vue app to `morya-ui`: install the dependency, inject styles, and optionally write the Agent skill, Cursor rules, and MCP. For manual install see [Quick start](/docs/quick-start). For AI page-generation workflow see [AI setup](/docs/ai-setup).\n\n## Commands\n\nFrom the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\nBy default this will:\n\n1. Install `morya-ui` (pnpm / yarn / npm from the lockfile)\n2. Copy `DESIGN.md`, Agent skill, Cursor rules, and check scripts\n3. Merge `.cursor/mcp.json` for [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. Try to inject `import 'morya-ui/styles.css'`\n5. Add a `check:colors` script when missing\n\nOther common commands:\n\n```bash\n# Library + styles only\nnpx @morya-ui/setup app\n\n# AI config + MCP only (library already installed)\nnpx @morya-ui/setup ai\n\n# Non-interactive skill selection\nnpx @morya-ui/setup ai --yes\nnpx @morya-ui/setup ai --skills=morya-ui-pages,frontend-design,impeccable\nnpx @morya-ui/setup ai --skills=all\n```\n\nOn a TTY, `full` / `ai` prompts for optional Agent skills (required `morya-ui-pages` is always included). Optional companions are installed at **latest** via the [skills CLI](https://skills.sh/). If MCP was written, **restart Cursor** (or reload MCP). Have the agent read `DESIGN.md` before generating pages.\n\n## Options\n\n| Flag | Meaning |\n| --- | --- |\n| `--cwd <dir>` | Target project root (default: cwd) |\n| `--pm pnpm\\|yarn\\|npm` | Package manager |\n| `--skills <list>` | Comma-separated skill ids, or `all` (skips the prompt) |\n| `--yes` / `-y` | Use default skills without prompting |\n| `--force` | Overwrite existing template files and the `morya-ui` MCP entry |\n| `--dry-run` | Print actions only |\n| `--skip-install` | Skip dependency install |\n| `--skip-template` | Skip copying skill / rules / docs (also skips companion install) |\n| `--skip-mcp` | Skip writing MCP config |\n| `--skip-styles` | Skip styles import injection |\n| `--skip-scripts` | Skip `package.json` scripts |\n\nTemplate files are **not** overwritten by default; use `--force` for templates and the MCP entry. Selected companion skills always refresh to latest.\n\n### Skills\n\n| Id | Default | Install | Role |\n| --- | --- | --- | --- |\n| `morya-ui-pages` | required | package template | Page generation with `M*` + golden layouts |\n| `frontend-design` | optional | skills CLI (`anthropics/skills`, latest) | Express / brand visual taste |\n| `fixing-accessibility` | optional | skills CLI (`ibelick/ui-skills`, latest) | A11y audit and targeted fixes |\n| `impeccable` | optional | skills CLI (`pbakaus/impeccable`, latest) | Named polish / audit / redesign |\n\nCatalog: [`packages/setup/catalog/skills.json`](https://github.com/morya-space/morya-ui/blob/main/packages/setup/catalog/skills.json).\n\nExample: MCP only:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```\n\n## What lands in the project\n\n| Path | Role |\n| --- | --- |\n| `DESIGN.md` | Primary design brief (principles, app root, token summary, bans) |\n| `.agents/skills/morya-ui-pages/` | Page-generation Agent skill (see [Agent Skill](/docs/agent-skill)) |\n| `.agents/skills/<optional>/` | Latest companion skills via skills CLI when selected |\n| `.cursor/rules/` | Cursor always-on rules |\n| `scripts/check-raw-colors.mjs` | Raw color scan |\n| `.cursor/mcp.json` | Cursor MCP (`npx -y @morya-ui/mcp`) |\n\nTemplate source: [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit). The CLI does not call `app.use(MoryaUI)` or edit `App.vue`.\n\n## Conflict policy\n\n- Template files and `.cursor/rules/*`: skip if the destination exists (unless `--force`)\n- Companion skills (skills CLI): always install/update to latest when selected\n- `.cursor/mcp.json`: merge other servers; skip an existing `morya-ui` entry unless `--force`\n- `check:colors`: add only if missing (unless `--force`)\n- Styles: inject only when an entry is found and the import is not already present\n\n## Next steps\n\n- [Quick start](/docs/quick-start): component usage and a minimal example \n- [AI setup](/docs/ai-setup): how setup relates to Skill / MCP for AI page generation \n- [Agent Skill](/docs/agent-skill) · [Agent MCP](/docs/mcp) \n- [Components](/components): browse APIs and previews\n",
26880
27046
  "sections": [
26881
27047
  {
26882
27048
  "title": "",
@@ -26886,22 +27052,22 @@
26886
27052
  {
26887
27053
  "title": "Commands",
26888
27054
  "id": "commands",
26889
- "body": "From the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\nBy default this will:\n\n1. Install `morya-ui` (pnpm / yarn / npm from the lockfile)\n2. Copy `DESIGN.md`, Agent skill, Cursor rules, and check scripts\n3. Merge `.cursor/mcp.json` for [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. Try to inject `import 'morya-ui/styles.css'`\n5. Add a `check:colors` script when missing\n\nOther common commands:\n\n```bash\n# Library + styles only\nnpx @morya-ui/setup app\n\n# AI config + MCP only (library already installed)\nnpx @morya-ui/setup ai\n\n# Non-interactive skill selection\nnpx @morya-ui/setup ai --yes\nnpx @morya-ui/setup ai --skills=morya-ui-pages,frontend-design\nnpx @morya-ui/setup ai --skills=all\n```\n\nOn a TTY, `full` / `ai` prompts for optional Agent skills (required `morya-ui-pages` is always included). If MCP was written, **restart Cursor** (or reload MCP). Have the agent read `DESIGN.md` before generating pages."
27055
+ "body": "From the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\nBy default this will:\n\n1. Install `morya-ui` (pnpm / yarn / npm from the lockfile)\n2. Copy `DESIGN.md`, Agent skill, Cursor rules, and check scripts\n3. Merge `.cursor/mcp.json` for [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp)\n4. Try to inject `import 'morya-ui/styles.css'`\n5. Add a `check:colors` script when missing\n\nOther common commands:\n\n```bash\n# Library + styles only\nnpx @morya-ui/setup app\n\n# AI config + MCP only (library already installed)\nnpx @morya-ui/setup ai\n\n# Non-interactive skill selection\nnpx @morya-ui/setup ai --yes\nnpx @morya-ui/setup ai --skills=morya-ui-pages,frontend-design,impeccable\nnpx @morya-ui/setup ai --skills=all\n```\n\nOn a TTY, `full` / `ai` prompts for optional Agent skills (required `morya-ui-pages` is always included). Optional companions are installed at **latest** via the [skills CLI](https://skills.sh/). If MCP was written, **restart Cursor** (or reload MCP). Have the agent read `DESIGN.md` before generating pages."
26890
27056
  },
26891
27057
  {
26892
27058
  "title": "Options",
26893
27059
  "id": "options",
26894
- "body": "| Flag | Meaning |\n| --- | --- |\n| `--cwd <dir>` | Target project root (default: cwd) |\n| `--pm pnpm\\|yarn\\|npm` | Package manager |\n| `--skills <list>` | Comma-separated skill ids, or `all` (skips the prompt) |\n| `--yes` / `-y` | Use default skills without prompting |\n| `--force` | Overwrite existing template files and the `morya-ui` MCP entry |\n| `--dry-run` | Print actions only |\n| `--skip-install` | Skip dependency install |\n| `--skip-template` | Skip copying skill / rules / docs |\n| `--skip-mcp` | Skip writing MCP config |\n| `--skip-styles` | Skip styles import injection |\n| `--skip-scripts` | Skip `package.json` scripts |\n\nBy default **existing files are not overwritten**; use `--force` to overwrite templates and the MCP entry.\n\n### Skills\n\n| Id | Default | Role |\n| --- | --- | --- |\n| `morya-ui-pages` | required | Page generation with `M*` + golden layouts |\n| `frontend-design` | optional | Express / brand visual taste |\n| `fixing-accessibility` | optional | A11y audit and targeted fixes |\n\nCatalog: [`packages/setup/catalog/skills.json`](https://github.com/morya-space/morya-ui/blob/main/packages/setup/catalog/skills.json).\n\nExample: MCP only:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```"
27060
+ "body": "| Flag | Meaning |\n| --- | --- |\n| `--cwd <dir>` | Target project root (default: cwd) |\n| `--pm pnpm\\|yarn\\|npm` | Package manager |\n| `--skills <list>` | Comma-separated skill ids, or `all` (skips the prompt) |\n| `--yes` / `-y` | Use default skills without prompting |\n| `--force` | Overwrite existing template files and the `morya-ui` MCP entry |\n| `--dry-run` | Print actions only |\n| `--skip-install` | Skip dependency install |\n| `--skip-template` | Skip copying skill / rules / docs (also skips companion install) |\n| `--skip-mcp` | Skip writing MCP config |\n| `--skip-styles` | Skip styles import injection |\n| `--skip-scripts` | Skip `package.json` scripts |\n\nTemplate files are **not** overwritten by default; use `--force` for templates and the MCP entry. Selected companion skills always refresh to latest.\n\n### Skills\n\n| Id | Default | Install | Role |\n| --- | --- | --- | --- |\n| `morya-ui-pages` | required | package template | Page generation with `M*` + golden layouts |\n| `frontend-design` | optional | skills CLI (`anthropics/skills`, latest) | Express / brand visual taste |\n| `fixing-accessibility` | optional | skills CLI (`ibelick/ui-skills`, latest) | A11y audit and targeted fixes |\n| `impeccable` | optional | skills CLI (`pbakaus/impeccable`, latest) | Named polish / audit / redesign |\n\nCatalog: [`packages/setup/catalog/skills.json`](https://github.com/morya-space/morya-ui/blob/main/packages/setup/catalog/skills.json).\n\nExample: MCP only:\n\n```bash\nnpx @morya-ui/setup ai --skip-template --skip-scripts\n```"
26895
27061
  },
26896
27062
  {
26897
27063
  "title": "What lands in the project",
26898
27064
  "id": "what-lands-in-the-project",
26899
- "body": "| Path | Role |\n| --- | --- |\n| `DESIGN.md` | Primary design brief (principles, app root, token summary, bans) |\n| `.agents/skills/morya-ui-pages/` | Page-generation Agent skill (see [Agent Skill](/docs/agent-skill)) |\n| `.agents/skills/<optional>/` | Companion skills when selected |\n| `.cursor/rules/` | Cursor always-on rules |\n| `scripts/check-raw-colors.mjs` | Raw color scan |\n| `.cursor/mcp.json` | Cursor MCP (`npx -y @morya-ui/mcp`) |\n\nTemplate source: [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit). The CLI does not call `app.use(MoryaUI)` or edit `App.vue`."
27065
+ "body": "| Path | Role |\n| --- | --- |\n| `DESIGN.md` | Primary design brief (principles, app root, token summary, bans) |\n| `.agents/skills/morya-ui-pages/` | Page-generation Agent skill (see [Agent Skill](/docs/agent-skill)) |\n| `.agents/skills/<optional>/` | Latest companion skills via skills CLI when selected |\n| `.cursor/rules/` | Cursor always-on rules |\n| `scripts/check-raw-colors.mjs` | Raw color scan |\n| `.cursor/mcp.json` | Cursor MCP (`npx -y @morya-ui/mcp`) |\n\nTemplate source: [`design-kit/`](https://github.com/morya-space/morya-ui/tree/main/design-kit). The CLI does not call `app.use(MoryaUI)` or edit `App.vue`."
26900
27066
  },
26901
27067
  {
26902
27068
  "title": "Conflict policy",
26903
27069
  "id": "conflict-policy",
26904
- "body": "- Template files and `.cursor/rules/*`: skip if the destination exists (unless `--force`)\n- `.cursor/mcp.json`: merge other servers; skip an existing `morya-ui` entry unless `--force`\n- `check:colors`: add only if missing (unless `--force`)\n- Styles: inject only when an entry is found and the import is not already present"
27070
+ "body": "- Template files and `.cursor/rules/*`: skip if the destination exists (unless `--force`)\n- Companion skills (skills CLI): always install/update to latest when selected\n- `.cursor/mcp.json`: merge other servers; skip an existing `morya-ui` entry unless `--force`\n- `check:colors`: add only if missing (unless `--force`)\n- Styles: inject only when an entry is found and the import is not already present"
26905
27071
  },
26906
27072
  {
26907
27073
  "title": "Next steps",
@@ -27071,7 +27237,7 @@
27071
27237
  "zh-CN": {
27072
27238
  "title": "动效",
27073
27239
  "description": "动效强度偏好、进出场预设与相关设计令牌。",
27074
- "markdown": "---\ntitle: 动效\norder: 6\ndescription: 动效强度偏好、进出场预设与相关设计令牌。\n---\n\n# 动效\n\n动效分两层,彼此正交:\n\n1. **强度**:`useMotion` → `full` / `reduced` / `none`(写到 `data-m-motion`)\n2. **形态**:命名进出场预设(Vue `<Transition>`)\n\n时长、缓动与位移由 `--m-motion-*` 令牌驱动;完整列表见 [设计令牌](/docs/design-tokens)。\n\n## 动效偏好\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`:标准过渡与浮层动画 \n- `reduced`:缩短时长、弱化位移;循环指示器停掉 \n- `none`:立即切换 \n\n文档站组件页侧栏「动效」分段控件调用的是同一套 API。偏好会持久化到 `localStorage`(键名 `morya-ui-motion`)。\n\n系统开启 `prefers-reduced-motion` 时,默认会按减弱策略处理。若仍要保留完整过渡,可在 `createMoryaUI` / `MConfigProvider` 上设 `respectReducedMotion: false`。\n\n## 动效预设(进出场)\n\n浮层组件通过命名预设选择 Vue `<Transition>` 效果,解析优先级:\n\n1. 组件 `transition` prop \n2. `componentDefaults[Component].transition` \n3. `motion.transitions[role]`(`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) \n4. 组件内置默认 \n\n内置 id:`fade`、`scale-fade`、`slide-fade`、`zoom`、`dialog`、`slide-up` / `slide-down` / `slide-left` / `slide-right`、`drawer`、`popover`、`loading`、`blockui`、`message`、`none`。 \n`transition={false}` 或 `'none'` 关闭 CSS 过渡。\n\n```ts\nimport { createMoryaUI, registerMotionPreset } from 'morya-ui'\n\napp.use(createMoryaUI({\n motion: { transitions: { popup: 'slide-up', dialog: 'zoom' } },\n componentDefaults: { Select: { transition: 'fade' } },\n}))\n\n// 自定义:先写好 .m-brand-enter-active 等 CSS,再注册\nregisterMotionPreset('brand', { name: 'm-brand' })\n```\n\n```vue\n<MDialog transition=\"slide-up\" />\n<MSelect :transition=\"false\" />\n```\n\n```vue preview src=\"./demos/theme/MotionPresets.vue\"\n```\n\n切换下拉中的预设后,请重新打开 Dialog / Drawer / Select 或再点一次 Toast,才能看到新的进出场。\n\n## 可选:接入 Animate.css\n\n`morya-ui` **不依赖** Animate.css。若业务需要 bounce / zoomIn 等 keyframe 动效,可在应用侧安装后,用桥接 CSS + `registerMotionPreset` 挂到现有 `transition` API。时长继续用 `--m-motion-enter` / `--m-motion-exit`,即可跟 `useMotion` 强度联动。\n\n```bash\npnpm add animate.css\n```\n\n```ts\nimport { registerMotionPreset } from 'morya-ui'\nimport 'animate.css'\n// 桥接 CSS:把 Animate.css keyframes 映射到 .m-animate-*-enter-active 等\n// 完整示例见 demos/theme/animate-css-bridge.css 或下方演示源码\n\nregisterMotionPreset('animate-bounce', { name: 'm-animate-bounce' })\nregisterMotionPreset('animate-zoom', { name: 'm-animate-zoom' })\nregisterMotionPreset('animate-fade-up', { name: 'm-animate-fade-up' })\n```\n\n```vue\n<MDialog transition=\"animate-bounce\" />\n<MSelect transition=\"animate-fade-up\" />\n```\n\n要点:\n\n- Vue `<Transition>` 需要 `.{name}-enter-active` / `leave-active`;把 Animate.css 的 `@keyframes` 写进这些类即可。\n- **Dialog / Drawer** 的 Transition 类在遮罩上:遮罩用同时长的 `fadeIn` / `fadeOut`,表达性动画写在内部 `.m-dialog-zoom` / `.m-drawer`,否则面板动效容易被截断或整层遮罩一起弹跳。\n- **Select / Toast** 等浮层根节点即 Transition 目标,可直接在 `-enter-active` 上挂 keyframe。\n\n文档站已引入 Animate.css,可直接试用:\n\n```vue preview src=\"./demos/theme/AnimateCssPresets.vue\"\n```\n\n## 相关令牌\n\n| Token | 用途 |\n| --- | --- |\n| `--m-motion-fast/normal/enter/exit` | 过渡时长 |\n| `--m-motion-distance` / `--m-motion-ease` | 进出场位移与缓动 |\n| `--m-motion-spin*` / `--m-motion-pulse` / `--m-motion-skeleton` | 循环指示器(`reduced`/`none` 下为 `0ms`) |\n| `--m-motion-loading-*` | Loading 变体循环时长 |\n\n亮暗主题与密度见 [主题](/docs/theme);无障碍说明见 [无障碍](/docs/accessibility)。\n",
27240
+ "markdown": "---\ntitle: 动效\norder: 6\ndescription: 动效强度偏好、进出场预设与相关设计令牌。\n---\n\n# 动效\n\n动效分两层,彼此正交:\n\n1. **强度**:`useMotion` → `full` / `reduced` / `none`(写到 `data-m-motion`)\n2. **形态**:命名进出场预设(Vue `<Transition>`)\n\n时长、缓动与位移由 `--m-motion-*` 令牌驱动;完整列表见 [设计令牌](/docs/design-tokens)。\n\n## 动效偏好\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`:标准过渡与浮层动画 \n- `reduced`:缩短时长、弱化位移;循环指示器停掉 \n- `none`:立即切换 \n\n文档站组件页侧栏「动效」分段控件调用的是同一套 API。偏好会持久化到 `localStorage`(键名 `morya-ui-motion`)。组件动效只跟这一套配置走,不读取系统的 `prefers-reduced-motion`。\n\n## 动效预设(进出场)\n\n浮层组件通过命名预设选择 Vue `<Transition>` 效果,解析优先级:\n\n1. 组件 `transition` prop \n2. `componentDefaults[Component].transition` \n3. `motion.transitions[role]`(`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) \n4. 组件内置默认 \n\n内置 id:`fade`、`scale-fade`、`slide-fade`、`zoom`、`dialog`、`slide-up` / `slide-down` / `slide-left` / `slide-right`、`drawer`、`popover`、`loading`、`blockui`、`message`、`none`。 \n`transition={false}` 或 `'none'` 关闭 CSS 过渡。\n\n```ts\nimport { createMoryaUI, registerMotionPreset } from 'morya-ui'\n\napp.use(createMoryaUI({\n motion: { transitions: { popup: 'slide-up', dialog: 'zoom' } },\n componentDefaults: { Select: { transition: 'fade' } },\n}))\n\n// 自定义:先写好 .m-brand-enter-active 等 CSS,再注册\nregisterMotionPreset('brand', { name: 'm-brand' })\n```\n\n```vue\n<MDialog transition=\"slide-up\" />\n<MSelect :transition=\"false\" />\n```\n\n```vue preview src=\"./demos/theme/MotionPresets.vue\"\n```\n\n切换下拉中的预设后,请重新打开 Dialog / Drawer / Select 或再点一次 Toast,才能看到新的进出场。\n\n## 可选:接入 Animate.css\n\n`morya-ui` **不依赖** Animate.css。若业务需要 bounce / zoomIn 等 keyframe 动效,可在应用侧安装后,用桥接 CSS + `registerMotionPreset` 挂到现有 `transition` API。时长继续用 `--m-motion-enter` / `--m-motion-exit`,即可跟 `useMotion` 强度联动。\n\n```bash\npnpm add animate.css\n```\n\n```ts\nimport { registerMotionPreset } from 'morya-ui'\nimport 'animate.css'\n// 桥接 CSS:把 Animate.css keyframes 映射到 .m-animate-*-enter-active 等\n// 完整示例见 demos/theme/animate-css-bridge.css 或下方演示源码\n\nregisterMotionPreset('animate-bounce', { name: 'm-animate-bounce' })\nregisterMotionPreset('animate-zoom', { name: 'm-animate-zoom' })\nregisterMotionPreset('animate-fade-up', { name: 'm-animate-fade-up' })\n```\n\n```vue\n<MDialog transition=\"animate-bounce\" />\n<MSelect transition=\"animate-fade-up\" />\n```\n\n要点:\n\n- Vue `<Transition>` 需要 `.{name}-enter-active` / `leave-active`;把 Animate.css 的 `@keyframes` 写进这些类即可。\n- **Dialog / Drawer** 的 Transition 类在遮罩上:遮罩用同时长的 `fadeIn` / `fadeOut`,表达性动画写在内部 `.m-dialog-zoom` / `.m-drawer`,否则面板动效容易被截断或整层遮罩一起弹跳。\n- **Select / Toast** 等浮层根节点即 Transition 目标,可直接在 `-enter-active` 上挂 keyframe。\n\n文档站已引入 Animate.css,可直接试用:\n\n```vue preview src=\"./demos/theme/AnimateCssPresets.vue\"\n```\n\n## 相关令牌\n\n| Token | 用途 |\n| --- | --- |\n| `--m-motion-fast/normal/enter/exit` | 过渡时长 |\n| `--m-motion-distance` / `--m-motion-ease` | 进出场位移与缓动 |\n| `--m-motion-spin*` / `--m-motion-pulse` / `--m-motion-skeleton` | 循环指示器(`reduced`/`none` 下为 `0ms`) |\n| `--m-motion-loading-*` | Loading 变体循环时长 |\n\n亮暗主题与密度见 [主题](/docs/theme);无障碍说明见 [无障碍](/docs/accessibility)。\n",
27075
27241
  "sections": [
27076
27242
  {
27077
27243
  "title": "",
@@ -27081,7 +27247,7 @@
27081
27247
  {
27082
27248
  "title": "动效偏好",
27083
27249
  "id": "动效偏好",
27084
- "body": "```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`:标准过渡与浮层动画 \n- `reduced`:缩短时长、弱化位移;循环指示器停掉 \n- `none`:立即切换 \n\n文档站组件页侧栏「动效」分段控件调用的是同一套 API。偏好会持久化到 `localStorage`(键名 `morya-ui-motion`)。\n\n系统开启 `prefers-reduced-motion` 时,默认会按减弱策略处理。若仍要保留完整过渡,可在 `createMoryaUI` / `MConfigProvider` 上设 `respectReducedMotion: false`。"
27250
+ "body": "```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`:标准过渡与浮层动画 \n- `reduced`:缩短时长、弱化位移;循环指示器停掉 \n- `none`:立即切换 \n\n文档站组件页侧栏「动效」分段控件调用的是同一套 API。偏好会持久化到 `localStorage`(键名 `morya-ui-motion`)。组件动效只跟这一套配置走,不读取系统的 `prefers-reduced-motion`。"
27085
27251
  },
27086
27252
  {
27087
27253
  "title": "动效预设(进出场)",
@@ -27103,7 +27269,7 @@
27103
27269
  "en-US": {
27104
27270
  "title": "Motion",
27105
27271
  "description": "Motion intensity preferences, enter/exit presets, and related design tokens.",
27106
- "markdown": "---\ntitle: Motion\norder: 6\ndescription: Motion intensity preferences, enter/exit presets, and related design tokens.\n---\n\n# Motion\n\nMotion has two orthogonal layers:\n\n1. **Intensity**: `useMotion` → `full` / `reduced` / `none` (writes `data-m-motion`)\n2. **Shape**: named enter/exit presets (Vue `<Transition>`)\n\nDurations, easing, and travel come from `--m-motion-*` tokens; see the full [Design tokens](/docs/design-tokens) catalog.\n\n## Motion preference\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`: standard transitions and overlay motion \n- `reduced`: shorter duration, less travel; looping indicators stop \n- `none`: instant switches \n\nThe Components page sidebar Motion control uses the same API. The preference is persisted in `localStorage` (`morya-ui-motion`).\n\nWhen the OS enables `prefers-reduced-motion`, reduced policies apply by default. Set `respectReducedMotion: false` on `createMoryaUI` / `MConfigProvider` to keep full transitions.\n\n## Motion presets (enter/exit)\n\nOverlay components pick a named Vue `<Transition>` preset. Resolution order:\n\n1. Component `transition` prop \n2. `componentDefaults[Component].transition` \n3. `motion.transitions[role]` (`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) \n4. Component built-in default \n\nBuilt-in ids: `fade`, `scale-fade`, `slide-fade`, `zoom`, `dialog`, `slide-up` / `slide-down` / `slide-left` / `slide-right`, `drawer`, `popover`, `loading`, `blockui`, `message`, `none`. \n`transition={false}` or `'none'` disables CSS transitions.\n\n```ts\nimport { createMoryaUI, registerMotionPreset } from 'morya-ui'\n\napp.use(createMoryaUI({\n motion: { transitions: { popup: 'slide-up', dialog: 'zoom' } },\n componentDefaults: { Select: { transition: 'fade' } },\n}))\n\n// Custom: provide .m-brand-enter-active CSS, then register\nregisterMotionPreset('brand', { name: 'm-brand' })\n```\n\n```vue\n<MDialog transition=\"slide-up\" />\n<MSelect :transition=\"false\" />\n```\n\n```vue preview src=\"./demos/theme/MotionPresets.vue\"\n```\n\nAfter changing a preset in the dropdowns, reopen Dialog / Drawer / Select or trigger Toast again to replay enter/exit.\n\n## Optional: Animate.css\n\n`morya-ui` does **not** depend on Animate.css. If your app wants keyframe effects such as bounce / zoomIn, install it on the app side and wire it through bridge CSS + `registerMotionPreset` into the existing `transition` API. Keep durations on `--m-motion-enter` / `--m-motion-exit` so they stay linked to `useMotion` intensity.\n\n```bash\npnpm add animate.css\n```\n\n```ts\nimport { registerMotionPreset } from 'morya-ui'\nimport 'animate.css'\n// Bridge CSS: map Animate.css keyframes onto .m-animate-*-enter-active etc.\n// Full example: demos/theme/animate-css-bridge.css or the live demo source below\n\nregisterMotionPreset('animate-bounce', { name: 'm-animate-bounce' })\nregisterMotionPreset('animate-zoom', { name: 'm-animate-zoom' })\nregisterMotionPreset('animate-fade-up', { name: 'm-animate-fade-up' })\n```\n\n```vue\n<MDialog transition=\"animate-bounce\" />\n<MSelect transition=\"animate-fade-up\" />\n```\n\nNotes:\n\n- Vue `<Transition>` expects `.{name}-enter-active` / `leave-active`; map Animate.css `@keyframes` onto those classes.\n- **Dialog / Drawer** put Transition classes on the backdrop: use a same-duration `fadeIn` / `fadeOut` on the mask, and put the expressive animation on nested `.m-dialog-zoom` / `.m-drawer` so the panel is not cut short and the scrim does not bounce.\n- **Select / Toast** and similar overlays transition the panel root, so keyframes can sit directly on `-enter-active`.\n\nThis docs site already depends on Animate.css for the live demo:\n\n```vue preview src=\"./demos/theme/AnimateCssPresets.vue\"\n```\n\n## Related tokens\n\n| Token | Use |\n| --- | --- |\n| `--m-motion-fast/normal/enter/exit` | Transition duration |\n| `--m-motion-distance` / `--m-motion-ease` | Enter/exit travel and easing |\n| `--m-motion-spin*` / `--m-motion-pulse` / `--m-motion-skeleton` | Looping indicators (`0ms` under `reduced`/`none`) |\n| `--m-motion-loading-*` | Loading variant loop durations |\n\nLight/dark theme and density: [Theme](/docs/theme). Accessibility notes: [Accessibility](/docs/accessibility).\n",
27272
+ "markdown": "---\ntitle: Motion\norder: 6\ndescription: Motion intensity preferences, enter/exit presets, and related design tokens.\n---\n\n# Motion\n\nMotion has two orthogonal layers:\n\n1. **Intensity**: `useMotion` → `full` / `reduced` / `none` (writes `data-m-motion`)\n2. **Shape**: named enter/exit presets (Vue `<Transition>`)\n\nDurations, easing, and travel come from `--m-motion-*` tokens; see the full [Design tokens](/docs/design-tokens) catalog.\n\n## Motion preference\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`: standard transitions and overlay motion \n- `reduced`: shorter duration, less travel; looping indicators stop \n- `none`: instant switches \n\nThe Components page sidebar Motion control uses the same API. The preference is persisted in `localStorage` (`morya-ui-motion`). Component motion follows this setting only and does not read the OS `prefers-reduced-motion` media query.\n\n## Motion presets (enter/exit)\n\nOverlay components pick a named Vue `<Transition>` preset. Resolution order:\n\n1. Component `transition` prop \n2. `componentDefaults[Component].transition` \n3. `motion.transitions[role]` (`dialog` / `drawer` / `popup` / `toast` / `tooltip` / `overlay`) \n4. Component built-in default \n\nBuilt-in ids: `fade`, `scale-fade`, `slide-fade`, `zoom`, `dialog`, `slide-up` / `slide-down` / `slide-left` / `slide-right`, `drawer`, `popover`, `loading`, `blockui`, `message`, `none`. \n`transition={false}` or `'none'` disables CSS transitions.\n\n```ts\nimport { createMoryaUI, registerMotionPreset } from 'morya-ui'\n\napp.use(createMoryaUI({\n motion: { transitions: { popup: 'slide-up', dialog: 'zoom' } },\n componentDefaults: { Select: { transition: 'fade' } },\n}))\n\n// Custom: provide .m-brand-enter-active CSS, then register\nregisterMotionPreset('brand', { name: 'm-brand' })\n```\n\n```vue\n<MDialog transition=\"slide-up\" />\n<MSelect :transition=\"false\" />\n```\n\n```vue preview src=\"./demos/theme/MotionPresets.vue\"\n```\n\nAfter changing a preset in the dropdowns, reopen Dialog / Drawer / Select or trigger Toast again to replay enter/exit.\n\n## Optional: Animate.css\n\n`morya-ui` does **not** depend on Animate.css. If your app wants keyframe effects such as bounce / zoomIn, install it on the app side and wire it through bridge CSS + `registerMotionPreset` into the existing `transition` API. Keep durations on `--m-motion-enter` / `--m-motion-exit` so they stay linked to `useMotion` intensity.\n\n```bash\npnpm add animate.css\n```\n\n```ts\nimport { registerMotionPreset } from 'morya-ui'\nimport 'animate.css'\n// Bridge CSS: map Animate.css keyframes onto .m-animate-*-enter-active etc.\n// Full example: demos/theme/animate-css-bridge.css or the live demo source below\n\nregisterMotionPreset('animate-bounce', { name: 'm-animate-bounce' })\nregisterMotionPreset('animate-zoom', { name: 'm-animate-zoom' })\nregisterMotionPreset('animate-fade-up', { name: 'm-animate-fade-up' })\n```\n\n```vue\n<MDialog transition=\"animate-bounce\" />\n<MSelect transition=\"animate-fade-up\" />\n```\n\nNotes:\n\n- Vue `<Transition>` expects `.{name}-enter-active` / `leave-active`; map Animate.css `@keyframes` onto those classes.\n- **Dialog / Drawer** put Transition classes on the backdrop: use a same-duration `fadeIn` / `fadeOut` on the mask, and put the expressive animation on nested `.m-dialog-zoom` / `.m-drawer` so the panel is not cut short and the scrim does not bounce.\n- **Select / Toast** and similar overlays transition the panel root, so keyframes can sit directly on `-enter-active`.\n\nThis docs site already depends on Animate.css for the live demo:\n\n```vue preview src=\"./demos/theme/AnimateCssPresets.vue\"\n```\n\n## Related tokens\n\n| Token | Use |\n| --- | --- |\n| `--m-motion-fast/normal/enter/exit` | Transition duration |\n| `--m-motion-distance` / `--m-motion-ease` | Enter/exit travel and easing |\n| `--m-motion-spin*` / `--m-motion-pulse` / `--m-motion-skeleton` | Looping indicators (`0ms` under `reduced`/`none`) |\n| `--m-motion-loading-*` | Loading variant loop durations |\n\nLight/dark theme and density: [Theme](/docs/theme). Accessibility notes: [Accessibility](/docs/accessibility).\n",
27107
27273
  "sections": [
27108
27274
  {
27109
27275
  "title": "",
@@ -27113,7 +27279,7 @@
27113
27279
  {
27114
27280
  "title": "Motion preference",
27115
27281
  "id": "motion-preference",
27116
- "body": "```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`: standard transitions and overlay motion \n- `reduced`: shorter duration, less travel; looping indicators stop \n- `none`: instant switches \n\nThe Components page sidebar Motion control uses the same API. The preference is persisted in `localStorage` (`morya-ui-motion`).\n\nWhen the OS enables `prefers-reduced-motion`, reduced policies apply by default. Set `respectReducedMotion: false` on `createMoryaUI` / `MConfigProvider` to keep full transitions."
27282
+ "body": "```ts\nimport { useMotion } from 'morya-ui'\n\nconst { preference, setMotion } = useMotion()\nsetMotion('full') // 'full' | 'reduced' | 'none'\n```\n\n- `full`: standard transitions and overlay motion \n- `reduced`: shorter duration, less travel; looping indicators stop \n- `none`: instant switches \n\nThe Components page sidebar Motion control uses the same API. The preference is persisted in `localStorage` (`morya-ui-motion`). Component motion follows this setting only and does not read the OS `prefers-reduced-motion` media query."
27117
27283
  },
27118
27284
  {
27119
27285
  "title": "Motion presets (enter/exit)",
@@ -27511,7 +27677,7 @@
27511
27677
  "zh-CN": {
27512
27678
  "title": "无障碍",
27513
27679
  "description": "使用 Morya UI 组件时的无障碍约定与检查清单。",
27514
- "markdown": "---\ntitle: 无障碍\norder: 11\ndescription: 使用 Morya UI 组件时的无障碍约定与检查清单。\n---\n\n# 无障碍\n\nMorya UI 以**语义化 HTML 优先、必要时补充 ARIA**为原则。组件尽量自带标签关联、键盘路径与浮层焦点管理;业务侧仍需提供有意义的文案与结构。\n\n## 快速检查清单\n\n| 场景 | 建议 |\n| --- | --- |\n| 图标按钮 | 设置 `aria-label` 或可见文本,勿仅靠图标传达含义 |\n| 表单字段 | 使用 `label`;错误时用 `invalid` + `error-message` |\n| 装饰性图标 | 省略 `label`,组件会使用 `aria-hidden` |\n| 浮层 / 对话框 | 确认 Esc 可关闭;打开后焦点在面板内 |\n| 动效敏感用户 | 使用 `useMotion()` 设为 `reduced` 或 `none` |\n| 仅颜色区分状态 | 同时提供文案、图标或 `error-message` |\n\n## 表单与校验\n\n输入类组件(`Input`、`Textarea`、`Select` 等)共享字段模式:\n\n```vue\n<MInput\n id=\"email\"\n v-model=\"email\"\n label=\"邮箱\"\n invalid\n error-message=\"请输入有效邮箱\"\n/>\n```\n\n要点:\n\n- **`label`** 会关联到控件;配合 `FloatLabel` 时也会写入 `for`。\n- **`invalid`** 会设置 `aria-invalid` 与错误样式。\n- **`error-message`** 会通过 `aria-describedby` 关联帮助/错误区域。\n- 必填请同时使用原生 `required`(若组件支持)或业务层校验提示,不要只用颜色表达。\n\n## 图标与按钮\n\n`MIcon` 仅承载**系统图标**。无 `label` 时视为装饰并隐藏;信息性图标请传 `label`:\n\n```vue\n<MIcon name=\"info\" label=\"更多信息\" />\n<MButton icon=\"search\" aria-label=\"搜索\" icon-only />\n```\n\n带文字的按钮优先用默认插槽或 `label`,不必重复 `aria-label`。\n\n## 浮层与焦点\n\n以下组件默认 Teleport 到 `body`,并在打开时锁定滚动、支持 `Escape` 关闭:\n\n- `Dialog`、`Drawer`、`CommandMenu`\n- `Select`、`Popover`、`Tooltip`(按组件实现)\n\n弹出层触发器应设置:\n\n- `aria-expanded` / `aria-controls`(如 `Popover`)\n- 可见标签或 `aria-label`\n\n模态对话框打开后,焦点应落在可交互元素上;关闭后宜将焦点还原到触发器(业务层使用 `Dialog` 时可自行管理)。\n\n## 键盘交互\n\n| 组件 | 常用按键 |\n| --- | --- |\n| `CommandMenu` | `↑`/`↓` 选择,`Enter` 执行,`Esc` 关闭 |\n| `Select` | `Enter`/`Space` 打开,`↑`/`↓` 移动选项,`Esc` 关闭 |\n| `Tabs` | 方向键在 Tab 列表间移动(实现依组件) |\n| `Slider` | 方向键调整值;可通过 `aria-label` 命名 |\n\n具体行为以各组件文档为准;新增组件请在 `docs/` 中说明键盘表。\n\n## 动效与对比度\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { setMotion } = useMotion()\nsetMotion('reduced') // 或 'none'\n```\n\n`reduced` / `none` 会缩短或关闭 `--m-motion-*` 过渡,减轻 vestibular 不适。\n\n颜色应通过 `--m-color-*` 令牌消费,以保证亮/暗主题下对比度一致。自定义主题后请在真实内容上抽查正文与错误态可读性。\n\n## 组件库内已知实践\n\n近期实现/改进包括:\n\n- **FloatLabel**:`label[for]` 关联首个输入控件\n- **Popover**:触发器 `aria-expanded` / `aria-haspopup` / `aria-controls`\n- **Slider**:单 thumb 默认 `aria-label`(可通过 prop 覆盖)\n- **Select / CascadeSelect / TreeSelect / DatePicker**:`combobox` 语义、键盘导航与字段反馈(`invalid` / `error-message` / `help-text`)\n\n## 测试建议\n\n- 使用键盘完成主流程(Tab、Enter、Esc、方向键)。\n- 使用系统屏幕阅读器(NVDA / VoiceOver)抽查表单与对话框。\n- 在 `prefers-reduced-motion: reduce` 或 `useMotion('none')` 下确认界面仍可用。\n\n## 相关\n\n- [动效](/docs/motion):强度偏好、进出场预设与令牌\\n- [主题](/docs/theme):亮暗色与密度\n- [全局配置](/docs/config):语言包与默认尺寸\n",
27680
+ "markdown": "---\ntitle: 无障碍\norder: 11\ndescription: 使用 Morya UI 组件时的无障碍约定与检查清单。\n---\n\n# 无障碍\n\nMorya UI 以**语义化 HTML 优先、必要时补充 ARIA**为原则。组件尽量自带标签关联、键盘路径与浮层焦点管理;业务侧仍需提供有意义的文案与结构。\n\n## 快速检查清单\n\n| 场景 | 建议 |\n| --- | --- |\n| 图标按钮 | 设置 `aria-label` 或可见文本,勿仅靠图标传达含义 |\n| 表单字段 | 使用 `label`;错误时用 `invalid` + `error-message` |\n| 装饰性图标 | 省略 `label`,组件会使用 `aria-hidden` |\n| 浮层 / 对话框 | 确认 Esc 可关闭;打开后焦点在面板内 |\n| 动效敏感用户 | 使用 `useMotion()` 设为 `reduced` 或 `none` |\n| 仅颜色区分状态 | 同时提供文案、图标或 `error-message` |\n\n## 表单与校验\n\n输入类组件(`Input`、`Textarea`、`Select` 等)共享字段模式:\n\n```vue\n<MInput\n id=\"email\"\n v-model=\"email\"\n label=\"邮箱\"\n invalid\n error-message=\"请输入有效邮箱\"\n/>\n```\n\n要点:\n\n- **`label`** 会关联到控件;配合 `FloatLabel` 时也会写入 `for`。\n- **`invalid`** 会设置 `aria-invalid` 与错误样式。\n- **`error-message`** 会通过 `aria-describedby` 关联帮助/错误区域。\n- 必填请同时使用原生 `required`(若组件支持)或业务层校验提示,不要只用颜色表达。\n\n## 图标与按钮\n\n`MIcon` 仅承载**系统图标**。无 `label` 时视为装饰并隐藏;信息性图标请传 `label`:\n\n```vue\n<MIcon name=\"info\" label=\"更多信息\" />\n<MButton icon=\"search\" aria-label=\"搜索\" icon-only />\n```\n\n带文字的按钮优先用默认插槽或 `label`,不必重复 `aria-label`。\n\n## 浮层与焦点\n\n以下组件默认 Teleport 到 `body`,并在打开时锁定滚动、支持 `Escape` 关闭:\n\n- `Dialog`、`Drawer`、`CommandMenu`\n- `Select`、`Popover`、`Tooltip`(按组件实现)\n\n弹出层触发器应设置:\n\n- `aria-expanded` / `aria-controls`(如 `Popover`)\n- 可见标签或 `aria-label`\n\n模态对话框打开后,焦点应落在可交互元素上;关闭后宜将焦点还原到触发器(业务层使用 `Dialog` 时可自行管理)。\n\n## 键盘交互\n\n| 组件 | 常用按键 |\n| --- | --- |\n| `CommandMenu` | `↑`/`↓` 选择,`Enter` 执行,`Esc` 关闭 |\n| `Select` | `Enter`/`Space` 打开,`↑`/`↓` 移动选项,`Esc` 关闭 |\n| `Tabs` | 方向键在 Tab 列表间移动(实现依组件) |\n| `Slider` | 方向键调整值;可通过 `aria-label` 命名 |\n\n具体行为以各组件文档为准;新增组件请在 `docs/` 中说明键盘表。\n\n## 动效与对比度\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { setMotion } = useMotion()\nsetMotion('reduced') // 或 'none'\n```\n\n`reduced` / `none` 会缩短或关闭 `--m-motion-*` 过渡,减轻 vestibular 不适。\n\n颜色应通过 `--m-color-*` 令牌消费,以保证亮/暗主题下对比度一致。自定义主题后请在真实内容上抽查正文与错误态可读性。\n\n## 组件库内已知实践\n\n近期实现/改进包括:\n\n- **FloatLabel**:`label[for]` 关联首个输入控件\n- **Popover**:触发器 `aria-expanded` / `aria-haspopup` / `aria-controls`\n- **Slider**:单 thumb 默认 `aria-label`(可通过 prop 覆盖)\n- **Select / CascadeSelect / TreeSelect / DatePicker**:`combobox` 语义、键盘导航与字段反馈(`invalid` / `error-message` / `help-text`)\n\n## 测试建议\n\n- 使用键盘完成主流程(Tab、Enter、Esc、方向键)。\n- 使用系统屏幕阅读器(NVDA / VoiceOver)抽查表单与对话框。\n- 在 `useMotion('reduced')` 或 `useMotion('none')` 下确认界面仍可用。\n\n## 相关\n\n- [动效](/docs/motion):强度偏好、进出场预设与令牌\\n- [主题](/docs/theme):亮暗色与密度\n- [全局配置](/docs/config):语言包与默认尺寸\n",
27515
27681
  "sections": [
27516
27682
  {
27517
27683
  "title": "",
@@ -27556,7 +27722,7 @@
27556
27722
  {
27557
27723
  "title": "测试建议",
27558
27724
  "id": "测试建议",
27559
- "body": "- 使用键盘完成主流程(Tab、Enter、Esc、方向键)。\n- 使用系统屏幕阅读器(NVDA / VoiceOver)抽查表单与对话框。\n- 在 `prefers-reduced-motion: reduce` 或 `useMotion('none')` 下确认界面仍可用。"
27725
+ "body": "- 使用键盘完成主流程(Tab、Enter、Esc、方向键)。\n- 使用系统屏幕阅读器(NVDA / VoiceOver)抽查表单与对话框。\n- 在 `useMotion('reduced')` 或 `useMotion('none')` 下确认界面仍可用。"
27560
27726
  },
27561
27727
  {
27562
27728
  "title": "相关",
@@ -27568,7 +27734,7 @@
27568
27734
  "en-US": {
27569
27735
  "title": "Accessibility",
27570
27736
  "description": "Accessibility conventions when using Morya UI components.",
27571
- "markdown": "---\ntitle: Accessibility\norder: 11\ndescription: Accessibility conventions when using Morya UI components.\n---\n\n# Accessibility\n\nMorya UI favors **semantic HTML first, ARIA when necessary**. Components handle labels, keyboard paths, and overlay focus where possible; apps still must supply meaningful copy and structure.\n\n## Quick checklist\n\n| Scenario | Guidance |\n| --- | --- |\n| Icon-only buttons | Set `aria-label` or visible text—do not rely on icon shape alone |\n| Form fields | Use `label`; on failure use `invalid` + `error-message` |\n| Decorative icons | Omit `label`; the icon is `aria-hidden` |\n| Overlays / dialogs | Ensure Escape closes; focus stays manageable while open |\n| Motion sensitivity | Use `useMotion()` with `reduced` or `none` |\n| Status by color only | Add text, icons, or `error-message` |\n\n## Forms and validation\n\nInput-family components (`Input`, `Textarea`, `Select`, …) share the same field pattern:\n\n```vue\n<MInput\n id=\"email\"\n v-model=\"email\"\n label=\"Email\"\n invalid\n error-message=\"Enter a valid email address\"\n/>\n```\n\nNotes:\n\n- **`label`** wires to the control; `FloatLabel` also sets `for` on the label element.\n- **`invalid`** sets `aria-invalid` and error styling.\n- **`error-message`** is linked through `aria-describedby`.\n- Mark required fields with native `required` when supported **and** validation copy—not color alone.\n\n## Icons and buttons\n\n`MIcon` covers **system icons** only. Without `label` the icon is decorative (`aria-hidden`); informative icons need `label`:\n\n```vue\n<MIcon name=\"info\" label=\"More information\" />\n<MButton icon=\"search\" aria-label=\"Search\" icon-only />\n```\n\nPrefer default slot / `label` text on buttons; avoid duplicating `aria-label` when visible text exists.\n\n## Overlays and focus\n\nThese default to Teleport on `body`, block scroll while open, and close on Escape where applicable:\n\n- `Dialog`, `Drawer`, `CommandMenu`\n- `Select`, `Popover`, `Tooltip` (per component)\n\nTriggers should expose:\n\n- `aria-expanded` / `aria-controls` (e.g. `Popover`)\n- Visible text or `aria-label`\n\nAfter closing a modal, return focus to the trigger when your UX requires it.\n\n## Keyboard\n\n| Component | Keys |\n| --- | --- |\n| `CommandMenu` | `↑`/`↓` move, `Enter` run, `Esc` close |\n| `Select` | `Enter`/`Space` open, `↑`/`↓` options, `Esc` close |\n| `Tabs` | Arrow keys between tabs (see component doc) |\n| `Slider` | Arrow keys adjust value; override naming with `aria-label` |\n\nDocument keyboard tables in component `docs/` when adding new widgets.\n\n## Motion and contrast\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { setMotion } = useMotion()\nsetMotion('reduced') // or 'none'\n```\n\n`reduced` / `none` shortens or disables `--m-motion-*` transitions.\n\nConsume colors through `--m-color-*` tokens for light/dark parity. After theming, spot-check body text and error states on real content.\n\n## In-library improvements\n\nRecent work includes:\n\n- **FloatLabel**: `label[for]` linked to the first input\n- **Popover**: trigger `aria-expanded` / `aria-haspopup` / `aria-controls`\n- **Slider**: default `aria-label` on a single thumb (overridable)\n- **Select / CascadeSelect / TreeSelect / DatePicker**: combobox semantics, keyboard navigation, and field feedback (`invalid` / `error-message` / `help-text`)\n\n## Testing tips\n\n- Complete primary flows with keyboard only (Tab, Enter, Esc, arrows).\n- Spot-check forms and dialogs with NVDA or VoiceOver.\n- Verify usability under `prefers-reduced-motion: reduce` or `useMotion('none')`.\n\n## See also\n\n- [Motion](/docs/motion): intensity, enter/exit presets, and tokens\\n- [Theme](/docs/theme): light/dark and density\n- [Configuration](/docs/config): locale and defaults\n",
27737
+ "markdown": "---\ntitle: Accessibility\norder: 11\ndescription: Accessibility conventions when using Morya UI components.\n---\n\n# Accessibility\n\nMorya UI favors **semantic HTML first, ARIA when necessary**. Components handle labels, keyboard paths, and overlay focus where possible; apps still must supply meaningful copy and structure.\n\n## Quick checklist\n\n| Scenario | Guidance |\n| --- | --- |\n| Icon-only buttons | Set `aria-label` or visible text—do not rely on icon shape alone |\n| Form fields | Use `label`; on failure use `invalid` + `error-message` |\n| Decorative icons | Omit `label`; the icon is `aria-hidden` |\n| Overlays / dialogs | Ensure Escape closes; focus stays manageable while open |\n| Motion sensitivity | Use `useMotion()` with `reduced` or `none` |\n| Status by color only | Add text, icons, or `error-message` |\n\n## Forms and validation\n\nInput-family components (`Input`, `Textarea`, `Select`, …) share the same field pattern:\n\n```vue\n<MInput\n id=\"email\"\n v-model=\"email\"\n label=\"Email\"\n invalid\n error-message=\"Enter a valid email address\"\n/>\n```\n\nNotes:\n\n- **`label`** wires to the control; `FloatLabel` also sets `for` on the label element.\n- **`invalid`** sets `aria-invalid` and error styling.\n- **`error-message`** is linked through `aria-describedby`.\n- Mark required fields with native `required` when supported **and** validation copy—not color alone.\n\n## Icons and buttons\n\n`MIcon` covers **system icons** only. Without `label` the icon is decorative (`aria-hidden`); informative icons need `label`:\n\n```vue\n<MIcon name=\"info\" label=\"More information\" />\n<MButton icon=\"search\" aria-label=\"Search\" icon-only />\n```\n\nPrefer default slot / `label` text on buttons; avoid duplicating `aria-label` when visible text exists.\n\n## Overlays and focus\n\nThese default to Teleport on `body`, block scroll while open, and close on Escape where applicable:\n\n- `Dialog`, `Drawer`, `CommandMenu`\n- `Select`, `Popover`, `Tooltip` (per component)\n\nTriggers should expose:\n\n- `aria-expanded` / `aria-controls` (e.g. `Popover`)\n- Visible text or `aria-label`\n\nAfter closing a modal, return focus to the trigger when your UX requires it.\n\n## Keyboard\n\n| Component | Keys |\n| --- | --- |\n| `CommandMenu` | `↑`/`↓` move, `Enter` run, `Esc` close |\n| `Select` | `Enter`/`Space` open, `↑`/`↓` options, `Esc` close |\n| `Tabs` | Arrow keys between tabs (see component doc) |\n| `Slider` | Arrow keys adjust value; override naming with `aria-label` |\n\nDocument keyboard tables in component `docs/` when adding new widgets.\n\n## Motion and contrast\n\n```ts\nimport { useMotion } from 'morya-ui'\n\nconst { setMotion } = useMotion()\nsetMotion('reduced') // or 'none'\n```\n\n`reduced` / `none` shortens or disables `--m-motion-*` transitions.\n\nConsume colors through `--m-color-*` tokens for light/dark parity. After theming, spot-check body text and error states on real content.\n\n## In-library improvements\n\nRecent work includes:\n\n- **FloatLabel**: `label[for]` linked to the first input\n- **Popover**: trigger `aria-expanded` / `aria-haspopup` / `aria-controls`\n- **Slider**: default `aria-label` on a single thumb (overridable)\n- **Select / CascadeSelect / TreeSelect / DatePicker**: combobox semantics, keyboard navigation, and field feedback (`invalid` / `error-message` / `help-text`)\n\n## Testing tips\n\n- Complete primary flows with keyboard only (Tab, Enter, Esc, arrows).\n- Spot-check forms and dialogs with NVDA or VoiceOver.\n- Verify usability under `useMotion('reduced')` or `useMotion('none')`.\n\n## See also\n\n- [Motion](/docs/motion): intensity, enter/exit presets, and tokens\\n- [Theme](/docs/theme): light/dark and density\n- [Configuration](/docs/config): locale and defaults\n",
27572
27738
  "sections": [
27573
27739
  {
27574
27740
  "title": "",
@@ -27613,7 +27779,7 @@
27613
27779
  {
27614
27780
  "title": "Testing tips",
27615
27781
  "id": "testing-tips",
27616
- "body": "- Complete primary flows with keyboard only (Tab, Enter, Esc, arrows).\n- Spot-check forms and dialogs with NVDA or VoiceOver.\n- Verify usability under `prefers-reduced-motion: reduce` or `useMotion('none')`."
27782
+ "body": "- Complete primary flows with keyboard only (Tab, Enter, Esc, arrows).\n- Spot-check forms and dialogs with NVDA or VoiceOver.\n- Verify usability under `useMotion('reduced')` or `useMotion('none')`."
27617
27783
  },
27618
27784
  {
27619
27785
  "title": "See also",
@@ -27699,7 +27865,7 @@
27699
27865
  "zh-CN": {
27700
27866
  "title": "Agent Skill",
27701
27867
  "description": "消费方 morya-ui-pages skill:何时触发、与 rules/MCP 分工、页面类型地图。",
27702
- "markdown": "---\ntitle: Agent Skill\norder: 13\ndescription: 消费方 morya-ui-pages skill:何时触发、与 rules/MCP 分工、页面类型地图。\n---\n\n# Agent Skill\n\n消费方用 AI 生成 **基于 `morya-ui` 的业务页面** 时,应加载 **`morya-ui-pages`** skill。它规定组件契约、页面类型与工作流;**不是**组件库源码里写新组件用的 skill。\n\n安装方式见 [一键接入](/docs/setup)(`npx @morya-ui/setup` 会复制到项目);AI 侧流程见 [AI 接入](/docs/ai-setup)。本文说明 skill **是什么、何时用、和其它配置怎么分工**。\n\n## 装到哪里\n\n```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # 布局、表面、令牌、反馈、检查清单等\n```\n\n支持 Agent Skills 自动发现的客户端(如 Cursor)会从 `.agents/skills` 读取。生成列表 / 表单 / 登录 / 落地等页面前,应优先匹配本 skill。\n\n源文件在仓库 [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages),随 `@morya-ui/setup` 的 template 同步。可选 companion(`frontend-design`、`fixing-accessibility`)可用 `npx @morya-ui/setup ai --skills=…` 一并写入,见 [一键接入](/docs/setup)。\n\n## 何时触发\n\n典型话术或主题:\n\n- `morya-ui`、`M*` 组件、`--m-*` 令牌、黄金样例\n- 后台 / 列表 / 表单 / 仪表盘 / 详情 / 设置\n- 登录 / 注册 / 空状态 / 向导 / 落地页 / 官网\n\n**优先于**通用 `frontend-design`、Impeccable、UI-UX-Pro-Max 等:那些只能当审美参考;栈是 morya-ui 时以本 skill 为准。\n\n**不要**用于:纯后端、或在本仓库 `src/components` 里新增组件库组件。\n\n## 与其它配置的分工\n\n| 层 | 角色 |\n| --- | --- |\n| [一键接入](/docs/setup) / `@morya-ui/setup` | 一次性把库 + skill + rules + MCP 装进项目 |\n| [AI 接入](/docs/ai-setup) | 装好后如何配合 Agent 生成页面 |\n| **`morya-ui-pages` skill** | 按需工作流:选表面、读黄金样例、组 `M*`、自检 |\n| `.cursor/rules/` | 编辑器常驻短规则(设计系统、组件用法、布局) |\n| `DESIGN.md` | 项目设计第一信源;与 skill 冲突时以项目 `DESIGN.md` 为准 |\n| [Agent MCP](/docs/mcp) | 运行时查真实 Props / Events / 示例,禁止臆造 API |\n\n两层始终生效:\n\n1. **契约** — 只用 `M*` 与 `--m-*`,API 以 MCP / 文档为准 \n2. **工艺** — 先定表面类型,再做视觉;后台偏克制,落地 / 品牌向可有意表达,但仍上令牌、上组件\n\n## 页面类型(Surface)地图\n\n| 车道 | 典型表面 | 优先参考 |\n| --- | --- | --- |\n| **Ops** | 列表、表单、仪表盘、详情、设置、筛选抽屉 | 黄金样例 + skill `page-layouts` |\n| **Account** | 登录、注册、邀请、重置密码、个人资料 | skill `surfaces` § Account |\n| **Flow** | 引导、空状态、向导、成功页 | skill `surfaces` § Flow |\n| **System** | 404、无权限、维护中 | skill `surfaces` § System |\n| **Express** | 营销落地、定价、功能展示 | skill `surfaces` + `visual-craft` |\n| **Overlay** | 以 Dialog / Drawer / CommandMenu 为主界面 | skill `surfaces` § Overlay |\n\n不确定时:后台默认 Ops → 最近黄金样例;对外营销 → Express。\n\n## Agent 推荐工作流(摘要)\n\n1. 钉死主体、受众、表面、第一屏单一任务 \n2. 优先 MCP:`recommend_page` → **`get_golden_page`(镜像)** → `get_component` / `get_example` \n3. 无 MCP 时读 skill `references/`(布局、表面、反馈) \n4. 反馈默认 `message`;`toast` 仅 summary+detail / 异步感。表单常驻错误用字段 `errorMessage` 或 token 样式的 `role=\"alert\"`,不要把 `<MMessage>` 当成内嵌 Alert。表格行数据用 `rows`。交付前默认做一轮 craft(Ops polish / 氛围配方,见 skill `visual-craft`)。 \n5. **必须**跑 MCP `validate_usage`(API 准确)与 `validate_page`(布局/契约建议);对照 skill 检查清单\n\n细节与硬边界以项目内 `SKILL.md` 为准,本文不重复全文。\n\n## 下一步\n\n- [一键接入](/docs/setup):安装 skill 与其它配置 \n- [AI 接入](/docs/ai-setup):用 AI 生成页面时的流程 \n- [Agent MCP](/docs/mcp):工具与客户端配置 \n- [快速上手](/docs/quick-start):手写安装组件库 \n- [组件](/components):浏览 API\n",
27868
+ "markdown": "---\ntitle: Agent Skill\norder: 13\ndescription: 消费方 morya-ui-pages skill:何时触发、与 rules/MCP 分工、页面类型地图。\n---\n\n# Agent Skill\n\n消费方用 AI 生成 **基于 `morya-ui` 的业务页面** 时,应加载 **`morya-ui-pages`** skill。它规定组件契约、页面类型与工作流;**不是**组件库源码里写新组件用的 skill。\n\n安装方式见 [一键接入](/docs/setup)(`npx @morya-ui/setup` 会复制到项目);AI 侧流程见 [AI 接入](/docs/ai-setup)。本文说明 skill **是什么、何时用、和其它配置怎么分工**。\n\n## 装到哪里\n\n```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # 布局、表面、令牌、反馈、检查清单等\n```\n\n支持 Agent Skills 自动发现的客户端(如 Cursor)会从 `.agents/skills` 读取。生成列表 / 表单 / 登录 / 落地等页面前,应优先匹配本 skill。\n\n源文件在仓库 [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages),随 `@morya-ui/setup` 的 template 同步。可选 companion(`frontend-design`、`fixing-accessibility`、`impeccable`)由 setup 通过 skills CLI 安装**最新版**,见 [一键接入](/docs/setup)。\n\n## 何时触发\n\n典型话术或主题:\n\n- `morya-ui`、`M*` 组件、`--m-*` 令牌、黄金样例\n- 后台 / 列表 / 表单 / 仪表盘 / 详情 / 设置\n- 登录 / 注册 / 空状态 / 向导 / 落地页 / 官网\n\n**优先于**通用 `frontend-design`、Impeccable、UI-UX-Pro-Max 等:那些只能当审美参考;栈是 morya-ui 时以本 skill 为准。\n\n**不要**用于:纯后端、或在本仓库 `src/components` 里新增组件库组件。\n\n## 与其它配置的分工\n\n| 层 | 角色 |\n| --- | --- |\n| [一键接入](/docs/setup) / `@morya-ui/setup` | 一次性把库 + skill + rules + MCP 装进项目 |\n| [AI 接入](/docs/ai-setup) | 装好后如何配合 Agent 生成页面 |\n| **`morya-ui-pages` skill** | 按需工作流:选表面、读黄金样例、组 `M*`、自检 |\n| `.cursor/rules/` | 编辑器常驻短规则(设计系统、组件用法、布局) |\n| `DESIGN.md` | 项目设计第一信源;与 skill 冲突时以项目 `DESIGN.md` 为准 |\n| [Agent MCP](/docs/mcp) | 运行时查真实 Props / Events / 示例,禁止臆造 API |\n\n两层始终生效:\n\n1. **契约** — 只用 `M*` 与 `--m-*`,API 以 MCP / 文档为准 \n2. **工艺** — 先定表面类型,再做视觉;后台偏克制,落地 / 品牌向可有意表达,但仍上令牌、上组件\n\n## 页面类型(Surface)地图\n\n| 车道 | 典型表面 | 优先参考 |\n| --- | --- | --- |\n| **Ops** | 列表、表单、仪表盘、详情、设置、筛选抽屉 | 黄金样例 + skill `page-layouts` |\n| **Account** | 登录、注册、邀请、重置密码、个人资料 | skill `surfaces` § Account |\n| **Flow** | 引导、空状态、向导、成功页 | skill `surfaces` § Flow |\n| **System** | 404、无权限、维护中 | skill `surfaces` § System |\n| **Express** | 营销落地、定价、功能展示 | skill `surfaces` + `visual-craft` |\n| **Overlay** | 以 Dialog / Drawer / CommandMenu 为主界面 | skill `surfaces` § Overlay |\n\n不确定时:后台默认 Ops → 最近黄金样例;对外营销 → Express。\n\n## Agent 推荐工作流(摘要)\n\n1. 钉死主体、受众、表面、第一屏单一任务 \n2. 优先 MCP:`recommend_page` → **`get_golden_page`(镜像)** → `get_component` / `get_example` \n3. 无 MCP 时读 skill `references/`(布局、表面、反馈) \n4. 反馈默认 `message`;`toast` 仅 summary+detail / 异步感。表单常驻错误用字段 `errorMessage` 或 token 样式的 `role=\"alert\"`,不要把 `<MMessage>` 当成内嵌 Alert。表格行数据用 `rows`。选型冲突面用 MCP `recommend_component`(返回 recipe),无 MCP 时读 skill `decision-recipes`。交付前默认做一轮 craft(Ops polish / 氛围配方,见 skill `visual-craft`)。 \n5. **必须**跑 MCP `validate_usage`(API 准确)与 `validate_page`(布局/契约建议);对照 skill 检查清单\n\n细节与硬边界以项目内 `SKILL.md` 为准,本文不重复全文。\n\n## 下一步\n\n- [一键接入](/docs/setup):安装 skill 与其它配置 \n- [AI 接入](/docs/ai-setup):用 AI 生成页面时的流程 \n- [Agent MCP](/docs/mcp):工具与客户端配置 \n- [快速上手](/docs/quick-start):手写安装组件库 \n- [组件](/components):浏览 API\n",
27703
27869
  "sections": [
27704
27870
  {
27705
27871
  "title": "",
@@ -27709,7 +27875,7 @@
27709
27875
  {
27710
27876
  "title": "装到哪里",
27711
27877
  "id": "装到哪里",
27712
- "body": "```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # 布局、表面、令牌、反馈、检查清单等\n```\n\n支持 Agent Skills 自动发现的客户端(如 Cursor)会从 `.agents/skills` 读取。生成列表 / 表单 / 登录 / 落地等页面前,应优先匹配本 skill。\n\n源文件在仓库 [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages),随 `@morya-ui/setup` 的 template 同步。可选 companion(`frontend-design`、`fixing-accessibility`)可用 `npx @morya-ui/setup ai --skills=…` 一并写入,见 [一键接入](/docs/setup)。"
27878
+ "body": "```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # 布局、表面、令牌、反馈、检查清单等\n```\n\n支持 Agent Skills 自动发现的客户端(如 Cursor)会从 `.agents/skills` 读取。生成列表 / 表单 / 登录 / 落地等页面前,应优先匹配本 skill。\n\n源文件在仓库 [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages),随 `@morya-ui/setup` 的 template 同步。可选 companion(`frontend-design`、`fixing-accessibility`、`impeccable`)由 setup 通过 skills CLI 安装**最新版**,见 [一键接入](/docs/setup)。"
27713
27879
  },
27714
27880
  {
27715
27881
  "title": "何时触发",
@@ -27729,7 +27895,7 @@
27729
27895
  {
27730
27896
  "title": "Agent 推荐工作流(摘要)",
27731
27897
  "id": "agent-推荐工作流-摘要",
27732
- "body": "1. 钉死主体、受众、表面、第一屏单一任务 \n2. 优先 MCP:`recommend_page` → **`get_golden_page`(镜像)** → `get_component` / `get_example` \n3. 无 MCP 时读 skill `references/`(布局、表面、反馈) \n4. 反馈默认 `message`;`toast` 仅 summary+detail / 异步感。表单常驻错误用字段 `errorMessage` 或 token 样式的 `role=\"alert\"`,不要把 `<MMessage>` 当成内嵌 Alert。表格行数据用 `rows`。交付前默认做一轮 craft(Ops polish / 氛围配方,见 skill `visual-craft`)。 \n5. **必须**跑 MCP `validate_usage`(API 准确)与 `validate_page`(布局/契约建议);对照 skill 检查清单\n\n细节与硬边界以项目内 `SKILL.md` 为准,本文不重复全文。"
27898
+ "body": "1. 钉死主体、受众、表面、第一屏单一任务 \n2. 优先 MCP:`recommend_page` → **`get_golden_page`(镜像)** → `get_component` / `get_example` \n3. 无 MCP 时读 skill `references/`(布局、表面、反馈) \n4. 反馈默认 `message`;`toast` 仅 summary+detail / 异步感。表单常驻错误用字段 `errorMessage` 或 token 样式的 `role=\"alert\"`,不要把 `<MMessage>` 当成内嵌 Alert。表格行数据用 `rows`。选型冲突面用 MCP `recommend_component`(返回 recipe),无 MCP 时读 skill `decision-recipes`。交付前默认做一轮 craft(Ops polish / 氛围配方,见 skill `visual-craft`)。 \n5. **必须**跑 MCP `validate_usage`(API 准确)与 `validate_page`(布局/契约建议);对照 skill 检查清单\n\n细节与硬边界以项目内 `SKILL.md` 为准,本文不重复全文。"
27733
27899
  },
27734
27900
  {
27735
27901
  "title": "下一步",
@@ -27741,7 +27907,7 @@
27741
27907
  "en-US": {
27742
27908
  "title": "Agent Skill",
27743
27909
  "description": "Consumer morya-ui-pages skill — when it triggers, vs rules/MCP, and the surface map.",
27744
- "markdown": "---\ntitle: Agent Skill\norder: 13\ndescription: Consumer morya-ui-pages skill — when it triggers, vs rules/MCP, and the surface map.\n---\n\n# Agent Skill\n\nWhen AI generates **morya-ui consumer pages**, load the **`morya-ui-pages`** skill. It defines the component contract, surface types, and workflow. It is **not** for authoring new components inside the library source.\n\nInstall via [One-shot setup](/docs/setup) (`npx @morya-ui/setup` copies it into the project); AI workflow: [AI setup](/docs/ai-setup). This page explains **what it is, when to use it, and how it relates to other config**.\n\n## Where it lives\n\n```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # layouts, surfaces, tokens, feedback, checklist, …\n```\n\nClients that auto-discover Agent Skills (e.g. Cursor) read `.agents/skills`. Prefer this skill before generating list / form / login / landing pages.\n\nSource: [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages), synced into the `@morya-ui/setup` template. Optional companions (`frontend-design`, `fixing-accessibility`) can be installed with `npx @morya-ui/setup ai --skills=…` — see [One-shot setup](/docs/setup).\n\n## When it triggers\n\nTypical topics:\n\n- `morya-ui`, `M*` components, `--m-*` tokens, golden pages\n- Admin list / form / dashboard / detail / settings\n- Login / register / empty state / wizard / landing / marketing site\n\n**Prefer over** generic `frontend-design`, Impeccable, or UI-UX-Pro-Max when the stack is morya-ui — those may inform taste only.\n\n**Do not** use for backend-only work or for adding components under this repo’s `src/components`.\n\n## How it relates to other config\n\n| Layer | Role |\n| --- | --- |\n| [One-shot setup](/docs/setup) / `@morya-ui/setup` | One-shot install of library + skill + rules + MCP |\n| [AI setup](/docs/ai-setup) | How to use the Agent after install |\n| **`morya-ui-pages` skill** | On-demand workflow: pick surface, golden pages, compose `M*`, review |\n| `.cursor/rules/` | Always-on short editor rules |\n| `DESIGN.md` | Project design source of truth; wins over skill on conflict |\n| [Agent MCP](/docs/mcp) | Runtime lookup of real props / events / examples |\n\nTwo layers always apply:\n\n1. **Contract** — only `M*` and `--m-*`; APIs from MCP / docs \n2. **Craft** — pick the surface first; Ops stays restrained; Express may take intentional aesthetic risk on-token and on-component\n\n## Surface map\n\n| Lane | Surfaces | Prefer |\n| --- | --- | --- |\n| **Ops** | list, form, dashboard, detail, settings, filter drawer | Golden pages + skill `page-layouts` |\n| **Account** | login, register, invite, reset password, profile | skill `surfaces` § Account |\n| **Flow** | onboarding, empty, wizard, success | skill `surfaces` § Flow |\n| **System** | 404, permission denied, maintenance | skill `surfaces` § System |\n| **Express** | marketing landing, pricing, feature showcase | skill `surfaces` + `visual-craft` |\n| **Overlay** | Dialog / Drawer / CommandMenu as the main UI | skill `surfaces` § Overlay |\n\nUnclear brief → Ops → nearest golden page; public marketing → Express.\n\n## Recommended agent workflow (summary)\n\n1. Pin subject, audience, surface, and the first viewport’s single job \n2. Prefer MCP: `recommend_page` → **`get_golden_page` (mirror)** → `get_component` / `get_example` \n3. Without MCP, read skill `references/` (layouts, surfaces, feedback) \n4. Feedback defaults to `message`; `toast` only for summary+detail / async feel. Persistent form errors use field `errorMessage` or a token-styled `role=\"alert\"` — `<MMessage>` is not an inline alert. Table rows use `rows`. Always run a light craft pass before delivery (Ops polish / atmosphere — see skill `visual-craft`). \n5. **Always** run MCP `validate_usage` (API accuracy) and `validate_page` (layout/contract advisories); use the skill checklist \n\nFull rules and hard boundaries live in the project’s `SKILL.md` — this page does not duplicate it.\n\n## Next steps\n\n- [One-shot setup](/docs/setup): install the skill and related config \n- [AI setup](/docs/ai-setup): AI page-generation workflow \n- [Agent MCP](/docs/mcp): tools and client config \n- [Quick start](/docs/quick-start): manual library install \n- [Components](/components): browse APIs\n",
27910
+ "markdown": "---\ntitle: Agent Skill\norder: 13\ndescription: Consumer morya-ui-pages skill — when it triggers, vs rules/MCP, and the surface map.\n---\n\n# Agent Skill\n\nWhen AI generates **morya-ui consumer pages**, load the **`morya-ui-pages`** skill. It defines the component contract, surface types, and workflow. It is **not** for authoring new components inside the library source.\n\nInstall via [One-shot setup](/docs/setup) (`npx @morya-ui/setup` copies it into the project); AI workflow: [AI setup](/docs/ai-setup). This page explains **what it is, when to use it, and how it relates to other config**.\n\n## Where it lives\n\n```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # layouts, surfaces, tokens, feedback, checklist, …\n```\n\nClients that auto-discover Agent Skills (e.g. Cursor) read `.agents/skills`. Prefer this skill before generating list / form / login / landing pages.\n\nSource: [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages), synced into the `@morya-ui/setup` template. Optional companions (`frontend-design`, `fixing-accessibility`, `impeccable`) are installed at **latest** via the skills CLI when selected — see [One-shot setup](/docs/setup).\n\n## When it triggers\n\nTypical topics:\n\n- `morya-ui`, `M*` components, `--m-*` tokens, golden pages\n- Admin list / form / dashboard / detail / settings\n- Login / register / empty state / wizard / landing / marketing site\n\n**Prefer over** generic `frontend-design`, Impeccable, or UI-UX-Pro-Max when the stack is morya-ui — those may inform taste only.\n\n**Do not** use for backend-only work or for adding components under this repo’s `src/components`.\n\n## How it relates to other config\n\n| Layer | Role |\n| --- | --- |\n| [One-shot setup](/docs/setup) / `@morya-ui/setup` | One-shot install of library + skill + rules + MCP |\n| [AI setup](/docs/ai-setup) | How to use the Agent after install |\n| **`morya-ui-pages` skill** | On-demand workflow: pick surface, golden pages, compose `M*`, review |\n| `.cursor/rules/` | Always-on short editor rules |\n| `DESIGN.md` | Project design source of truth; wins over skill on conflict |\n| [Agent MCP](/docs/mcp) | Runtime lookup of real props / events / examples |\n\nTwo layers always apply:\n\n1. **Contract** — only `M*` and `--m-*`; APIs from MCP / docs \n2. **Craft** — pick the surface first; Ops stays restrained; Express may take intentional aesthetic risk on-token and on-component\n\n## Surface map\n\n| Lane | Surfaces | Prefer |\n| --- | --- | --- |\n| **Ops** | list, form, dashboard, detail, settings, filter drawer | Golden pages + skill `page-layouts` |\n| **Account** | login, register, invite, reset password, profile | skill `surfaces` § Account |\n| **Flow** | onboarding, empty, wizard, success | skill `surfaces` § Flow |\n| **System** | 404, permission denied, maintenance | skill `surfaces` § System |\n| **Express** | marketing landing, pricing, feature showcase | skill `surfaces` + `visual-craft` |\n| **Overlay** | Dialog / Drawer / CommandMenu as the main UI | skill `surfaces` § Overlay |\n\nUnclear brief → Ops → nearest golden page; public marketing → Express.\n\n## Recommended agent workflow (summary)\n\n1. Pin subject, audience, surface, and the first viewport’s single job \n2. Prefer MCP: `recommend_page` → **`get_golden_page` (mirror)** → `get_component` / `get_example` \n3. Without MCP, read skill `references/` (layouts, surfaces, feedback) \n4. Feedback defaults to `message`; `toast` only for summary+detail / async feel. Persistent form errors use field `errorMessage` or a token-styled `role=\"alert\"` — `<MMessage>` is not an inline alert. Table rows use `rows`. Always run a light craft pass before delivery (Ops polish / atmosphere — see skill `visual-craft`). \n5. **Always** run MCP `validate_usage` (API accuracy) and `validate_page` (layout/contract advisories); use the skill checklist \n\nFull rules and hard boundaries live in the project’s `SKILL.md` — this page does not duplicate it.\n\n## Next steps\n\n- [One-shot setup](/docs/setup): install the skill and related config \n- [AI setup](/docs/ai-setup): AI page-generation workflow \n- [Agent MCP](/docs/mcp): tools and client config \n- [Quick start](/docs/quick-start): manual library install \n- [Components](/components): browse APIs\n",
27745
27911
  "sections": [
27746
27912
  {
27747
27913
  "title": "",
@@ -27751,7 +27917,7 @@
27751
27917
  {
27752
27918
  "title": "Where it lives",
27753
27919
  "id": "where-it-lives",
27754
- "body": "```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # layouts, surfaces, tokens, feedback, checklist, …\n```\n\nClients that auto-discover Agent Skills (e.g. Cursor) read `.agents/skills`. Prefer this skill before generating list / form / login / landing pages.\n\nSource: [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages), synced into the `@morya-ui/setup` template. Optional companions (`frontend-design`, `fixing-accessibility`) can be installed with `npx @morya-ui/setup ai --skills=…` — see [One-shot setup](/docs/setup)."
27920
+ "body": "```text\n.agents/skills/morya-ui-pages/\n├── SKILL.md\n└── references/ # layouts, surfaces, tokens, feedback, checklist, …\n```\n\nClients that auto-discover Agent Skills (e.g. Cursor) read `.agents/skills`. Prefer this skill before generating list / form / login / landing pages.\n\nSource: [`design-kit/.agents/skills/morya-ui-pages/`](https://github.com/morya-space/morya-ui/tree/main/design-kit/.agents/skills/morya-ui-pages), synced into the `@morya-ui/setup` template. Optional companions (`frontend-design`, `fixing-accessibility`, `impeccable`) are installed at **latest** via the skills CLI when selected — see [One-shot setup](/docs/setup)."
27755
27921
  },
27756
27922
  {
27757
27923
  "title": "When it triggers",