@morya-ui/mcp 0.4.3 → 0.4.5
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 +969 -182
- package/data/example-coverage.json +30 -37
- package/package.json +1 -1
package/data/catalog.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-10-
|
|
2
|
+
"generatedAt": "2026-10-12T07:47:04.752Z",
|
|
3
3
|
"library": {
|
|
4
4
|
"name": "morya-ui",
|
|
5
|
-
"version": "0.4.
|
|
5
|
+
"version": "0.4.5"
|
|
6
6
|
},
|
|
7
7
|
"mcp": {
|
|
8
8
|
"name": "@morya-ui/mcp",
|
|
9
|
-
"version": "0.4.
|
|
9
|
+
"version": "0.4.5"
|
|
10
10
|
},
|
|
11
11
|
"components": [
|
|
12
12
|
{
|
|
@@ -6106,7 +6106,31 @@
|
|
|
6106
6106
|
"name": "shortcuts",
|
|
6107
6107
|
"type": "DatePickerShortcut[]",
|
|
6108
6108
|
"default": "[]",
|
|
6109
|
-
"description": "
|
|
6109
|
+
"description": "面板快捷选项;与当前值匹配时高亮。"
|
|
6110
|
+
},
|
|
6111
|
+
{
|
|
6112
|
+
"name": "status",
|
|
6113
|
+
"type": "'default' | 'warning' | 'error'",
|
|
6114
|
+
"default": "'default'",
|
|
6115
|
+
"description": "视觉警示;`invalid` / `errorMessage` 自动视为 `error`。"
|
|
6116
|
+
},
|
|
6117
|
+
{
|
|
6118
|
+
"name": "needConfirm",
|
|
6119
|
+
"type": "boolean",
|
|
6120
|
+
"default": "false",
|
|
6121
|
+
"description": "选择后仅写入 draft,按「确认」提交、「取消」回滚。"
|
|
6122
|
+
},
|
|
6123
|
+
{
|
|
6124
|
+
"name": "multiple",
|
|
6125
|
+
"type": "boolean",
|
|
6126
|
+
"default": "false",
|
|
6127
|
+
"description": "多选日期(仅 `type='date'`);`modelValue` 为 `string[]`。"
|
|
6128
|
+
},
|
|
6129
|
+
{
|
|
6130
|
+
"name": "mask",
|
|
6131
|
+
"type": "boolean",
|
|
6132
|
+
"default": "false",
|
|
6133
|
+
"description": "输入框可编辑,按 `format` 自动补分隔符;Enter 提交,Esc/失焦回滚。"
|
|
6110
6134
|
},
|
|
6111
6135
|
{
|
|
6112
6136
|
"name": "fluid",
|
|
@@ -6206,6 +6230,14 @@
|
|
|
6206
6230
|
{
|
|
6207
6231
|
"name": "trigger",
|
|
6208
6232
|
"description": "自定义触发器 `{ value, open }`。"
|
|
6233
|
+
},
|
|
6234
|
+
{
|
|
6235
|
+
"name": "footer",
|
|
6236
|
+
"description": "面板底部自定义操作区,作用域 `{ close }`。`need-confirm` 时若未提供则显示默认「取消/确认」。"
|
|
6237
|
+
},
|
|
6238
|
+
{
|
|
6239
|
+
"name": "cell",
|
|
6240
|
+
"description": "自定义日期单元格,作用域 `{ date, inMonth, selected, inRange, rangeStart, rangeEnd, isToday, disabled }`。"
|
|
6209
6241
|
}
|
|
6210
6242
|
],
|
|
6211
6243
|
"methods": [],
|
|
@@ -6309,6 +6341,123 @@
|
|
|
6309
6341
|
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst value = ref<string | null>(null)\nconst shortcuts = [\n { label: '今天', value: () => new Date() },\n { label: '六月一日', value: '2024-06-01' },\n]\n</script>\n\n<template>\n <MDatePicker v-model=\"value\" label=\"快捷选项\" :shortcuts=\"shortcuts\" />\n</template>",
|
|
6310
6342
|
"locale": "zh-CN"
|
|
6311
6343
|
},
|
|
6344
|
+
{
|
|
6345
|
+
"id": "范围快捷键-1",
|
|
6346
|
+
"section": "范围快捷键",
|
|
6347
|
+
"sectionId": "范围快捷键",
|
|
6348
|
+
"lang": "vue",
|
|
6349
|
+
"preview": true,
|
|
6350
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst recent = ref<[string, string] | null>(null)\nconst month = ref<[string, string] | null>(null)\n\nfunction iso(date: Date) {\n const y = date.getFullYear()\n const m = String(date.getMonth() + 1).padStart(2, '0')\n const d = String(date.getDate()).padStart(2, '0')\n return `${y}-${m}-${d}`\n}\n\nfunction daysAgo(n: number) {\n const d = new Date()\n d.setDate(d.getDate() - n)\n return d\n}\n\nconst recentShortcuts = [\n { label: '最近 7 天', value: () => [iso(daysAgo(6)), iso(new Date())] as [string, string] },\n { label: '最近 30 天', value: () => [iso(daysAgo(29)), iso(new Date())] as [string, string] },\n { label: '最近 90 天', value: () => [iso(daysAgo(89)), iso(new Date())] as [string, string] },\n]\n\nconst monthShortcuts = [\n {\n label: '本月',\n value: () => {\n const now = new Date()\n const start = new Date(now.getFullYear(), now.getMonth(), 1)\n return [iso(start), iso(now)] as [string, string]\n },\n },\n {\n label: '上月',\n value: () => {\n const now = new Date()\n const start = new Date(now.getFullYear(), now.getMonth() - 1, 1)\n const end = new Date(now.getFullYear(), now.getMonth(), 0)\n return [iso(start), iso(end)] as [string, string]\n },\n },\n {\n label: '今年',\n value: () => {\n const now = new Date()\n return [`${now.getFullYear()}-01-01`, iso(now)] as [string, string]\n },\n },\n]\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px; max-width: 32rem\">\n <MDatePicker\n v-model=\"recent\"\n type=\"daterange\"\n label=\"最近 N 天\"\n :shortcuts=\"recentShortcuts\"\n help-text=\"匹配当前值的快捷键会高亮\"\n />\n <MDatePicker\n v-model=\"month\"\n type=\"daterange\"\n label=\"按月 / 按年\"\n :shortcuts=\"monthShortcuts\"\n />\n </div>\n</template>",
|
|
6351
|
+
"locale": "zh-CN"
|
|
6352
|
+
},
|
|
6353
|
+
{
|
|
6354
|
+
"id": "自定义格式-1",
|
|
6355
|
+
"section": "自定义格式",
|
|
6356
|
+
"sectionId": "自定义格式",
|
|
6357
|
+
"lang": "vue",
|
|
6358
|
+
"preview": true,
|
|
6359
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst isoDate = ref<string | null>('2024-06-15')\nconst slashDate = ref<string | null>('2024-06-15')\nconst chineseDate = ref<string | null>('2024-06-15')\nconst time12 = ref<string | null>('2024-06-15 14:30')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px; max-width: 32rem\">\n <MDatePicker v-model=\"isoDate\" label=\"默认 ISO(YYYY-MM-DD)\" />\n <MDatePicker v-model=\"slashDate\" label=\"斜杠格式(YYYY/MM/DD)\" format=\"YYYY/MM/DD\" />\n <MDatePicker v-model=\"chineseDate\" label=\"中文格式(YYYY年MM月DD日)\" format=\"YYYY年MM月DD日\" />\n <MDatePicker\n v-model=\"time12\"\n type=\"datetime\"\n label=\"日期时间带斜杠(YYYY/MM/DD HH:mm)\"\n format=\"YYYY/MM/DD\"\n />\n </div>\n</template>",
|
|
6360
|
+
"locale": "zh-CN"
|
|
6361
|
+
},
|
|
6362
|
+
{
|
|
6363
|
+
"id": "日期时间-1",
|
|
6364
|
+
"section": "日期时间",
|
|
6365
|
+
"sectionId": "日期时间",
|
|
6366
|
+
"lang": "vue",
|
|
6367
|
+
"preview": true,
|
|
6368
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst datetime = ref<string | null>('2024-06-15 14:30')\nconst datetimeSec = ref<string | null>('2024-06-15 14:30:45')\nconst range = ref<[string, string] | null>(null)\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px; max-width: 32rem\">\n <MDatePicker\n v-model=\"datetime\"\n type=\"datetime\"\n label=\"日期时间(分钟)\"\n help-text=\"点击日期后再选时间,配合 need-confirm 体验更佳\"\n />\n <MDatePicker\n v-model=\"datetimeSec\"\n type=\"datetime\"\n label=\"日期时间(含秒)\"\n show-seconds\n need-confirm\n />\n <MDatePicker\n v-model=\"range\"\n type=\"datetimerange\"\n label=\"日期时间范围\"\n need-confirm\n help-text=\"两次点击选定日期,再用时间列调整起止时刻\"\n />\n </div>\n</template>",
|
|
6369
|
+
"locale": "zh-CN"
|
|
6370
|
+
},
|
|
6371
|
+
{
|
|
6372
|
+
"id": "自定义触发器-1",
|
|
6373
|
+
"section": "自定义触发器",
|
|
6374
|
+
"sectionId": "自定义触发器",
|
|
6375
|
+
"lang": "vue",
|
|
6376
|
+
"preview": true,
|
|
6377
|
+
"code": "<script setup lang=\"ts\">\nimport { MButton, MDatePicker, MIcon } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst date1 = ref<string | null>('2024-06-15')\nconst date2 = ref<string | null>(null)\n</script>\n\n<template>\n <div style=\"display: grid; gap: 16px; max-width: 32rem\">\n <MDatePicker v-model=\"date1\" label=\"按钮触发器\">\n <template #trigger=\"{ value }\">\n <MButton type=\"default\" size=\"small\">\n <MIcon name=\"calendar\" size=\"sm\" style=\"margin-right: 4px\" />\n {{ value || '选择日期' }}\n </MButton>\n </template>\n </MDatePicker>\n\n <MDatePicker v-model=\"date2\" label=\"纯图标触发器\">\n <template #trigger=\"{ value }\">\n <button\n type=\"button\"\n style=\"display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border: 1px solid var(--m-color-border); border-radius: var(--m-radius-control); background: var(--m-color-surface); cursor: pointer\"\n >\n <MIcon name=\"calendar\" size=\"sm\" />\n <span v-if=\"value\">{{ value }}</span>\n <span v-else style=\"color: var(--m-color-text-muted)\">未选择</span>\n </button>\n </template>\n </MDatePicker>\n </div>\n</template>",
|
|
6378
|
+
"locale": "zh-CN"
|
|
6379
|
+
},
|
|
6380
|
+
{
|
|
6381
|
+
"id": "禁用区间-1",
|
|
6382
|
+
"section": "禁用区间",
|
|
6383
|
+
"sectionId": "禁用区间",
|
|
6384
|
+
"lang": "vue",
|
|
6385
|
+
"preview": true,
|
|
6386
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { computed, ref } from 'vue'\n\nconst weekdayOnly = ref<string | null>(null)\nconst futureOnly = ref<string | null>(null)\nconst next30 = ref<string | null>(null)\n\nfunction iso(date: Date) {\n const y = date.getFullYear()\n const m = String(date.getMonth() + 1).padStart(2, '0')\n const d = String(date.getDate()).padStart(2, '0')\n return `${y}-${m}-${d}`\n}\n\nconst today = computed(() => iso(new Date()))\nconst in30Days = computed(() => {\n const d = new Date()\n d.setDate(d.getDate() + 30)\n return iso(d)\n})\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px; max-width: 32rem\">\n <MDatePicker\n v-model=\"weekdayOnly\"\n label=\"只能选今天之前\"\n :max-date=\"today\"\n help-text=\"max-date = 今天\"\n />\n <MDatePicker\n v-model=\"futureOnly\"\n label=\"只能选未来日期\"\n :min-date=\"today\"\n help-text=\"min-date = 今天\"\n />\n <MDatePicker\n v-model=\"next30\"\n label=\"只能选未来 30 天内\"\n :min-date=\"today\"\n :max-date=\"in30Days\"\n help-text=\"min-date 与 max-date 组合\"\n />\n </div>\n</template>",
|
|
6387
|
+
"locale": "zh-CN"
|
|
6388
|
+
},
|
|
6389
|
+
{
|
|
6390
|
+
"id": "内联面板-1",
|
|
6391
|
+
"section": "内联面板",
|
|
6392
|
+
"sectionId": "内联面板",
|
|
6393
|
+
"lang": "vue",
|
|
6394
|
+
"preview": true,
|
|
6395
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst date = ref<string | null>('2024-06-15')\n</script>\n\n<template>\n <div style=\"max-width: 32rem\">\n <p style=\"margin: 0 0 8px; color: var(--m-color-text-muted); font-size: 13px\">\n 使用 <code>:teleport=\"false\"</code> + <code>append-to=\"self\"</code> 让面板就地渲染,适合嵌入卡片或自定义布局。\n </p>\n <div style=\"border: 1px solid var(--m-color-border); border-radius: 8px; padding: 16px; background: var(--m-color-surface)\">\n <MDatePicker v-model=\"date\" label=\"内联面板\" :teleport=\"false\" append-to=\"self\" />\n </div>\n </div>\n</template>",
|
|
6396
|
+
"locale": "zh-CN"
|
|
6397
|
+
},
|
|
6398
|
+
{
|
|
6399
|
+
"id": "状态-status-1",
|
|
6400
|
+
"section": "状态(status)",
|
|
6401
|
+
"sectionId": "状态-status",
|
|
6402
|
+
"lang": "vue",
|
|
6403
|
+
"preview": true,
|
|
6404
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst warning = ref<string | null>('2024-06-15')\nconst error = ref<string | null>('2024-06-20')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px\">\n <MDatePicker v-model=\"warning\" label=\"Warning 状态\" status=\"warning\" help-text=\"这是一个温馨提示\" />\n <MDatePicker v-model=\"error\" label=\"Error 状态\" status=\"error\" help-text=\"字段存在错误\" />\n </div>\n</template>",
|
|
6405
|
+
"locale": "zh-CN"
|
|
6406
|
+
},
|
|
6407
|
+
{
|
|
6408
|
+
"id": "页脚与自定义单元格-1",
|
|
6409
|
+
"section": "页脚与自定义单元格",
|
|
6410
|
+
"sectionId": "页脚与自定义单元格",
|
|
6411
|
+
"lang": "vue",
|
|
6412
|
+
"preview": true,
|
|
6413
|
+
"code": "<script setup lang=\"ts\">\nimport { MButton, MDatePicker, MTag } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst value = ref<string | null>('2024-06-15')\n\nconst holidays = new Set(['2024-06-10', '2024-06-17'])\n\nfunction pad(n: number) {\n return String(n).padStart(2, '0')\n}\nfunction iso(date: Date) {\n return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`\n}\nfunction today(): string {\n return iso(new Date())\n}\n</script>\n\n<template>\n <MDatePicker v-model=\"value\" label=\"带页脚与自定义单元格\">\n <template #cell=\"{ date }\">\n <span style=\"position: relative\">\n {{ date.getDate() }}\n <span\n v-if=\"holidays.has(iso(date))\"\n style=\"position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%); width: 4px; height: 4px; border-radius: 50%; background: var(--m-color-primary)\"\n />\n </span>\n </template>\n <template #footer=\"{ close }\">\n <MTag value=\"演示:圆点 = 节假日\" type=\"secondary\" />\n <MButton size=\"small\" @click=\"value = today(); close()\">今天</MButton>\n </template>\n </MDatePicker>\n</template>",
|
|
6414
|
+
"locale": "zh-CN"
|
|
6415
|
+
},
|
|
6416
|
+
{
|
|
6417
|
+
"id": "needconfirm-确认提交-1",
|
|
6418
|
+
"section": "needConfirm 确认提交",
|
|
6419
|
+
"sectionId": "needconfirm-确认提交",
|
|
6420
|
+
"lang": "vue",
|
|
6421
|
+
"preview": true,
|
|
6422
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst datetime = ref<string | null>('2024-06-15 14:30')\nconst time = ref<string | null>('09:15')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px\">\n <MDatePicker v-model=\"datetime\" type=\"datetime\" label=\"日期时间(需确认)\" need-confirm />\n <MDatePicker v-model=\"time\" type=\"time\" label=\"时间(需确认)\" need-confirm />\n </div>\n</template>",
|
|
6423
|
+
"locale": "zh-CN"
|
|
6424
|
+
},
|
|
6425
|
+
{
|
|
6426
|
+
"id": "多选日期-1",
|
|
6427
|
+
"section": "多选日期",
|
|
6428
|
+
"sectionId": "多选日期",
|
|
6429
|
+
"lang": "vue",
|
|
6430
|
+
"preview": true,
|
|
6431
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst dates = ref<string[]>(['2024-06-10', '2024-06-15'])\n</script>\n\n<template>\n <MDatePicker v-model=\"dates\" label=\"多选日期\" multiple />\n</template>",
|
|
6432
|
+
"locale": "zh-CN"
|
|
6433
|
+
},
|
|
6434
|
+
{
|
|
6435
|
+
"id": "多选实战-排班-1",
|
|
6436
|
+
"section": "多选实战:排班",
|
|
6437
|
+
"sectionId": "多选实战-排班",
|
|
6438
|
+
"lang": "vue",
|
|
6439
|
+
"preview": true,
|
|
6440
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker, MTag } from 'morya-ui'\nimport { computed, ref } from 'vue'\n\nconst selectedDates = ref<string[]>([])\n\nconst sorted = computed(() =>\n [...selectedDates.value].sort((a, b) => (a < b ? -1 : 1)),\n)\n\nconst weekdayMap = ['日', '一', '二', '三', '四', '五', '六']\nfunction formatDay(iso: string) {\n const d = new Date(iso)\n return `${iso.slice(5)} 周${weekdayMap[d.getDay()]}`\n}\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px; max-width: 32rem\">\n <MDatePicker\n v-model=\"selectedDates\"\n label=\"选择排班日期\"\n multiple\n help-text=\"点击切换选中;可跨月选择多天\"\n />\n <div v-if=\"sorted.length\" style=\"display: flex; flex-wrap: wrap; gap: 6px\">\n <MTag v-for=\"iso in sorted\" :key=\"iso\" :value=\"formatDay(iso)\" type=\"primary\" />\n </div>\n <p v-else style=\"color: var(--m-color-text-muted); font-size: 13px; margin: 0\">\n 尚未选择任何日期\n </p>\n </div>\n</template>",
|
|
6441
|
+
"locale": "zh-CN"
|
|
6442
|
+
},
|
|
6443
|
+
{
|
|
6444
|
+
"id": "表单集成-1",
|
|
6445
|
+
"section": "表单集成",
|
|
6446
|
+
"sectionId": "表单集成",
|
|
6447
|
+
"lang": "vue",
|
|
6448
|
+
"preview": true,
|
|
6449
|
+
"code": "<script setup lang=\"ts\">\nimport { MButton, MDatePicker } from 'morya-ui'\nimport { reactive, ref } from 'vue'\n\nconst form = reactive({\n name: '',\n startDate: null as string | null,\n endDate: null as string | null,\n})\n\nconst submitted = ref<string | null>(null)\n\nfunction iso(date: Date) {\n const y = date.getFullYear()\n const m = String(date.getMonth() + 1).padStart(2, '0')\n const d = String(date.getDate()).padStart(2, '0')\n return `${y}-${m}-${d}`\n}\nconst today = iso(new Date())\n\nconst startError = ref('')\nconst endError = ref('')\n\nfunction submit() {\n startError.value = form.startDate ? '' : '请选择开始日期'\n endError.value = form.endDate ? '' : '请选择结束日期'\n if (form.startDate && form.endDate && form.endDate < form.startDate) {\n endError.value = '结束日期不能早于开始日期'\n }\n if (startError.value || endError.value) return\n submitted.value = JSON.stringify(form, null, 2)\n}\n</script>\n\n<template>\n <form style=\"display: grid; gap: 12px; max-width: 32rem\" @submit.prevent=\"submit\">\n <MDatePicker\n v-model=\"form.startDate\"\n label=\"开始日期\"\n required\n :min-date=\"today\"\n :error-message=\"startError\"\n />\n <MDatePicker\n v-model=\"form.endDate\"\n label=\"结束日期\"\n required\n :min-date=\"form.startDate ?? today\"\n :error-message=\"endError\"\n />\n <div>\n <MButton type=\"primary\" html-type=\"submit\">提交</MButton>\n </div>\n <pre v-if=\"submitted\" style=\"background: var(--m-color-surface-sunken); padding: 8px; border-radius: 4px; font-size: 12px\">{{ submitted }}</pre>\n </form>\n</template>",
|
|
6450
|
+
"locale": "zh-CN"
|
|
6451
|
+
},
|
|
6452
|
+
{
|
|
6453
|
+
"id": "输入掩码-1",
|
|
6454
|
+
"section": "输入掩码",
|
|
6455
|
+
"sectionId": "输入掩码",
|
|
6456
|
+
"lang": "vue",
|
|
6457
|
+
"preview": true,
|
|
6458
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst date = ref<string | null>('2024-06-15')\nconst datetime = ref<string | null>('2024-06-15 14:30')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px\">\n <MDatePicker v-model=\"date\" label=\"输入掩码(date)\" mask />\n <MDatePicker v-model=\"datetime\" type=\"datetime\" label=\"输入掩码(datetime)\" mask />\n </div>\n</template>",
|
|
6459
|
+
"locale": "zh-CN"
|
|
6460
|
+
},
|
|
6312
6461
|
{
|
|
6313
6462
|
"id": "类型-1",
|
|
6314
6463
|
"section": "类型",
|
|
@@ -6417,6 +6566,123 @@
|
|
|
6417
6566
|
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst value = ref<string | null>(null)\nconst shortcuts = [\n { label: 'Today', value: () => new Date() },\n { label: 'June 1', value: '2024-06-01' },\n]\n</script>\n\n<template>\n <MDatePicker v-model=\"value\" label=\"Shortcuts\" :shortcuts=\"shortcuts\" />\n</template>",
|
|
6418
6567
|
"locale": "en-US"
|
|
6419
6568
|
},
|
|
6569
|
+
{
|
|
6570
|
+
"id": "range-shortcuts-1",
|
|
6571
|
+
"section": "Range Shortcuts",
|
|
6572
|
+
"sectionId": "range-shortcuts",
|
|
6573
|
+
"lang": "vue",
|
|
6574
|
+
"preview": true,
|
|
6575
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst recent = ref<[string, string] | null>(null)\nconst month = ref<[string, string] | null>(null)\n\nfunction iso(date: Date) {\n const y = date.getFullYear()\n const m = String(date.getMonth() + 1).padStart(2, '0')\n const d = String(date.getDate()).padStart(2, '0')\n return `${y}-${m}-${d}`\n}\n\nfunction daysAgo(n: number) {\n const d = new Date()\n d.setDate(d.getDate() - n)\n return d\n}\n\nconst recentShortcuts = [\n { label: 'Last 7 days', value: () => [iso(daysAgo(6)), iso(new Date())] as [string, string] },\n { label: 'Last 30 days', value: () => [iso(daysAgo(29)), iso(new Date())] as [string, string] },\n { label: 'Last 90 days', value: () => [iso(daysAgo(89)), iso(new Date())] as [string, string] },\n]\n\nconst monthShortcuts = [\n {\n label: 'This month',\n value: () => {\n const now = new Date()\n const start = new Date(now.getFullYear(), now.getMonth(), 1)\n return [iso(start), iso(now)] as [string, string]\n },\n },\n {\n label: 'Last month',\n value: () => {\n const now = new Date()\n const start = new Date(now.getFullYear(), now.getMonth() - 1, 1)\n const end = new Date(now.getFullYear(), now.getMonth(), 0)\n return [iso(start), iso(end)] as [string, string]\n },\n },\n {\n label: 'Year to date',\n value: () => {\n const now = new Date()\n return [`${now.getFullYear()}-01-01`, iso(now)] as [string, string]\n },\n },\n]\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px; max-width: 32rem\">\n <MDatePicker\n v-model=\"recent\"\n type=\"daterange\"\n label=\"Recent N days\"\n :shortcuts=\"recentShortcuts\"\n help-text=\"Shortcuts matching the current value get highlighted\"\n />\n <MDatePicker\n v-model=\"month\"\n type=\"daterange\"\n label=\"By month / year\"\n :shortcuts=\"monthShortcuts\"\n />\n </div>\n</template>",
|
|
6576
|
+
"locale": "en-US"
|
|
6577
|
+
},
|
|
6578
|
+
{
|
|
6579
|
+
"id": "custom-format-1",
|
|
6580
|
+
"section": "Custom Format",
|
|
6581
|
+
"sectionId": "custom-format",
|
|
6582
|
+
"lang": "vue",
|
|
6583
|
+
"preview": true,
|
|
6584
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst isoDate = ref<string | null>('2024-06-15')\nconst slashDate = ref<string | null>('2024-06-15')\nconst usDate = ref<string | null>('2024-06-15')\nconst time = ref<string | null>('2024-06-15 14:30')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px; max-width: 32rem\">\n <MDatePicker v-model=\"isoDate\" label=\"Default ISO (YYYY-MM-DD)\" />\n <MDatePicker v-model=\"slashDate\" label=\"Slash (YYYY/MM/DD)\" format=\"YYYY/MM/DD\" />\n <MDatePicker v-model=\"usDate\" label=\"US style (MM/DD/YYYY)\" format=\"MM/DD/YYYY\" />\n <MDatePicker\n v-model=\"time\"\n type=\"datetime\"\n label=\"Datetime with slash (YYYY/MM/DD HH:mm)\"\n format=\"YYYY/MM/DD\"\n />\n </div>\n</template>",
|
|
6585
|
+
"locale": "en-US"
|
|
6586
|
+
},
|
|
6587
|
+
{
|
|
6588
|
+
"id": "datetime-1",
|
|
6589
|
+
"section": "Datetime",
|
|
6590
|
+
"sectionId": "datetime",
|
|
6591
|
+
"lang": "vue",
|
|
6592
|
+
"preview": true,
|
|
6593
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst datetime = ref<string | null>('2024-06-15 14:30')\nconst datetimeSec = ref<string | null>('2024-06-15 14:30:45')\nconst range = ref<[string, string] | null>(null)\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px; max-width: 32rem\">\n <MDatePicker\n v-model=\"datetime\"\n type=\"datetime\"\n label=\"Datetime (minute)\"\n help-text=\"Pick a date, then time; pair with need-confirm for a smoother flow\"\n />\n <MDatePicker\n v-model=\"datetimeSec\"\n type=\"datetime\"\n label=\"Datetime (with seconds)\"\n show-seconds\n need-confirm\n />\n <MDatePicker\n v-model=\"range\"\n type=\"datetimerange\"\n label=\"Datetime range\"\n need-confirm\n help-text=\"Pick two dates, then adjust start / end time in the time columns\"\n />\n </div>\n</template>",
|
|
6594
|
+
"locale": "en-US"
|
|
6595
|
+
},
|
|
6596
|
+
{
|
|
6597
|
+
"id": "custom-trigger-1",
|
|
6598
|
+
"section": "Custom Trigger",
|
|
6599
|
+
"sectionId": "custom-trigger",
|
|
6600
|
+
"lang": "vue",
|
|
6601
|
+
"preview": true,
|
|
6602
|
+
"code": "<script setup lang=\"ts\">\nimport { MButton, MDatePicker, MIcon } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst date1 = ref<string | null>('2024-06-15')\nconst date2 = ref<string | null>(null)\n</script>\n\n<template>\n <div style=\"display: grid; gap: 16px; max-width: 32rem\">\n <MDatePicker v-model=\"date1\" label=\"Button trigger\">\n <template #trigger=\"{ value }\">\n <MButton type=\"default\" size=\"small\">\n <MIcon name=\"calendar\" size=\"sm\" style=\"margin-right: 4px\" />\n {{ value || 'Pick a date' }}\n </MButton>\n </template>\n </MDatePicker>\n\n <MDatePicker v-model=\"date2\" label=\"Icon trigger\">\n <template #trigger=\"{ value }\">\n <button\n type=\"button\"\n style=\"display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border: 1px solid var(--m-color-border); border-radius: var(--m-radius-control); background: var(--m-color-surface); cursor: pointer\"\n >\n <MIcon name=\"calendar\" size=\"sm\" />\n <span v-if=\"value\">{{ value }}</span>\n <span v-else style=\"color: var(--m-color-text-muted)\">Not set</span>\n </button>\n </template>\n </MDatePicker>\n </div>\n</template>",
|
|
6603
|
+
"locale": "en-US"
|
|
6604
|
+
},
|
|
6605
|
+
{
|
|
6606
|
+
"id": "disabled-ranges-1",
|
|
6607
|
+
"section": "Disabled Ranges",
|
|
6608
|
+
"sectionId": "disabled-ranges",
|
|
6609
|
+
"lang": "vue",
|
|
6610
|
+
"preview": true,
|
|
6611
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { computed, ref } from 'vue'\n\nconst pastOnly = ref<string | null>(null)\nconst futureOnly = ref<string | null>(null)\nconst next30 = ref<string | null>(null)\n\nfunction iso(date: Date) {\n const y = date.getFullYear()\n const m = String(date.getMonth() + 1).padStart(2, '0')\n const d = String(date.getDate()).padStart(2, '0')\n return `${y}-${m}-${d}`\n}\n\nconst today = computed(() => iso(new Date()))\nconst in30Days = computed(() => {\n const d = new Date()\n d.setDate(d.getDate() + 30)\n return iso(d)\n})\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px; max-width: 32rem\">\n <MDatePicker\n v-model=\"pastOnly\"\n label=\"Past dates only\"\n :max-date=\"today\"\n help-text=\"max-date = today\"\n />\n <MDatePicker\n v-model=\"futureOnly\"\n label=\"Future dates only\"\n :min-date=\"today\"\n help-text=\"min-date = today\"\n />\n <MDatePicker\n v-model=\"next30\"\n label=\"Within next 30 days\"\n :min-date=\"today\"\n :max-date=\"in30Days\"\n help-text=\"min-date + max-date combined\"\n />\n </div>\n</template>",
|
|
6612
|
+
"locale": "en-US"
|
|
6613
|
+
},
|
|
6614
|
+
{
|
|
6615
|
+
"id": "inline-panel-1",
|
|
6616
|
+
"section": "Inline Panel",
|
|
6617
|
+
"sectionId": "inline-panel",
|
|
6618
|
+
"lang": "vue",
|
|
6619
|
+
"preview": true,
|
|
6620
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst date = ref<string | null>('2024-06-15')\n</script>\n\n<template>\n <div style=\"max-width: 32rem\">\n <p style=\"margin: 0 0 8px; color: var(--m-color-text-muted); font-size: 13px\">\n Use <code>:teleport=\"false\"</code> with <code>append-to=\"self\"</code> to render the panel inline — useful inside cards or custom layouts.\n </p>\n <div style=\"border: 1px solid var(--m-color-border); border-radius: 8px; padding: 16px; background: var(--m-color-surface)\">\n <MDatePicker v-model=\"date\" label=\"Inline panel\" :teleport=\"false\" append-to=\"self\" />\n </div>\n </div>\n</template>",
|
|
6621
|
+
"locale": "en-US"
|
|
6622
|
+
},
|
|
6623
|
+
{
|
|
6624
|
+
"id": "status-1",
|
|
6625
|
+
"section": "Status",
|
|
6626
|
+
"sectionId": "status",
|
|
6627
|
+
"lang": "vue",
|
|
6628
|
+
"preview": true,
|
|
6629
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst warning = ref<string | null>('2024-06-15')\nconst error = ref<string | null>('2024-06-20')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px\">\n <MDatePicker v-model=\"warning\" label=\"Warning status\" status=\"warning\" help-text=\"A friendly reminder\" />\n <MDatePicker v-model=\"error\" label=\"Error status\" status=\"error\" help-text=\"Something is wrong\" />\n </div>\n</template>",
|
|
6630
|
+
"locale": "en-US"
|
|
6631
|
+
},
|
|
6632
|
+
{
|
|
6633
|
+
"id": "footer-custom-cell-1",
|
|
6634
|
+
"section": "Footer & Custom Cell",
|
|
6635
|
+
"sectionId": "footer-custom-cell",
|
|
6636
|
+
"lang": "vue",
|
|
6637
|
+
"preview": true,
|
|
6638
|
+
"code": "<script setup lang=\"ts\">\nimport { MButton, MDatePicker, MTag } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst value = ref<string | null>('2024-06-15')\n\nconst holidays = new Set(['2024-06-10', '2024-06-17'])\n\nfunction pad(n: number) {\n return String(n).padStart(2, '0')\n}\nfunction iso(date: Date) {\n return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`\n}\nfunction today(): string {\n return iso(new Date())\n}\n</script>\n\n<template>\n <MDatePicker v-model=\"value\" label=\"Footer + custom cell\">\n <template #cell=\"{ date }\">\n <span style=\"position: relative\">\n {{ date.getDate() }}\n <span\n v-if=\"holidays.has(iso(date))\"\n style=\"position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%); width: 4px; height: 4px; border-radius: 50%; background: var(--m-color-primary)\"\n />\n </span>\n </template>\n <template #footer=\"{ close }\">\n <MTag value=\"Dot = holiday\" type=\"secondary\" />\n <MButton size=\"small\" @click=\"value = today(); close()\">Today</MButton>\n </template>\n </MDatePicker>\n</template>",
|
|
6639
|
+
"locale": "en-US"
|
|
6640
|
+
},
|
|
6641
|
+
{
|
|
6642
|
+
"id": "needconfirm-1",
|
|
6643
|
+
"section": "needConfirm",
|
|
6644
|
+
"sectionId": "needconfirm",
|
|
6645
|
+
"lang": "vue",
|
|
6646
|
+
"preview": true,
|
|
6647
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst datetime = ref<string | null>('2024-06-15 14:30')\nconst time = ref<string | null>('09:15')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px\">\n <MDatePicker v-model=\"datetime\" type=\"datetime\" label=\"Datetime (need confirm)\" need-confirm />\n <MDatePicker v-model=\"time\" type=\"time\" label=\"Time (need confirm)\" need-confirm />\n </div>\n</template>",
|
|
6648
|
+
"locale": "en-US"
|
|
6649
|
+
},
|
|
6650
|
+
{
|
|
6651
|
+
"id": "multiple-dates-1",
|
|
6652
|
+
"section": "Multiple Dates",
|
|
6653
|
+
"sectionId": "multiple-dates",
|
|
6654
|
+
"lang": "vue",
|
|
6655
|
+
"preview": true,
|
|
6656
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst dates = ref<string[]>(['2024-06-10', '2024-06-15'])\n</script>\n\n<template>\n <MDatePicker v-model=\"dates\" label=\"Multiple dates\" multiple />\n</template>",
|
|
6657
|
+
"locale": "en-US"
|
|
6658
|
+
},
|
|
6659
|
+
{
|
|
6660
|
+
"id": "multiple-in-practice-shift-planning-1",
|
|
6661
|
+
"section": "Multiple in Practice: Shift Planning",
|
|
6662
|
+
"sectionId": "multiple-in-practice-shift-planning",
|
|
6663
|
+
"lang": "vue",
|
|
6664
|
+
"preview": true,
|
|
6665
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker, MTag } from 'morya-ui'\nimport { computed, ref } from 'vue'\n\nconst selectedDates = ref<string[]>([])\n\nconst sorted = computed(() =>\n [...selectedDates.value].sort((a, b) => (a < b ? -1 : 1)),\n)\n\nconst weekdayMap = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']\nfunction formatDay(iso: string) {\n const d = new Date(iso)\n return `${iso.slice(5)} ${weekdayMap[d.getDay()]}`\n}\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px; max-width: 32rem\">\n <MDatePicker\n v-model=\"selectedDates\"\n label=\"Pick shift days\"\n multiple\n help-text=\"Click to toggle; you can pick across months\"\n />\n <div v-if=\"sorted.length\" style=\"display: flex; flex-wrap: wrap; gap: 6px\">\n <MTag v-for=\"iso in sorted\" :key=\"iso\" :value=\"formatDay(iso)\" type=\"primary\" />\n </div>\n <p v-else style=\"color: var(--m-color-text-muted); font-size: 13px; margin: 0\">\n No days selected yet\n </p>\n </div>\n</template>",
|
|
6666
|
+
"locale": "en-US"
|
|
6667
|
+
},
|
|
6668
|
+
{
|
|
6669
|
+
"id": "form-integration-1",
|
|
6670
|
+
"section": "Form Integration",
|
|
6671
|
+
"sectionId": "form-integration",
|
|
6672
|
+
"lang": "vue",
|
|
6673
|
+
"preview": true,
|
|
6674
|
+
"code": "<script setup lang=\"ts\">\nimport { MButton, MDatePicker } from 'morya-ui'\nimport { reactive, ref } from 'vue'\n\nconst form = reactive({\n name: '',\n startDate: null as string | null,\n endDate: null as string | null,\n})\n\nconst submitted = ref<string | null>(null)\n\nfunction iso(date: Date) {\n const y = date.getFullYear()\n const m = String(date.getMonth() + 1).padStart(2, '0')\n const d = String(date.getDate()).padStart(2, '0')\n return `${y}-${m}-${d}`\n}\nconst today = iso(new Date())\n\nconst startError = ref('')\nconst endError = ref('')\n\nfunction submit() {\n startError.value = form.startDate ? '' : 'Start date is required'\n endError.value = form.endDate ? '' : 'End date is required'\n if (form.startDate && form.endDate && form.endDate < form.startDate) {\n endError.value = 'End date cannot be earlier than start date'\n }\n if (startError.value || endError.value) return\n submitted.value = JSON.stringify(form, null, 2)\n}\n</script>\n\n<template>\n <form style=\"display: grid; gap: 12px; max-width: 32rem\" @submit.prevent=\"submit\">\n <MDatePicker\n v-model=\"form.startDate\"\n label=\"Start date\"\n required\n :min-date=\"today\"\n :error-message=\"startError\"\n />\n <MDatePicker\n v-model=\"form.endDate\"\n label=\"End date\"\n required\n :min-date=\"form.startDate ?? today\"\n :error-message=\"endError\"\n />\n <div>\n <MButton type=\"primary\" html-type=\"submit\">Submit</MButton>\n </div>\n <pre v-if=\"submitted\" style=\"background: var(--m-color-surface-sunken); padding: 8px; border-radius: 4px; font-size: 12px\">{{ submitted }}</pre>\n </form>\n</template>",
|
|
6675
|
+
"locale": "en-US"
|
|
6676
|
+
},
|
|
6677
|
+
{
|
|
6678
|
+
"id": "input-mask-1",
|
|
6679
|
+
"section": "Input Mask",
|
|
6680
|
+
"sectionId": "input-mask",
|
|
6681
|
+
"lang": "vue",
|
|
6682
|
+
"preview": true,
|
|
6683
|
+
"code": "<script setup lang=\"ts\">\nimport { MDatePicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst date = ref<string | null>('2024-06-15')\nconst datetime = ref<string | null>('2024-06-15 14:30')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px\">\n <MDatePicker v-model=\"date\" label=\"Mask (date)\" mask />\n <MDatePicker v-model=\"datetime\" type=\"datetime\" label=\"Mask (datetime)\" mask />\n </div>\n</template>",
|
|
6684
|
+
"locale": "en-US"
|
|
6685
|
+
},
|
|
6420
6686
|
{
|
|
6421
6687
|
"id": "types-1",
|
|
6422
6688
|
"section": "Types",
|
|
@@ -6497,10 +6763,80 @@
|
|
|
6497
6763
|
"title": "Shortcuts",
|
|
6498
6764
|
"body": "```vue preview src=\"./demos/Shortcuts.zh.vue\"\n```"
|
|
6499
6765
|
},
|
|
6766
|
+
{
|
|
6767
|
+
"id": "范围快捷键",
|
|
6768
|
+
"title": "范围快捷键",
|
|
6769
|
+
"body": "`shortcuts` 在 `daterange` / `datetimerange` 下更强大:返回 `[start, end]` 元组即可一键选定区间。与当前值匹配的快捷键会自动高亮。\n\n```vue preview src=\"./demos/RangeShortcuts.zh.vue\"\n```"
|
|
6770
|
+
},
|
|
6771
|
+
{
|
|
6772
|
+
"id": "自定义格式",
|
|
6773
|
+
"title": "自定义格式",
|
|
6774
|
+
"body": "`format` 仅控制显示,提交值仍按 `type` 约定(`YYYY-MM-DD` 等)。支持任意 `YYYY` / `MM` / `DD` / `HH` / `mm` / `ss` 组合与自由文本。\n\n```vue preview src=\"./demos/Format.zh.vue\"\n```"
|
|
6775
|
+
},
|
|
6776
|
+
{
|
|
6777
|
+
"id": "日期时间",
|
|
6778
|
+
"title": "日期时间",
|
|
6779
|
+
"body": "`datetime` 与 `datetimerange` 把日历与时间列放在同一面板;`show-seconds` 含秒;`need-confirm` 让用户从容完成两步选择后再提交。\n\n```vue preview src=\"./demos/Datetime.zh.vue\"\n```"
|
|
6780
|
+
},
|
|
6781
|
+
{
|
|
6782
|
+
"id": "自定义触发器",
|
|
6783
|
+
"title": "自定义触发器",
|
|
6784
|
+
"body": "`#trigger` 插槽完全接管触发元素,作用域 `{ value, open }`。适合按钮、图标或复合排版。\n\n```vue preview src=\"./demos/CustomTrigger.zh.vue\"\n```"
|
|
6785
|
+
},
|
|
6786
|
+
{
|
|
6787
|
+
"id": "禁用区间",
|
|
6788
|
+
"title": "禁用区间",
|
|
6789
|
+
"body": "`min-date` / `max-date` 之外的日期会在日历中置灰禁用。两者可单独或组合使用。\n\n```vue preview src=\"./demos/DisabledDates.zh.vue\"\n```"
|
|
6790
|
+
},
|
|
6791
|
+
{
|
|
6792
|
+
"id": "内联面板",
|
|
6793
|
+
"title": "内联面板",
|
|
6794
|
+
"body": "`:teleport=\"false\"` + `append-to=\"self\"` 让面板嵌入文档流,不浮出层叠上下文,适合卡片、抽屉或复合表单内嵌。\n\n```vue preview src=\"./demos/InlinePanel.zh.vue\"\n```"
|
|
6795
|
+
},
|
|
6796
|
+
{
|
|
6797
|
+
"id": "面板模式切换",
|
|
6798
|
+
"title": "面板模式切换",
|
|
6799
|
+
"body": "点击面板头部的月份/年份标签,可在 日 → 月 → 年 三个子面板间循环切换,方便快速跳到目标年份/月份再回到日视图。"
|
|
6800
|
+
},
|
|
6801
|
+
{
|
|
6802
|
+
"id": "状态-status",
|
|
6803
|
+
"title": "状态(status)",
|
|
6804
|
+
"body": "`status` 提供 `'warning'` 与 `'error'` 两种视觉警示(`invalid` / `errorMessage` 会自动落到 `error`)。`warning` 通常配合 `helpText` 表达温和提醒,不阻断提交。\n\n```vue preview src=\"./demos/Status.zh.vue\"\n```"
|
|
6805
|
+
},
|
|
6806
|
+
{
|
|
6807
|
+
"id": "页脚与自定义单元格",
|
|
6808
|
+
"title": "页脚与自定义单元格",
|
|
6809
|
+
"body": "`#footer` 插槽在面板底部渲染操作区(作用域 `{ close }`);`#cell` 插槽自定义日期单元格内容(作用域含 `date / inMonth / selected / inRange / rangeStart / rangeEnd / isToday / disabled`),适合加节假日标记、日程点、自定义排版。\n\n```vue preview src=\"./demos/FooterAndCell.zh.vue\"\n```"
|
|
6810
|
+
},
|
|
6811
|
+
{
|
|
6812
|
+
"id": "needconfirm-确认提交",
|
|
6813
|
+
"title": "needConfirm 确认提交",
|
|
6814
|
+
"body": "`need-confirm` 启用后,选择值只写入暂存 draft,点击「确认」才提交并关闭,「取消」回滚。适合 `datetime` / `datetimerange` / `time` 等需要多步操作的场景。\n\n```vue preview src=\"./demos/NeedConfirm.zh.vue\"\n```"
|
|
6815
|
+
},
|
|
6816
|
+
{
|
|
6817
|
+
"id": "多选日期",
|
|
6818
|
+
"title": "多选日期",
|
|
6819
|
+
"body": "`multiple` 仅在 `type='date'` 下生效。`modelValue` 变为 `string[]`,每次点击切换选中,面板保持打开。\n\n```vue preview src=\"./demos/Multiple.zh.vue\"\n```"
|
|
6820
|
+
},
|
|
6821
|
+
{
|
|
6822
|
+
"id": "多选实战-排班",
|
|
6823
|
+
"title": "多选实战:排班",
|
|
6824
|
+
"body": "多选配合 `MTag` 展示所选日期,直观易读。\n\n```vue preview src=\"./demos/WorkSchedule.zh.vue\"\n```"
|
|
6825
|
+
},
|
|
6826
|
+
{
|
|
6827
|
+
"id": "表单集成",
|
|
6828
|
+
"title": "表单集成",
|
|
6829
|
+
"body": "结合 `required` / `error-message` / `min-date`,实现一个完整的项目日期范围校验表单。\n\n```vue preview src=\"./demos/FormIntegration.zh.vue\"\n```"
|
|
6830
|
+
},
|
|
6831
|
+
{
|
|
6832
|
+
"id": "输入掩码",
|
|
6833
|
+
"title": "输入掩码",
|
|
6834
|
+
"body": "`mask` 让输入框可编辑,按 `format` 自动插入 `-` `/` `:` 分隔符;`Enter` 提交,`Esc` 或失焦回滚。仅 `date` / `datetime` / `time` 类型支持。\n\n```vue preview src=\"./demos/Mask.zh.vue\"\n```"
|
|
6835
|
+
},
|
|
6500
6836
|
{
|
|
6501
6837
|
"id": "props",
|
|
6502
6838
|
"title": "Props",
|
|
6503
|
-
"body": "| 参数 | 类型 | 默认值 | 说明 |\n| -------------- | --------------------------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------- |\n| `modelValue` | `string \\| Date \\| [string, string] \\| null` | `null` | 按 `type`:`YYYY-MM-DD`、`[start,end]`、`YYYY-MM-DD HH:mm`、`HH:mm`、`YYYY-MM`、`YYYY` 等。 |\n| `type` | `'date' \\| 'daterange' \\| 'datetime' \\| 'datetimerange' \\| 'time' \\| 'month' \\| 'year'` | `'date'` | 面板与值格式。 |\n| `showSeconds` | `boolean` | `false` | `time` / `datetime` / `datetimerange` 是否含秒。 |\n| `label` | `string` | — | 标签。 |\n| `minDate` | `string \\| Date \\| null` | — | 可选下限。 |\n| `maxDate` | `string \\| Date \\| null` | — | 可选上限。 |\n| `placeholder` | `string` | locale | 占位。 |\n| `format` | `string` | `'YYYY-MM-DD'` | 输入框展示格式(`YYYY`/`MM`/`DD`/`HH`/`mm`/`ss`);提交值仍按 `type` 约定。 |\n| `clearable` | `boolean` | `true` | 显示清除按钮。 |\n| `shortcuts` | `DatePickerShortcut[]` | `[]` |
|
|
6839
|
+
"body": "| 参数 | 类型 | 默认值 | 说明 |\n| -------------- | --------------------------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------- |\n| `modelValue` | `string \\| Date \\| [string, string] \\| null` | `null` | 按 `type`:`YYYY-MM-DD`、`[start,end]`、`YYYY-MM-DD HH:mm`、`HH:mm`、`YYYY-MM`、`YYYY` 等。 |\n| `type` | `'date' \\| 'daterange' \\| 'datetime' \\| 'datetimerange' \\| 'time' \\| 'month' \\| 'year'` | `'date'` | 面板与值格式。 |\n| `showSeconds` | `boolean` | `false` | `time` / `datetime` / `datetimerange` 是否含秒。 |\n| `label` | `string` | — | 标签。 |\n| `minDate` | `string \\| Date \\| null` | — | 可选下限。 |\n| `maxDate` | `string \\| Date \\| null` | — | 可选上限。 |\n| `placeholder` | `string` | locale | 占位。 |\n| `format` | `string` | `'YYYY-MM-DD'` | 输入框展示格式(`YYYY`/`MM`/`DD`/`HH`/`mm`/`ss`);提交值仍按 `type` 约定。 |\n| `clearable` | `boolean` | `true` | 显示清除按钮。 |\n| `shortcuts` | `DatePickerShortcut[]` | `[]` | 面板快捷选项;与当前值匹配时高亮。 |\n| `status` | `'default' \\| 'warning' \\| 'error'` | `'default'` | 视觉警示;`invalid` / `errorMessage` 自动视为 `error`。 |\n| `needConfirm` | `boolean` | `false` | 选择后仅写入 draft,按「确认」提交、「取消」回滚。 |\n| `multiple` | `boolean` | `false` | 多选日期(仅 `type='date'`);`modelValue` 为 `string[]`。 |\n| `mask` | `boolean` | `false` | 输入框可编辑,按 `format` 自动补分隔符;Enter 提交,Esc/失焦回滚。 |\n| `fluid` | `boolean` | `false` | 宽度撑满。 |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | `small` / `large`;可继承 ConfigProvider。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `invalid` | `boolean` | `false` | 校验失败态。 |\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| `errorMessage` | `string` | — | — |\n| `helpText` | `string` | — | — |\n| `id` | `string` | — | — |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
|
|
6504
6840
|
},
|
|
6505
6841
|
{
|
|
6506
6842
|
"id": "events",
|
|
@@ -6510,7 +6846,7 @@
|
|
|
6510
6846
|
{
|
|
6511
6847
|
"id": "slots",
|
|
6512
6848
|
"title": "Slots",
|
|
6513
|
-
"body": "| 插槽名 | 说明
|
|
6849
|
+
"body": "| 插槽名 | 说明 |\n| --------- | --------------------------------------------------------------------------------------------------------------------------------- |\n| `trigger` | 自定义触发器 `{ value, open }`。 |\n| `footer` | 面板底部自定义操作区,作用域 `{ close }`。`need-confirm` 时若未提供则显示默认「取消/确认」。 |\n| `cell` | 自定义日期单元格,作用域 `{ date, inMonth, selected, inRange, rangeStart, rangeEnd, isToday, disabled }`。 |"
|
|
6514
6850
|
},
|
|
6515
6851
|
{
|
|
6516
6852
|
"id": "类型",
|
|
@@ -6523,7 +6859,7 @@
|
|
|
6523
6859
|
"body": "用 `type` 区分日期/范围/时间模式(含 `daterange`、`datetime`、`time` 等)。"
|
|
6524
6860
|
}
|
|
6525
6861
|
],
|
|
6526
|
-
"markdown": "---\ntitle: DatePicker\ncategory: 02 / FORM\ndescription: 日历弹层选择日期、时间、月份或年份。单值或范围,字符串格式按 `type` 约定。支持 min/max、shortcuts、format、showSeconds、clearable。\n---\n\n# DatePicker\n\n带月份导航与日网格的日期选择器;也可切换为时间列、月/年面板。\n\n## 何时使用\n\n- 需要选择日期、日期范围、日期时间、月或年时。\n- 仅选时刻时优先使用独立入口 [TimePicker](/components/TimePicker)(仍可用 `type=\"time\"`)。\n\n## 引入\n\n```ts\nimport { MDatePicker } from \"morya-ui\";\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Size\n\n```vue preview src=\"./demos/Size.vue\"\n```\n\n## Min / Max\n\n超出范围的日期在日历中禁用。\n\n```vue preview src=\"./demos/MinMax.zh.vue\"\n```\n\n## Invalid\n\n```vue preview src=\"./demos/Invalid.zh.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.zh.vue\"\n```\n\n## Fluid\n\n```vue preview src=\"./demos/Fluid.zh.vue\"\n```\n\n## Teleport\n\n面板默认 Teleport 到 `body`。可用 `append-to=\"self\"` 或 `teleport={false}` 就地渲染。\n\n```vue preview src=\"./demos/Teleport.zh.vue\"\n```\n\n## Range\n\n`type=\"daterange\"` 时先点起点、再点终点;值为 `[start, end]`(ISO 日期)。\n\n```vue preview src=\"./demos/Range.zh.vue\"\n```\n\n## 类型扩展\n\n`type` 支持 `month` / `year` / `time` / `datetime` / `datetimerange`。`showSeconds` 控制是否包含秒。\n\n仅时间场景优先用独立组件 [TimePicker](/components/TimePicker);本页 `type=\"time\"` 仍可用。\n\n`datetimerange`:两次点击选定日期后以两端 `00:00`(或 `00:00:00`)发出;面板保持打开时可用时间列调整终点时刻,点选最细粒度单位后关闭。\n\n```vue preview src=\"./demos/Types.vue\"\n```\n\n## Shortcuts\n\n```vue preview src=\"./demos/Shortcuts.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| -------------- | --------------------------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------- |\n| `modelValue` | `string \\| Date \\| [string, string] \\| null` | `null` | 按 `type`:`YYYY-MM-DD`、`[start,end]`、`YYYY-MM-DD HH:mm`、`HH:mm`、`YYYY-MM`、`YYYY` 等。 |\n| `type` | `'date' \\| 'daterange' \\| 'datetime' \\| 'datetimerange' \\| 'time' \\| 'month' \\| 'year'` | `'date'` | 面板与值格式。 |\n| `showSeconds` | `boolean` | `false` | `time` / `datetime` / `datetimerange` 是否含秒。 |\n| `label` | `string` | — | 标签。 |\n| `minDate` | `string \\| Date \\| null` | — | 可选下限。 |\n| `maxDate` | `string \\| Date \\| null` | — | 可选上限。 |\n| `placeholder` | `string` | locale | 占位。 |\n| `format` | `string` | `'YYYY-MM-DD'` | 输入框展示格式(`YYYY`/`MM`/`DD`/`HH`/`mm`/`ss`);提交值仍按 `type` 约定。 |\n| `clearable` | `boolean` | `true` | 显示清除按钮。 |\n| `shortcuts` | `DatePickerShortcut[]` | `[]` | 面板快捷选项。 |\n| `fluid` | `boolean` | `false` | 宽度撑满。 |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | `small` / `large`;可继承 ConfigProvider。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `invalid` | `boolean` | `false` | 校验失败态。 |\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| `errorMessage` | `string` | — | — |\n| `helpText` | `string` | — | — |\n| `id` | `string` | — | — |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| ------------------- | ------------------------------------ | ---------------- |\n| `update:modelValue` | `string \\| [string, string] \\| null` | 值变化。 |\n| `clear` | — | 点击清除时触发。 |\n| `change` | — | — |\n| `hide` | — | — |\n| `show` | — | — |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --------- | -------------------------------- |\n| `trigger` | 自定义触发器 `{ value, open }`。 |\n\n## 类型\n\n<h4 id=\"DatePickerShortcut\">DatePickerShortcut</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface DatePickerShortcut {\n label: string;\n value:\n | DatePickerDateValue\n | [DatePickerDateValue, DatePickerDateValue]\n | (() => DatePickerDateValue | [DatePickerDateValue, DatePickerDateValue]);\n}\n```\n\n## 功能边界\n\n用 `type` 区分日期/范围/时间模式(含 `daterange`、`datetime`、`time` 等)。\n"
|
|
6862
|
+
"markdown": "---\ntitle: DatePicker\ncategory: 02 / FORM\ndescription: 日历弹层选择日期、时间、月份或年份。单值或范围,字符串格式按 `type` 约定。支持 min/max、shortcuts、format、showSeconds、clearable。\n---\n\n# DatePicker\n\n带月份导航与日网格的日期选择器;也可切换为时间列、月/年面板。\n\n## 何时使用\n\n- 需要选择日期、日期范围、日期时间、月或年时。\n- 仅选时刻时优先使用独立入口 [TimePicker](/components/TimePicker)(仍可用 `type=\"time\"`)。\n\n## 引入\n\n```ts\nimport { MDatePicker } from \"morya-ui\";\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## Size\n\n```vue preview src=\"./demos/Size.vue\"\n```\n\n## Min / Max\n\n超出范围的日期在日历中禁用。\n\n```vue preview src=\"./demos/MinMax.zh.vue\"\n```\n\n## Invalid\n\n```vue preview src=\"./demos/Invalid.zh.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.zh.vue\"\n```\n\n## Fluid\n\n```vue preview src=\"./demos/Fluid.zh.vue\"\n```\n\n## Teleport\n\n面板默认 Teleport 到 `body`。可用 `append-to=\"self\"` 或 `teleport={false}` 就地渲染。\n\n```vue preview src=\"./demos/Teleport.zh.vue\"\n```\n\n## Range\n\n`type=\"daterange\"` 时先点起点、再点终点;值为 `[start, end]`(ISO 日期)。\n\n```vue preview src=\"./demos/Range.zh.vue\"\n```\n\n## 类型扩展\n\n`type` 支持 `month` / `year` / `time` / `datetime` / `datetimerange`。`showSeconds` 控制是否包含秒。\n\n仅时间场景优先用独立组件 [TimePicker](/components/TimePicker);本页 `type=\"time\"` 仍可用。\n\n`datetimerange`:两次点击选定日期后以两端 `00:00`(或 `00:00:00`)发出;面板保持打开时可用时间列调整终点时刻,点选最细粒度单位后关闭。\n\n```vue preview src=\"./demos/Types.vue\"\n```\n\n## Shortcuts\n\n```vue preview src=\"./demos/Shortcuts.zh.vue\"\n```\n\n## 范围快捷键\n\n`shortcuts` 在 `daterange` / `datetimerange` 下更强大:返回 `[start, end]` 元组即可一键选定区间。与当前值匹配的快捷键会自动高亮。\n\n```vue preview src=\"./demos/RangeShortcuts.zh.vue\"\n```\n\n## 自定义格式\n\n`format` 仅控制显示,提交值仍按 `type` 约定(`YYYY-MM-DD` 等)。支持任意 `YYYY` / `MM` / `DD` / `HH` / `mm` / `ss` 组合与自由文本。\n\n```vue preview src=\"./demos/Format.zh.vue\"\n```\n\n## 日期时间\n\n`datetime` 与 `datetimerange` 把日历与时间列放在同一面板;`show-seconds` 含秒;`need-confirm` 让用户从容完成两步选择后再提交。\n\n```vue preview src=\"./demos/Datetime.zh.vue\"\n```\n\n## 自定义触发器\n\n`#trigger` 插槽完全接管触发元素,作用域 `{ value, open }`。适合按钮、图标或复合排版。\n\n```vue preview src=\"./demos/CustomTrigger.zh.vue\"\n```\n\n## 禁用区间\n\n`min-date` / `max-date` 之外的日期会在日历中置灰禁用。两者可单独或组合使用。\n\n```vue preview src=\"./demos/DisabledDates.zh.vue\"\n```\n\n## 内联面板\n\n`:teleport=\"false\"` + `append-to=\"self\"` 让面板嵌入文档流,不浮出层叠上下文,适合卡片、抽屉或复合表单内嵌。\n\n```vue preview src=\"./demos/InlinePanel.zh.vue\"\n```\n\n## 面板模式切换\n\n点击面板头部的月份/年份标签,可在 日 → 月 → 年 三个子面板间循环切换,方便快速跳到目标年份/月份再回到日视图。\n\n## 状态(status)\n\n`status` 提供 `'warning'` 与 `'error'` 两种视觉警示(`invalid` / `errorMessage` 会自动落到 `error`)。`warning` 通常配合 `helpText` 表达温和提醒,不阻断提交。\n\n```vue preview src=\"./demos/Status.zh.vue\"\n```\n\n## 页脚与自定义单元格\n\n`#footer` 插槽在面板底部渲染操作区(作用域 `{ close }`);`#cell` 插槽自定义日期单元格内容(作用域含 `date / inMonth / selected / inRange / rangeStart / rangeEnd / isToday / disabled`),适合加节假日标记、日程点、自定义排版。\n\n```vue preview src=\"./demos/FooterAndCell.zh.vue\"\n```\n\n## needConfirm 确认提交\n\n`need-confirm` 启用后,选择值只写入暂存 draft,点击「确认」才提交并关闭,「取消」回滚。适合 `datetime` / `datetimerange` / `time` 等需要多步操作的场景。\n\n```vue preview src=\"./demos/NeedConfirm.zh.vue\"\n```\n\n## 多选日期\n\n`multiple` 仅在 `type='date'` 下生效。`modelValue` 变为 `string[]`,每次点击切换选中,面板保持打开。\n\n```vue preview src=\"./demos/Multiple.zh.vue\"\n```\n\n## 多选实战:排班\n\n多选配合 `MTag` 展示所选日期,直观易读。\n\n```vue preview src=\"./demos/WorkSchedule.zh.vue\"\n```\n\n## 表单集成\n\n结合 `required` / `error-message` / `min-date`,实现一个完整的项目日期范围校验表单。\n\n```vue preview src=\"./demos/FormIntegration.zh.vue\"\n```\n\n## 输入掩码\n\n`mask` 让输入框可编辑,按 `format` 自动插入 `-` `/` `:` 分隔符;`Enter` 提交,`Esc` 或失焦回滚。仅 `date` / `datetime` / `time` 类型支持。\n\n```vue preview src=\"./demos/Mask.zh.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| -------------- | --------------------------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------- |\n| `modelValue` | `string \\| Date \\| [string, string] \\| null` | `null` | 按 `type`:`YYYY-MM-DD`、`[start,end]`、`YYYY-MM-DD HH:mm`、`HH:mm`、`YYYY-MM`、`YYYY` 等。 |\n| `type` | `'date' \\| 'daterange' \\| 'datetime' \\| 'datetimerange' \\| 'time' \\| 'month' \\| 'year'` | `'date'` | 面板与值格式。 |\n| `showSeconds` | `boolean` | `false` | `time` / `datetime` / `datetimerange` 是否含秒。 |\n| `label` | `string` | — | 标签。 |\n| `minDate` | `string \\| Date \\| null` | — | 可选下限。 |\n| `maxDate` | `string \\| Date \\| null` | — | 可选上限。 |\n| `placeholder` | `string` | locale | 占位。 |\n| `format` | `string` | `'YYYY-MM-DD'` | 输入框展示格式(`YYYY`/`MM`/`DD`/`HH`/`mm`/`ss`);提交值仍按 `type` 约定。 |\n| `clearable` | `boolean` | `true` | 显示清除按钮。 |\n| `shortcuts` | `DatePickerShortcut[]` | `[]` | 面板快捷选项;与当前值匹配时高亮。 |\n| `status` | `'default' \\| 'warning' \\| 'error'` | `'default'` | 视觉警示;`invalid` / `errorMessage` 自动视为 `error`。 |\n| `needConfirm` | `boolean` | `false` | 选择后仅写入 draft,按「确认」提交、「取消」回滚。 |\n| `multiple` | `boolean` | `false` | 多选日期(仅 `type='date'`);`modelValue` 为 `string[]`。 |\n| `mask` | `boolean` | `false` | 输入框可编辑,按 `format` 自动补分隔符;Enter 提交,Esc/失焦回滚。 |\n| `fluid` | `boolean` | `false` | 宽度撑满。 |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | `small` / `large`;可继承 ConfigProvider。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `invalid` | `boolean` | `false` | 校验失败态。 |\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| `errorMessage` | `string` | — | — |\n| `helpText` | `string` | — | — |\n| `id` | `string` | — | — |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| ------------------- | ------------------------------------ | ---------------- |\n| `update:modelValue` | `string \\| [string, string] \\| null` | 值变化。 |\n| `clear` | — | 点击清除时触发。 |\n| `change` | — | — |\n| `hide` | — | — |\n| `show` | — | — |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --------- | --------------------------------------------------------------------------------------------------------------------------------- |\n| `trigger` | 自定义触发器 `{ value, open }`。 |\n| `footer` | 面板底部自定义操作区,作用域 `{ close }`。`need-confirm` 时若未提供则显示默认「取消/确认」。 |\n| `cell` | 自定义日期单元格,作用域 `{ date, inMonth, selected, inRange, rangeStart, rangeEnd, isToday, disabled }`。 |\n\n## 类型\n\n<h4 id=\"DatePickerShortcut\">DatePickerShortcut</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ninterface DatePickerShortcut {\n label: string;\n value:\n | DatePickerDateValue\n | [DatePickerDateValue, DatePickerDateValue]\n | (() => DatePickerDateValue | [DatePickerDateValue, DatePickerDateValue]);\n}\n```\n\n## 功能边界\n\n用 `type` 区分日期/范围/时间模式(含 `daterange`、`datetime`、`time` 等)。\n"
|
|
6527
6863
|
},
|
|
6528
6864
|
"en-US": {
|
|
6529
6865
|
"title": "DatePicker",
|
|
@@ -6594,10 +6930,80 @@
|
|
|
6594
6930
|
"title": "Shortcuts",
|
|
6595
6931
|
"body": "```vue preview src=\"./demos/Shortcuts.en.vue\"\n```"
|
|
6596
6932
|
},
|
|
6933
|
+
{
|
|
6934
|
+
"id": "range-shortcuts",
|
|
6935
|
+
"title": "Range Shortcuts",
|
|
6936
|
+
"body": "`shortcuts` shine for `daterange` / `datetimerange`: return a `[start, end]` tuple to select a range in one click. The shortcut matching the current value is highlighted automatically.\n\n```vue preview src=\"./demos/RangeShortcuts.en.vue\"\n```"
|
|
6937
|
+
},
|
|
6938
|
+
{
|
|
6939
|
+
"id": "custom-format",
|
|
6940
|
+
"title": "Custom Format",
|
|
6941
|
+
"body": "`format` only affects display; the emitted value still follows the `type` convention (`YYYY-MM-DD`, etc.). Mix `YYYY` / `MM` / `DD` / `HH` / `mm` / `ss` with free text.\n\n```vue preview src=\"./demos/Format.en.vue\"\n```"
|
|
6942
|
+
},
|
|
6943
|
+
{
|
|
6944
|
+
"id": "datetime",
|
|
6945
|
+
"title": "Datetime",
|
|
6946
|
+
"body": "`datetime` and `datetimerange` combine the calendar and time columns in one panel. `show-seconds` includes seconds; `need-confirm` lets users finish the two-step pick before committing.\n\n```vue preview src=\"./demos/Datetime.en.vue\"\n```"
|
|
6947
|
+
},
|
|
6948
|
+
{
|
|
6949
|
+
"id": "custom-trigger",
|
|
6950
|
+
"title": "Custom Trigger",
|
|
6951
|
+
"body": "The `#trigger` slot takes full control of the trigger element with scope `{ value, open }` — handy for buttons, icons, or composite layouts.\n\n```vue preview src=\"./demos/CustomTrigger.en.vue\"\n```"
|
|
6952
|
+
},
|
|
6953
|
+
{
|
|
6954
|
+
"id": "disabled-ranges",
|
|
6955
|
+
"title": "Disabled Ranges",
|
|
6956
|
+
"body": "Dates outside `min-date` / `max-date` are disabled in the calendar. Use them alone or together.\n\n```vue preview src=\"./demos/DisabledDates.en.vue\"\n```"
|
|
6957
|
+
},
|
|
6958
|
+
{
|
|
6959
|
+
"id": "inline-panel",
|
|
6960
|
+
"title": "Inline Panel",
|
|
6961
|
+
"body": "`:teleport=\"false\"` with `append-to=\"self\"` renders the panel inline, outside the overlay stacking context — useful inside cards, drawers, or complex forms.\n\n```vue preview src=\"./demos/InlinePanel.en.vue\"\n```"
|
|
6962
|
+
},
|
|
6963
|
+
{
|
|
6964
|
+
"id": "panel-mode-cycling",
|
|
6965
|
+
"title": "Panel Mode Cycling",
|
|
6966
|
+
"body": "Click the panel header label to cycle through days → months → years sub-panels, handy for jumping to a target year/month before returning to the day grid."
|
|
6967
|
+
},
|
|
6968
|
+
{
|
|
6969
|
+
"id": "status",
|
|
6970
|
+
"title": "Status",
|
|
6971
|
+
"body": "`status` accepts `'warning'` or `'error'` for visual emphasis (`invalid` / `errorMessage` imply `error`). Use `warning` with `helpText` for friendly reminders that don't block submission.\n\n```vue preview src=\"./demos/Status.en.vue\"\n```"
|
|
6972
|
+
},
|
|
6973
|
+
{
|
|
6974
|
+
"id": "footer-custom-cell",
|
|
6975
|
+
"title": "Footer & Custom Cell",
|
|
6976
|
+
"body": "The `#footer` slot renders an action area at the bottom of the panel (scope `{ close }`); `#cell` customizes the day cell (scope includes `date / inMonth / selected / inRange / rangeStart / rangeEnd / isToday / disabled`) — great for holiday dots, schedule markers, or custom layouts.\n\n```vue preview src=\"./demos/FooterAndCell.en.vue\"\n```"
|
|
6977
|
+
},
|
|
6978
|
+
{
|
|
6979
|
+
"id": "needconfirm",
|
|
6980
|
+
"title": "needConfirm",
|
|
6981
|
+
"body": "With `need-confirm`, picking a value only writes to a draft; **OK** commits and closes, **Cancel** rolls back. Recommended for `datetime` / `datetimerange` / `time` where selection takes multiple steps.\n\n```vue preview src=\"./demos/NeedConfirm.en.vue\"\n```"
|
|
6982
|
+
},
|
|
6983
|
+
{
|
|
6984
|
+
"id": "multiple-dates",
|
|
6985
|
+
"title": "Multiple Dates",
|
|
6986
|
+
"body": "`multiple` (only valid for `type='date'`) makes `modelValue` a `string[]`; each click toggles selection and the panel stays open.\n\n```vue preview src=\"./demos/Multiple.en.vue\"\n```"
|
|
6987
|
+
},
|
|
6988
|
+
{
|
|
6989
|
+
"id": "multiple-in-practice-shift-planning",
|
|
6990
|
+
"title": "Multiple in Practice: Shift Planning",
|
|
6991
|
+
"body": "Combine `multiple` with `MTag` to display picked days in a friendly, readable way.\n\n```vue preview src=\"./demos/WorkSchedule.en.vue\"\n```"
|
|
6992
|
+
},
|
|
6993
|
+
{
|
|
6994
|
+
"id": "form-integration",
|
|
6995
|
+
"title": "Form Integration",
|
|
6996
|
+
"body": "Combine `required`, `error-message` and `min-date` for a complete date-range validation form.\n\n```vue preview src=\"./demos/FormIntegration.en.vue\"\n```"
|
|
6997
|
+
},
|
|
6998
|
+
{
|
|
6999
|
+
"id": "input-mask",
|
|
7000
|
+
"title": "Input Mask",
|
|
7001
|
+
"body": "`mask` makes the input editable, auto-inserting `-` / `/` / `:` separators matching the display `format`. Press **Enter** to commit, **Esc** or blur to revert. Supported on `date` / `datetime` / `time` only.\n\n```vue preview src=\"./demos/Mask.en.vue\"\n```"
|
|
7002
|
+
},
|
|
6597
7003
|
{
|
|
6598
7004
|
"id": "props",
|
|
6599
7005
|
"title": "Props",
|
|
6600
|
-
"body": "| Prop | Type | Default | Description |\n| -------------- | --------------------------------------------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------- |\n| `modelValue` | `string \\| Date \\| [string, string] \\| null` | `null` | By `type`: `YYYY-MM-DD`, `[start,end]`, `YYYY-MM-DD HH:mm`, `HH:mm`, `YYYY-MM`, `YYYY`, etc. |\n| `type` | `'date' \\| 'daterange' \\| 'datetime' \\| 'datetimerange' \\| 'time' \\| 'month' \\| 'year'` | `'date'` | Panel and value shape. |\n| `showSeconds` | `boolean` | `false` | Include seconds for `time` / `datetime` / `datetimerange`. |\n| `label` | `string` | — | Label. |\n| `minDate` | `string \\| Date \\| null` | — | Optional lower bound. |\n| `maxDate` | `string \\| Date \\| null` | — | Optional upper bound. |\n| `placeholder` | `string` | locale | Placeholder. |\n| `format` | `string` | `'YYYY-MM-DD'` | Input display pattern (`YYYY`/`MM`/`DD`/`HH`/`mm`/`ss`); emitted value follows `type`. |\n| `clearable` | `boolean` | `true` | Show a clear button. |\n| `shortcuts` | `DatePickerShortcut[]` | `[]` | Panel shortcuts.
|
|
7006
|
+
"body": "| Prop | Type | Default | Description |\n| -------------- | --------------------------------------------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------- |\n| `modelValue` | `string \\| Date \\| [string, string] \\| null` | `null` | By `type`: `YYYY-MM-DD`, `[start,end]`, `YYYY-MM-DD HH:mm`, `HH:mm`, `YYYY-MM`, `YYYY`, etc. |\n| `type` | `'date' \\| 'daterange' \\| 'datetime' \\| 'datetimerange' \\| 'time' \\| 'month' \\| 'year'` | `'date'` | Panel and value shape. |\n| `showSeconds` | `boolean` | `false` | Include seconds for `time` / `datetime` / `datetimerange`. |\n| `label` | `string` | — | Label. |\n| `minDate` | `string \\| Date \\| null` | — | Optional lower bound. |\n| `maxDate` | `string \\| Date \\| null` | — | Optional upper bound. |\n| `placeholder` | `string` | locale | Placeholder. |\n| `format` | `string` | `'YYYY-MM-DD'` | Input display pattern (`YYYY`/`MM`/`DD`/`HH`/`mm`/`ss`); emitted value follows `type`. |\n| `clearable` | `boolean` | `true` | Show a clear button. |\n| `shortcuts` | `DatePickerShortcut[]` | `[]` | Panel shortcuts; the one matching the current value is highlighted. |\n| `status` | `'default' \\| 'warning' \\| 'error'` | `'default'` | Visual status; `invalid` / `errorMessage` imply `error`. |\n| `needConfirm` | `boolean` | `false` | Defer commit until OK; Cancel rolls back. |\n| `multiple` | `boolean` | `false` | Pick many dates (`type='date'` only); `modelValue` is `string[]`. |\n| `mask` | `boolean` | `false` | Editable input with auto separators; Enter commits, Esc/blur reverts. |\n| `fluid` | `boolean` | `false` | Stretch to full width. |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | `small` / `large`; can inherit from ConfigProvider. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `invalid` | `boolean` | `false` | Invalid state. |\n| `teleport` | `boolean` | `true` | Panel 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| `errorMessage` | `string` | — | — |\n| `helpText` | `string` | — | — |\n| `id` | `string` | — | — |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
|
|
6601
7007
|
},
|
|
6602
7008
|
{
|
|
6603
7009
|
"id": "events",
|
|
@@ -6607,7 +7013,7 @@
|
|
|
6607
7013
|
{
|
|
6608
7014
|
"id": "slots",
|
|
6609
7015
|
"title": "Slots",
|
|
6610
|
-
"body": "| Slot | Description
|
|
7016
|
+
"body": "| Slot | Description |\n| --------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| `trigger` | Custom trigger `{ value, open }`. |\n| `footer` | Panel bottom action area, scope `{ close }`. When `need-confirm` is on and no footer is given, default OK/Cancel is shown. |\n| `cell` | Custom day cell, scope `{ date, inMonth, selected, inRange, rangeStart, rangeEnd, isToday, disabled }`. |"
|
|
6611
7017
|
},
|
|
6612
7018
|
{
|
|
6613
7019
|
"id": "types",
|
|
@@ -6620,7 +7026,7 @@
|
|
|
6620
7026
|
"body": "Date, range, and time modes are selected via `type` (`daterange`, `datetime`, `time`, etc.)."
|
|
6621
7027
|
}
|
|
6622
7028
|
],
|
|
6623
|
-
"markdown": "---\ntitle: DatePicker\ncategory: 02 / FORM\ndescription: Calendar overlay for a date, time, month, or year. String shape follows `type`. Supports min/max, shortcuts, format, showSeconds, and clearable.\n---\n\n# DatePicker\n\nDate picker with month navigation and a day grid; also supports time columns and month/year panels.\n\n## When to use\n\n- Use for date, date range, date-time, month, or year selection.\n- For time-only, prefer the dedicated [TimePicker](/components/TimePicker) entry (`type=\"time\"` still works).\n\n## Import\n\n```ts\nimport { MDatePicker } from \"morya-ui\";\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Size\n\n```vue preview src=\"./demos/Size.vue\"\n```\n\n## Min / Max\n\nDates outside the range are disabled in the calendar.\n\n```vue preview src=\"./demos/MinMax.en.vue\"\n```\n\n## Invalid\n\n```vue preview src=\"./demos/Invalid.en.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.en.vue\"\n```\n\n## Fluid\n\n```vue preview src=\"./demos/Fluid.en.vue\"\n```\n\n## Teleport\n\nThe panel Teleports to `body` by default. Use `append-to=\"self\"` or `teleport={false}` to render in place.\n\n```vue preview src=\"./demos/Teleport.en.vue\"\n```\n\n## Range\n\nWith `type=\"daterange\"`, click the start date then the end date. The value is `[start, end]` (ISO dates).\n\n```vue preview src=\"./demos/Range.en.vue\"\n```\n\n## Type variants\n\n`type` also supports `month` / `year` / `time` / `datetime` / `datetimerange`. Use `showSeconds` to include seconds.\n\nFor time-only, prefer the dedicated [TimePicker](/components/TimePicker); `type=\"time\"` on this component still works.\n\n`datetimerange`: after two date clicks, emits both ends with `00:00` (or `00:00:00`); while the panel stays open, time columns adjust the end time and selecting the finest unit closes.\n\n```vue preview src=\"./demos/Types.vue\"\n```\n\n## Shortcuts\n\n```vue preview src=\"./demos/Shortcuts.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| -------------- | --------------------------------------------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------- |\n| `modelValue` | `string \\| Date \\| [string, string] \\| null` | `null` | By `type`: `YYYY-MM-DD`, `[start,end]`, `YYYY-MM-DD HH:mm`, `HH:mm`, `YYYY-MM`, `YYYY`, etc. |\n| `type` | `'date' \\| 'daterange' \\| 'datetime' \\| 'datetimerange' \\| 'time' \\| 'month' \\| 'year'` | `'date'` | Panel and value shape. |\n| `showSeconds` | `boolean` | `false` | Include seconds for `time` / `datetime` / `datetimerange`. |\n| `label` | `string` | — | Label. |\n| `minDate` | `string \\| Date \\| null` | — | Optional lower bound. |\n| `maxDate` | `string \\| Date \\| null` | — | Optional upper bound. |\n| `placeholder` | `string` | locale | Placeholder. |\n| `format` | `string` | `'YYYY-MM-DD'` | Input display pattern (`YYYY`/`MM`/`DD`/`HH`/`mm`/`ss`); emitted value follows `type`. |\n| `clearable` | `boolean` | `true` | Show a clear button. |\n| `shortcuts` | `DatePickerShortcut[]` | `[]` | Panel shortcuts. |\n| `fluid` | `boolean` | `false` | Stretch to full width. |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | `small` / `large`; can inherit from ConfigProvider. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `invalid` | `boolean` | `false` | Invalid state. |\n| `teleport` | `boolean` | `true` | Panel 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| `errorMessage` | `string` | — | — |\n| `helpText` | `string` | — | — |\n| `id` | `string` | — | — |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n## Events\n\n| Event | Prop | Description |\n| ------------------- | ------------------------------------ | --------------------------------------- |\n| `update:modelValue` | `string \\| [string, string] \\| null` | Value change. |\n| `clear` | — | Fired when the clear button is clicked. |\n| `change` | — | — |\n| `hide` | — | — |\n| `show` | — | — |\n\n## Slots\n\n| Slot | Description |\n| --------- | --------------------------------- |\n| `trigger` | Custom trigger `{ value, open }`. |\n\n## Types\n\n<h4 id=\"DatePickerShortcut\">DatePickerShortcut</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface DatePickerShortcut {\n label: string;\n value:\n | DatePickerDateValue\n | [DatePickerDateValue, DatePickerDateValue]\n | (() => DatePickerDateValue | [DatePickerDateValue, DatePickerDateValue]);\n}\n```\n\n## Boundaries\n\nDate, range, and time modes are selected via `type` (`daterange`, `datetime`, `time`, etc.).\n"
|
|
7029
|
+
"markdown": "---\ntitle: DatePicker\ncategory: 02 / FORM\ndescription: Calendar overlay for a date, time, month, or year. String shape follows `type`. Supports min/max, shortcuts, format, showSeconds, and clearable.\n---\n\n# DatePicker\n\nDate picker with month navigation and a day grid; also supports time columns and month/year panels.\n\n## When to use\n\n- Use for date, date range, date-time, month, or year selection.\n- For time-only, prefer the dedicated [TimePicker](/components/TimePicker) entry (`type=\"time\"` still works).\n\n## Import\n\n```ts\nimport { MDatePicker } from \"morya-ui\";\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Size\n\n```vue preview src=\"./demos/Size.vue\"\n```\n\n## Min / Max\n\nDates outside the range are disabled in the calendar.\n\n```vue preview src=\"./demos/MinMax.en.vue\"\n```\n\n## Invalid\n\n```vue preview src=\"./demos/Invalid.en.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.en.vue\"\n```\n\n## Fluid\n\n```vue preview src=\"./demos/Fluid.en.vue\"\n```\n\n## Teleport\n\nThe panel Teleports to `body` by default. Use `append-to=\"self\"` or `teleport={false}` to render in place.\n\n```vue preview src=\"./demos/Teleport.en.vue\"\n```\n\n## Range\n\nWith `type=\"daterange\"`, click the start date then the end date. The value is `[start, end]` (ISO dates).\n\n```vue preview src=\"./demos/Range.en.vue\"\n```\n\n## Type variants\n\n`type` also supports `month` / `year` / `time` / `datetime` / `datetimerange`. Use `showSeconds` to include seconds.\n\nFor time-only, prefer the dedicated [TimePicker](/components/TimePicker); `type=\"time\"` on this component still works.\n\n`datetimerange`: after two date clicks, emits both ends with `00:00` (or `00:00:00`); while the panel stays open, time columns adjust the end time and selecting the finest unit closes.\n\n```vue preview src=\"./demos/Types.vue\"\n```\n\n## Shortcuts\n\n```vue preview src=\"./demos/Shortcuts.en.vue\"\n```\n\n## Range Shortcuts\n\n`shortcuts` shine for `daterange` / `datetimerange`: return a `[start, end]` tuple to select a range in one click. The shortcut matching the current value is highlighted automatically.\n\n```vue preview src=\"./demos/RangeShortcuts.en.vue\"\n```\n\n## Custom Format\n\n`format` only affects display; the emitted value still follows the `type` convention (`YYYY-MM-DD`, etc.). Mix `YYYY` / `MM` / `DD` / `HH` / `mm` / `ss` with free text.\n\n```vue preview src=\"./demos/Format.en.vue\"\n```\n\n## Datetime\n\n`datetime` and `datetimerange` combine the calendar and time columns in one panel. `show-seconds` includes seconds; `need-confirm` lets users finish the two-step pick before committing.\n\n```vue preview src=\"./demos/Datetime.en.vue\"\n```\n\n## Custom Trigger\n\nThe `#trigger` slot takes full control of the trigger element with scope `{ value, open }` — handy for buttons, icons, or composite layouts.\n\n```vue preview src=\"./demos/CustomTrigger.en.vue\"\n```\n\n## Disabled Ranges\n\nDates outside `min-date` / `max-date` are disabled in the calendar. Use them alone or together.\n\n```vue preview src=\"./demos/DisabledDates.en.vue\"\n```\n\n## Inline Panel\n\n`:teleport=\"false\"` with `append-to=\"self\"` renders the panel inline, outside the overlay stacking context — useful inside cards, drawers, or complex forms.\n\n```vue preview src=\"./demos/InlinePanel.en.vue\"\n```\n\n## Panel Mode Cycling\n\nClick the panel header label to cycle through days → months → years sub-panels, handy for jumping to a target year/month before returning to the day grid.\n\n## Status\n\n`status` accepts `'warning'` or `'error'` for visual emphasis (`invalid` / `errorMessage` imply `error`). Use `warning` with `helpText` for friendly reminders that don't block submission.\n\n```vue preview src=\"./demos/Status.en.vue\"\n```\n\n## Footer & Custom Cell\n\nThe `#footer` slot renders an action area at the bottom of the panel (scope `{ close }`); `#cell` customizes the day cell (scope includes `date / inMonth / selected / inRange / rangeStart / rangeEnd / isToday / disabled`) — great for holiday dots, schedule markers, or custom layouts.\n\n```vue preview src=\"./demos/FooterAndCell.en.vue\"\n```\n\n## needConfirm\n\nWith `need-confirm`, picking a value only writes to a draft; **OK** commits and closes, **Cancel** rolls back. Recommended for `datetime` / `datetimerange` / `time` where selection takes multiple steps.\n\n```vue preview src=\"./demos/NeedConfirm.en.vue\"\n```\n\n## Multiple Dates\n\n`multiple` (only valid for `type='date'`) makes `modelValue` a `string[]`; each click toggles selection and the panel stays open.\n\n```vue preview src=\"./demos/Multiple.en.vue\"\n```\n\n## Multiple in Practice: Shift Planning\n\nCombine `multiple` with `MTag` to display picked days in a friendly, readable way.\n\n```vue preview src=\"./demos/WorkSchedule.en.vue\"\n```\n\n## Form Integration\n\nCombine `required`, `error-message` and `min-date` for a complete date-range validation form.\n\n```vue preview src=\"./demos/FormIntegration.en.vue\"\n```\n\n## Input Mask\n\n`mask` makes the input editable, auto-inserting `-` / `/` / `:` separators matching the display `format`. Press **Enter** to commit, **Esc** or blur to revert. Supported on `date` / `datetime` / `time` only.\n\n```vue preview src=\"./demos/Mask.en.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| -------------- | --------------------------------------------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------- |\n| `modelValue` | `string \\| Date \\| [string, string] \\| null` | `null` | By `type`: `YYYY-MM-DD`, `[start,end]`, `YYYY-MM-DD HH:mm`, `HH:mm`, `YYYY-MM`, `YYYY`, etc. |\n| `type` | `'date' \\| 'daterange' \\| 'datetime' \\| 'datetimerange' \\| 'time' \\| 'month' \\| 'year'` | `'date'` | Panel and value shape. |\n| `showSeconds` | `boolean` | `false` | Include seconds for `time` / `datetime` / `datetimerange`. |\n| `label` | `string` | — | Label. |\n| `minDate` | `string \\| Date \\| null` | — | Optional lower bound. |\n| `maxDate` | `string \\| Date \\| null` | — | Optional upper bound. |\n| `placeholder` | `string` | locale | Placeholder. |\n| `format` | `string` | `'YYYY-MM-DD'` | Input display pattern (`YYYY`/`MM`/`DD`/`HH`/`mm`/`ss`); emitted value follows `type`. |\n| `clearable` | `boolean` | `true` | Show a clear button. |\n| `shortcuts` | `DatePickerShortcut[]` | `[]` | Panel shortcuts; the one matching the current value is highlighted. |\n| `status` | `'default' \\| 'warning' \\| 'error'` | `'default'` | Visual status; `invalid` / `errorMessage` imply `error`. |\n| `needConfirm` | `boolean` | `false` | Defer commit until OK; Cancel rolls back. |\n| `multiple` | `boolean` | `false` | Pick many dates (`type='date'` only); `modelValue` is `string[]`. |\n| `mask` | `boolean` | `false` | Editable input with auto separators; Enter commits, Esc/blur reverts. |\n| `fluid` | `boolean` | `false` | Stretch to full width. |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | `small` / `large`; can inherit from ConfigProvider. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `invalid` | `boolean` | `false` | Invalid state. |\n| `teleport` | `boolean` | `true` | Panel 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| `errorMessage` | `string` | — | — |\n| `helpText` | `string` | — | — |\n| `id` | `string` | — | — |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n## Events\n\n| Event | Prop | Description |\n| ------------------- | ------------------------------------ | --------------------------------------- |\n| `update:modelValue` | `string \\| [string, string] \\| null` | Value change. |\n| `clear` | — | Fired when the clear button is clicked. |\n| `change` | — | — |\n| `hide` | — | — |\n| `show` | — | — |\n\n## Slots\n\n| Slot | Description |\n| --------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| `trigger` | Custom trigger `{ value, open }`. |\n| `footer` | Panel bottom action area, scope `{ close }`. When `need-confirm` is on and no footer is given, default OK/Cancel is shown. |\n| `cell` | Custom day cell, scope `{ date, inMonth, selected, inRange, rangeStart, rangeEnd, isToday, disabled }`. |\n\n## Types\n\n<h4 id=\"DatePickerShortcut\">DatePickerShortcut</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ninterface DatePickerShortcut {\n label: string;\n value:\n | DatePickerDateValue\n | [DatePickerDateValue, DatePickerDateValue]\n | (() => DatePickerDateValue | [DatePickerDateValue, DatePickerDateValue]);\n}\n```\n\n## Boundaries\n\nDate, range, and time modes are selected via `type` (`daterange`, `datetime`, `time`, etc.).\n"
|
|
6624
7030
|
}
|
|
6625
7031
|
}
|
|
6626
7032
|
},
|
|
@@ -17783,7 +18189,7 @@
|
|
|
17783
18189
|
"exportName": "MOrderList",
|
|
17784
18190
|
"category": "03 / DATA",
|
|
17785
18191
|
"description": "列表拖拽与上下按钮排序。",
|
|
17786
|
-
"descriptionEn": "Reorder a list with drag
|
|
18192
|
+
"descriptionEn": "Reorder a list with drag handles and up/down buttons.",
|
|
17787
18193
|
"import": "import { MOrderList } from 'morya-ui'",
|
|
17788
18194
|
"props": [
|
|
17789
18195
|
{
|
|
@@ -17792,6 +18198,12 @@
|
|
|
17792
18198
|
"default": "[]",
|
|
17793
18199
|
"description": "列表数据。"
|
|
17794
18200
|
},
|
|
18201
|
+
{
|
|
18202
|
+
"name": "selection",
|
|
18203
|
+
"type": "number | null",
|
|
18204
|
+
"default": "—",
|
|
18205
|
+
"description": "受控选中下标,配合 `v-model:selection`。"
|
|
18206
|
+
},
|
|
17795
18207
|
{
|
|
17796
18208
|
"name": "dataKey",
|
|
17797
18209
|
"type": "string",
|
|
@@ -17810,15 +18222,21 @@
|
|
|
17810
18222
|
"default": "true",
|
|
17811
18223
|
"description": "是否启用拖拽。"
|
|
17812
18224
|
},
|
|
18225
|
+
{
|
|
18226
|
+
"name": "disabled",
|
|
18227
|
+
"type": "boolean",
|
|
18228
|
+
"default": "false",
|
|
18229
|
+
"description": "禁用全部交互(按钮、拖拽、选中)。"
|
|
18230
|
+
},
|
|
17813
18231
|
{
|
|
17814
18232
|
"name": "emptyMessage",
|
|
17815
18233
|
"type": "string",
|
|
17816
18234
|
"default": "—",
|
|
17817
|
-
"description": "
|
|
18235
|
+
"description": "空态文案,默认取 locale `emptyMessage`。"
|
|
17818
18236
|
},
|
|
17819
18237
|
{
|
|
17820
18238
|
"name": "pt",
|
|
17821
|
-
"type": "[
|
|
18239
|
+
"type": "[OrderListPassThrough](/docs/types#OrderListPassThrough)",
|
|
17822
18240
|
"default": "—",
|
|
17823
18241
|
"description": "DOM 透传,见 [样式与 attrs](/docs/attrs)."
|
|
17824
18242
|
}
|
|
@@ -17827,22 +18245,27 @@
|
|
|
17827
18245
|
{
|
|
17828
18246
|
"name": "update:modelValue",
|
|
17829
18247
|
"payload": "unknown[]",
|
|
17830
|
-
"description": "
|
|
18248
|
+
"description": "顺序变化后的新数组。"
|
|
18249
|
+
},
|
|
18250
|
+
{
|
|
18251
|
+
"name": "update:selection",
|
|
18252
|
+
"payload": "number | null",
|
|
18253
|
+
"description": "选中下标变化。"
|
|
17831
18254
|
},
|
|
17832
18255
|
{
|
|
17833
18256
|
"name": "reorder",
|
|
17834
|
-
"payload": "
|
|
17835
|
-
"description": "
|
|
18257
|
+
"payload": "{ item, from, to }",
|
|
18258
|
+
"description": "单次移动的详情(移动项、原下标、新下标)。"
|
|
17836
18259
|
}
|
|
17837
18260
|
],
|
|
17838
18261
|
"slots": [
|
|
17839
18262
|
{
|
|
17840
18263
|
"name": "item",
|
|
17841
|
-
"description": "`{ item, index }` 自定义项。"
|
|
18264
|
+
"description": "`{ item, index, selected, dragging }` 自定义项。"
|
|
17842
18265
|
},
|
|
17843
18266
|
{
|
|
17844
18267
|
"name": "empty",
|
|
17845
|
-
"description": "
|
|
18268
|
+
"description": "自定义空态内容。"
|
|
17846
18269
|
}
|
|
17847
18270
|
],
|
|
17848
18271
|
"methods": [],
|
|
@@ -17865,6 +18288,24 @@
|
|
|
17865
18288
|
"code": "<script setup lang=\"ts\">\nimport { MOrderList } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst items = ref(['设计', '开发', '测试', '发布'])\n</script>\n\n<template>\n <MOrderList v-model=\"items\" />\n</template>",
|
|
17866
18289
|
"locale": "zh-CN"
|
|
17867
18290
|
},
|
|
18291
|
+
{
|
|
18292
|
+
"id": "禁用-1",
|
|
18293
|
+
"section": "禁用",
|
|
18294
|
+
"sectionId": "禁用",
|
|
18295
|
+
"lang": "vue",
|
|
18296
|
+
"preview": true,
|
|
18297
|
+
"code": "<script setup lang=\"ts\">\nimport { MOrderList } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst items = ref(['设计', '开发', '测试', '发布'])\n</script>\n\n<template>\n <MOrderList v-model=\"items\" disabled />\n</template>",
|
|
18298
|
+
"locale": "zh-CN"
|
|
18299
|
+
},
|
|
18300
|
+
{
|
|
18301
|
+
"id": "自定义项-1",
|
|
18302
|
+
"section": "自定义项",
|
|
18303
|
+
"sectionId": "自定义项",
|
|
18304
|
+
"lang": "vue",
|
|
18305
|
+
"preview": true,
|
|
18306
|
+
"code": "<script setup lang=\"ts\">\nimport { MOrderList } from 'morya-ui'\nimport { ref } from 'vue'\n\ninterface Task {\n id: number\n title: string\n tag: string\n}\n\nconst tasks = ref<Task[]>([\n { id: 1, title: '需求评审', tag: '产品' },\n { id: 2, title: '接口设计', tag: '后端' },\n { id: 3, title: '页面开发', tag: '前端' },\n { id: 4, title: '联调测试', tag: 'QA' },\n])\n</script>\n\n<template>\n <MOrderList v-model=\"tasks\" data-key=\"id\">\n <template #item=\"{ item, selected }\">\n <span style=\"display:flex;justify-content:space-between;width:100%;gap:0.5rem\">\n <span>{{ (item as Task).title }}</span>\n <span\n :style=\"{\n fontSize: '0.75rem',\n padding: '0 0.4rem',\n borderRadius: '999px',\n background: selected ? 'var(--m-color-primary)' : 'var(--m-color-border)',\n color: selected ? 'var(--m-color-on-emphasis)' : 'var(--m-color-text-muted)',\n }\"\n >{{ (item as Task).tag }}</span>\n </span>\n </template>\n </MOrderList>\n</template>",
|
|
18307
|
+
"locale": "zh-CN"
|
|
18308
|
+
},
|
|
17868
18309
|
{
|
|
17869
18310
|
"id": "import-1",
|
|
17870
18311
|
"section": "Import",
|
|
@@ -17882,6 +18323,24 @@
|
|
|
17882
18323
|
"preview": true,
|
|
17883
18324
|
"code": "<script setup lang=\"ts\">\nimport { MOrderList } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst items = ref(['Design', 'Development', 'Testing', 'Release'])\n</script>\n\n<template>\n <MOrderList v-model=\"items\" />\n</template>",
|
|
17884
18325
|
"locale": "en-US"
|
|
18326
|
+
},
|
|
18327
|
+
{
|
|
18328
|
+
"id": "disabled-1",
|
|
18329
|
+
"section": "Disabled",
|
|
18330
|
+
"sectionId": "disabled",
|
|
18331
|
+
"lang": "vue",
|
|
18332
|
+
"preview": true,
|
|
18333
|
+
"code": "<script setup lang=\"ts\">\nimport { MOrderList } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst items = ref(['Design', 'Develop', 'Test', 'Release'])\n</script>\n\n<template>\n <MOrderList v-model=\"items\" disabled />\n</template>",
|
|
18334
|
+
"locale": "en-US"
|
|
18335
|
+
},
|
|
18336
|
+
{
|
|
18337
|
+
"id": "custom-item-1",
|
|
18338
|
+
"section": "Custom item",
|
|
18339
|
+
"sectionId": "custom-item",
|
|
18340
|
+
"lang": "vue",
|
|
18341
|
+
"preview": true,
|
|
18342
|
+
"code": "<script setup lang=\"ts\">\nimport { MOrderList } from 'morya-ui'\nimport { ref } from 'vue'\n\ninterface Task {\n id: number\n title: string\n tag: string\n}\n\nconst tasks = ref<Task[]>([\n { id: 1, title: 'Requirement review', tag: 'Product' },\n { id: 2, title: 'API design', tag: 'Backend' },\n { id: 3, title: 'Page development', tag: 'Frontend' },\n { id: 4, title: 'Integration test', tag: 'QA' },\n])\n</script>\n\n<template>\n <MOrderList v-model=\"tasks\" data-key=\"id\">\n <template #item=\"{ item, selected }\">\n <span style=\"display:flex;justify-content:space-between;width:100%;gap:0.5rem\">\n <span>{{ (item as Task).title }}</span>\n <span\n :style=\"{\n fontSize: '0.75rem',\n padding: '0 0.4rem',\n borderRadius: '999px',\n background: selected ? 'var(--m-color-primary)' : 'var(--m-color-border)',\n color: selected ? 'var(--m-color-on-emphasis)' : 'var(--m-color-text-muted)',\n }\"\n >{{ (item as Task).tag }}</span>\n </span>\n </template>\n </MOrderList>\n</template>",
|
|
18343
|
+
"locale": "en-US"
|
|
17885
18344
|
}
|
|
17886
18345
|
],
|
|
17887
18346
|
"locales": {
|
|
@@ -17892,7 +18351,7 @@
|
|
|
17892
18351
|
{
|
|
17893
18352
|
"id": "overview",
|
|
17894
18353
|
"title": "",
|
|
17895
|
-
"body": "# OrderList\n\n支持拖拽手柄重排(原生 HTML5 DnD
|
|
18354
|
+
"body": "# OrderList\n\n支持拖拽手柄重排(原生 HTML5 DnD,无外部拖拽库),并保留上下/置顶/置底按钮作为键盘友好备选。"
|
|
17896
18355
|
},
|
|
17897
18356
|
{
|
|
17898
18357
|
"id": "引入",
|
|
@@ -17904,32 +18363,52 @@
|
|
|
17904
18363
|
"title": "基础用法",
|
|
17905
18364
|
"body": "```vue preview src=\"./demos/Basic.zh.vue\"\n```"
|
|
17906
18365
|
},
|
|
18366
|
+
{
|
|
18367
|
+
"id": "禁用",
|
|
18368
|
+
"title": "禁用",
|
|
18369
|
+
"body": "```vue preview src=\"./demos/Disabled.zh.vue\"\n```"
|
|
18370
|
+
},
|
|
18371
|
+
{
|
|
18372
|
+
"id": "自定义项",
|
|
18373
|
+
"title": "自定义项",
|
|
18374
|
+
"body": "通过 `#item` 插槽自定义渲染,作用域含 `{ item, index, selected, dragging }`。\n\n```vue preview src=\"./demos/CustomItem.zh.vue\"\n```"
|
|
18375
|
+
},
|
|
18376
|
+
{
|
|
18377
|
+
"id": "键盘操作",
|
|
18378
|
+
"title": "键盘操作",
|
|
18379
|
+
"body": "| 按键 | 说明 |\n| --- | --- |\n| `↑` / `↓` | 移动选中项高亮。 |\n| `Ctrl/⌘ + ↑` / `Ctrl/⌘ + ↓` | 将选中项上移 / 下移一位。 |\n| `Ctrl/⌘ + Home` / `Ctrl/⌘ + End` | 将选中项置顶 / 置底。 |\n| `Home` / `End` | 高亮首项 / 末项。 |"
|
|
18380
|
+
},
|
|
17907
18381
|
{
|
|
17908
18382
|
"id": "props",
|
|
17909
18383
|
"title": "Props",
|
|
17910
|
-
"body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `unknown[]` | `[]` | 列表数据。 |\n| `dataKey` | `string` | — | 对象项的唯一键。 |\n| `listStyle` | `string \\| object` | — | 列表样式。 |\n| `dragdrop` | `boolean` | `true` | 是否启用拖拽。 |\n| `emptyMessage` | `string` | — |
|
|
18384
|
+
"body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `unknown[]` | `[]` | 列表数据。 |\n| `selection` | `number \\| null` | — | 受控选中下标,配合 `v-model:selection`。 |\n| `dataKey` | `string` | — | 对象项的唯一键。 |\n| `listStyle` | `string \\| object` | — | 列表样式。 |\n| `dragdrop` | `boolean` | `true` | 是否启用拖拽。 |\n| `disabled` | `boolean` | `false` | 禁用全部交互(按钮、拖拽、选中)。 |\n| `emptyMessage` | `string` | — | 空态文案,默认取 locale `emptyMessage`。 |\n| `pt` | [OrderListPassThrough](/docs/types#OrderListPassThrough) | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
|
|
17911
18385
|
},
|
|
17912
18386
|
{
|
|
17913
18387
|
"id": "slots",
|
|
17914
18388
|
"title": "Slots",
|
|
17915
|
-
"body": "| 插槽 | 说明 |\n| --- | --- |\n| `item` | `{ item, index }` 自定义项。 |\n| `empty` |
|
|
18389
|
+
"body": "| 插槽 | 说明 |\n| --- | --- |\n| `item` | `{ item, index, selected, dragging }` 自定义项。 |\n| `empty` | 自定义空态内容。 |"
|
|
17916
18390
|
},
|
|
17917
18391
|
{
|
|
17918
18392
|
"id": "events",
|
|
17919
18393
|
"title": "Events",
|
|
17920
|
-
"body": "| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `unknown[]` |
|
|
18394
|
+
"body": "| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `unknown[]` | 顺序变化后的新数组。 |\n| `update:selection` | `number \\| null` | 选中下标变化。 |\n| `reorder` | `{ item, from, to }` | 单次移动的详情(移动项、原下标、新下标)。 |"
|
|
18395
|
+
},
|
|
18396
|
+
{
|
|
18397
|
+
"id": "无障碍",
|
|
18398
|
+
"title": "无障碍",
|
|
18399
|
+
"body": "- 列表为 `role=\"listbox\"`,项为 `role=\"option\"`,选中项同步 `aria-selected`。\n- 拖拽仅在手柄 `pointerdown` 后启动,避免误触;键盘可完整完成所有排序操作。\n- `disabled` 时列表标记 `aria-disabled`,项不可聚焦、不可拖拽。"
|
|
17921
18400
|
}
|
|
17922
18401
|
],
|
|
17923
|
-
"markdown": "---\ntitle: OrderList\ncategory: 03 / DATA\ndescription: 列表拖拽与上下按钮排序。\n---\n\n# OrderList\n\n支持拖拽手柄重排(原生 HTML5 DnD
|
|
18402
|
+
"markdown": "---\ntitle: OrderList\ncategory: 03 / DATA\ndescription: 列表拖拽与上下按钮排序。\n---\n\n# OrderList\n\n支持拖拽手柄重排(原生 HTML5 DnD,无外部拖拽库),并保留上下/置顶/置底按钮作为键盘友好备选。\n\n## 引入\n\n```ts\nimport { MOrderList } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## 禁用\n\n```vue preview src=\"./demos/Disabled.zh.vue\"\n```\n\n## 自定义项\n\n通过 `#item` 插槽自定义渲染,作用域含 `{ item, index, selected, dragging }`。\n\n```vue preview src=\"./demos/CustomItem.zh.vue\"\n```\n\n## 键盘操作\n\n| 按键 | 说明 |\n| --- | --- |\n| `↑` / `↓` | 移动选中项高亮。 |\n| `Ctrl/⌘ + ↑` / `Ctrl/⌘ + ↓` | 将选中项上移 / 下移一位。 |\n| `Ctrl/⌘ + Home` / `Ctrl/⌘ + End` | 将选中项置顶 / 置底。 |\n| `Home` / `End` | 高亮首项 / 末项。 |\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `unknown[]` | `[]` | 列表数据。 |\n| `selection` | `number \\| null` | — | 受控选中下标,配合 `v-model:selection`。 |\n| `dataKey` | `string` | — | 对象项的唯一键。 |\n| `listStyle` | `string \\| object` | — | 列表样式。 |\n| `dragdrop` | `boolean` | `true` | 是否启用拖拽。 |\n| `disabled` | `boolean` | `false` | 禁用全部交互(按钮、拖拽、选中)。 |\n| `emptyMessage` | `string` | — | 空态文案,默认取 locale `emptyMessage`。 |\n| `pt` | [OrderListPassThrough](/docs/types#OrderListPassThrough) | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n## Slots\n\n| 插槽 | 说明 |\n| --- | --- |\n| `item` | `{ item, index, selected, dragging }` 自定义项。 |\n| `empty` | 自定义空态内容。 |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `unknown[]` | 顺序变化后的新数组。 |\n| `update:selection` | `number \\| null` | 选中下标变化。 |\n| `reorder` | `{ item, from, to }` | 单次移动的详情(移动项、原下标、新下标)。 |\n\n## 无障碍\n\n- 列表为 `role=\"listbox\"`,项为 `role=\"option\"`,选中项同步 `aria-selected`。\n- 拖拽仅在手柄 `pointerdown` 后启动,避免误触;键盘可完整完成所有排序操作。\n- `disabled` 时列表标记 `aria-disabled`,项不可聚焦、不可拖拽。\n"
|
|
17924
18403
|
},
|
|
17925
18404
|
"en-US": {
|
|
17926
18405
|
"title": "OrderList",
|
|
17927
|
-
"description": "Reorder a list with drag
|
|
18406
|
+
"description": "Reorder a list with drag handles and up/down buttons.",
|
|
17928
18407
|
"sections": [
|
|
17929
18408
|
{
|
|
17930
18409
|
"id": "overview",
|
|
17931
18410
|
"title": "",
|
|
17932
|
-
"body": "# OrderList\n\nReorder with
|
|
18411
|
+
"body": "# OrderList\n\nReorder items with drag handles (native HTML5 DnD, no external library), with up/down and top/bottom buttons as a keyboard-friendly alternative."
|
|
17933
18412
|
},
|
|
17934
18413
|
{
|
|
17935
18414
|
"id": "import",
|
|
@@ -17941,23 +18420,43 @@
|
|
|
17941
18420
|
"title": "Basic",
|
|
17942
18421
|
"body": "```vue preview src=\"./demos/Basic.en.vue\"\n```"
|
|
17943
18422
|
},
|
|
18423
|
+
{
|
|
18424
|
+
"id": "disabled",
|
|
18425
|
+
"title": "Disabled",
|
|
18426
|
+
"body": "```vue preview src=\"./demos/Disabled.en.vue\"\n```"
|
|
18427
|
+
},
|
|
18428
|
+
{
|
|
18429
|
+
"id": "custom-item",
|
|
18430
|
+
"title": "Custom item",
|
|
18431
|
+
"body": "Customize rendering via the `#item` slot with scope `{ item, index, selected, dragging }`.\n\n```vue preview src=\"./demos/CustomItem.en.vue\"\n```"
|
|
18432
|
+
},
|
|
18433
|
+
{
|
|
18434
|
+
"id": "keyboard",
|
|
18435
|
+
"title": "Keyboard",
|
|
18436
|
+
"body": "| Key | Action |\n| --- | --- |\n| `↑` / `↓` | Move the selection highlight. |\n| `Ctrl/⌘ + ↑` / `Ctrl/⌘ + ↓` | Move the selected item up / down one step. |\n| `Ctrl/⌘ + Home` / `Ctrl/⌘ + End` | Move the selected item to top / bottom. |\n| `Home` / `End` | Highlight the first / last item. |"
|
|
18437
|
+
},
|
|
17944
18438
|
{
|
|
17945
18439
|
"id": "props",
|
|
17946
18440
|
"title": "Props",
|
|
17947
|
-
"body": "|
|
|
18441
|
+
"body": "| Name | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `unknown[]` | `[]` | List data. |\n| `selection` | `number \\| null` | — | Controlled selected index, with `v-model:selection`. |\n| `dataKey` | `string` | — | Unique key for object items. |\n| `listStyle` | `string \\| object` | — | List style. |\n| `dragdrop` | `boolean` | `true` | Enable drag-and-drop reorder. |\n| `disabled` | `boolean` | `false` | Disable all interactions (buttons, drag, selection). |\n| `emptyMessage` | `string` | — | Empty state message; defaults to locale `emptyMessage`. |\n| `pt` | [OrderListPassThrough](/docs/types#OrderListPassThrough) | — | DOM pass-through; see [Styling & attrs](/docs/attrs). |"
|
|
17948
18442
|
},
|
|
17949
18443
|
{
|
|
17950
18444
|
"id": "slots",
|
|
17951
18445
|
"title": "Slots",
|
|
17952
|
-
"body": "| Slot | Description |\n| --- | --- |\n| `item` | `{ item, index }` custom item. |"
|
|
18446
|
+
"body": "| Slot | Description |\n| --- | --- |\n| `item` | `{ item, index, selected, dragging }` custom item. |\n| `empty` | Custom empty content. |"
|
|
17953
18447
|
},
|
|
17954
18448
|
{
|
|
17955
18449
|
"id": "events",
|
|
17956
18450
|
"title": "Events",
|
|
17957
|
-
"body": "| Event |
|
|
18451
|
+
"body": "| Event | Payload | Description |\n| --- | --- | --- |\n| `update:modelValue` | `unknown[]` | New order after reorder. |\n| `update:selection` | `number \\| null` | Selected index change. |\n| `reorder` | `{ item, from, to }` | Detail of a single move (item, original index, new index). |"
|
|
18452
|
+
},
|
|
18453
|
+
{
|
|
18454
|
+
"id": "accessibility",
|
|
18455
|
+
"title": "Accessibility",
|
|
18456
|
+
"body": "- The list is `role=\"listbox\"` and items are `role=\"option\"` with `aria-selected`.\n- Dragging only starts after the handle is pressed, avoiding accidental drags; every reorder is fully keyboard-operable.\n- When `disabled`, the list is marked `aria-disabled`; items are not focusable or draggable."
|
|
17958
18457
|
}
|
|
17959
18458
|
],
|
|
17960
|
-
"markdown": "---\ntitle: OrderList\ncategory: 03 / DATA\ndescription: Reorder a list with drag
|
|
18459
|
+
"markdown": "---\ntitle: OrderList\ncategory: 03 / DATA\ndescription: Reorder a list with drag handles and up/down buttons.\n---\n\n# OrderList\n\nReorder items with drag handles (native HTML5 DnD, no external library), with up/down and top/bottom buttons as a keyboard-friendly alternative.\n\n## Import\n\n```ts\nimport { MOrderList } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Disabled\n\n```vue preview src=\"./demos/Disabled.en.vue\"\n```\n\n## Custom item\n\nCustomize rendering via the `#item` slot with scope `{ item, index, selected, dragging }`.\n\n```vue preview src=\"./demos/CustomItem.en.vue\"\n```\n\n## Keyboard\n\n| Key | Action |\n| --- | --- |\n| `↑` / `↓` | Move the selection highlight. |\n| `Ctrl/⌘ + ↑` / `Ctrl/⌘ + ↓` | Move the selected item up / down one step. |\n| `Ctrl/⌘ + Home` / `Ctrl/⌘ + End` | Move the selected item to top / bottom. |\n| `Home` / `End` | Highlight the first / last item. |\n\n## Props\n\n| Name | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `unknown[]` | `[]` | List data. |\n| `selection` | `number \\| null` | — | Controlled selected index, with `v-model:selection`. |\n| `dataKey` | `string` | — | Unique key for object items. |\n| `listStyle` | `string \\| object` | — | List style. |\n| `dragdrop` | `boolean` | `true` | Enable drag-and-drop reorder. |\n| `disabled` | `boolean` | `false` | Disable all interactions (buttons, drag, selection). |\n| `emptyMessage` | `string` | — | Empty state message; defaults to locale `emptyMessage`. |\n| `pt` | [OrderListPassThrough](/docs/types#OrderListPassThrough) | — | DOM pass-through; see [Styling & attrs](/docs/attrs). |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `item` | `{ item, index, selected, dragging }` custom item. |\n| `empty` | Custom empty content. |\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `update:modelValue` | `unknown[]` | New order after reorder. |\n| `update:selection` | `number \\| null` | Selected index change. |\n| `reorder` | `{ item, from, to }` | Detail of a single move (item, original index, new index). |\n\n## Accessibility\n\n- The list is `role=\"listbox\"` and items are `role=\"option\"` with `aria-selected`.\n- Dragging only starts after the handle is pressed, avoiding accidental drags; every reorder is fully keyboard-operable.\n- When `disabled`, the list is marked `aria-disabled`; items are not focusable or draggable.\n"
|
|
17961
18460
|
}
|
|
17962
18461
|
}
|
|
17963
18462
|
},
|
|
@@ -25743,8 +26242,8 @@
|
|
|
25743
26242
|
"name": "Table",
|
|
25744
26243
|
"exportName": "MTable",
|
|
25745
26244
|
"category": "03 / DATA",
|
|
25746
|
-
"description": "
|
|
25747
|
-
"descriptionEn": "Data table with sorting, filtering, selection, pagination,
|
|
26245
|
+
"description": "数据表格。支持排序、筛选、选择、分页、固定列、列拖拽、列设置、骨架屏与虚拟滚动。列宽支持 width / minWidth / fit。",
|
|
26246
|
+
"descriptionEn": "Data table with sorting, filtering, selection, pagination, fixed columns, column drag, column settings, skeleton loading and virtual scrolling. Column widths support width / minWidth / fit.",
|
|
25748
26247
|
"import": "import { MTable } from 'morya-ui'",
|
|
25749
26248
|
"props": [
|
|
25750
26249
|
{
|
|
@@ -25855,6 +26354,18 @@
|
|
|
25855
26354
|
"default": "40",
|
|
25856
26355
|
"description": "虚拟行高估算。"
|
|
25857
26356
|
},
|
|
26357
|
+
{
|
|
26358
|
+
"name": "virtualDynamicRowHeight",
|
|
26359
|
+
"type": "boolean",
|
|
26360
|
+
"default": "false",
|
|
26361
|
+
"description": "动态行高虚拟滚动(实测行高缓存,配合 `ResizeObserver`)。"
|
|
26362
|
+
},
|
|
26363
|
+
{
|
|
26364
|
+
"name": "virtualOverscan",
|
|
26365
|
+
"type": "number",
|
|
26366
|
+
"default": "4",
|
|
26367
|
+
"description": "虚拟滚动上下额外渲染的行数,减少白屏闪烁。"
|
|
26368
|
+
},
|
|
25858
26369
|
{
|
|
25859
26370
|
"name": "hiddenColumns",
|
|
25860
26371
|
"type": "string[] | null",
|
|
@@ -25867,6 +26378,30 @@
|
|
|
25867
26378
|
"default": "null",
|
|
25868
26379
|
"description": "叶列顺序(`v-model:column-order`)。"
|
|
25869
26380
|
},
|
|
26381
|
+
{
|
|
26382
|
+
"name": "columnSetting",
|
|
26383
|
+
"type": "boolean",
|
|
26384
|
+
"default": "false",
|
|
26385
|
+
"description": "显示列设置按钮(显示/隐藏列)。"
|
|
26386
|
+
},
|
|
26387
|
+
{
|
|
26388
|
+
"name": "columnDrag",
|
|
26389
|
+
"type": "boolean",
|
|
26390
|
+
"default": "false",
|
|
26391
|
+
"description": "表头拖拽排序。"
|
|
26392
|
+
},
|
|
26393
|
+
{
|
|
26394
|
+
"name": "skeleton",
|
|
26395
|
+
"type": "boolean",
|
|
26396
|
+
"default": "false",
|
|
26397
|
+
"description": "骨架屏加载态。"
|
|
26398
|
+
},
|
|
26399
|
+
{
|
|
26400
|
+
"name": "skeletonRows",
|
|
26401
|
+
"type": "number",
|
|
26402
|
+
"default": "5",
|
|
26403
|
+
"description": "骨架屏行数。"
|
|
26404
|
+
},
|
|
25870
26405
|
{
|
|
25871
26406
|
"name": "showFooter",
|
|
25872
26407
|
"type": "boolean",
|
|
@@ -25939,23 +26474,41 @@
|
|
|
25939
26474
|
"default": "true",
|
|
25940
26475
|
"description": "行 hover 高亮。"
|
|
25941
26476
|
},
|
|
26477
|
+
{
|
|
26478
|
+
"name": "sortConfig",
|
|
26479
|
+
"type": "TableSortConfig | null",
|
|
26480
|
+
"default": "null",
|
|
26481
|
+
"description": "统一排序配置 `{ field, order, multiple, must, mode }`。"
|
|
26482
|
+
},
|
|
25942
26483
|
{
|
|
25943
26484
|
"name": "sortField",
|
|
25944
|
-
"type": "
|
|
25945
|
-
"default": "
|
|
25946
|
-
"description": "
|
|
26485
|
+
"type": "string | null",
|
|
26486
|
+
"default": "null",
|
|
26487
|
+
"description": "(兼容)单字段排序。建议用 `sortConfig`。"
|
|
25947
26488
|
},
|
|
25948
26489
|
{
|
|
25949
26490
|
"name": "sortOrder",
|
|
25950
|
-
"type": "
|
|
25951
|
-
"default": "
|
|
25952
|
-
"description": "
|
|
26491
|
+
"type": "'asc' | 'desc' | null",
|
|
26492
|
+
"default": "null",
|
|
26493
|
+
"description": "(兼容)单字段排序方向。建议用 `sortConfig`。"
|
|
26494
|
+
},
|
|
26495
|
+
{
|
|
26496
|
+
"name": "multiSort",
|
|
26497
|
+
"type": "boolean",
|
|
26498
|
+
"default": "false",
|
|
26499
|
+
"description": "(兼容)多列排序。建议用 `sortConfig.multiple`。"
|
|
26500
|
+
},
|
|
26501
|
+
{
|
|
26502
|
+
"name": "mustSort",
|
|
26503
|
+
"type": "boolean",
|
|
26504
|
+
"default": "false",
|
|
26505
|
+
"description": "(兼容)禁止取消排序。建议用 `sortConfig.must`。"
|
|
25953
26506
|
},
|
|
25954
26507
|
{
|
|
25955
26508
|
"name": "sortMode",
|
|
25956
26509
|
"type": "'client' | 'emit'",
|
|
25957
26510
|
"default": "'client'",
|
|
25958
|
-
"description": "
|
|
26511
|
+
"description": "(兼容)排序模式。建议用 `sortConfig.mode`。"
|
|
25959
26512
|
},
|
|
25960
26513
|
{
|
|
25961
26514
|
"name": "searchField",
|
|
@@ -25975,6 +26528,18 @@
|
|
|
25975
26528
|
"default": "null",
|
|
25976
26529
|
"description": "结构化筛选条件。"
|
|
25977
26530
|
},
|
|
26531
|
+
{
|
|
26532
|
+
"name": "filterModel",
|
|
26533
|
+
"type": "Record<string, unknown> | null",
|
|
26534
|
+
"default": "null",
|
|
26535
|
+
"description": "列筛选 v-model(与 `update:filter-model` 配合)。"
|
|
26536
|
+
},
|
|
26537
|
+
{
|
|
26538
|
+
"name": "filters",
|
|
26539
|
+
"type": "Record<string, unknown> | null",
|
|
26540
|
+
"default": "null",
|
|
26541
|
+
"description": "(兼容)旧筛选 v-model 名。"
|
|
26542
|
+
},
|
|
25978
26543
|
{
|
|
25979
26544
|
"name": "loading",
|
|
25980
26545
|
"type": "boolean",
|
|
@@ -26077,12 +26642,6 @@
|
|
|
26077
26642
|
"default": "—",
|
|
26078
26643
|
"description": "—"
|
|
26079
26644
|
},
|
|
26080
|
-
{
|
|
26081
|
-
"name": "filters",
|
|
26082
|
-
"type": "Record<string, unknown> | null",
|
|
26083
|
-
"default": "—",
|
|
26084
|
-
"description": "—"
|
|
26085
|
-
},
|
|
26086
26645
|
{
|
|
26087
26646
|
"name": "fixedCheckbox",
|
|
26088
26647
|
"type": "boolean",
|
|
@@ -26131,18 +26690,6 @@
|
|
|
26131
26690
|
"default": "—",
|
|
26132
26691
|
"description": "—"
|
|
26133
26692
|
},
|
|
26134
|
-
{
|
|
26135
|
-
"name": "multiSort",
|
|
26136
|
-
"type": "boolean",
|
|
26137
|
-
"default": "—",
|
|
26138
|
-
"description": "—"
|
|
26139
|
-
},
|
|
26140
|
-
{
|
|
26141
|
-
"name": "mustSort",
|
|
26142
|
-
"type": "boolean",
|
|
26143
|
-
"default": "—",
|
|
26144
|
-
"description": "—"
|
|
26145
|
-
},
|
|
26146
26693
|
{
|
|
26147
26694
|
"name": "showIndex",
|
|
26148
26695
|
"type": "boolean",
|
|
@@ -26175,17 +26722,27 @@
|
|
|
26175
26722
|
},
|
|
26176
26723
|
{
|
|
26177
26724
|
"name": "pt",
|
|
26178
|
-
"type": "
|
|
26725
|
+
"type": "TablePassThrough",
|
|
26179
26726
|
"default": "—",
|
|
26180
|
-
"description": "DOM
|
|
26727
|
+
"description": "多部分 DOM 透传:`{ root, scrollbar, thead, tbody, tfoot, pagination, emptyMessage }`。"
|
|
26181
26728
|
}
|
|
26182
26729
|
],
|
|
26183
26730
|
"events": [
|
|
26184
26731
|
{
|
|
26185
|
-
"name": "sort",
|
|
26732
|
+
"name": "sort-change",
|
|
26186
26733
|
"payload": "{ sortField?, sortOrder? }",
|
|
26187
26734
|
"description": "排序变化。"
|
|
26188
26735
|
},
|
|
26736
|
+
{
|
|
26737
|
+
"name": "filter-change",
|
|
26738
|
+
"payload": "Record<string, unknown> | null",
|
|
26739
|
+
"description": "列筛选提交(与 `update:filter-model` 同步)。"
|
|
26740
|
+
},
|
|
26741
|
+
{
|
|
26742
|
+
"name": "expand-change",
|
|
26743
|
+
"payload": "{ row, expanded }",
|
|
26744
|
+
"description": "行展开状态变化(详情展开或树节点展开)。"
|
|
26745
|
+
},
|
|
26189
26746
|
{
|
|
26190
26747
|
"name": "row-click",
|
|
26191
26748
|
"payload": "{ row, index }`, `Event",
|
|
@@ -26221,11 +26778,6 @@
|
|
|
26221
26778
|
"payload": "row | null, oldRow | null",
|
|
26222
26779
|
"description": "当前高亮行变化。"
|
|
26223
26780
|
},
|
|
26224
|
-
{
|
|
26225
|
-
"name": "expand",
|
|
26226
|
-
"payload": "{ row, expanded }",
|
|
26227
|
-
"description": "行展开。"
|
|
26228
|
-
},
|
|
26229
26781
|
{
|
|
26230
26782
|
"name": "update:selection",
|
|
26231
26783
|
"payload": "TableItem[]",
|
|
@@ -26247,39 +26799,34 @@
|
|
|
26247
26799
|
"description": "当前行键 v-model。"
|
|
26248
26800
|
},
|
|
26249
26801
|
{
|
|
26250
|
-
"name": "
|
|
26251
|
-
"payload": "
|
|
26252
|
-
"description": "
|
|
26253
|
-
},
|
|
26254
|
-
{
|
|
26255
|
-
"name": "update:expandedRowKeys",
|
|
26256
|
-
"payload": "—",
|
|
26257
|
-
"description": "—"
|
|
26802
|
+
"name": "update:expanded-row-keys",
|
|
26803
|
+
"payload": "Array<string | number>",
|
|
26804
|
+
"description": "树/详情展开键 v-model。"
|
|
26258
26805
|
},
|
|
26259
26806
|
{
|
|
26260
|
-
"name": "update:
|
|
26261
|
-
"payload": "
|
|
26262
|
-
"description": "
|
|
26807
|
+
"name": "update:filter-model",
|
|
26808
|
+
"payload": "Record<string, unknown> | null",
|
|
26809
|
+
"description": "列筛选 v-model。"
|
|
26263
26810
|
},
|
|
26264
26811
|
{
|
|
26265
|
-
"name": "update:
|
|
26812
|
+
"name": "update:column-widths",
|
|
26266
26813
|
"payload": "Record<string, number>",
|
|
26267
26814
|
"description": "列宽 v-model。"
|
|
26268
26815
|
},
|
|
26269
26816
|
{
|
|
26270
|
-
"name": "update:
|
|
26817
|
+
"name": "update:hidden-columns",
|
|
26271
26818
|
"payload": "string[]",
|
|
26272
26819
|
"description": "隐藏列 v-model。"
|
|
26273
26820
|
},
|
|
26274
26821
|
{
|
|
26275
|
-
"name": "update:
|
|
26822
|
+
"name": "update:column-order",
|
|
26276
26823
|
"payload": "string[]",
|
|
26277
26824
|
"description": "列顺序 v-model。"
|
|
26278
26825
|
},
|
|
26279
26826
|
{
|
|
26280
|
-
"name": "update:
|
|
26281
|
-
"payload": "
|
|
26282
|
-
"description": "
|
|
26827
|
+
"name": "update:selected-item",
|
|
26828
|
+
"payload": "TableItem | null",
|
|
26829
|
+
"description": "单选 v-model。"
|
|
26283
26830
|
}
|
|
26284
26831
|
],
|
|
26285
26832
|
"slots": [
|
|
@@ -26305,7 +26852,7 @@
|
|
|
26305
26852
|
},
|
|
26306
26853
|
{
|
|
26307
26854
|
"name": "loading",
|
|
26308
|
-
"description": "
|
|
26855
|
+
"description": "自定义加载态(`skeleton` 为 true 时不生效)。"
|
|
26309
26856
|
},
|
|
26310
26857
|
{
|
|
26311
26858
|
"name": "pagination",
|
|
@@ -26501,7 +27048,7 @@
|
|
|
26501
27048
|
"sectionId": "引入",
|
|
26502
27049
|
"lang": "ts",
|
|
26503
27050
|
"preview": false,
|
|
26504
|
-
"code": "import type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'",
|
|
27051
|
+
"code": "import type { TableColumnDefinition, TableItem, TableSortConfig, TablePassThrough } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'",
|
|
26505
27052
|
"locale": "zh-CN"
|
|
26506
27053
|
},
|
|
26507
27054
|
{
|
|
@@ -26549,6 +27096,15 @@
|
|
|
26549
27096
|
"code": "<script setup lang=\"ts\">\nimport type { TableItem } from 'morya-ui'\nimport { MTable } from 'morya-ui'\n\ntype Row = { id: number; name: string; role: string; extra: string }\n\nconst columns = [\n { key: 'name', label: '姓名' },\n { key: 'role', label: '角色' },\n]\nconst rows: Row[] = [{ id: 1, name: 'Ada', role: '设计师', extra: '设计系统细节' }]\n\nfunction extraOf(row: TableItem) {\n return (row as Row).extra\n}\n</script>\n\n<template>\n <MTable :columns=\"columns\" :rows=\"rows\" expandable bordered :paginator=\"false\">\n <template #expansion=\"{ row }\">\n {{ extraOf(row) }}\n </template>\n </MTable>\n</template>",
|
|
26550
27097
|
"locale": "zh-CN"
|
|
26551
27098
|
},
|
|
27099
|
+
{
|
|
27100
|
+
"id": "排序-sortconfig-1",
|
|
27101
|
+
"section": "排序(sortConfig)",
|
|
27102
|
+
"sectionId": "排序-sortconfig",
|
|
27103
|
+
"lang": "vue",
|
|
27104
|
+
"preview": true,
|
|
27105
|
+
"code": "<script setup lang=\"ts\">\nimport type { TableSortConfig } from 'morya-ui'\nimport { MTable } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns = [\n { key: 'name', label: '项目', minWidth: 160, sortable: true },\n { key: 'owner', label: '负责人', minWidth: 100, sortable: true },\n { key: 'progress', label: '进度', width: 110, align: 'end' as const, sortable: true },\n]\n\nconst rows = [\n { id: 1, name: 'Landing Redesign', owner: 'Ada', progress: 100 },\n { id: 2, name: 'Dashboard v2', owner: 'Lin', progress: 62 },\n { id: 3, name: 'Auth Gateway', owner: 'Kai', progress: 88 },\n { id: 4, name: 'Billing Migration', owner: 'Ada', progress: 24 },\n]\n\nconst sortConfig = ref<TableSortConfig>({\n field: 'progress',\n order: 'desc',\n mode: 'client',\n})\n</script>\n\n<template>\n <MTable :columns=\"columns\" :rows=\"rows\" :sort-config=\"sortConfig\" bordered striped />\n</template>",
|
|
27106
|
+
"locale": "zh-CN"
|
|
27107
|
+
},
|
|
26552
27108
|
{
|
|
26553
27109
|
"id": "列宽拖拽与表头筛选-1",
|
|
26554
27110
|
"section": "列宽拖拽与表头筛选",
|
|
@@ -26558,6 +27114,33 @@
|
|
|
26558
27114
|
"code": "<script setup lang=\"ts\">\nimport type { TableColumnDefinition } from 'morya-ui'\nimport { MTable } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns: TableColumnDefinition[] = [\n {\n key: 'name',\n label: '姓名',\n width: 140,\n resizable: true,\n filterable: true,\n },\n {\n key: 'status',\n label: '状态',\n width: 120,\n resizable: true,\n filterable: true,\n filters: [\n { label: '草稿', value: 'Draft' },\n { label: '上线', value: 'Live' },\n ],\n },\n { key: 'role', label: '角色', minWidth: 120 },\n]\n\nconst rows = [\n { id: 1, name: 'Ada', status: 'Draft', role: 'Designer' },\n { id: 2, name: 'Lin', status: 'Live', role: 'Engineer' },\n { id: 3, name: 'Kai', status: 'Live', role: 'Engineer' },\n { id: 4, name: 'Mia', status: 'Draft', role: 'Designer' },\n]\n\nconst columnWidths = ref<Record<string, number>>({})\n</script>\n\n<template>\n <MTable\n v-model:column-widths=\"columnWidths\"\n :columns=\"columns\"\n :rows=\"rows\"\n bordered\n :paginator=\"false\"\n />\n</template>",
|
|
26559
27115
|
"locale": "zh-CN"
|
|
26560
27116
|
},
|
|
27117
|
+
{
|
|
27118
|
+
"id": "列设置面板-1",
|
|
27119
|
+
"section": "列设置面板",
|
|
27120
|
+
"sectionId": "列设置面板",
|
|
27121
|
+
"lang": "vue",
|
|
27122
|
+
"preview": true,
|
|
27123
|
+
"code": "<script setup lang=\"ts\">\nimport { MTable, MTag } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns = [\n { key: 'name', label: '项目', minWidth: 140 },\n { key: 'status', label: '状态', width: 120 },\n { key: 'owner', label: '负责人', minWidth: 100 },\n { key: 'team', label: '团队', minWidth: 120 },\n { key: 'progress', label: '进度', width: 100, align: 'end' as const },\n]\n\nconst rows = [\n { id: 1, name: 'Landing Redesign', status: 'Published', owner: 'Ada', team: 'Design', progress: '100%' },\n { id: 2, name: 'Dashboard v2', status: 'Draft', owner: 'Lin', team: 'Frontend', progress: '62%' },\n { id: 3, name: 'Auth Gateway', status: 'Review', owner: 'Kai', team: 'Backend', progress: '88%' },\n]\n\nconst hiddenColumns = ref<string[]>([])\n</script>\n\n<template>\n <MTable\n v-model:hidden-columns=\"hiddenColumns\"\n :columns=\"columns\"\n :rows=\"rows\"\n column-setting\n bordered\n striped\n >\n <template #cell-status=\"{ value }\">\n <MTag\n :value=\"String(value)\"\n :type=\"value === 'Published' ? 'success' : value === 'Review' ? 'warning' : 'secondary'\"\n />\n </template>\n </MTable>\n</template>",
|
|
27124
|
+
"locale": "zh-CN"
|
|
27125
|
+
},
|
|
27126
|
+
{
|
|
27127
|
+
"id": "列拖拽排序-1",
|
|
27128
|
+
"section": "列拖拽排序",
|
|
27129
|
+
"sectionId": "列拖拽排序",
|
|
27130
|
+
"lang": "vue",
|
|
27131
|
+
"preview": true,
|
|
27132
|
+
"code": "<script setup lang=\"ts\">\nimport { MTable, MTag } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns = [\n { key: 'name', label: '项目', minWidth: 140 },\n { key: 'status', label: '状态', width: 120 },\n { key: 'owner', label: '负责人', minWidth: 100 },\n { key: 'team', label: '团队', minWidth: 120 },\n { key: 'progress', label: '进度', width: 100, align: 'end' as const },\n]\n\nconst rows = [\n { id: 1, name: 'Landing Redesign', status: 'Published', owner: 'Ada', team: 'Design', progress: '100%' },\n { id: 2, name: 'Dashboard v2', status: 'Draft', owner: 'Lin', team: 'Frontend', progress: '62%' },\n { id: 3, name: 'Auth Gateway', status: 'Review', owner: 'Kai', team: 'Backend', progress: '88%' },\n]\n\nconst columnOrder = ref<string[]>([])\n</script>\n\n<template>\n <MTable\n v-model:column-order=\"columnOrder\"\n :columns=\"columns\"\n :rows=\"rows\"\n column-drag\n bordered\n striped\n >\n <template #cell-status=\"{ value }\">\n <MTag\n :value=\"String(value)\"\n :type=\"value === 'Published' ? 'success' : value === 'Review' ? 'warning' : 'secondary'\"\n />\n </template>\n </MTable>\n</template>",
|
|
27133
|
+
"locale": "zh-CN"
|
|
27134
|
+
},
|
|
27135
|
+
{
|
|
27136
|
+
"id": "骨架屏加载-1",
|
|
27137
|
+
"section": "骨架屏加载",
|
|
27138
|
+
"sectionId": "骨架屏加载",
|
|
27139
|
+
"lang": "vue",
|
|
27140
|
+
"preview": true,
|
|
27141
|
+
"code": "<script setup lang=\"ts\">\nimport { MButton, MTable } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns = [\n { key: 'name', label: '项目', minWidth: 160 },\n { key: 'owner', label: '负责人', minWidth: 100 },\n { key: 'team', label: '团队', minWidth: 120 },\n { key: 'progress', label: '进度', width: 100, align: 'end' as const },\n]\n\nconst allRows = [\n { id: 1, name: 'Landing Redesign', owner: 'Ada', team: 'Design', progress: '100%' },\n { id: 2, name: 'Dashboard v2', owner: 'Lin', team: 'Frontend', progress: '62%' },\n { id: 3, name: 'Auth Gateway', owner: 'Kai', team: 'Backend', progress: '88%' },\n]\n\nconst rows = ref<typeof allRows>([])\nconst loading = ref(true)\n\nfunction reload() {\n loading.value = true\n rows.value = []\n window.setTimeout(() => {\n rows.value = allRows\n loading.value = false\n }, 1500)\n}\n\nreload()\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px\">\n <div>\n <MButton size=\"small\" @click=\"reload\">重新加载</MButton>\n </div>\n <MTable\n :columns=\"columns\"\n :rows=\"rows\"\n :loading=\"loading\"\n :skeleton=\"loading\"\n :skeleton-rows=\"4\"\n bordered\n striped\n />\n </div>\n</template>",
|
|
27142
|
+
"locale": "zh-CN"
|
|
27143
|
+
},
|
|
26561
27144
|
{
|
|
26562
27145
|
"id": "虚拟滚动-1",
|
|
26563
27146
|
"section": "虚拟滚动",
|
|
@@ -26567,6 +27150,15 @@
|
|
|
26567
27150
|
"code": "<script setup lang=\"ts\">\nimport { MTable } from 'morya-ui'\n\nconst columns = [\n { key: 'id', label: 'ID', width: 80 },\n { key: 'name', label: '姓名', minWidth: 160 },\n]\n\nconst rows = Array.from({ length: 5000 }, (_, i) => ({\n id: i + 1,\n name: `行 ${i + 1}`,\n}))\n</script>\n\n<template>\n <MTable\n :columns=\"columns\"\n :rows=\"rows\"\n virtual\n :virtual-row-height=\"40\"\n :max-height=\"320\"\n bordered\n :paginator=\"false\"\n />\n</template>",
|
|
26568
27151
|
"locale": "zh-CN"
|
|
26569
27152
|
},
|
|
27153
|
+
{
|
|
27154
|
+
"id": "动态行高虚拟滚动-1",
|
|
27155
|
+
"section": "动态行高虚拟滚动",
|
|
27156
|
+
"sectionId": "动态行高虚拟滚动",
|
|
27157
|
+
"lang": "vue",
|
|
27158
|
+
"preview": true,
|
|
27159
|
+
"code": "<script setup lang=\"ts\">\nimport { MTable } from 'morya-ui'\n\nconst columns = [\n { key: 'id', label: 'ID', width: 80 },\n { key: 'title', label: '标题', minWidth: 200 },\n { key: 'summary', label: '摘要', minWidth: 320 },\n]\n\n// 模拟内容长度不一的行:摘要字段长短不同 → 行高不同\nconst rows = Array.from({ length: 2000 }, (_, i) => ({\n id: i + 1,\n title: `任务 ${i + 1}`,\n summary: i % 7 === 0\n ? `这是一段比较长的摘要,用来演示动态行高。`.repeat((i % 5) + 2)\n : `简短摘要 ${i + 1}`,\n}))\n</script>\n\n<template>\n <MTable\n :columns=\"columns\"\n :rows=\"rows\"\n virtual\n virtual-dynamic-row-height\n :virtual-row-height=\"44\"\n :max-height=\"360\"\n bordered\n :paginator=\"false\"\n />\n</template>",
|
|
27160
|
+
"locale": "zh-CN"
|
|
27161
|
+
},
|
|
26570
27162
|
{
|
|
26571
27163
|
"id": "多级表头-表尾与合并-1",
|
|
26572
27164
|
"section": "多级表头、表尾与合并",
|
|
@@ -26618,7 +27210,7 @@
|
|
|
26618
27210
|
"sectionId": "类型",
|
|
26619
27211
|
"lang": "ts",
|
|
26620
27212
|
"preview": false,
|
|
26621
|
-
"code": "
|
|
27213
|
+
"code": "interface TableSortConfig {\n field?: string | null\n order?: 'asc' | 'desc' | null\n multiple?: boolean\n must?: boolean\n mode?: 'client' | 'emit'\n}",
|
|
26622
27214
|
"locale": "zh-CN"
|
|
26623
27215
|
},
|
|
26624
27216
|
{
|
|
@@ -26627,7 +27219,7 @@
|
|
|
26627
27219
|
"sectionId": "类型",
|
|
26628
27220
|
"lang": "ts",
|
|
26629
27221
|
"preview": false,
|
|
26630
|
-
"code": "
|
|
27222
|
+
"code": "interface TablePassThrough {\n root?: Record<string, unknown>\n scrollbar?: Record<string, unknown>\n thead?: Record<string, unknown>\n tbody?: Record<string, unknown>\n tfoot?: Record<string, unknown>\n pagination?: Record<string, unknown>\n emptyMessage?: Record<string, unknown>\n}",
|
|
26631
27223
|
"locale": "zh-CN"
|
|
26632
27224
|
},
|
|
26633
27225
|
{
|
|
@@ -26636,7 +27228,7 @@
|
|
|
26636
27228
|
"sectionId": "类型",
|
|
26637
27229
|
"lang": "ts",
|
|
26638
27230
|
"preview": false,
|
|
26639
|
-
"code": "type
|
|
27231
|
+
"code": "type TableTextDirection = 'left' | 'center' | 'right'",
|
|
26640
27232
|
"locale": "zh-CN"
|
|
26641
27233
|
},
|
|
26642
27234
|
{
|
|
@@ -26645,7 +27237,7 @@
|
|
|
26645
27237
|
"sectionId": "类型",
|
|
26646
27238
|
"lang": "ts",
|
|
26647
27239
|
"preview": false,
|
|
26648
|
-
"code": "type
|
|
27240
|
+
"code": "type TableFilterOption =\n | { field: string; comparison: 'between'; criteria: [number, number] }\n | { field: string; comparison: '=' | '!='; criteria: number | string }\n | { field: string; comparison: '>' | '>=' | '<' | '<='; criteria: number }\n | { field: number | string; comparison: 'in'; criteria: number[] | string[] }\n | { field: string; comparison: (value: unknown, criteria: string) => boolean; criteria: string }",
|
|
26649
27241
|
"locale": "zh-CN"
|
|
26650
27242
|
},
|
|
26651
27243
|
{
|
|
@@ -26654,7 +27246,7 @@
|
|
|
26654
27246
|
"sectionId": "类型",
|
|
26655
27247
|
"lang": "ts",
|
|
26656
27248
|
"preview": false,
|
|
26657
|
-
"code": "type
|
|
27249
|
+
"code": "type TableHeaderItemClassName = string | ((header: TableHeader, columnNumber: number) => string)",
|
|
26658
27250
|
"locale": "zh-CN"
|
|
26659
27251
|
},
|
|
26660
27252
|
{
|
|
@@ -26663,7 +27255,7 @@
|
|
|
26663
27255
|
"sectionId": "类型",
|
|
26664
27256
|
"lang": "ts",
|
|
26665
27257
|
"preview": false,
|
|
26666
|
-
"code": "
|
|
27258
|
+
"code": "type TableBodyRowClassName = string | ((item: TableItem, rowNumber: number) => string)",
|
|
26667
27259
|
"locale": "zh-CN"
|
|
26668
27260
|
},
|
|
26669
27261
|
{
|
|
@@ -26672,7 +27264,7 @@
|
|
|
26672
27264
|
"sectionId": "类型",
|
|
26673
27265
|
"lang": "ts",
|
|
26674
27266
|
"preview": false,
|
|
26675
|
-
"code": "
|
|
27267
|
+
"code": "type TableBodyItemClassName = string | ((column: string, rowNumber: number) => string)",
|
|
26676
27268
|
"locale": "zh-CN"
|
|
26677
27269
|
},
|
|
26678
27270
|
{
|
|
@@ -26681,6 +27273,24 @@
|
|
|
26681
27273
|
"sectionId": "类型",
|
|
26682
27274
|
"lang": "ts",
|
|
26683
27275
|
"preview": false,
|
|
27276
|
+
"code": "interface TableTreeConfig {\n childrenField?: string // default 'children'\n indent?: number // default 16\n expandAll?: boolean\n accordion?: boolean\n trigger?: 'default' | 'row'\n lazy?: boolean\n hasChildField?: string // default 'hasChild'\n loadMethod?: (row: TableItem) => Promise<TableItem[]> | TableItem[]\n transform?: boolean // flat parentId → tree\n rowField?: string\n parentField?: string // default 'parentId'\n treeNode?: string // column key for toggler; default first column\n showLine?: boolean\n}",
|
|
27277
|
+
"locale": "zh-CN"
|
|
27278
|
+
},
|
|
27279
|
+
{
|
|
27280
|
+
"id": "类型-10",
|
|
27281
|
+
"section": "类型",
|
|
27282
|
+
"sectionId": "类型",
|
|
27283
|
+
"lang": "ts",
|
|
27284
|
+
"preview": false,
|
|
27285
|
+
"code": "interface TableColumnDefinition {\n key: string\n label: string\n width?: number\n minWidth?: number\n sortable?: boolean\n fixed?: boolean | 'left' | 'right'\n align?: 'start' | 'center' | 'end'\n render?: (row: TableItem) => unknown\n showOverflowTooltip?: boolean\n resizable?: boolean\n filterable?: boolean\n filters?: TableColumnFilter[]\n children?: TableColumnDefinition[]\n}",
|
|
27286
|
+
"locale": "zh-CN"
|
|
27287
|
+
},
|
|
27288
|
+
{
|
|
27289
|
+
"id": "类型-11",
|
|
27290
|
+
"section": "类型",
|
|
27291
|
+
"sectionId": "类型",
|
|
27292
|
+
"lang": "ts",
|
|
27293
|
+
"preview": false,
|
|
26684
27294
|
"code": "interface TableServerOptions {\n page: number\n rowsPerPage: number\n sortBy?: string | string[]\n sortType?: 'asc' | 'desc' | ('asc' | 'desc')[]\n}",
|
|
26685
27295
|
"locale": "zh-CN"
|
|
26686
27296
|
},
|
|
@@ -26690,7 +27300,7 @@
|
|
|
26690
27300
|
"sectionId": "import",
|
|
26691
27301
|
"lang": "ts",
|
|
26692
27302
|
"preview": false,
|
|
26693
|
-
"code": "import type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'",
|
|
27303
|
+
"code": "import type { TableColumnDefinition, TableItem, TableSortConfig, TablePassThrough } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'",
|
|
26694
27304
|
"locale": "en-US"
|
|
26695
27305
|
},
|
|
26696
27306
|
{
|
|
@@ -26703,72 +27313,117 @@
|
|
|
26703
27313
|
"locale": "en-US"
|
|
26704
27314
|
},
|
|
26705
27315
|
{
|
|
26706
|
-
"id": "selection-1",
|
|
26707
|
-
"section": "Selection",
|
|
26708
|
-
"sectionId": "selection",
|
|
27316
|
+
"id": "row-selection-1",
|
|
27317
|
+
"section": "Row Selection",
|
|
27318
|
+
"sectionId": "row-selection",
|
|
26709
27319
|
"lang": "vue",
|
|
26710
27320
|
"preview": true,
|
|
26711
27321
|
"code": "<script setup lang=\"ts\">\nimport { MTable } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns = [\n { key: 'name', label: 'Name', minWidth: 120 },\n { key: 'role', label: 'Role', minWidth: 120 },\n]\nconst rows = [\n { id: 1, name: 'Ada', role: 'Designer' },\n { id: 2, name: 'Lin', role: 'Engineer' },\n]\nconst selection = ref<Record<string, unknown>[]>([])\n</script>\n\n<template>\n <MTable\n v-model:selection=\"selection\"\n :columns=\"columns\"\n :rows=\"rows\"\n selection-mode=\"multiple\"\n highlight-current\n :paginator=\"false\"\n />\n</template>",
|
|
26712
27322
|
"locale": "en-US"
|
|
26713
27323
|
},
|
|
26714
27324
|
{
|
|
26715
|
-
"id": "
|
|
26716
|
-
"section": "
|
|
26717
|
-
"sectionId": "
|
|
27325
|
+
"id": "filtering-pagination-1",
|
|
27326
|
+
"section": "Filtering & Pagination",
|
|
27327
|
+
"sectionId": "filtering-pagination",
|
|
26718
27328
|
"lang": "vue",
|
|
26719
27329
|
"preview": true,
|
|
26720
27330
|
"code": "<script setup lang=\"ts\">\nimport { MTable } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns = [\n { key: 'name', label: 'Name', sortable: true, minWidth: 120 },\n { key: 'role', label: 'Role', minWidth: 120 },\n]\nconst rows = [\n { id: 1, name: 'Ada', role: 'Designer' },\n { id: 2, name: 'Lin', role: 'Engineer' },\n { id: 3, name: 'Kai', role: 'Engineer' },\n { id: 4, name: 'Mia', role: 'Designer' },\n]\nconst page = ref(1)\n</script>\n\n<template>\n <MTable\n v-model:page=\"page\"\n :columns=\"columns\"\n :rows=\"rows\"\n paginator\n :rows-per-page=\"2\"\n />\n</template>",
|
|
26721
27331
|
"locale": "en-US"
|
|
26722
27332
|
},
|
|
26723
27333
|
{
|
|
26724
|
-
"id": "
|
|
26725
|
-
"section": "
|
|
26726
|
-
"sectionId": "
|
|
27334
|
+
"id": "fixed-columns-1",
|
|
27335
|
+
"section": "Fixed Columns",
|
|
27336
|
+
"sectionId": "fixed-columns",
|
|
27337
|
+
"lang": "vue",
|
|
27338
|
+
"preview": true,
|
|
27339
|
+
"code": "<script setup lang=\"ts\">\nimport { MTable } from 'morya-ui'\n\nconst columns = [\n { key: 'name', label: 'Name', width: 120, fixed: 'left' as const },\n { key: 'q1', label: 'Q1 Revenue', width: 140 },\n { key: 'q2', label: 'Q2 Revenue', width: 140 },\n { key: 'q3', label: 'Q3 Revenue', width: 140 },\n { key: 'action', label: 'Action', width: 100, fixed: 'right' as const },\n]\nconst rows = [\n { id: 1, name: 'Ada', q1: '124k', q2: '131k', q3: '140k', action: 'Edit' },\n { id: 2, name: 'Lin', q1: '98k', q2: '102k', q3: '115k', action: 'Edit' },\n]\n</script>\n\n<template>\n <MTable :columns=\"columns\" :rows=\"rows\" bordered :paginator=\"false\" />\n</template>",
|
|
27340
|
+
"locale": "en-US"
|
|
27341
|
+
},
|
|
27342
|
+
{
|
|
27343
|
+
"id": "expandable-rows-cell-rendering-1",
|
|
27344
|
+
"section": "Expandable Rows & Cell Rendering",
|
|
27345
|
+
"sectionId": "expandable-rows-cell-rendering",
|
|
26727
27346
|
"lang": "vue",
|
|
26728
27347
|
"preview": true,
|
|
26729
27348
|
"code": "<script setup lang=\"ts\">\nimport type { TableItem } from 'morya-ui'\nimport { MTable } from 'morya-ui'\n\ntype Row = { id: number; name: string; role: string; extra: string }\n\nconst columns = [\n { key: 'name', label: 'Name' },\n { key: 'role', label: 'Role' },\n]\nconst rows: Row[] = [{ id: 1, name: 'Ada', role: 'Designer', extra: 'Design system' }]\n\nfunction extraOf(row: TableItem) {\n return (row as Row).extra\n}\n</script>\n\n<template>\n <MTable :columns=\"columns\" :rows=\"rows\" expandable bordered :paginator=\"false\">\n <template #expansion=\"{ row }\">\n {{ extraOf(row) }}\n </template>\n </MTable>\n</template>",
|
|
26730
27349
|
"locale": "en-US"
|
|
26731
27350
|
},
|
|
26732
27351
|
{
|
|
26733
|
-
"id": "
|
|
26734
|
-
"section": "
|
|
26735
|
-
"sectionId": "
|
|
27352
|
+
"id": "sorting-sortconfig-1",
|
|
27353
|
+
"section": "Sorting (sortConfig)",
|
|
27354
|
+
"sectionId": "sorting-sortconfig",
|
|
26736
27355
|
"lang": "vue",
|
|
26737
27356
|
"preview": true,
|
|
26738
|
-
"code": "<script setup lang=\"ts\">\nimport { MTable } from 'morya-ui'\n\nconst columns = [\n { key: 'name', label: '
|
|
27357
|
+
"code": "<script setup lang=\"ts\">\nimport type { TableSortConfig } from 'morya-ui'\nimport { MTable } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns = [\n { key: 'name', label: 'Project', minWidth: 160, sortable: true },\n { key: 'owner', label: 'Owner', minWidth: 100, sortable: true },\n { key: 'progress', label: 'Progress', width: 110, align: 'end' as const, sortable: true },\n]\n\nconst rows = [\n { id: 1, name: 'Landing Redesign', owner: 'Ada', progress: 100 },\n { id: 2, name: 'Dashboard v2', owner: 'Lin', progress: 62 },\n { id: 3, name: 'Auth Gateway', owner: 'Kai', progress: 88 },\n { id: 4, name: 'Billing Migration', owner: 'Ada', progress: 24 },\n]\n\nconst sortConfig = ref<TableSortConfig>({\n field: 'progress',\n order: 'desc',\n mode: 'client',\n})\n</script>\n\n<template>\n <MTable :columns=\"columns\" :rows=\"rows\" :sort-config=\"sortConfig\" bordered striped />\n</template>",
|
|
26739
27358
|
"locale": "en-US"
|
|
26740
27359
|
},
|
|
26741
27360
|
{
|
|
26742
|
-
"id": "column-
|
|
26743
|
-
"section": "Column
|
|
26744
|
-
"sectionId": "column-
|
|
27361
|
+
"id": "column-resizing-header-filters-1",
|
|
27362
|
+
"section": "Column Resizing & Header Filters",
|
|
27363
|
+
"sectionId": "column-resizing-header-filters",
|
|
26745
27364
|
"lang": "vue",
|
|
26746
27365
|
"preview": true,
|
|
26747
27366
|
"code": "<script setup lang=\"ts\">\nimport type { TableColumnDefinition } from 'morya-ui'\nimport { MTable } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns: TableColumnDefinition[] = [\n {\n key: 'name',\n label: 'Name',\n width: 140,\n resizable: true,\n filterable: true,\n },\n {\n key: 'status',\n label: 'Status',\n width: 120,\n resizable: true,\n filterable: true,\n filters: [\n { label: 'Draft', value: 'Draft' },\n { label: 'Live', value: 'Live' },\n ],\n },\n { key: 'role', label: 'Role', minWidth: 120 },\n]\n\nconst rows = [\n { id: 1, name: 'Ada', status: 'Draft', role: 'Designer' },\n { id: 2, name: 'Lin', status: 'Live', role: 'Engineer' },\n { id: 3, name: 'Kai', status: 'Live', role: 'Engineer' },\n { id: 4, name: 'Mia', status: 'Draft', role: 'Designer' },\n]\n\nconst columnWidths = ref<Record<string, number>>({})\n</script>\n\n<template>\n <MTable\n v-model:column-widths=\"columnWidths\"\n :columns=\"columns\"\n :rows=\"rows\"\n bordered\n :paginator=\"false\"\n />\n</template>",
|
|
26748
27367
|
"locale": "en-US"
|
|
26749
27368
|
},
|
|
26750
27369
|
{
|
|
26751
|
-
"id": "
|
|
26752
|
-
"section": "
|
|
26753
|
-
"sectionId": "
|
|
27370
|
+
"id": "column-settings-panel-1",
|
|
27371
|
+
"section": "Column Settings Panel",
|
|
27372
|
+
"sectionId": "column-settings-panel",
|
|
27373
|
+
"lang": "vue",
|
|
27374
|
+
"preview": true,
|
|
27375
|
+
"code": "<script setup lang=\"ts\">\nimport { MTable, MTag } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns = [\n { key: 'name', label: 'Project', minWidth: 140 },\n { key: 'status', label: 'Status', width: 120 },\n { key: 'owner', label: 'Owner', minWidth: 100 },\n { key: 'team', label: 'Team', minWidth: 120 },\n { key: 'progress', label: 'Progress', width: 100, align: 'end' as const },\n]\n\nconst rows = [\n { id: 1, name: 'Landing Redesign', status: 'Published', owner: 'Ada', team: 'Design', progress: '100%' },\n { id: 2, name: 'Dashboard v2', status: 'Draft', owner: 'Lin', team: 'Frontend', progress: '62%' },\n { id: 3, name: 'Auth Gateway', status: 'Review', owner: 'Kai', team: 'Backend', progress: '88%' },\n]\n\nconst hiddenColumns = ref<string[]>([])\n</script>\n\n<template>\n <MTable\n v-model:hidden-columns=\"hiddenColumns\"\n :columns=\"columns\"\n :rows=\"rows\"\n column-setting\n bordered\n striped\n >\n <template #cell-status=\"{ value }\">\n <MTag\n :value=\"String(value)\"\n :type=\"value === 'Published' ? 'success' : value === 'Review' ? 'warning' : 'secondary'\"\n />\n </template>\n </MTable>\n</template>",
|
|
27376
|
+
"locale": "en-US"
|
|
27377
|
+
},
|
|
27378
|
+
{
|
|
27379
|
+
"id": "column-drag-1",
|
|
27380
|
+
"section": "Column Drag",
|
|
27381
|
+
"sectionId": "column-drag",
|
|
27382
|
+
"lang": "vue",
|
|
27383
|
+
"preview": true,
|
|
27384
|
+
"code": "<script setup lang=\"ts\">\nimport { MTable, MTag } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns = [\n { key: 'name', label: 'Project', minWidth: 140 },\n { key: 'status', label: 'Status', width: 120 },\n { key: 'owner', label: 'Owner', minWidth: 100 },\n { key: 'team', label: 'Team', minWidth: 120 },\n { key: 'progress', label: 'Progress', width: 100, align: 'end' as const },\n]\n\nconst rows = [\n { id: 1, name: 'Landing Redesign', status: 'Published', owner: 'Ada', team: 'Design', progress: '100%' },\n { id: 2, name: 'Dashboard v2', status: 'Draft', owner: 'Lin', team: 'Frontend', progress: '62%' },\n { id: 3, name: 'Auth Gateway', status: 'Review', owner: 'Kai', team: 'Backend', progress: '88%' },\n]\n\nconst columnOrder = ref<string[]>([])\n</script>\n\n<template>\n <MTable\n v-model:column-order=\"columnOrder\"\n :columns=\"columns\"\n :rows=\"rows\"\n column-drag\n bordered\n striped\n >\n <template #cell-status=\"{ value }\">\n <MTag\n :value=\"String(value)\"\n :type=\"value === 'Published' ? 'success' : value === 'Review' ? 'warning' : 'secondary'\"\n />\n </template>\n </MTable>\n</template>",
|
|
27385
|
+
"locale": "en-US"
|
|
27386
|
+
},
|
|
27387
|
+
{
|
|
27388
|
+
"id": "skeleton-loading-1",
|
|
27389
|
+
"section": "Skeleton Loading",
|
|
27390
|
+
"sectionId": "skeleton-loading",
|
|
27391
|
+
"lang": "vue",
|
|
27392
|
+
"preview": true,
|
|
27393
|
+
"code": "<script setup lang=\"ts\">\nimport { MButton, MTable } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns = [\n { key: 'name', label: 'Project', minWidth: 160 },\n { key: 'owner', label: 'Owner', minWidth: 100 },\n { key: 'team', label: 'Team', minWidth: 120 },\n { key: 'progress', label: 'Progress', width: 100, align: 'end' as const },\n]\n\nconst allRows = [\n { id: 1, name: 'Landing Redesign', owner: 'Ada', team: 'Design', progress: '100%' },\n { id: 2, name: 'Dashboard v2', owner: 'Lin', team: 'Frontend', progress: '62%' },\n { id: 3, name: 'Auth Gateway', owner: 'Kai', team: 'Backend', progress: '88%' },\n]\n\nconst rows = ref<typeof allRows>([])\nconst loading = ref(true)\n\nfunction reload() {\n loading.value = true\n rows.value = []\n window.setTimeout(() => {\n rows.value = allRows\n loading.value = false\n }, 1500)\n}\n\nreload()\n</script>\n\n<template>\n <div style=\"display: grid; gap: 12px\">\n <div>\n <MButton size=\"small\" @click=\"reload\">Reload</MButton>\n </div>\n <MTable\n :columns=\"columns\"\n :rows=\"rows\"\n :loading=\"loading\"\n :skeleton=\"loading\"\n :skeleton-rows=\"4\"\n bordered\n striped\n />\n </div>\n</template>",
|
|
27394
|
+
"locale": "en-US"
|
|
27395
|
+
},
|
|
27396
|
+
{
|
|
27397
|
+
"id": "virtual-scrolling-1",
|
|
27398
|
+
"section": "Virtual Scrolling",
|
|
27399
|
+
"sectionId": "virtual-scrolling",
|
|
26754
27400
|
"lang": "vue",
|
|
26755
27401
|
"preview": true,
|
|
26756
27402
|
"code": "<script setup lang=\"ts\">\nimport { MTable } from 'morya-ui'\n\nconst columns = [\n { key: 'id', label: 'ID', width: 80 },\n { key: 'name', label: 'Name', minWidth: 160 },\n]\n\nconst rows = Array.from({ length: 5000 }, (_, i) => ({\n id: i + 1,\n name: `Row ${i + 1}`,\n}))\n</script>\n\n<template>\n <MTable\n :columns=\"columns\"\n :rows=\"rows\"\n virtual\n :virtual-row-height=\"40\"\n :max-height=\"320\"\n bordered\n :paginator=\"false\"\n />\n</template>",
|
|
26757
27403
|
"locale": "en-US"
|
|
26758
27404
|
},
|
|
26759
27405
|
{
|
|
26760
|
-
"id": "
|
|
26761
|
-
"section": "
|
|
26762
|
-
"sectionId": "
|
|
27406
|
+
"id": "dynamic-row-height-virtual-scrolling-1",
|
|
27407
|
+
"section": "Dynamic Row Height Virtual Scrolling",
|
|
27408
|
+
"sectionId": "dynamic-row-height-virtual-scrolling",
|
|
27409
|
+
"lang": "vue",
|
|
27410
|
+
"preview": true,
|
|
27411
|
+
"code": "<script setup lang=\"ts\">\nimport { MTable } from 'morya-ui'\n\nconst columns = [\n { key: 'id', label: 'ID', width: 80 },\n { key: 'title', label: 'Title', minWidth: 200 },\n { key: 'summary', label: 'Summary', minWidth: 320 },\n]\n\n// Rows with variable content length → variable row height\nconst rows = Array.from({ length: 2000 }, (_, i) => ({\n id: i + 1,\n title: `Task ${i + 1}`,\n summary: i % 7 === 0\n ? 'A longer summary used to demonstrate dynamic row height. '.repeat((i % 5) + 2)\n : `Short summary ${i + 1}`,\n}))\n</script>\n\n<template>\n <MTable\n :columns=\"columns\"\n :rows=\"rows\"\n virtual\n virtual-dynamic-row-height\n :virtual-row-height=\"44\"\n :max-height=\"360\"\n bordered\n :paginator=\"false\"\n />\n</template>",
|
|
27412
|
+
"locale": "en-US"
|
|
27413
|
+
},
|
|
27414
|
+
{
|
|
27415
|
+
"id": "multi-level-headers-footer-span-1",
|
|
27416
|
+
"section": "Multi-level Headers, Footer & Span",
|
|
27417
|
+
"sectionId": "multi-level-headers-footer-span",
|
|
26763
27418
|
"lang": "vue",
|
|
26764
27419
|
"preview": true,
|
|
26765
27420
|
"code": "<script setup lang=\"ts\">\nimport type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst columns: TableColumnDefinition[] = [\n {\n key: 'info',\n label: 'Info',\n children: [\n { key: 'name', label: 'Name' },\n { key: 'role', label: 'Role' },\n ],\n },\n { key: 'score', label: 'Score', align: 'end' },\n]\n\nconst rows = ref<TableItem[]>([\n { id: 1, name: 'Ada', role: 'Designer', score: 96 },\n { id: 2, name: 'Lin', role: 'Engineer', score: 88 },\n { id: 3, name: 'Kai', role: 'Engineer', score: 91 },\n])\n\nconst hiddenColumns = ref<string[]>([])\n</script>\n\n<template>\n <MTable\n v-model:hidden-columns=\"hiddenColumns\"\n :columns=\"columns\"\n :rows=\"rows\"\n bordered\n show-footer\n :footer-method=\"({ data }) => [[\n 'Total',\n '',\n data.reduce((sum, row) => sum + Number(row.score ?? 0), 0),\n ]]\"\n :span-method=\"({ column, rowIndex }) => {\n if (column.value === 'role' && rowIndex === 1) return { rowspan: 2, colspan: 1 }\n if (column.value === 'role' && rowIndex === 2) return { rowspan: 0, colspan: 0 }\n return { rowspan: 1, colspan: 1 }\n }\"\n :paginator=\"false\"\n />\n</template>",
|
|
26766
27421
|
"locale": "en-US"
|
|
26767
27422
|
},
|
|
26768
27423
|
{
|
|
26769
|
-
"id": "empty-
|
|
26770
|
-
"section": "Empty
|
|
26771
|
-
"sectionId": "empty-
|
|
27424
|
+
"id": "empty-loading-1",
|
|
27425
|
+
"section": "Empty & Loading",
|
|
27426
|
+
"sectionId": "empty-loading",
|
|
26772
27427
|
"lang": "vue",
|
|
26773
27428
|
"preview": true,
|
|
26774
27429
|
"code": "<script setup lang=\"ts\">\nimport { MButton, MTable } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst loading = ref(false)\nconst columns = [\n { key: 'name', label: 'Name', minWidth: 120 },\n { key: 'role', label: 'Role', minWidth: 120 },\n]\n</script>\n\n<template>\n <div class=\"grid gap-3\">\n <MButton :label=\"loading ? 'Stop loading' : 'Start loading'\" @click=\"loading = !loading\" />\n <MTable\n :columns=\"columns\"\n :rows=\"[]\"\n :loading=\"loading\"\n empty-text=\"No data yet\"\n empty-description=\"Records will appear here after you create the first one\"\n :paginator=\"false\"\n />\n </div>\n</template>",
|
|
@@ -26776,7 +27431,7 @@
|
|
|
26776
27431
|
},
|
|
26777
27432
|
{
|
|
26778
27433
|
"id": "tree-table-1",
|
|
26779
|
-
"section": "Tree
|
|
27434
|
+
"section": "Tree Table",
|
|
26780
27435
|
"sectionId": "tree-table",
|
|
26781
27436
|
"lang": "vue",
|
|
26782
27437
|
"preview": true,
|
|
@@ -26785,7 +27440,7 @@
|
|
|
26785
27440
|
},
|
|
26786
27441
|
{
|
|
26787
27442
|
"id": "server-mode-1",
|
|
26788
|
-
"section": "Server
|
|
27443
|
+
"section": "Server Mode",
|
|
26789
27444
|
"sectionId": "server-mode",
|
|
26790
27445
|
"lang": "vue",
|
|
26791
27446
|
"preview": true,
|
|
@@ -26807,7 +27462,7 @@
|
|
|
26807
27462
|
"sectionId": "types",
|
|
26808
27463
|
"lang": "ts",
|
|
26809
27464
|
"preview": false,
|
|
26810
|
-
"code": "interface
|
|
27465
|
+
"code": "interface TableSortConfig {\n field?: string | null\n order?: 'asc' | 'desc' | null\n multiple?: boolean\n must?: boolean\n mode?: 'client' | 'emit'\n}",
|
|
26811
27466
|
"locale": "en-US"
|
|
26812
27467
|
},
|
|
26813
27468
|
{
|
|
@@ -26816,6 +27471,78 @@
|
|
|
26816
27471
|
"sectionId": "types",
|
|
26817
27472
|
"lang": "ts",
|
|
26818
27473
|
"preview": false,
|
|
27474
|
+
"code": "interface TablePassThrough {\n root?: Record<string, unknown>\n scrollbar?: Record<string, unknown>\n thead?: Record<string, unknown>\n tbody?: Record<string, unknown>\n tfoot?: Record<string, unknown>\n pagination?: Record<string, unknown>\n emptyMessage?: Record<string, unknown>\n}",
|
|
27475
|
+
"locale": "en-US"
|
|
27476
|
+
},
|
|
27477
|
+
{
|
|
27478
|
+
"id": "types-4",
|
|
27479
|
+
"section": "Types",
|
|
27480
|
+
"sectionId": "types",
|
|
27481
|
+
"lang": "ts",
|
|
27482
|
+
"preview": false,
|
|
27483
|
+
"code": "type TableTextDirection = 'left' | 'center' | 'right'",
|
|
27484
|
+
"locale": "en-US"
|
|
27485
|
+
},
|
|
27486
|
+
{
|
|
27487
|
+
"id": "types-5",
|
|
27488
|
+
"section": "Types",
|
|
27489
|
+
"sectionId": "types",
|
|
27490
|
+
"lang": "ts",
|
|
27491
|
+
"preview": false,
|
|
27492
|
+
"code": "type TableFilterOption =\n | { field: string; comparison: 'between'; criteria: [number, number] }\n | { field: string; comparison: '=' | '!='; criteria: number | string }\n | { field: string; comparison: '>' | '>=' | '<' | '<='; criteria: number }\n | { field: number | string; comparison: 'in'; criteria: number[] | string[] }\n | { field: string; comparison: (value: unknown, criteria: string) => boolean; criteria: string }",
|
|
27493
|
+
"locale": "en-US"
|
|
27494
|
+
},
|
|
27495
|
+
{
|
|
27496
|
+
"id": "types-6",
|
|
27497
|
+
"section": "Types",
|
|
27498
|
+
"sectionId": "types",
|
|
27499
|
+
"lang": "ts",
|
|
27500
|
+
"preview": false,
|
|
27501
|
+
"code": "type TableHeaderItemClassName = string | ((header: TableHeader, columnNumber: number) => string)",
|
|
27502
|
+
"locale": "en-US"
|
|
27503
|
+
},
|
|
27504
|
+
{
|
|
27505
|
+
"id": "types-7",
|
|
27506
|
+
"section": "Types",
|
|
27507
|
+
"sectionId": "types",
|
|
27508
|
+
"lang": "ts",
|
|
27509
|
+
"preview": false,
|
|
27510
|
+
"code": "type TableBodyRowClassName = string | ((item: TableItem, rowNumber: number) => string)",
|
|
27511
|
+
"locale": "en-US"
|
|
27512
|
+
},
|
|
27513
|
+
{
|
|
27514
|
+
"id": "types-8",
|
|
27515
|
+
"section": "Types",
|
|
27516
|
+
"sectionId": "types",
|
|
27517
|
+
"lang": "ts",
|
|
27518
|
+
"preview": false,
|
|
27519
|
+
"code": "type TableBodyItemClassName = string | ((column: string, rowNumber: number) => string)",
|
|
27520
|
+
"locale": "en-US"
|
|
27521
|
+
},
|
|
27522
|
+
{
|
|
27523
|
+
"id": "types-9",
|
|
27524
|
+
"section": "Types",
|
|
27525
|
+
"sectionId": "types",
|
|
27526
|
+
"lang": "ts",
|
|
27527
|
+
"preview": false,
|
|
27528
|
+
"code": "interface TableTreeConfig {\n childrenField?: string // default 'children'\n indent?: number // default 16\n expandAll?: boolean\n accordion?: boolean\n trigger?: 'default' | 'row'\n lazy?: boolean\n hasChildField?: string // default 'hasChild'\n loadMethod?: (row: TableItem) => Promise<TableItem[]> | TableItem[]\n transform?: boolean // flat parentId → tree\n rowField?: string\n parentField?: string // default 'parentId'\n treeNode?: string // column key for toggler; default first column\n showLine?: boolean\n}",
|
|
27529
|
+
"locale": "en-US"
|
|
27530
|
+
},
|
|
27531
|
+
{
|
|
27532
|
+
"id": "types-10",
|
|
27533
|
+
"section": "Types",
|
|
27534
|
+
"sectionId": "types",
|
|
27535
|
+
"lang": "ts",
|
|
27536
|
+
"preview": false,
|
|
27537
|
+
"code": "interface TableColumnDefinition {\n key: string\n label: string\n width?: number\n minWidth?: number\n sortable?: boolean\n fixed?: boolean | 'left' | 'right'\n align?: 'start' | 'center' | 'end'\n render?: (row: TableItem) => unknown\n showOverflowTooltip?: boolean\n resizable?: boolean\n filterable?: boolean\n filters?: TableColumnFilter[]\n children?: TableColumnDefinition[]\n}",
|
|
27538
|
+
"locale": "en-US"
|
|
27539
|
+
},
|
|
27540
|
+
{
|
|
27541
|
+
"id": "types-11",
|
|
27542
|
+
"section": "Types",
|
|
27543
|
+
"sectionId": "types",
|
|
27544
|
+
"lang": "ts",
|
|
27545
|
+
"preview": false,
|
|
26819
27546
|
"code": "interface TableServerOptions {\n page: number\n rowsPerPage: number\n sortBy?: string | string[]\n sortType?: 'asc' | 'desc' | ('asc' | 'desc')[]\n}",
|
|
26820
27547
|
"locale": "en-US"
|
|
26821
27548
|
}
|
|
@@ -26823,7 +27550,7 @@
|
|
|
26823
27550
|
"locales": {
|
|
26824
27551
|
"zh-CN": {
|
|
26825
27552
|
"title": "Table",
|
|
26826
|
-
"description": "
|
|
27553
|
+
"description": "数据表格。支持排序、筛选、选择、分页、固定列、列拖拽、列设置、骨架屏与虚拟滚动。列宽支持 width / minWidth / fit。",
|
|
26827
27554
|
"sections": [
|
|
26828
27555
|
{
|
|
26829
27556
|
"id": "overview",
|
|
@@ -26833,7 +27560,7 @@
|
|
|
26833
27560
|
{
|
|
26834
27561
|
"id": "引入",
|
|
26835
27562
|
"title": "引入",
|
|
26836
|
-
"body": "```ts\nimport type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```"
|
|
27563
|
+
"body": "```ts\nimport type { TableColumnDefinition, TableItem, TableSortConfig, TablePassThrough } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```"
|
|
26837
27564
|
},
|
|
26838
27565
|
{
|
|
26839
27566
|
"id": "基础用法",
|
|
@@ -26860,16 +27587,41 @@
|
|
|
26860
27587
|
"title": "展开行与列渲染",
|
|
26861
27588
|
"body": "列可通过 `render` 或 `#cell-{key}` 自定义单元格。展开行设置 `expandable`(或 `expandConfig`),详情由 `#expansion` 提供。树模式下 `expandedRowKeys` 用于树节点展开,不可同时用于详情展开。\n\n```vue preview src=\"./demos/ExpandableRows.zh.vue\"\n```"
|
|
26862
27589
|
},
|
|
27590
|
+
{
|
|
27591
|
+
"id": "排序-sortconfig",
|
|
27592
|
+
"title": "排序(sortConfig)",
|
|
27593
|
+
"body": "通过 `sort-config` 统一配置排序:`{ field, order, multiple, must, mode }`。`mode: 'client'`(默认)由表格内部对当前页数据排序;`mode: 'emit'` 时表格只触发 `sort-change` 事件,数据由外部接管(适合服务端排序)。多列排序设 `multiple: true`,禁止取消排序设 `must: true`。\n\n```vue preview src=\"./demos/Sorting.zh.vue\"\n```"
|
|
27594
|
+
},
|
|
26863
27595
|
{
|
|
26864
27596
|
"id": "列宽拖拽与表头筛选",
|
|
26865
27597
|
"title": "列宽拖拽与表头筛选",
|
|
26866
|
-
"body": "列设置 `resizable` 可拖拽改宽(`v-model:column-widths`);`filterable`
|
|
27598
|
+
"body": "列设置 `resizable` 可拖拽改宽(`v-model:column-widths`);`filterable` 显示表头筛选,列定义里的 `filters` 为多选选项,省略则为文本包含筛选。面板内 **清除** 仅重置草稿,**确认** 后才写入 `v-model:filter-model`(旧 prop 名 `filters` 仍兼容)。\n\n```vue preview src=\"./demos/ResizeAndFilter.zh.vue\"\n```"
|
|
27599
|
+
},
|
|
27600
|
+
{
|
|
27601
|
+
"id": "列设置面板",
|
|
27602
|
+
"title": "列设置面板",
|
|
27603
|
+
"body": "开启 `column-setting` 在表头右上角显示「列设置」按钮,弹出面板可勾选显示/隐藏列,配合 `v-model:hidden-columns` 持久化。面板文案随 `MLocale` 切换。\n\n```vue preview src=\"./demos/ColumnSetting.zh.vue\"\n```"
|
|
27604
|
+
},
|
|
27605
|
+
{
|
|
27606
|
+
"id": "列拖拽排序",
|
|
27607
|
+
"title": "列拖拽排序",
|
|
27608
|
+
"body": "开启 `column-drag` 后,拖拽表头单元格可调整叶列顺序,顺序由 `v-model:column-order` 同步。拖放仅在同一层级内进行,不会破坏多级表头结构。\n\n```vue preview src=\"./demos/ColumnDrag.zh.vue\"\n```"
|
|
27609
|
+
},
|
|
27610
|
+
{
|
|
27611
|
+
"id": "骨架屏加载",
|
|
27612
|
+
"title": "骨架屏加载",
|
|
27613
|
+
"body": "通过 `skeleton` 启用骨架屏加载态,替代整页遮罩 spinner;`skeleton-rows` 控制骨架行数(默认 `5`)。骨架屏会让用户提前感知表格布局,加载体验更好。\n\n```vue preview src=\"./demos/Skeleton.zh.vue\"\n```"
|
|
26867
27614
|
},
|
|
26868
27615
|
{
|
|
26869
27616
|
"id": "虚拟滚动",
|
|
26870
27617
|
"title": "虚拟滚动",
|
|
26871
27618
|
"body": "开启 `virtual`,并提供 `maxHeight` / `tableHeight` / `fill` 之一以形成滚动视口;缺高度时开发环境会 `console.warn`。展开行 / `#expansion` / `expandConfig` 与虚拟滚动互斥,会自动降级为普通渲染(开发环境会提示)。\n\n```vue preview src=\"./demos/VirtualScroll.zh.vue\"\n```"
|
|
26872
27619
|
},
|
|
27620
|
+
{
|
|
27621
|
+
"id": "动态行高虚拟滚动",
|
|
27622
|
+
"title": "动态行高虚拟滚动",
|
|
27623
|
+
"body": "默认虚拟滚动要求所有行等高(由 `virtual-row-height` 估算)。如果某些行由于内容差异存在不同高度,可开启 `virtual-dynamic-row-height`:表格会通过 `ResizeObserver` 实测每行高度并缓存,配合前缀和 + 二分查找实现 O(log n) 滚动定位,长列表下滚动仍保持流畅。\n\n```vue preview src=\"./demos/DynamicRowHeight.zh.vue\"\n```"
|
|
27624
|
+
},
|
|
26873
27625
|
{
|
|
26874
27626
|
"id": "多级表头-表尾与合并",
|
|
26875
27627
|
"title": "多级表头、表尾与合并",
|
|
@@ -26893,7 +27645,7 @@
|
|
|
26893
27645
|
{
|
|
26894
27646
|
"id": "breaking-changes",
|
|
26895
27647
|
"title": "Breaking changes",
|
|
26896
|
-
"body": "- 移除内置单元格编辑:`editConfig`、列 `editable`、`edit-change`、`#edit-{key}`;请用 `#cell-{key}` / `render` 自定义\n- 移除 `MTreeTable`(含 `morya-ui/tree-table`);树表改用 `MTable` + `treeConfig`\n- `serverItemsLength` → `serverTotal`;`rowsItems` → `pageSizes`\n- `hideHeader` 移除;改用 `showHeader`(默认 `true`)\n- `hideRowsPerPage` 移除;改用 `showRowsPerPage`(默认 `true`)\n- 移除:`clickEventType`、`rowsPerPageMessage`、`rowsOfPageSeparatorMessage`、`preventContextMenuRow`、`tableNodeId`\n- 事件:`contextmenuRow` → `row-contextmenu`;`selectRow` / `deselectRow` / `selectAll` → `select-row` / `deselect-row` / `select-all`\n- 移除事件:`updatePageItems`、`updateTotalItems`、`page`(保留 `update:page`)\n- 行交互:始终同时支持单击 / 双击(`row-click` / `row-dblclick`);右键始终 `preventDefault` 并抛出 `row-contextmenu`"
|
|
27648
|
+
"body": "- 移除内置单元格编辑:`editConfig`、列 `editable`、`edit-change`、`#edit-{key}`;请用 `#cell-{key}` / `render` 自定义\n- 移除 `MTreeTable`(含 `morya-ui/tree-table`);树表改用 `MTable` + `treeConfig`\n- `serverItemsLength` → `serverTotal`;`rowsItems` → `pageSizes`\n- `hideHeader` 移除;改用 `showHeader`(默认 `true`)\n- `hideRowsPerPage` 移除;改用 `showRowsPerPage`(默认 `true`)\n- 移除:`clickEventType`、`rowsPerPageMessage`、`rowsOfPageSeparatorMessage`、`preventContextMenuRow`、`tableNodeId`\n- 事件:`sortChange` → `sort-change`;`expandRow` → `expand-change`;`contextmenuRow` → `row-contextmenu`;`selectRow` / `deselectRow` / `selectAll` → `select-row` / `deselect-row` / `select-all`\n- 新增事件:`filter-change`(列筛选提交)\n- 移除事件:`updatePageItems`、`updateTotalItems`、`page`(保留 `update:page`)\n- 行交互:始终同时支持单击 / 双击(`row-click` / `row-dblclick`);右键始终 `preventDefault` 并抛出 `row-contextmenu`\n- 排序 props 合并:`sortField` / `sortOrder` / `multiSort` / `mustSort` / `sortMode` 仍兼容,新代码请使用 `sortConfig: TableSortConfig`\n- 筛选 v-model:`v-model:filters` 仍兼容,新代码请使用 `v-model:filter-model`"
|
|
26897
27649
|
},
|
|
26898
27650
|
{
|
|
26899
27651
|
"id": "tablecolumndefinition",
|
|
@@ -26903,17 +27655,17 @@
|
|
|
26903
27655
|
{
|
|
26904
27656
|
"id": "props",
|
|
26905
27657
|
"title": "Props",
|
|
26906
|
-
"body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `columns` | `TableColumnDefinition[]` | — | 列定义。 |\n| `rows` | `TableItem[]` | — | 行数据。 |\n| `fit` | `boolean` | `true` | 弹性列是否撑满表格宽度。 |\n| `selectionMode` | `'single' \\| 'multiple' \\| null` | `null` | 行选择模式。 |\n| `selection` | `TableItem[] \\| null` | `null` | 多选绑定(`v-model:selection`)。 |\n| `selectedItem` | `TableItem \\| null` | `null` | 单选绑定(`v-model:selected-item`)。 |\n| `serverOptions` | `TableServerOptions \\| null` | `null` | 服务端分页/排序选项。 |\n| `serverTotal` | `number` | `0` | 服务端总条数。 |\n| `paginator` | `boolean` | `false` | 显示内置分页页脚。 |\n| `page` | `number` | `1` | 当前页(`v-model:page`)。 |\n| `rowsPerPage` | `number` | `25` | 每页条数。 |\n| `pageSizes` | `number[]` | `[25, 50, 100]` | 分页每页条数选项。 |\n| `showHeader` | `boolean` | `true` | 是否显示表头。 |\n| `showRowsPerPage` | `boolean` | `true` | 是否显示每页条数选择器。 |\n| `fill` | `boolean` | `false` | 撑满父级剩余高度(仅全视口主列表配 `MPageContent fill`);表体滚动,分页贴底。设置 `maxHeight` / `tableHeight` 时忽略。 |\n| `columnWidths` | `Record<string, number> \\| null` | `null` | 列宽(`v-model:column-widths`)。 |\n| `virtual` | `boolean` | `false` | 行虚拟滚动(需高度;展开行时跳过)。 |\n| `virtualRowHeight` | `number` | `40` | 虚拟行高估算。 |\n| `hiddenColumns` | `string[] \\| null` | `null` | 隐藏列键(`v-model:hidden-columns`)。 |\n| `columnOrder` | `string[] \\| null` | `null` | 叶列顺序(`v-model:column-order`)。 |\n| `showFooter` | `boolean` | `false` | 显示表尾。 |\n| `footerMethod` | `TableFooterMethod \\| null` | `null` | 表尾数据。 |\n| `spanMethod` | `TableSpanMethod \\| null` | `null` | 单元格合并。 |\n| `treeConfig` | `TableTreeConfig \\| null` | `null` | 树形行。 |\n| `expandConfig` | `TableExpandConfig \\| null` | `null` | 详情展开配置(与树互斥)。 |\n| `checkboxConfig` | `TableCheckboxConfig \\| null` | `null` | 多选:级联 / `checkMethod` / `checkRowKeys` / `trigger` / `reserve`。 |\n| `radioConfig` | `TableRadioConfig \\| null` | `null` | 单选:`strict` / `checkMethod` / `trigger`。 |\n| `expandable` | `boolean` | `false` | 显示展开列(也可由 `#expansion` 或 `expandConfig` 启用)。 |\n| `striped` | `boolean` | `false` | 斑马纹行。 |\n| `bordered` | `boolean` | `false` | 单元格边框。 |\n| `highlightCurrent` | `boolean` | `false` | 高亮当前行,配合 `v-model:current-row-key`。 |\n| `rowHover` | `boolean` | `true` | 行 hover 高亮。 |\n| `sortField`
|
|
27658
|
+
"body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `columns` | `TableColumnDefinition[]` | — | 列定义。 |\n| `rows` | `TableItem[]` | — | 行数据。 |\n| `fit` | `boolean` | `true` | 弹性列是否撑满表格宽度。 |\n| `selectionMode` | `'single' \\| 'multiple' \\| null` | `null` | 行选择模式。 |\n| `selection` | `TableItem[] \\| null` | `null` | 多选绑定(`v-model:selection`)。 |\n| `selectedItem` | `TableItem \\| null` | `null` | 单选绑定(`v-model:selected-item`)。 |\n| `serverOptions` | `TableServerOptions \\| null` | `null` | 服务端分页/排序选项。 |\n| `serverTotal` | `number` | `0` | 服务端总条数。 |\n| `paginator` | `boolean` | `false` | 显示内置分页页脚。 |\n| `page` | `number` | `1` | 当前页(`v-model:page`)。 |\n| `rowsPerPage` | `number` | `25` | 每页条数。 |\n| `pageSizes` | `number[]` | `[25, 50, 100]` | 分页每页条数选项。 |\n| `showHeader` | `boolean` | `true` | 是否显示表头。 |\n| `showRowsPerPage` | `boolean` | `true` | 是否显示每页条数选择器。 |\n| `fill` | `boolean` | `false` | 撑满父级剩余高度(仅全视口主列表配 `MPageContent fill`);表体滚动,分页贴底。设置 `maxHeight` / `tableHeight` 时忽略。 |\n| `columnWidths` | `Record<string, number> \\| null` | `null` | 列宽(`v-model:column-widths`)。 |\n| `virtual` | `boolean` | `false` | 行虚拟滚动(需高度;展开行时跳过)。 |\n| `virtualRowHeight` | `number` | `40` | 虚拟行高估算。 |\n| `virtualDynamicRowHeight` | `boolean` | `false` | 动态行高虚拟滚动(实测行高缓存,配合 `ResizeObserver`)。 |\n| `virtualOverscan` | `number` | `4` | 虚拟滚动上下额外渲染的行数,减少白屏闪烁。 |\n| `hiddenColumns` | `string[] \\| null` | `null` | 隐藏列键(`v-model:hidden-columns`)。 |\n| `columnOrder` | `string[] \\| null` | `null` | 叶列顺序(`v-model:column-order`)。 |\n| `columnSetting` | `boolean` | `false` | 显示列设置按钮(显示/隐藏列)。 |\n| `columnDrag` | `boolean` | `false` | 表头拖拽排序。 |\n| `skeleton` | `boolean` | `false` | 骨架屏加载态。 |\n| `skeletonRows` | `number` | `5` | 骨架屏行数。 |\n| `showFooter` | `boolean` | `false` | 显示表尾。 |\n| `footerMethod` | `TableFooterMethod \\| null` | `null` | 表尾数据。 |\n| `spanMethod` | `TableSpanMethod \\| null` | `null` | 单元格合并。 |\n| `treeConfig` | `TableTreeConfig \\| null` | `null` | 树形行。 |\n| `expandConfig` | `TableExpandConfig \\| null` | `null` | 详情展开配置(与树互斥)。 |\n| `checkboxConfig` | `TableCheckboxConfig \\| null` | `null` | 多选:级联 / `checkMethod` / `checkRowKeys` / `trigger` / `reserve`。 |\n| `radioConfig` | `TableRadioConfig \\| null` | `null` | 单选:`strict` / `checkMethod` / `trigger`。 |\n| `expandable` | `boolean` | `false` | 显示展开列(也可由 `#expansion` 或 `expandConfig` 启用)。 |\n| `striped` | `boolean` | `false` | 斑马纹行。 |\n| `bordered` | `boolean` | `false` | 单元格边框。 |\n| `highlightCurrent` | `boolean` | `false` | 高亮当前行,配合 `v-model:current-row-key`。 |\n| `rowHover` | `boolean` | `true` | 行 hover 高亮。 |\n| `sortConfig` | `TableSortConfig \\| null` | `null` | 统一排序配置 `{ field, order, multiple, must, mode }`。 |\n| `sortField` | `string \\| null` | `null` | (兼容)单字段排序。建议用 `sortConfig`。 |\n| `sortOrder` | `'asc' \\| 'desc' \\| null` | `null` | (兼容)单字段排序方向。建议用 `sortConfig`。 |\n| `multiSort` | `boolean` | `false` | (兼容)多列排序。建议用 `sortConfig.multiple`。 |\n| `mustSort` | `boolean` | `false` | (兼容)禁止取消排序。建议用 `sortConfig.must`。 |\n| `sortMode` | `'client' \\| 'emit'` | `'client'` | (兼容)排序模式。建议用 `sortConfig.mode`。 |\n| `searchField` / `searchValue` | — | — | 客户端搜索。 |\n| `filterOptions` | `TableFilterOption[]` | `null` | 结构化筛选条件。 |\n| `filterModel` | `Record<string, unknown> \\| null` | `null` | 列筛选 v-model(与 `update:filter-model` 配合)。 |\n| `filters` | `Record<string, unknown> \\| null` | `null` | (兼容)旧筛选 v-model 名。 |\n| `loading` | `boolean` | `false` | 加载中。 |\n| `emptyText` | `string` | — | 空数据文案。 |\n| `emptyDescription` | `string` | — | 空数据补充说明。 |\n| `maxHeight` | `number \\| null` | `null` | 表格最大高度,超出滚动。 |\n| `showOverflowTooltip` | `boolean` | `false` | 全局单元格溢出 Tooltip。 |\n| `rowKey` | `string` | `'id'` | 行唯一键字段。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 表格密度(`large`/`small` 同步单元格 padding)。 |\n| `ariaLabel` | `string` | — | — |\n| `bodyExpandRowClassName` | `TableBodyRowClassName` | — | — |\n| `bodyItemClassName` | `TableBodyItemClassName` | — | — |\n| `bodyRowClassName` | `TableBodyRowClassName` | — | — |\n| `bodyTextDirection` | `TableTextDirection` | — | — |\n| `checkboxColumnWidth` | `number \\| null` | — | — |\n| `clickRowToExpand` | `boolean` | — | — |\n| `currentRowKey` | `string \\| number \\| null` | — | — |\n| `expandColumnWidth` | `number` | — | — |\n| `expandedRowKeys` | `Array<string \\| number>` | — | — |\n| `fixedCheckbox` | `boolean` | — | — |\n| `fixedExpand` | `boolean` | — | — |\n| `fixedHeader` | `boolean` | — | — |\n| `fixedIndex` | `boolean` | — | — |\n| `headerClassName` | `string` | — | — |\n| `headerItemClassName` | `TableHeaderItemClassName` | — | — |\n| `headerTextDirection` | `TableTextDirection` | — | — |\n| `indexColumnWidth` | `number` | — | — |\n| `showIndex` | `boolean` | — | — |\n| `showIndexSymbol` | `string` | — | — |\n| `tableClassName` | `string` | — | — |\n| `tableHeight` | `number \\| null` | — | — |\n| `tableMinHeight` | `number` | — | — |\n| `pt` | `TablePassThrough` | — | 多部分 DOM 透传:`{ root, scrollbar, thead, tbody, tfoot, pagination, emptyMessage }`。 |"
|
|
26907
27659
|
},
|
|
26908
27660
|
{
|
|
26909
27661
|
"id": "slots",
|
|
26910
27662
|
"title": "Slots",
|
|
26911
|
-
"body": "| 插槽 | 说明 |\n| --- | --- |\n| `cell-{key}` | 列 `{key}` 单元格,作用域 `{ row, value, column }`(可自行实现编辑器)。 |\n| `footer` | 自定义表尾。 |\n| `body-cell` | 任意单元格,作用域 `{ row, column, value }`。 |\n| `expansion` | 展开行内容,作用域 `{ row }`。 |\n| `empty` | 自定义空态。 |\n| `loading` |
|
|
27663
|
+
"body": "| 插槽 | 说明 |\n| --- | --- |\n| `cell-{key}` | 列 `{key}` 单元格,作用域 `{ row, value, column }`(可自行实现编辑器)。 |\n| `footer` | 自定义表尾。 |\n| `body-cell` | 任意单元格,作用域 `{ row, column, value }`。 |\n| `expansion` | 展开行内容,作用域 `{ row }`。 |\n| `empty` | 自定义空态。 |\n| `loading` | 自定义加载态(`skeleton` 为 true 时不生效)。 |\n| `pagination` | 自定义分页区域。 |\n| `body` | 自定义 `body` 内容。 |\n| `body-append` | 自定义 `body-append` 内容。 |\n| `body-prepend` | 自定义 `body-prepend` 内容。 |\n| `customize-headers` | 自定义 `customize-headers` 内容。 |\n| `header` | 自定义 `header` 内容。 |\n| `header-{key}` | 列头插槽(键名大小写与 `columns[].key` 一致)。 |"
|
|
26912
27664
|
},
|
|
26913
27665
|
{
|
|
26914
27666
|
"id": "events",
|
|
26915
27667
|
"title": "Events",
|
|
26916
|
-
"body": "| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `sort` | `{ sortField?, sortOrder? }` | 排序变化。 |\n| `row-click` | `{ row, index }`, `Event` | 行单击。 |\n| `row-dblclick` | `{ row, index }`, `Event` | 行双击。 |\n| `row-contextmenu` | `item`, `MouseEvent` | 行右键。 |\n| `select-row` | `TableItem` | 选中一行。 |\n| `deselect-row` | `TableItem` | 取消选中一行。 |\n| `select-all` | — | 全选当前页。 |\n| `current-change` | `row \\| null, oldRow \\| null` | 当前高亮行变化。 |\n| `
|
|
27668
|
+
"body": "| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `sort-change` | `{ sortField?, sortOrder? }` | 排序变化。 |\n| `filter-change` | `Record<string, unknown> \\| null` | 列筛选提交(与 `update:filter-model` 同步)。 |\n| `expand-change` | `{ row, expanded }` | 行展开状态变化(详情展开或树节点展开)。 |\n| `row-click` | `{ row, index }`, `Event` | 行单击。 |\n| `row-dblclick` | `{ row, index }`, `Event` | 行双击。 |\n| `row-contextmenu` | `item`, `MouseEvent` | 行右键。 |\n| `select-row` | `TableItem` | 选中一行。 |\n| `deselect-row` | `TableItem` | 取消选中一行。 |\n| `select-all` | — | 全选当前页。 |\n| `current-change` | `row \\| null, oldRow \\| null` | 当前高亮行变化。 |\n| `update:selection` | `TableItem[]` | 多选 v-model。 |\n| `update:page` | `number` | 页码 v-model。 |\n| `update:server-options` | `TableServerOptions` | 服务端选项 v-model。 |\n| `update:current-row-key` | `string \\| number \\| null` | 当前行键 v-model。 |\n| `update:expanded-row-keys` | `Array<string \\| number>` | 树/详情展开键 v-model。 |\n| `update:filter-model` | `Record<string, unknown> \\| null` | 列筛选 v-model。 |\n| `update:column-widths` | `Record<string, number>` | 列宽 v-model。 |\n| `update:hidden-columns` | `string[]` | 隐藏列 v-model。 |\n| `update:column-order` | `string[]` | 列顺序 v-model。 |\n| `update:selected-item` | `TableItem \\| null` | 单选 v-model。 |"
|
|
26917
27669
|
},
|
|
26918
27670
|
{
|
|
26919
27671
|
"id": "实例方法",
|
|
@@ -26923,24 +27675,24 @@
|
|
|
26923
27675
|
{
|
|
26924
27676
|
"id": "类型",
|
|
26925
27677
|
"title": "类型",
|
|
26926
|
-
"body": "<h4 id=\"TableItem\">TableItem</h4>\n\n
|
|
27678
|
+
"body": "<h4 id=\"TableItem\">TableItem</h4>\n\n```ts\ntype TableItem = Record<string, unknown>\n```\n\n<h4 id=\"TableSortConfig\">TableSortConfig</h4>\n\n统一排序配置;`field` / `order` 描述当前单列排序状态,`mode` 决定由表格内部或外部接管排序:\n\n```ts\ninterface TableSortConfig {\n field?: string | null\n order?: 'asc' | 'desc' | null\n multiple?: boolean\n must?: boolean\n mode?: 'client' | 'emit'\n}\n```\n\n<h4 id=\"TablePassThrough\">TablePassThrough</h4>\n\n多部分 DOM 透传,支持 class / style / 任意 attrs:\n\n```ts\ninterface TablePassThrough {\n root?: Record<string, unknown>\n scrollbar?: Record<string, unknown>\n thead?: Record<string, unknown>\n tbody?: Record<string, unknown>\n tfoot?: Record<string, unknown>\n pagination?: Record<string, unknown>\n emptyMessage?: Record<string, unknown>\n}\n```\n\n<h4 id=\"TableTextDirection\">TableTextDirection</h4>\n\n```ts\ntype TableTextDirection = 'left' | 'center' | 'right'\n```\n\n<h4 id=\"TableFilterOption\">TableFilterOption</h4>\n\n```ts\ntype TableFilterOption =\n | { field: string; comparison: 'between'; criteria: [number, number] }\n | { field: string; comparison: '=' | '!='; criteria: number | string }\n | { field: string; comparison: '>' | '>=' | '<' | '<='; criteria: number }\n | { field: number | string; comparison: 'in'; criteria: number[] | string[] }\n | { field: string; comparison: (value: unknown, criteria: string) => boolean; criteria: string }\n```\n\n<h4 id=\"TableHeaderItemClassName\">TableHeaderItemClassName</h4>\n\n```ts\ntype TableHeaderItemClassName = string | ((header: TableHeader, columnNumber: number) => string)\n```\n\n<h4 id=\"TableBodyRowClassName\">TableBodyRowClassName</h4>\n\n```ts\ntype TableBodyRowClassName = string | ((item: TableItem, rowNumber: number) => string)\n```\n\n<h4 id=\"TableBodyItemClassName\">TableBodyItemClassName</h4>\n\n```ts\ntype TableBodyItemClassName = string | ((column: string, rowNumber: number) => string)\n```\n\n<h4 id=\"TableTreeConfig\">TableTreeConfig</h4>\n\n```ts\ninterface TableTreeConfig {\n childrenField?: string // default 'children'\n indent?: number // default 16\n expandAll?: boolean\n accordion?: boolean\n trigger?: 'default' | 'row'\n lazy?: boolean\n hasChildField?: string // default 'hasChild'\n loadMethod?: (row: TableItem) => Promise<TableItem[]> | TableItem[]\n transform?: boolean // flat parentId → tree\n rowField?: string\n parentField?: string // default 'parentId'\n treeNode?: string // column key for toggler; default first column\n showLine?: boolean\n}\n```\n\n<h4 id=\"TableColumnDefinition\">TableColumnDefinition</h4>\n\n列定义,传给 `columns`:\n\n```ts\ninterface TableColumnDefinition {\n key: string\n label: string\n width?: number\n minWidth?: number\n sortable?: boolean\n fixed?: boolean | 'left' | 'right'\n align?: 'start' | 'center' | 'end'\n render?: (row: TableItem) => unknown\n showOverflowTooltip?: boolean\n resizable?: boolean\n filterable?: boolean\n filters?: TableColumnFilter[]\n children?: TableColumnDefinition[]\n}\n```\n\n<h4 id=\"TableServerOptions\">TableServerOptions</h4>\n\n服务端分页/排序时传给 `serverOptions`,配合 `serverTotal`:\n\n```ts\ninterface TableServerOptions {\n page: number\n rowsPerPage: number\n sortBy?: string | string[]\n sortType?: 'asc' | 'desc' | ('asc' | 'desc')[]\n}\n```\n\n更多见 [API 类型](/docs/types)。"
|
|
26927
27679
|
}
|
|
26928
27680
|
],
|
|
26929
|
-
"markdown": "---\ntitle: Table\ncategory: 03 / DATA\ndescription: 数据表格。支持排序、筛选、选择、分页、固定列与空/加载态。列宽支持 width / minWidth / fit。\n---\n\n# Table\n\n`MTable` 用于展示结构化行数据。通过 `columns` 定义列、`rows` 传入数据;内置客户端排序、筛选、分页与行选择,也支持服务端分页模式。多选表头「全选」仅作用于当前页。\n\n列宽规则:\n\n- 设置了 `width` 的列为固定宽度\n- 未设 `width` 的列以 `minWidth`(默认 `80`)为弹性下限;`fit` 为 `true`(默认)时,剩余宽度按比例分配给弹性列\n- 总最小宽度超出容器时出现横向滚动\n- 需要表体自己滚动时用 `maxHeight` / `tableHeight`;与 `MLayout` 根滚动叠用时优先固定表高,避免双层滚动条\n- 全视口主列表可用 `MPageContent fill` + `MTable fill paginator`(表体滚动、分页贴底);嵌入表或短页不必使用 `fill`\n\n## 引入\n\n```ts\nimport type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## 行选择\n\n多选配合 `selection-mode=\"multiple\"` 与 `v-model:selection`;单选使用 `selection-mode=\"single\"` 与 `v-model:selected-item`。表头全选仅选中当前页。\n\n```vue preview src=\"./demos/Selection.zh.vue\"\n```\n\n## 筛选与分页\n\n客户端筛选可通过 `search-value` / `filter-options`;分页开启 `paginator` 并配合 `v-model:page` 与 `rows-per-page`(受控同步)。\n\n```vue preview src=\"./demos/FilterAndPagination.zh.vue\"\n```\n\n## 固定列\n\n列定义中设置 `fixed: 'left' | 'right'`(或 `fixed: true` 视为左固定)。\n\n```vue preview src=\"./demos/FixedColumns.zh.vue\"\n```\n\n## 展开行与列渲染\n\n列可通过 `render` 或 `#cell-{key}` 自定义单元格。展开行设置 `expandable`(或 `expandConfig`),详情由 `#expansion` 提供。树模式下 `expandedRowKeys` 用于树节点展开,不可同时用于详情展开。\n\n```vue preview src=\"./demos/ExpandableRows.zh.vue\"\n```\n\n## 列宽拖拽与表头筛选\n\n列设置 `resizable` 可拖拽改宽(`v-model:column-widths`);`filterable` 显示表头筛选,可选 `filters` 为多选选项,否则为文本包含筛选。面板内 **清除** 仅重置草稿,**确认** 后才写入 `v-model:filters`。\n\n```vue preview src=\"./demos/ResizeAndFilter.zh.vue\"\n```\n\n## 虚拟滚动\n\n开启 `virtual`,并提供 `maxHeight` / `tableHeight` / `fill` 之一以形成滚动视口;缺高度时开发环境会 `console.warn`。展开行 / `#expansion` / `expandConfig` 与虚拟滚动互斥,会自动降级为普通渲染(开发环境会提示)。\n\n```vue preview src=\"./demos/VirtualScroll.zh.vue\"\n```\n\n## 多级表头、表尾与合并\n\n列支持 `children` 多级表头;`show-footer` + `footer-method` 渲染合计(`footerMethod({ columns, data })` 返回行矩阵,或使用 `#footer` 插槽完全自定义);`span-method` 合并单元格。\n\n```vue preview src=\"./demos/GridFeatures.zh.vue\"\n```\n\n## 空态与加载\n\n```vue preview src=\"./demos/EmptyAndLoading.zh.vue\"\n```\n\n## 树形表格\n\n传入 `tree-config` 启用树模式:嵌套 `children`,或 `transform` + `parentId` 扁平数据。展开状态用 `v-model:expanded-row-keys`。支持 `expandAll` / `expandRowKeys`、`accordion`、`trigger`、`toggleMethod`、懒加载 `lazy` + `loadMethod`。\n\n实例方法:`setTreeExpand`、`setAllTreeExpand`、`toggleTreeExpand`、`isTreeExpandByRow`、`getTreeExpandRecords`、`clearTreeExpand`。\n\n树 + 多选时默认父子级联与半选(`checkbox-config.check-strictly=false`);`checkMethod` 可禁用单行勾选。\n\n```vue preview src=\"./demos/Tree.zh.vue\"\n```\n\n## 服务端模式\n\n传入 `server-options` 与 `server-total`,通过 `v-model:server-options` 同步页码、每页条数与排序字段。\n\n```vue preview src=\"./demos/Demo7.vue\"\n```\n\n## Breaking changes\n\n- 移除内置单元格编辑:`editConfig`、列 `editable`、`edit-change`、`#edit-{key}`;请用 `#cell-{key}` / `render` 自定义\n- 移除 `MTreeTable`(含 `morya-ui/tree-table`);树表改用 `MTable` + `treeConfig`\n- `serverItemsLength` → `serverTotal`;`rowsItems` → `pageSizes`\n- `hideHeader` 移除;改用 `showHeader`(默认 `true`)\n- `hideRowsPerPage` 移除;改用 `showRowsPerPage`(默认 `true`)\n- 移除:`clickEventType`、`rowsPerPageMessage`、`rowsOfPageSeparatorMessage`、`preventContextMenuRow`、`tableNodeId`\n- 事件:`contextmenuRow` → `row-contextmenu`;`selectRow` / `deselectRow` / `selectAll` → `select-row` / `deselect-row` / `select-all`\n- 移除事件:`updatePageItems`、`updateTotalItems`、`page`(保留 `update:page`)\n- 行交互:始终同时支持单击 / 双击(`row-click` / `row-dblclick`);右键始终 `preventDefault` 并抛出 `row-contextmenu`\n\n## TableColumnDefinition\n\n| 字段 | 类型 | 说明 |\n| --- | --- | --- |\n| `key` | `string` | 列字段名(绑定行数据的键)。 |\n| `label` | `string` | 列头文案。 |\n| `width` | `number` | 固定列宽(px)。 |\n| `minWidth` | `number` | 弹性列最小宽度,默认 `80`。 |\n| `sortable` | `boolean` | 是否可排序。 |\n| `fixed` | `boolean \\| 'left' \\| 'right'` | 固定列;`true` 等同 `'left'`。 |\n| `align` | `'start' \\| 'center' \\| 'end'` | 单元格对齐。 |\n| `render` | `(row) => unknown` | 自定义单元格渲染。 |\n| `showOverflowTooltip` | `boolean` | 该列文本溢出时显示 Tooltip。 |\n| `resizable` | `boolean` | 可拖拽调整列宽。 |\n| `filterable` | `boolean` | 显示表头筛选。 |\n| `filters` | `TableColumnFilter[]` | 表头筛选选项;省略则为文本筛选。 |\n| `children` | `TableColumnDefinition[]` | 多级表头子列。 |\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `columns` | `TableColumnDefinition[]` | — | 列定义。 |\n| `rows` | `TableItem[]` | — | 行数据。 |\n| `fit` | `boolean` | `true` | 弹性列是否撑满表格宽度。 |\n| `selectionMode` | `'single' \\| 'multiple' \\| null` | `null` | 行选择模式。 |\n| `selection` | `TableItem[] \\| null` | `null` | 多选绑定(`v-model:selection`)。 |\n| `selectedItem` | `TableItem \\| null` | `null` | 单选绑定(`v-model:selected-item`)。 |\n| `serverOptions` | `TableServerOptions \\| null` | `null` | 服务端分页/排序选项。 |\n| `serverTotal` | `number` | `0` | 服务端总条数。 |\n| `paginator` | `boolean` | `false` | 显示内置分页页脚。 |\n| `page` | `number` | `1` | 当前页(`v-model:page`)。 |\n| `rowsPerPage` | `number` | `25` | 每页条数。 |\n| `pageSizes` | `number[]` | `[25, 50, 100]` | 分页每页条数选项。 |\n| `showHeader` | `boolean` | `true` | 是否显示表头。 |\n| `showRowsPerPage` | `boolean` | `true` | 是否显示每页条数选择器。 |\n| `fill` | `boolean` | `false` | 撑满父级剩余高度(仅全视口主列表配 `MPageContent fill`);表体滚动,分页贴底。设置 `maxHeight` / `tableHeight` 时忽略。 |\n| `columnWidths` | `Record<string, number> \\| null` | `null` | 列宽(`v-model:column-widths`)。 |\n| `virtual` | `boolean` | `false` | 行虚拟滚动(需高度;展开行时跳过)。 |\n| `virtualRowHeight` | `number` | `40` | 虚拟行高估算。 |\n| `hiddenColumns` | `string[] \\| null` | `null` | 隐藏列键(`v-model:hidden-columns`)。 |\n| `columnOrder` | `string[] \\| null` | `null` | 叶列顺序(`v-model:column-order`)。 |\n| `showFooter` | `boolean` | `false` | 显示表尾。 |\n| `footerMethod` | `TableFooterMethod \\| null` | `null` | 表尾数据。 |\n| `spanMethod` | `TableSpanMethod \\| null` | `null` | 单元格合并。 |\n| `treeConfig` | `TableTreeConfig \\| null` | `null` | 树形行。 |\n| `expandConfig` | `TableExpandConfig \\| null` | `null` | 详情展开配置(与树互斥)。 |\n| `checkboxConfig` | `TableCheckboxConfig \\| null` | `null` | 多选:级联 / `checkMethod` / `checkRowKeys` / `trigger` / `reserve`。 |\n| `radioConfig` | `TableRadioConfig \\| null` | `null` | 单选:`strict` / `checkMethod` / `trigger`。 |\n| `expandable` | `boolean` | `false` | 显示展开列(也可由 `#expansion` 或 `expandConfig` 启用)。 |\n| `striped` | `boolean` | `false` | 斑马纹行。 |\n| `bordered` | `boolean` | `false` | 单元格边框。 |\n| `highlightCurrent` | `boolean` | `false` | 高亮当前行,配合 `v-model:current-row-key`。 |\n| `rowHover` | `boolean` | `true` | 行 hover 高亮。 |\n| `sortField` / `sortOrder` | — | — | 受控排序字段与方向。 |\n| `sortMode` | `'client' \\| 'emit'` | `'client'` | 客户端排序或仅抛出排序事件。 |\n| `searchField` / `searchValue` | — | — | 客户端搜索。 |\n| `filterOptions` | `TableFilterOption[]` | `null` | 结构化筛选条件。 |\n| `loading` | `boolean` | `false` | 加载中。 |\n| `emptyText` | `string` | — | 空数据文案。 |\n| `emptyDescription` | `string` | — | 空数据补充说明。 |\n| `maxHeight` | `number \\| null` | `null` | 表格最大高度,超出滚动。 |\n| `showOverflowTooltip` | `boolean` | `false` | 全局单元格溢出 Tooltip。 |\n| `rowKey` | `string` | `'id'` | 行唯一键字段。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 表格密度(`large`/`small` 同步单元格 padding)。 |\n| `ariaLabel` | `string` | — | — |\n| `bodyExpandRowClassName` | `TableBodyRowClassName` | — | — |\n| `bodyItemClassName` | `TableBodyItemClassName` | — | — |\n| `bodyRowClassName` | `TableBodyRowClassName` | — | — |\n| `bodyTextDirection` | `TableTextDirection` | — | — |\n| `checkboxColumnWidth` | `number \\| null` | — | — |\n| `clickRowToExpand` | `boolean` | — | — |\n| `currentRowKey` | `string \\| number \\| null` | — | — |\n| `expandColumnWidth` | `number` | — | — |\n| `expandedRowKeys` | `Array<string \\| number>` | — | — |\n| `filters` | `Record<string, unknown> \\| null` | — | — |\n| `fixedCheckbox` | `boolean` | — | — |\n| `fixedExpand` | `boolean` | — | — |\n| `fixedHeader` | `boolean` | — | — |\n| `fixedIndex` | `boolean` | — | — |\n| `headerClassName` | `string` | — | — |\n| `headerItemClassName` | `TableHeaderItemClassName` | — | — |\n| `headerTextDirection` | `TableTextDirection` | — | — |\n| `indexColumnWidth` | `number` | — | — |\n| `multiSort` | `boolean` | — | — |\n| `mustSort` | `boolean` | — | — |\n| `showIndex` | `boolean` | — | — |\n| `showIndexSymbol` | `string` | — | — |\n| `tableClassName` | `string` | — | — |\n| `tableHeight` | `number \\| null` | — | — |\n| `tableMinHeight` | `number` | — | — |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n\n## Slots\n\n| 插槽 | 说明 |\n| --- | --- |\n| `cell-{key}` | 列 `{key}` 单元格,作用域 `{ row, value, column }`(可自行实现编辑器)。 |\n| `footer` | 自定义表尾。 |\n| `body-cell` | 任意单元格,作用域 `{ row, column, value }`。 |\n| `expansion` | 展开行内容,作用域 `{ row }`。 |\n| `empty` | 自定义空态。 |\n| `loading` | 自定义加载态。 |\n| `pagination` | 自定义分页区域。 |\n| `body` | 自定义 `body` 内容。 |\n| `body-append` | 自定义 `body-append` 内容。 |\n| `body-prepend` | 自定义 `body-prepend` 内容。 |\n| `customize-headers` | 自定义 `customize-headers` 内容。 |\n| `header` | 自定义 `header` 内容。 |\n| `header-{key}` | 列头插槽(键名大小写与 `columns[].key` 一致)。 |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `sort` | `{ sortField?, sortOrder? }` | 排序变化。 |\n| `row-click` | `{ row, index }`, `Event` | 行单击。 |\n| `row-dblclick` | `{ row, index }`, `Event` | 行双击。 |\n| `row-contextmenu` | `item`, `MouseEvent` | 行右键。 |\n| `select-row` | `TableItem` | 选中一行。 |\n| `deselect-row` | `TableItem` | 取消选中一行。 |\n| `select-all` | — | 全选当前页。 |\n| `current-change` | `row \\| null, oldRow \\| null` | 当前高亮行变化。 |\n| `expand` | `{ row, expanded }` | 行展开。 |\n| `update:selection` | `TableItem[]` | 多选 v-model。 |\n| `update:page` | `number` | 页码 v-model。 |\n| `update:server-options` | `TableServerOptions` | 服务端选项 v-model。 |\n| `update:current-row-key` | `string \\| number \\| null` | 当前行键 v-model。 |\n| `filter` | — | — |\n| `update:expandedRowKeys` | — | — |\n| `update:filters` | — | — |\n| `update:columnWidths` | `Record<string, number>` | 列宽 v-model。 |\n| `update:hiddenColumns` | `string[]` | 隐藏列 v-model。 |\n| `update:columnOrder` | `string[]` | 列顺序 v-model。 |\n| `update:selectedItem` | — | — |\n\n## 实例方法\n\n通过 `ref` 可访问分页、筛选、选择、滚动与展开控制:\n\n| 方法 / 属性 | 说明 |\n| --- | --- |\n| `currentPageFirstIndex` | 当前页首条记录的索引(无数据时为 `-1`)。 |\n| `currentPageLastIndex` | 当前页末条记录的索引。 |\n| `clientItemsLength` | 数据总条数(服务端模式下为服务端总数)。 |\n| `maxPaginationNumber` | 最大页码。 |\n| `currentPaginationNumber` | 当前页码。 |\n| `isLastPage` / `isFirstPage` | 是否末页 / 首页。 |\n| `nextPage()` / `prevPage()` | 下一页 / 上一页。 |\n| `updatePage(page)` | 跳到指定页码。 |\n| `rowsPerPageOptions` | 每页条数选项。 |\n| `rowsPerPageActiveOption` | 当前生效的每页条数。 |\n| `updateRowsPerPageActiveOption(n)` | 修改每页条数。 |\n| `setFilters(filters)` / `clearFilter()` | 设置 / 清空筛选。 |\n| `setColumnWidths(widths)` | 设置列宽(等同 `v-model:column-widths`)。 |\n| `setHiddenColumns(keys)` | 设置隐藏列键(等同 `v-model:hidden-columns`)。 |\n| `setColumnOrder(keys)` | 设置叶列顺序(等同 `v-model:column-order`)。 |\n| `clearSort()` | 清空排序。 |\n| `getCheckboxRecords()` | 当前多选行。 |\n| `setCheckboxRow(rows, checked)` | 设置行选中状态。 |\n| `clearCheckboxRow()` | 清空多选。 |\n| `isCheckedByCheckboxRow(row)` | 行是否选中。 |\n| `isAllCheckboxChecked()` | 当前页是否全选。 |\n| `getCheckboxIndeterminateRecords()` | 半选行(树级联)。 |\n| `scrollTo(...)` / `scrollToRow(row)` | 滚动定位。 |\n| `setRowExpand` / `setAllRowExpand` / `toggleRowExpand` / `clearRowExpand` / `isRowExpandByRow` / `getRowExpandRecords` | 详情展开(非树模式)。 |\n| `setTreeExpand` / `setAllTreeExpand` / `toggleTreeExpand` / `clearTreeExpand` / `isTreeExpandByRow` / `getTreeExpandRecords` | 树节点展开。 |\n\n## 类型\n\n<h4 id=\"TableItem\">TableItem</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ntype TableItem = Record<string, unknown>\n```\n\n<h4 id=\"TableTextDirection\">TableTextDirection</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ntype TableTextDirection = 'left' | 'center' | 'right'\n```\n\n<h4 id=\"TableFilterOption\">TableFilterOption</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ntype TableFilterOption = | { field: string; comparison: 'between'; criteria: [number, number] }\n | { field: string; comparison: '=' | '!='; criteria: number | string }\n | { field: string; comparison: '>' | '>=' | '<' | '<='; criteria: number }\n | { field: number | string; comparison: 'in'; criteria: number[] | string[] }\n | { field: string; comparison: (value: unknown, criteria: string) => boolean; criteria: string }\n```\n\n<h4 id=\"TableHeaderItemClassName\">TableHeaderItemClassName</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ntype TableHeaderItemClassName = string | ((header: TableHeader, columnNumber: number) => string)\n```\n\n<h4 id=\"TableBodyRowClassName\">TableBodyRowClassName</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ntype TableBodyRowClassName = string | ((item: TableItem, rowNumber: number) => string)\n```\n\n<h4 id=\"TableBodyItemClassName\">TableBodyItemClassName</h4>\n\n完整定义见源码 `types.ts`。\n\n```ts\ntype TableBodyItemClassName = string | ((column: string, rowNumber: number) => string)\n```\n\n\n<h4 id=\"TableTreeConfig\">TableTreeConfig</h4>\n\n```ts\ninterface TableTreeConfig {\n childrenField?: string // default 'children'\n indent?: number // default 16\n expandAll?: boolean\n accordion?: boolean\n trigger?: 'default' | 'row'\n lazy?: boolean\n hasChildField?: string // default 'hasChild'\n loadMethod?: (row: TableItem) => Promise<TableItem[]> | TableItem[]\n transform?: boolean // flat parentId → tree\n rowField?: string\n parentField?: string // default 'parentId'\n treeNode?: string // column key for toggler; default first column\n showLine?: boolean\n}\n```\n\n<h4 id=\"TableColumnDefinition\">TableColumnDefinition</h4>\n\n列定义,传给 `columns`:\n\n```ts\ninterface TableColumnDefinition {\n key: string\n label: string\n width?: number\n minWidth?: number\n sortable?: boolean\n fixed?: boolean | 'left' | 'right'\n align?: 'start' | 'center' | 'end'\n render?: (row: TableItem) => unknown\n showOverflowTooltip?: boolean\n}\n```\n\n<h4 id=\"TableServerOptions\">TableServerOptions</h4>\n\n服务端分页/排序时传给 `serverOptions`,配合 `serverTotal`:\n\n```ts\ninterface TableServerOptions {\n page: number\n rowsPerPage: number\n sortBy?: string | string[]\n sortType?: 'asc' | 'desc' | ('asc' | 'desc')[]\n}\n```\n\n更多见 [API 类型](/docs/types)。\n"
|
|
27681
|
+
"markdown": "---\ntitle: Table\ncategory: 03 / DATA\ndescription: 数据表格。支持排序、筛选、选择、分页、固定列、列拖拽、列设置、骨架屏与虚拟滚动。列宽支持 width / minWidth / fit。\n---\n\n# Table\n\n`MTable` 用于展示结构化行数据。通过 `columns` 定义列、`rows` 传入数据;内置客户端排序、筛选、分页与行选择,也支持服务端分页模式。多选表头「全选」仅作用于当前页。\n\n列宽规则:\n\n- 设置了 `width` 的列为固定宽度\n- 未设 `width` 的列以 `minWidth`(默认 `80`)为弹性下限;`fit` 为 `true`(默认)时,剩余宽度按比例分配给弹性列\n- 总最小宽度超出容器时出现横向滚动\n- 需要表体自己滚动时用 `maxHeight` / `tableHeight`;与 `MLayout` 根滚动叠用时优先固定表高,避免双层滚动条\n- 全视口主列表可用 `MPageContent fill` + `MTable fill paginator`(表体滚动、分页贴底);嵌入表或短页不必使用 `fill`\n\n## 引入\n\n```ts\nimport type { TableColumnDefinition, TableItem, TableSortConfig, TablePassThrough } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.zh.vue\"\n```\n\n## 行选择\n\n多选配合 `selection-mode=\"multiple\"` 与 `v-model:selection`;单选使用 `selection-mode=\"single\"` 与 `v-model:selected-item`。表头全选仅选中当前页。\n\n```vue preview src=\"./demos/Selection.zh.vue\"\n```\n\n## 筛选与分页\n\n客户端筛选可通过 `search-value` / `filter-options`;分页开启 `paginator` 并配合 `v-model:page` 与 `rows-per-page`(受控同步)。\n\n```vue preview src=\"./demos/FilterAndPagination.zh.vue\"\n```\n\n## 固定列\n\n列定义中设置 `fixed: 'left' | 'right'`(或 `fixed: true` 视为左固定)。\n\n```vue preview src=\"./demos/FixedColumns.zh.vue\"\n```\n\n## 展开行与列渲染\n\n列可通过 `render` 或 `#cell-{key}` 自定义单元格。展开行设置 `expandable`(或 `expandConfig`),详情由 `#expansion` 提供。树模式下 `expandedRowKeys` 用于树节点展开,不可同时用于详情展开。\n\n```vue preview src=\"./demos/ExpandableRows.zh.vue\"\n```\n\n## 排序(sortConfig)\n\n通过 `sort-config` 统一配置排序:`{ field, order, multiple, must, mode }`。`mode: 'client'`(默认)由表格内部对当前页数据排序;`mode: 'emit'` 时表格只触发 `sort-change` 事件,数据由外部接管(适合服务端排序)。多列排序设 `multiple: true`,禁止取消排序设 `must: true`。\n\n```vue preview src=\"./demos/Sorting.zh.vue\"\n```\n\n## 列宽拖拽与表头筛选\n\n列设置 `resizable` 可拖拽改宽(`v-model:column-widths`);`filterable` 显示表头筛选,列定义里的 `filters` 为多选选项,省略则为文本包含筛选。面板内 **清除** 仅重置草稿,**确认** 后才写入 `v-model:filter-model`(旧 prop 名 `filters` 仍兼容)。\n\n```vue preview src=\"./demos/ResizeAndFilter.zh.vue\"\n```\n\n## 列设置面板\n\n开启 `column-setting` 在表头右上角显示「列设置」按钮,弹出面板可勾选显示/隐藏列,配合 `v-model:hidden-columns` 持久化。面板文案随 `MLocale` 切换。\n\n```vue preview src=\"./demos/ColumnSetting.zh.vue\"\n```\n\n## 列拖拽排序\n\n开启 `column-drag` 后,拖拽表头单元格可调整叶列顺序,顺序由 `v-model:column-order` 同步。拖放仅在同一层级内进行,不会破坏多级表头结构。\n\n```vue preview src=\"./demos/ColumnDrag.zh.vue\"\n```\n\n## 骨架屏加载\n\n通过 `skeleton` 启用骨架屏加载态,替代整页遮罩 spinner;`skeleton-rows` 控制骨架行数(默认 `5`)。骨架屏会让用户提前感知表格布局,加载体验更好。\n\n```vue preview src=\"./demos/Skeleton.zh.vue\"\n```\n\n## 虚拟滚动\n\n开启 `virtual`,并提供 `maxHeight` / `tableHeight` / `fill` 之一以形成滚动视口;缺高度时开发环境会 `console.warn`。展开行 / `#expansion` / `expandConfig` 与虚拟滚动互斥,会自动降级为普通渲染(开发环境会提示)。\n\n```vue preview src=\"./demos/VirtualScroll.zh.vue\"\n```\n\n## 动态行高虚拟滚动\n\n默认虚拟滚动要求所有行等高(由 `virtual-row-height` 估算)。如果某些行由于内容差异存在不同高度,可开启 `virtual-dynamic-row-height`:表格会通过 `ResizeObserver` 实测每行高度并缓存,配合前缀和 + 二分查找实现 O(log n) 滚动定位,长列表下滚动仍保持流畅。\n\n```vue preview src=\"./demos/DynamicRowHeight.zh.vue\"\n```\n\n## 多级表头、表尾与合并\n\n列支持 `children` 多级表头;`show-footer` + `footer-method` 渲染合计(`footerMethod({ columns, data })` 返回行矩阵,或使用 `#footer` 插槽完全自定义);`span-method` 合并单元格。\n\n```vue preview src=\"./demos/GridFeatures.zh.vue\"\n```\n\n## 空态与加载\n\n```vue preview src=\"./demos/EmptyAndLoading.zh.vue\"\n```\n\n## 树形表格\n\n传入 `tree-config` 启用树模式:嵌套 `children`,或 `transform` + `parentId` 扁平数据。展开状态用 `v-model:expanded-row-keys`。支持 `expandAll` / `expandRowKeys`、`accordion`、`trigger`、`toggleMethod`、懒加载 `lazy` + `loadMethod`。\n\n实例方法:`setTreeExpand`、`setAllTreeExpand`、`toggleTreeExpand`、`isTreeExpandByRow`、`getTreeExpandRecords`、`clearTreeExpand`。\n\n树 + 多选时默认父子级联与半选(`checkbox-config.check-strictly=false`);`checkMethod` 可禁用单行勾选。\n\n```vue preview src=\"./demos/Tree.zh.vue\"\n```\n\n## 服务端模式\n\n传入 `server-options` 与 `server-total`,通过 `v-model:server-options` 同步页码、每页条数与排序字段。\n\n```vue preview src=\"./demos/Demo7.vue\"\n```\n\n## Breaking changes\n\n- 移除内置单元格编辑:`editConfig`、列 `editable`、`edit-change`、`#edit-{key}`;请用 `#cell-{key}` / `render` 自定义\n- 移除 `MTreeTable`(含 `morya-ui/tree-table`);树表改用 `MTable` + `treeConfig`\n- `serverItemsLength` → `serverTotal`;`rowsItems` → `pageSizes`\n- `hideHeader` 移除;改用 `showHeader`(默认 `true`)\n- `hideRowsPerPage` 移除;改用 `showRowsPerPage`(默认 `true`)\n- 移除:`clickEventType`、`rowsPerPageMessage`、`rowsOfPageSeparatorMessage`、`preventContextMenuRow`、`tableNodeId`\n- 事件:`sortChange` → `sort-change`;`expandRow` → `expand-change`;`contextmenuRow` → `row-contextmenu`;`selectRow` / `deselectRow` / `selectAll` → `select-row` / `deselect-row` / `select-all`\n- 新增事件:`filter-change`(列筛选提交)\n- 移除事件:`updatePageItems`、`updateTotalItems`、`page`(保留 `update:page`)\n- 行交互:始终同时支持单击 / 双击(`row-click` / `row-dblclick`);右键始终 `preventDefault` 并抛出 `row-contextmenu`\n- 排序 props 合并:`sortField` / `sortOrder` / `multiSort` / `mustSort` / `sortMode` 仍兼容,新代码请使用 `sortConfig: TableSortConfig`\n- 筛选 v-model:`v-model:filters` 仍兼容,新代码请使用 `v-model:filter-model`\n\n## TableColumnDefinition\n\n| 字段 | 类型 | 说明 |\n| --- | --- | --- |\n| `key` | `string` | 列字段名(绑定行数据的键)。 |\n| `label` | `string` | 列头文案。 |\n| `width` | `number` | 固定列宽(px)。 |\n| `minWidth` | `number` | 弹性列最小宽度,默认 `80`。 |\n| `sortable` | `boolean` | 是否可排序。 |\n| `fixed` | `boolean \\| 'left' \\| 'right'` | 固定列;`true` 等同 `'left'`。 |\n| `align` | `'start' \\| 'center' \\| 'end'` | 单元格对齐。 |\n| `render` | `(row) => unknown` | 自定义单元格渲染。 |\n| `showOverflowTooltip` | `boolean` | 该列文本溢出时显示 Tooltip。 |\n| `resizable` | `boolean` | 可拖拽调整列宽。 |\n| `filterable` | `boolean` | 显示表头筛选。 |\n| `filters` | `TableColumnFilter[]` | 表头筛选选项;省略则为文本筛选。 |\n| `children` | `TableColumnDefinition[]` | 多级表头子列。 |\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `columns` | `TableColumnDefinition[]` | — | 列定义。 |\n| `rows` | `TableItem[]` | — | 行数据。 |\n| `fit` | `boolean` | `true` | 弹性列是否撑满表格宽度。 |\n| `selectionMode` | `'single' \\| 'multiple' \\| null` | `null` | 行选择模式。 |\n| `selection` | `TableItem[] \\| null` | `null` | 多选绑定(`v-model:selection`)。 |\n| `selectedItem` | `TableItem \\| null` | `null` | 单选绑定(`v-model:selected-item`)。 |\n| `serverOptions` | `TableServerOptions \\| null` | `null` | 服务端分页/排序选项。 |\n| `serverTotal` | `number` | `0` | 服务端总条数。 |\n| `paginator` | `boolean` | `false` | 显示内置分页页脚。 |\n| `page` | `number` | `1` | 当前页(`v-model:page`)。 |\n| `rowsPerPage` | `number` | `25` | 每页条数。 |\n| `pageSizes` | `number[]` | `[25, 50, 100]` | 分页每页条数选项。 |\n| `showHeader` | `boolean` | `true` | 是否显示表头。 |\n| `showRowsPerPage` | `boolean` | `true` | 是否显示每页条数选择器。 |\n| `fill` | `boolean` | `false` | 撑满父级剩余高度(仅全视口主列表配 `MPageContent fill`);表体滚动,分页贴底。设置 `maxHeight` / `tableHeight` 时忽略。 |\n| `columnWidths` | `Record<string, number> \\| null` | `null` | 列宽(`v-model:column-widths`)。 |\n| `virtual` | `boolean` | `false` | 行虚拟滚动(需高度;展开行时跳过)。 |\n| `virtualRowHeight` | `number` | `40` | 虚拟行高估算。 |\n| `virtualDynamicRowHeight` | `boolean` | `false` | 动态行高虚拟滚动(实测行高缓存,配合 `ResizeObserver`)。 |\n| `virtualOverscan` | `number` | `4` | 虚拟滚动上下额外渲染的行数,减少白屏闪烁。 |\n| `hiddenColumns` | `string[] \\| null` | `null` | 隐藏列键(`v-model:hidden-columns`)。 |\n| `columnOrder` | `string[] \\| null` | `null` | 叶列顺序(`v-model:column-order`)。 |\n| `columnSetting` | `boolean` | `false` | 显示列设置按钮(显示/隐藏列)。 |\n| `columnDrag` | `boolean` | `false` | 表头拖拽排序。 |\n| `skeleton` | `boolean` | `false` | 骨架屏加载态。 |\n| `skeletonRows` | `number` | `5` | 骨架屏行数。 |\n| `showFooter` | `boolean` | `false` | 显示表尾。 |\n| `footerMethod` | `TableFooterMethod \\| null` | `null` | 表尾数据。 |\n| `spanMethod` | `TableSpanMethod \\| null` | `null` | 单元格合并。 |\n| `treeConfig` | `TableTreeConfig \\| null` | `null` | 树形行。 |\n| `expandConfig` | `TableExpandConfig \\| null` | `null` | 详情展开配置(与树互斥)。 |\n| `checkboxConfig` | `TableCheckboxConfig \\| null` | `null` | 多选:级联 / `checkMethod` / `checkRowKeys` / `trigger` / `reserve`。 |\n| `radioConfig` | `TableRadioConfig \\| null` | `null` | 单选:`strict` / `checkMethod` / `trigger`。 |\n| `expandable` | `boolean` | `false` | 显示展开列(也可由 `#expansion` 或 `expandConfig` 启用)。 |\n| `striped` | `boolean` | `false` | 斑马纹行。 |\n| `bordered` | `boolean` | `false` | 单元格边框。 |\n| `highlightCurrent` | `boolean` | `false` | 高亮当前行,配合 `v-model:current-row-key`。 |\n| `rowHover` | `boolean` | `true` | 行 hover 高亮。 |\n| `sortConfig` | `TableSortConfig \\| null` | `null` | 统一排序配置 `{ field, order, multiple, must, mode }`。 |\n| `sortField` | `string \\| null` | `null` | (兼容)单字段排序。建议用 `sortConfig`。 |\n| `sortOrder` | `'asc' \\| 'desc' \\| null` | `null` | (兼容)单字段排序方向。建议用 `sortConfig`。 |\n| `multiSort` | `boolean` | `false` | (兼容)多列排序。建议用 `sortConfig.multiple`。 |\n| `mustSort` | `boolean` | `false` | (兼容)禁止取消排序。建议用 `sortConfig.must`。 |\n| `sortMode` | `'client' \\| 'emit'` | `'client'` | (兼容)排序模式。建议用 `sortConfig.mode`。 |\n| `searchField` / `searchValue` | — | — | 客户端搜索。 |\n| `filterOptions` | `TableFilterOption[]` | `null` | 结构化筛选条件。 |\n| `filterModel` | `Record<string, unknown> \\| null` | `null` | 列筛选 v-model(与 `update:filter-model` 配合)。 |\n| `filters` | `Record<string, unknown> \\| null` | `null` | (兼容)旧筛选 v-model 名。 |\n| `loading` | `boolean` | `false` | 加载中。 |\n| `emptyText` | `string` | — | 空数据文案。 |\n| `emptyDescription` | `string` | — | 空数据补充说明。 |\n| `maxHeight` | `number \\| null` | `null` | 表格最大高度,超出滚动。 |\n| `showOverflowTooltip` | `boolean` | `false` | 全局单元格溢出 Tooltip。 |\n| `rowKey` | `string` | `'id'` | 行唯一键字段。 |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | 表格密度(`large`/`small` 同步单元格 padding)。 |\n| `ariaLabel` | `string` | — | — |\n| `bodyExpandRowClassName` | `TableBodyRowClassName` | — | — |\n| `bodyItemClassName` | `TableBodyItemClassName` | — | — |\n| `bodyRowClassName` | `TableBodyRowClassName` | — | — |\n| `bodyTextDirection` | `TableTextDirection` | — | — |\n| `checkboxColumnWidth` | `number \\| null` | — | — |\n| `clickRowToExpand` | `boolean` | — | — |\n| `currentRowKey` | `string \\| number \\| null` | — | — |\n| `expandColumnWidth` | `number` | — | — |\n| `expandedRowKeys` | `Array<string \\| number>` | — | — |\n| `fixedCheckbox` | `boolean` | — | — |\n| `fixedExpand` | `boolean` | — | — |\n| `fixedHeader` | `boolean` | — | — |\n| `fixedIndex` | `boolean` | — | — |\n| `headerClassName` | `string` | — | — |\n| `headerItemClassName` | `TableHeaderItemClassName` | — | — |\n| `headerTextDirection` | `TableTextDirection` | — | — |\n| `indexColumnWidth` | `number` | — | — |\n| `showIndex` | `boolean` | — | — |\n| `showIndexSymbol` | `string` | — | — |\n| `tableClassName` | `string` | — | — |\n| `tableHeight` | `number \\| null` | — | — |\n| `tableMinHeight` | `number` | — | — |\n| `pt` | `TablePassThrough` | — | 多部分 DOM 透传:`{ root, scrollbar, thead, tbody, tfoot, pagination, emptyMessage }`。 |\n\n## Slots\n\n| 插槽 | 说明 |\n| --- | --- |\n| `cell-{key}` | 列 `{key}` 单元格,作用域 `{ row, value, column }`(可自行实现编辑器)。 |\n| `footer` | 自定义表尾。 |\n| `body-cell` | 任意单元格,作用域 `{ row, column, value }`。 |\n| `expansion` | 展开行内容,作用域 `{ row }`。 |\n| `empty` | 自定义空态。 |\n| `loading` | 自定义加载态(`skeleton` 为 true 时不生效)。 |\n| `pagination` | 自定义分页区域。 |\n| `body` | 自定义 `body` 内容。 |\n| `body-append` | 自定义 `body-append` 内容。 |\n| `body-prepend` | 自定义 `body-prepend` 内容。 |\n| `customize-headers` | 自定义 `customize-headers` 内容。 |\n| `header` | 自定义 `header` 内容。 |\n| `header-{key}` | 列头插槽(键名大小写与 `columns[].key` 一致)。 |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `sort-change` | `{ sortField?, sortOrder? }` | 排序变化。 |\n| `filter-change` | `Record<string, unknown> \\| null` | 列筛选提交(与 `update:filter-model` 同步)。 |\n| `expand-change` | `{ row, expanded }` | 行展开状态变化(详情展开或树节点展开)。 |\n| `row-click` | `{ row, index }`, `Event` | 行单击。 |\n| `row-dblclick` | `{ row, index }`, `Event` | 行双击。 |\n| `row-contextmenu` | `item`, `MouseEvent` | 行右键。 |\n| `select-row` | `TableItem` | 选中一行。 |\n| `deselect-row` | `TableItem` | 取消选中一行。 |\n| `select-all` | — | 全选当前页。 |\n| `current-change` | `row \\| null, oldRow \\| null` | 当前高亮行变化。 |\n| `update:selection` | `TableItem[]` | 多选 v-model。 |\n| `update:page` | `number` | 页码 v-model。 |\n| `update:server-options` | `TableServerOptions` | 服务端选项 v-model。 |\n| `update:current-row-key` | `string \\| number \\| null` | 当前行键 v-model。 |\n| `update:expanded-row-keys` | `Array<string \\| number>` | 树/详情展开键 v-model。 |\n| `update:filter-model` | `Record<string, unknown> \\| null` | 列筛选 v-model。 |\n| `update:column-widths` | `Record<string, number>` | 列宽 v-model。 |\n| `update:hidden-columns` | `string[]` | 隐藏列 v-model。 |\n| `update:column-order` | `string[]` | 列顺序 v-model。 |\n| `update:selected-item` | `TableItem \\| null` | 单选 v-model。 |\n\n## 实例方法\n\n通过 `ref` 可访问分页、筛选、选择、滚动与展开控制:\n\n| 方法 / 属性 | 说明 |\n| --- | --- |\n| `currentPageFirstIndex` | 当前页首条记录的索引(无数据时为 `-1`)。 |\n| `currentPageLastIndex` | 当前页末条记录的索引。 |\n| `clientItemsLength` | 数据总条数(服务端模式下为服务端总数)。 |\n| `maxPaginationNumber` | 最大页码。 |\n| `currentPaginationNumber` | 当前页码。 |\n| `isLastPage` / `isFirstPage` | 是否末页 / 首页。 |\n| `nextPage()` / `prevPage()` | 下一页 / 上一页。 |\n| `updatePage(page)` | 跳到指定页码。 |\n| `rowsPerPageOptions` | 每页条数选项。 |\n| `rowsPerPageActiveOption` | 当前生效的每页条数。 |\n| `updateRowsPerPageActiveOption(n)` | 修改每页条数。 |\n| `setFilters(filters)` / `clearFilter()` | 设置 / 清空筛选。 |\n| `setColumnWidths(widths)` | 设置列宽(等同 `v-model:column-widths`)。 |\n| `setHiddenColumns(keys)` | 设置隐藏列键(等同 `v-model:hidden-columns`)。 |\n| `setColumnOrder(keys)` | 设置叶列顺序(等同 `v-model:column-order`)。 |\n| `clearSort()` | 清空排序。 |\n| `getCheckboxRecords()` | 当前多选行。 |\n| `setCheckboxRow(rows, checked)` | 设置行选中状态。 |\n| `clearCheckboxRow()` | 清空多选。 |\n| `isCheckedByCheckboxRow(row)` | 行是否选中。 |\n| `isAllCheckboxChecked()` | 当前页是否全选。 |\n| `getCheckboxIndeterminateRecords()` | 半选行(树级联)。 |\n| `scrollTo(...)` / `scrollToRow(row)` | 滚动定位。 |\n| `setRowExpand` / `setAllRowExpand` / `toggleRowExpand` / `clearRowExpand` / `isRowExpandByRow` / `getRowExpandRecords` | 详情展开(非树模式)。 |\n| `setTreeExpand` / `setAllTreeExpand` / `toggleTreeExpand` / `clearTreeExpand` / `isTreeExpandByRow` / `getTreeExpandRecords` | 树节点展开。 |\n\n## 类型\n\n<h4 id=\"TableItem\">TableItem</h4>\n\n```ts\ntype TableItem = Record<string, unknown>\n```\n\n<h4 id=\"TableSortConfig\">TableSortConfig</h4>\n\n统一排序配置;`field` / `order` 描述当前单列排序状态,`mode` 决定由表格内部或外部接管排序:\n\n```ts\ninterface TableSortConfig {\n field?: string | null\n order?: 'asc' | 'desc' | null\n multiple?: boolean\n must?: boolean\n mode?: 'client' | 'emit'\n}\n```\n\n<h4 id=\"TablePassThrough\">TablePassThrough</h4>\n\n多部分 DOM 透传,支持 class / style / 任意 attrs:\n\n```ts\ninterface TablePassThrough {\n root?: Record<string, unknown>\n scrollbar?: Record<string, unknown>\n thead?: Record<string, unknown>\n tbody?: Record<string, unknown>\n tfoot?: Record<string, unknown>\n pagination?: Record<string, unknown>\n emptyMessage?: Record<string, unknown>\n}\n```\n\n<h4 id=\"TableTextDirection\">TableTextDirection</h4>\n\n```ts\ntype TableTextDirection = 'left' | 'center' | 'right'\n```\n\n<h4 id=\"TableFilterOption\">TableFilterOption</h4>\n\n```ts\ntype TableFilterOption =\n | { field: string; comparison: 'between'; criteria: [number, number] }\n | { field: string; comparison: '=' | '!='; criteria: number | string }\n | { field: string; comparison: '>' | '>=' | '<' | '<='; criteria: number }\n | { field: number | string; comparison: 'in'; criteria: number[] | string[] }\n | { field: string; comparison: (value: unknown, criteria: string) => boolean; criteria: string }\n```\n\n<h4 id=\"TableHeaderItemClassName\">TableHeaderItemClassName</h4>\n\n```ts\ntype TableHeaderItemClassName = string | ((header: TableHeader, columnNumber: number) => string)\n```\n\n<h4 id=\"TableBodyRowClassName\">TableBodyRowClassName</h4>\n\n```ts\ntype TableBodyRowClassName = string | ((item: TableItem, rowNumber: number) => string)\n```\n\n<h4 id=\"TableBodyItemClassName\">TableBodyItemClassName</h4>\n\n```ts\ntype TableBodyItemClassName = string | ((column: string, rowNumber: number) => string)\n```\n\n<h4 id=\"TableTreeConfig\">TableTreeConfig</h4>\n\n```ts\ninterface TableTreeConfig {\n childrenField?: string // default 'children'\n indent?: number // default 16\n expandAll?: boolean\n accordion?: boolean\n trigger?: 'default' | 'row'\n lazy?: boolean\n hasChildField?: string // default 'hasChild'\n loadMethod?: (row: TableItem) => Promise<TableItem[]> | TableItem[]\n transform?: boolean // flat parentId → tree\n rowField?: string\n parentField?: string // default 'parentId'\n treeNode?: string // column key for toggler; default first column\n showLine?: boolean\n}\n```\n\n<h4 id=\"TableColumnDefinition\">TableColumnDefinition</h4>\n\n列定义,传给 `columns`:\n\n```ts\ninterface TableColumnDefinition {\n key: string\n label: string\n width?: number\n minWidth?: number\n sortable?: boolean\n fixed?: boolean | 'left' | 'right'\n align?: 'start' | 'center' | 'end'\n render?: (row: TableItem) => unknown\n showOverflowTooltip?: boolean\n resizable?: boolean\n filterable?: boolean\n filters?: TableColumnFilter[]\n children?: TableColumnDefinition[]\n}\n```\n\n<h4 id=\"TableServerOptions\">TableServerOptions</h4>\n\n服务端分页/排序时传给 `serverOptions`,配合 `serverTotal`:\n\n```ts\ninterface TableServerOptions {\n page: number\n rowsPerPage: number\n sortBy?: string | string[]\n sortType?: 'asc' | 'desc' | ('asc' | 'desc')[]\n}\n```\n\n更多见 [API 类型](/docs/types)。\n"
|
|
26930
27682
|
},
|
|
26931
27683
|
"en-US": {
|
|
26932
27684
|
"title": "Table",
|
|
26933
|
-
"description": "Data table with sorting, filtering, selection, pagination,
|
|
27685
|
+
"description": "Data table with sorting, filtering, selection, pagination, fixed columns, column drag, column settings, skeleton loading and virtual scrolling. Column widths support width / minWidth / fit.",
|
|
26934
27686
|
"sections": [
|
|
26935
27687
|
{
|
|
26936
27688
|
"id": "overview",
|
|
26937
27689
|
"title": "",
|
|
26938
|
-
"body": "# Table\n\n`MTable`
|
|
27690
|
+
"body": "# Table\n\n`MTable` renders structured row data. Pass `columns` for column definitions and `rows` for data; built-in client-side sorting, filtering, pagination and row selection are included, with a server-side mode for remote sources. The header \"select all\" only applies to the current page.\n\nColumn width rules:\n\n- Columns with `width` are fixed.\n- Columns without `width` flex from `minWidth` (default `80`); when `fit` is `true` (default), remaining space is distributed proportionally.\n- Total minimum width beyond the container triggers horizontal scrolling.\n- Use `maxHeight` / `tableHeight` for body scrolling; with `MLayout` root scrolling prefer a fixed table height to avoid double scrollbars.\n- Full-viewport lists: `MPageContent fill` + `MTable fill paginator` (body scrolls, paginator pinned). Embedded tables and short pages don't need `fill`."
|
|
26939
27691
|
},
|
|
26940
27692
|
{
|
|
26941
27693
|
"id": "import",
|
|
26942
27694
|
"title": "Import",
|
|
26943
|
-
"body": "```ts\nimport type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```"
|
|
27695
|
+
"body": "```ts\nimport type { TableColumnDefinition, TableItem, TableSortConfig, TablePassThrough } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```"
|
|
26944
27696
|
},
|
|
26945
27697
|
{
|
|
26946
27698
|
"id": "basic",
|
|
@@ -26948,92 +27700,117 @@
|
|
|
26948
27700
|
"body": "```vue preview src=\"./demos/Basic.en.vue\"\n```"
|
|
26949
27701
|
},
|
|
26950
27702
|
{
|
|
26951
|
-
"id": "selection",
|
|
26952
|
-
"title": "Selection",
|
|
26953
|
-
"body": "
|
|
27703
|
+
"id": "row-selection",
|
|
27704
|
+
"title": "Row Selection",
|
|
27705
|
+
"body": "Multiple selection uses `selection-mode=\"multiple\"` with `v-model:selection`; single selection uses `selection-mode=\"single\"` with `v-model:selected-item`. Header \"select all\" only applies to the current page.\n\n```vue preview src=\"./demos/Selection.en.vue\"\n```"
|
|
26954
27706
|
},
|
|
26955
27707
|
{
|
|
26956
|
-
"id": "
|
|
26957
|
-
"title": "
|
|
26958
|
-
"body": "
|
|
27708
|
+
"id": "filtering-pagination",
|
|
27709
|
+
"title": "Filtering & Pagination",
|
|
27710
|
+
"body": "Client-side filtering via `search-value` / `filter-options`; enable `paginator` with `v-model:page` and `rows-per-page` (controlled).\n\n```vue preview src=\"./demos/FilterAndPagination.en.vue\"\n```"
|
|
26959
27711
|
},
|
|
26960
27712
|
{
|
|
26961
|
-
"id": "
|
|
26962
|
-
"title": "
|
|
26963
|
-
"body": "
|
|
27713
|
+
"id": "fixed-columns",
|
|
27714
|
+
"title": "Fixed Columns",
|
|
27715
|
+
"body": "Set `fixed: 'left' | 'right'` in the column definition (`fixed: true` equals left).\n\n```vue preview src=\"./demos/FixedColumns.en.vue\"\n```"
|
|
26964
27716
|
},
|
|
26965
27717
|
{
|
|
26966
|
-
"id": "
|
|
26967
|
-
"title": "
|
|
26968
|
-
"body": "
|
|
27718
|
+
"id": "expandable-rows-cell-rendering",
|
|
27719
|
+
"title": "Expandable Rows & Cell Rendering",
|
|
27720
|
+
"body": "Customize cells via `render` or `#cell-{key}`. Enable row details with `expandable` (or `expandConfig`) and provide content via `#expansion`. In tree mode `expandedRowKeys` is reserved for tree nodes and cannot also drive detail expansion.\n\n```vue preview src=\"./demos/ExpandableRows.en.vue\"\n```"
|
|
27721
|
+
},
|
|
27722
|
+
{
|
|
27723
|
+
"id": "sorting-sortconfig",
|
|
27724
|
+
"title": "Sorting (sortConfig)",
|
|
27725
|
+
"body": "Use `sort-config` to configure sorting in one place: `{ field, order, multiple, must, mode }`. With `mode: 'client'` (default) the table sorts the current page itself; with `mode: 'emit'` only the `sort-change` event is emitted and the data is owned by the caller (useful for server-side sorting). Set `multiple: true` for multi-column sort and `must: true` to prevent clearing.\n\n```vue preview src=\"./demos/Sorting.en.vue\"\n```"
|
|
27726
|
+
},
|
|
27727
|
+
{
|
|
27728
|
+
"id": "column-resizing-header-filters",
|
|
27729
|
+
"title": "Column Resizing & Header Filters",
|
|
27730
|
+
"body": "Set `resizable` to drag column widths (`v-model:column-widths`); `filterable` adds a header filter — column `filters` becomes a multi-select, otherwise a text-contains filter. **Clear** resets the draft, **OK** commits to `v-model:filter-model` (legacy `v-model:filters` still supported).\n\n```vue preview src=\"./demos/ResizeAndFilter.en.vue\"\n```"
|
|
27731
|
+
},
|
|
27732
|
+
{
|
|
27733
|
+
"id": "column-settings-panel",
|
|
27734
|
+
"title": "Column Settings Panel",
|
|
27735
|
+
"body": "Enable `column-setting` to show a settings button in the header corner. The popover lets users toggle column visibility, synced via `v-model:hidden-columns`. Panel copy follows `MLocale`.\n\n```vue preview src=\"./demos/ColumnSetting.en.vue\"\n```"
|
|
27736
|
+
},
|
|
27737
|
+
{
|
|
27738
|
+
"id": "column-drag",
|
|
27739
|
+
"title": "Column Drag",
|
|
27740
|
+
"body": "Enable `column-drag` to reorder leaf columns by dragging header cells. Order is synced through `v-model:column-order`. Drag-and-drop stays within a single header level and never breaks multi-level headers.\n\n```vue preview src=\"./demos/ColumnDrag.en.vue\"\n```"
|
|
26969
27741
|
},
|
|
26970
27742
|
{
|
|
26971
|
-
"id": "
|
|
26972
|
-
"title": "
|
|
26973
|
-
"body": "
|
|
27743
|
+
"id": "skeleton-loading",
|
|
27744
|
+
"title": "Skeleton Loading",
|
|
27745
|
+
"body": "Enable `skeleton` for a skeleton loading state instead of a full-overlay spinner. `skeleton-rows` controls the number of placeholder rows (default `5`). Skeleton previews preserve the layout and feel much faster.\n\n```vue preview src=\"./demos/Skeleton.en.vue\"\n```"
|
|
26974
27746
|
},
|
|
26975
27747
|
{
|
|
26976
|
-
"id": "virtual-
|
|
26977
|
-
"title": "Virtual
|
|
26978
|
-
"body": "Enable `virtual`
|
|
27748
|
+
"id": "virtual-scrolling",
|
|
27749
|
+
"title": "Virtual Scrolling",
|
|
27750
|
+
"body": "Enable `virtual` and provide one of `maxHeight` / `tableHeight` / `fill` to form a scroll viewport; without one, the dev build warns. Expandable rows / `#expansion` / `expandConfig` are mutually exclusive with virtualization and fall back to plain rendering (with a dev warning).\n\n```vue preview src=\"./demos/VirtualScroll.en.vue\"\n```"
|
|
26979
27751
|
},
|
|
26980
27752
|
{
|
|
26981
|
-
"id": "
|
|
26982
|
-
"title": "
|
|
26983
|
-
"body": "
|
|
27753
|
+
"id": "dynamic-row-height-virtual-scrolling",
|
|
27754
|
+
"title": "Dynamic Row Height Virtual Scrolling",
|
|
27755
|
+
"body": "By default virtual scrolling assumes all rows have equal height (estimated by `virtual-row-height`). If your rows vary in height due to content, enable `virtual-dynamic-row-height`: the table measures each row with `ResizeObserver`, caches the result, and uses prefix sums + binary search for O(log n) positioning, keeping long lists smooth.\n\n```vue preview src=\"./demos/DynamicRowHeight.en.vue\"\n```"
|
|
26984
27756
|
},
|
|
26985
27757
|
{
|
|
26986
|
-
"id": "
|
|
26987
|
-
"title": "
|
|
27758
|
+
"id": "multi-level-headers-footer-span",
|
|
27759
|
+
"title": "Multi-level Headers, Footer & Span",
|
|
27760
|
+
"body": "Columns support `children` for multi-level headers; `show-footer` + `footer-method` renders totals (`footerMethod({ columns, data })` returns a row matrix, or use `#footer` for full customization); `span-method` merges cells.\n\n```vue preview src=\"./demos/GridFeatures.en.vue\"\n```"
|
|
27761
|
+
},
|
|
27762
|
+
{
|
|
27763
|
+
"id": "empty-loading",
|
|
27764
|
+
"title": "Empty & Loading",
|
|
26988
27765
|
"body": "```vue preview src=\"./demos/EmptyAndLoading.en.vue\"\n```"
|
|
26989
27766
|
},
|
|
26990
27767
|
{
|
|
26991
27768
|
"id": "tree-table",
|
|
26992
|
-
"title": "Tree
|
|
26993
|
-
"body": "Pass `tree-config`
|
|
27769
|
+
"title": "Tree Table",
|
|
27770
|
+
"body": "Pass `tree-config` to enable tree mode: nested `children`, or `transform` + `parentId` for flat data. Expansion state is bound with `v-model:expanded-row-keys`. Supports `expandAll` / `expandRowKeys`, `accordion`, `trigger`, `toggleMethod`, and lazy loading via `lazy` + `loadMethod`.\n\nInstance methods: `setTreeExpand`, `setAllTreeExpand`, `toggleTreeExpand`, `isTreeExpandByRow`, `getTreeExpandRecords`, `clearTreeExpand`.\n\nWith multiple selection, parent-child cascading with half-check is enabled by default (`checkbox-config.check-strictly=false`); use `checkMethod` to disable a row's checkbox.\n\n```vue preview src=\"./demos/Tree.en.vue\"\n```"
|
|
26994
27771
|
},
|
|
26995
27772
|
{
|
|
26996
27773
|
"id": "server-mode",
|
|
26997
|
-
"title": "Server
|
|
26998
|
-
"body": "Pass `server-options`
|
|
27774
|
+
"title": "Server Mode",
|
|
27775
|
+
"body": "Pass `server-options` and `server-total`, syncing page, rows-per-page and sort fields via `v-model:server-options`.\n\n```vue preview src=\"./demos/Demo7.vue\"\n```"
|
|
26999
27776
|
},
|
|
27000
27777
|
{
|
|
27001
27778
|
"id": "breaking-changes",
|
|
27002
27779
|
"title": "Breaking changes",
|
|
27003
|
-
"body": "-
|
|
27780
|
+
"body": "- Built-in cell editing removed: `editConfig`, column `editable`, `edit-change`, `#edit-{key}`; use `#cell-{key}` / `render` instead.\n- `MTreeTable` removed (including `morya-ui/tree-table`); use `MTable` + `treeConfig`.\n- `serverItemsLength` → `serverTotal`; `rowsItems` → `pageSizes`.\n- `hideHeader` removed; use `showHeader` (default `true`).\n- `hideRowsPerPage` removed; use `showRowsPerPage` (default `true`).\n- Removed: `clickEventType`, `rowsPerPageMessage`, `rowsOfPageSeparatorMessage`, `preventContextMenuRow`, `tableNodeId`.\n- Events: `sortChange` → `sort-change`; `expandRow` → `expand-change`; `contextmenuRow` → `row-contextmenu`; `selectRow` / `deselectRow` / `selectAll` → `select-row` / `deselect-row` / `select-all`.\n- New event: `filter-change` (header filter commit).\n- Removed events: `updatePageItems`, `updateTotalItems`, `page` (`update:page` kept).\n- Row interactions: always support single / double click (`row-click` / `row-dblclick`); right-click always `preventDefault` and emits `row-contextmenu`.\n- Sorting props merged: `sortField` / `sortOrder` / `multiSort` / `mustSort` / `sortMode` still work, but new code should use `sortConfig: TableSortConfig`.\n- Filter v-model: `v-model:filters` still works; new code should use `v-model:filter-model`."
|
|
27004
27781
|
},
|
|
27005
27782
|
{
|
|
27006
27783
|
"id": "tablecolumndefinition",
|
|
27007
27784
|
"title": "TableColumnDefinition",
|
|
27008
|
-
"body": "| Field | Type | Description |\n| --- | --- | --- |\n| `key` | `string` | Field name
|
|
27785
|
+
"body": "| Field | Type | Description |\n| --- | --- | --- |\n| `key` | `string` | Field name on the row. |\n| `label` | `string` | Header text. |\n| `width` | `number` | Fixed column width (px). |\n| `minWidth` | `number` | Flex column minimum width, default `80`. |\n| `sortable` | `boolean` | Sortable. |\n| `fixed` | `boolean \\| 'left' \\| 'right'` | Fixed column; `true` equals `'left'`. |\n| `align` | `'start' \\| 'center' \\| 'end'` | Cell alignment. |\n| `render` | `(row) => unknown` | Custom cell renderer. |\n| `showOverflowTooltip` | `boolean` | Show tooltip on overflow. |\n| `resizable` | `boolean` | Allow drag resizing. |\n| `filterable` | `boolean` | Show header filter. |\n| `filters` | `TableColumnFilter[]` | Header filter options; omit for text filter. |\n| `children` | `TableColumnDefinition[]` | Multi-level sub-columns. |"
|
|
27009
27786
|
},
|
|
27010
27787
|
{
|
|
27011
27788
|
"id": "props",
|
|
27012
27789
|
"title": "Props",
|
|
27013
|
-
"body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `columns` | `TableColumnDefinition[]` | — | Column definitions. |\n| `rows` | `TableItem[]` | — | Row data. |\n| `fit` | `boolean` | `true` |
|
|
27790
|
+
"body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `columns` | `TableColumnDefinition[]` | — | Column definitions. |\n| `rows` | `TableItem[]` | — | Row data. |\n| `fit` | `boolean` | `true` | Stretch flex columns to fill width. |\n| `selectionMode` | `'single' \\| 'multiple' \\| null` | `null` | Selection mode. |\n| `selection` | `TableItem[] \\| null` | `null` | Multiple selection (`v-model:selection`). |\n| `selectedItem` | `TableItem \\| null` | `null` | Single selection (`v-model:selected-item`). |\n| `serverOptions` | `TableServerOptions \\| null` | `null` | Server pagination/sort options. |\n| `serverTotal` | `number` | `0` | Server total count. |\n| `paginator` | `boolean` | `false` | Show built-in paginator. |\n| `page` | `number` | `1` | Current page (`v-model:page`). |\n| `rowsPerPage` | `number` | `25` | Rows per page. |\n| `pageSizes` | `number[]` | `[25, 50, 100]` | Page size options. |\n| `showHeader` | `boolean` | `true` | Show header. |\n| `showRowsPerPage` | `boolean` | `true` | Show rows-per-page selector. |\n| `fill` | `boolean` | `false` | Fill parent height (with `MPageContent fill`); body scrolls, paginator pinned. Ignored when `maxHeight` / `tableHeight` is set. |\n| `columnWidths` | `Record<string, number> \\| null` | `null` | Column widths (`v-model:column-widths`). |\n| `virtual` | `boolean` | `false` | Row virtualization (requires a height; skipped with expand rows). |\n| `virtualRowHeight` | `number` | `40` | Estimated virtual row height. |\n| `virtualDynamicRowHeight` | `boolean` | `false` | Dynamic row-height virtualization (measured & cached via `ResizeObserver`). |\n| `virtualOverscan` | `number` | `4` | Extra rows rendered above/below the viewport to avoid flicker. |\n| `hiddenColumns` | `string[] \\| null` | `null` | Hidden column keys (`v-model:hidden-columns`). |\n| `columnOrder` | `string[] \\| null` | `null` | Leaf column order (`v-model:column-order`). |\n| `columnSetting` | `boolean` | `false` | Show column settings button (visibility toggle). |\n| `columnDrag` | `boolean` | `false` | Header drag reordering. |\n| `skeleton` | `boolean` | `false` | Skeleton loading state. |\n| `skeletonRows` | `number` | `5` | Skeleton row count. |\n| `showFooter` | `boolean` | `false` | Show footer. |\n| `footerMethod` | `TableFooterMethod \\| null` | `null` | Footer data. |\n| `spanMethod` | `TableSpanMethod \\| null` | `null` | Cell span. |\n| `treeConfig` | `TableTreeConfig \\| null` | `null` | Tree rows. |\n| `expandConfig` | `TableExpandConfig \\| null` | `null` | Detail expansion (mutually exclusive with tree). |\n| `checkboxConfig` | `TableCheckboxConfig \\| null` | `null` | Multiple selection: cascade / `checkMethod` / `checkRowKeys` / `trigger` / `reserve`. |\n| `radioConfig` | `TableRadioConfig \\| null` | `null` | Single selection: `strict` / `checkMethod` / `trigger`. |\n| `expandable` | `boolean` | `false` | Show expand column (also enabled by `#expansion` or `expandConfig`). |\n| `striped` | `boolean` | `false` | Zebra rows. |\n| `bordered` | `boolean` | `false` | Cell borders. |\n| `highlightCurrent` | `boolean` | `false` | Highlight current row; pair with `v-model:current-row-key`. |\n| `rowHover` | `boolean` | `true` | Row hover highlight. |\n| `sortConfig` | `TableSortConfig \\| null` | `null` | Unified sorting config `{ field, order, multiple, must, mode }`. |\n| `sortField` | `string \\| null` | `null` | (legacy) Single-field sort. Prefer `sortConfig`. |\n| `sortOrder` | `'asc' \\| 'desc' \\| null` | `null` | (legacy) Sort direction. Prefer `sortConfig`. |\n| `multiSort` | `boolean` | `false` | (legacy) Multi-column sort. Prefer `sortConfig.multiple`. |\n| `mustSort` | `boolean` | `false` | (legacy) Disallow clearing sort. Prefer `sortConfig.must`. |\n| `sortMode` | `'client' \\| 'emit'` | `'client'` | (legacy) Sort mode. Prefer `sortConfig.mode`. |\n| `searchField` / `searchValue` | — | — | Client-side search. |\n| `filterOptions` | `TableFilterOption[]` | `null` | Structured filter criteria. |\n| `filterModel` | `Record<string, unknown> \\| null` | `null` | Header filter v-model (`update:filter-model`). |\n| `filters` | `Record<string, unknown> \\| null` | `null` | (legacy) Old filter v-model name. |\n| `loading` | `boolean` | `false` | Loading state. |\n| `emptyText` | `string` | — | Empty text. |\n| `emptyDescription` | `string` | — | Empty description. |\n| `maxHeight` | `number \\| null` | `null` | Max height, scrolls beyond. |\n| `showOverflowTooltip` | `boolean` | `false` | Global overflow tooltip. |\n| `rowKey` | `string` | `'id'` | Row unique key field. |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Density (`large`/`small` adjust cell padding). |\n| `ariaLabel` | `string` | — | — |\n| `bodyExpandRowClassName` | `TableBodyRowClassName` | — | — |\n| `bodyItemClassName` | `TableBodyItemClassName` | — | — |\n| `bodyRowClassName` | `TableBodyRowClassName` | — | — |\n| `bodyTextDirection` | `TableTextDirection` | — | — |\n| `checkboxColumnWidth` | `number \\| null` | — | — |\n| `clickRowToExpand` | `boolean` | — | — |\n| `currentRowKey` | `string \\| number \\| null` | — | — |\n| `expandColumnWidth` | `number` | — | — |\n| `expandedRowKeys` | `Array<string \\| number>` | — | — |\n| `fixedCheckbox` | `boolean` | — | — |\n| `fixedExpand` | `boolean` | — | — |\n| `fixedHeader` | `boolean` | — | — |\n| `fixedIndex` | `boolean` | — | — |\n| `headerClassName` | `string` | — | — |\n| `headerItemClassName` | `TableHeaderItemClassName` | — | — |\n| `headerTextDirection` | `TableTextDirection` | — | — |\n| `indexColumnWidth` | `number` | — | — |\n| `showIndex` | `boolean` | — | — |\n| `showIndexSymbol` | `string` | — | — |\n| `tableClassName` | `string` | — | — |\n| `tableHeight` | `number \\| null` | — | — |\n| `tableMinHeight` | `number` | — | — |\n| `pt` | `TablePassThrough` | — | Multi-part DOM pass-through: `{ root, scrollbar, thead, tbody, tfoot, pagination, emptyMessage }`. |"
|
|
27014
27791
|
},
|
|
27015
27792
|
{
|
|
27016
27793
|
"id": "slots",
|
|
27017
27794
|
"title": "Slots",
|
|
27018
|
-
"body": "| Slot | Description |\n| --- | --- |\n| `cell-{key}` | Cell
|
|
27795
|
+
"body": "| Slot | Description |\n| --- | --- |\n| `cell-{key}` | Cell of column `{key}`, scope `{ row, value, column }` (use it to build editors). |\n| `footer` | Custom footer. |\n| `body-cell` | Any cell, scope `{ row, column, value }`. |\n| `expansion` | Expanded row content, scope `{ row }`. |\n| `empty` | Custom empty state. |\n| `loading` | Custom loading state (ignored when `skeleton` is true). |\n| `pagination` | Custom pagination area. |\n| `body` | Custom `body` content. |\n| `body-append` | Custom `body-append` content. |\n| `body-prepend` | Custom `body-prepend` content. |\n| `customize-headers` | Custom `customize-headers` content. |\n| `header` | Custom `header` content. |\n| `header-{key}` | Header slot (case matches `columns[].key`). |"
|
|
27019
27796
|
},
|
|
27020
27797
|
{
|
|
27021
27798
|
"id": "events",
|
|
27022
27799
|
"title": "Events",
|
|
27023
|
-
"body": "| Event | Payload | Description |\n| --- | --- | --- |\n| `sort` | `{ sortField?, sortOrder? }` | Sort changed. |\n| `row-click` | `{ row, index }`, `Event` | Row
|
|
27800
|
+
"body": "| Event | Payload | Description |\n| --- | --- | --- |\n| `sort-change` | `{ sortField?, sortOrder? }` | Sort changed. |\n| `filter-change` | `Record<string, unknown> \\| null` | Header filter committed (mirrors `update:filter-model`). |\n| `expand-change` | `{ row, expanded }` | Row expansion changed (detail or tree). |\n| `row-click` | `{ row, index }`, `Event` | Row click. |\n| `row-dblclick` | `{ row, index }`, `Event` | Row double click. |\n| `row-contextmenu` | `item`, `MouseEvent` | Row right click. |\n| `select-row` | `TableItem` | Row selected. |\n| `deselect-row` | `TableItem` | Row deselected. |\n| `select-all` | — | All rows of current page selected. |\n| `current-change` | `row \\| null, oldRow \\| null` | Current row changed. |\n| `update:selection` | `TableItem[]` | Multiple selection v-model. |\n| `update:page` | `number` | Page v-model. |\n| `update:server-options` | `TableServerOptions` | Server options v-model. |\n| `update:current-row-key` | `string \\| number \\| null` | Current row key v-model. |\n| `update:expanded-row-keys` | `Array<string \\| number>` | Expanded row keys v-model. |\n| `update:filter-model` | `Record<string, unknown> \\| null` | Header filter v-model. |\n| `update:column-widths` | `Record<string, number>` | Column widths v-model. |\n| `update:hidden-columns` | `string[]` | Hidden columns v-model. |\n| `update:column-order` | `string[]` | Column order v-model. |\n| `update:selected-item` | `TableItem \\| null` | Single selection v-model. |"
|
|
27024
27801
|
},
|
|
27025
27802
|
{
|
|
27026
|
-
"id": "instance",
|
|
27027
|
-
"title": "Instance",
|
|
27028
|
-
"body": "
|
|
27803
|
+
"id": "instance-api",
|
|
27804
|
+
"title": "Instance API",
|
|
27805
|
+
"body": "Access via `ref`:\n\n| Method / Property | Description |\n| --- | --- |\n| `currentPageFirstIndex` | Index of the first record on the current page (`-1` if empty). |\n| `currentPageLastIndex` | Index of the last record on the current page. |\n| `clientItemsLength` | Total row count (server total in server mode). |\n| `maxPaginationNumber` | Maximum page number. |\n| `currentPaginationNumber` | Current page number. |\n| `isLastPage` / `isFirstPage` | Whether on the last / first page. |\n| `nextPage()` / `prevPage()` | Go to next / previous page. |\n| `updatePage(page)` | Go to a specific page. |\n| `rowsPerPageOptions` | Rows-per-page options. |\n| `rowsPerPageActiveOption` | Current rows-per-page value. |\n| `updateRowsPerPageActiveOption(n)` | Update rows-per-page. |\n| `setFilters(filters)` / `clearFilter()` | Set / clear filters. |\n| `setColumnWidths(widths)` | Set column widths (same as `v-model:column-widths`). |\n| `setHiddenColumns(keys)` | Set hidden column keys (same as `v-model:hidden-columns`). |\n| `setColumnOrder(keys)` | Set leaf column order (same as `v-model:column-order`). |\n| `clearSort()` | Clear sorting. |\n| `getCheckboxRecords()` | Currently checked rows. |\n| `setCheckboxRow(rows, checked)` | Set row checked state. |\n| `clearCheckboxRow()` | Clear all checked rows. |\n| `isCheckedByCheckboxRow(row)` | Whether a row is checked. |\n| `isAllCheckboxChecked()` | Whether all rows on the current page are checked. |\n| `getCheckboxIndeterminateRecords()` | Indeterminate (half-checked) rows in tree cascade. |\n| `scrollTo(...)` / `scrollToRow(row)` | Scroll positioning. |\n| `setRowExpand` / `setAllRowExpand` / `toggleRowExpand` / `clearRowExpand` / `isRowExpandByRow` / `getRowExpandRecords` | Detail expansion (non-tree). |\n| `setTreeExpand` / `setAllTreeExpand` / `toggleTreeExpand` / `clearTreeExpand` / `isTreeExpandByRow` / `getTreeExpandRecords` | Tree node expansion. |"
|
|
27029
27806
|
},
|
|
27030
27807
|
{
|
|
27031
27808
|
"id": "types",
|
|
27032
27809
|
"title": "Types",
|
|
27033
|
-
"body": "<h4 id=\"TableItem\">TableItem</h4>\n\
|
|
27810
|
+
"body": "<h4 id=\"TableItem\">TableItem</h4>\n\n```ts\ntype TableItem = Record<string, unknown>\n```\n\n<h4 id=\"TableSortConfig\">TableSortConfig</h4>\n\nUnified sort config; `field` / `order` describe the current single-column sort, `mode` chooses between internal and external sorting:\n\n```ts\ninterface TableSortConfig {\n field?: string | null\n order?: 'asc' | 'desc' | null\n multiple?: boolean\n must?: boolean\n mode?: 'client' | 'emit'\n}\n```\n\n<h4 id=\"TablePassThrough\">TablePassThrough</h4>\n\nMulti-part DOM pass-through; supports class / style / any attrs:\n\n```ts\ninterface TablePassThrough {\n root?: Record<string, unknown>\n scrollbar?: Record<string, unknown>\n thead?: Record<string, unknown>\n tbody?: Record<string, unknown>\n tfoot?: Record<string, unknown>\n pagination?: Record<string, unknown>\n emptyMessage?: Record<string, unknown>\n}\n```\n\n<h4 id=\"TableTextDirection\">TableTextDirection</h4>\n\n```ts\ntype TableTextDirection = 'left' | 'center' | 'right'\n```\n\n<h4 id=\"TableFilterOption\">TableFilterOption</h4>\n\n```ts\ntype TableFilterOption =\n | { field: string; comparison: 'between'; criteria: [number, number] }\n | { field: string; comparison: '=' | '!='; criteria: number | string }\n | { field: string; comparison: '>' | '>=' | '<' | '<='; criteria: number }\n | { field: number | string; comparison: 'in'; criteria: number[] | string[] }\n | { field: string; comparison: (value: unknown, criteria: string) => boolean; criteria: string }\n```\n\n<h4 id=\"TableHeaderItemClassName\">TableHeaderItemClassName</h4>\n\n```ts\ntype TableHeaderItemClassName = string | ((header: TableHeader, columnNumber: number) => string)\n```\n\n<h4 id=\"TableBodyRowClassName\">TableBodyRowClassName</h4>\n\n```ts\ntype TableBodyRowClassName = string | ((item: TableItem, rowNumber: number) => string)\n```\n\n<h4 id=\"TableBodyItemClassName\">TableBodyItemClassName</h4>\n\n```ts\ntype TableBodyItemClassName = string | ((column: string, rowNumber: number) => string)\n```\n\n<h4 id=\"TableTreeConfig\">TableTreeConfig</h4>\n\n```ts\ninterface TableTreeConfig {\n childrenField?: string // default 'children'\n indent?: number // default 16\n expandAll?: boolean\n accordion?: boolean\n trigger?: 'default' | 'row'\n lazy?: boolean\n hasChildField?: string // default 'hasChild'\n loadMethod?: (row: TableItem) => Promise<TableItem[]> | TableItem[]\n transform?: boolean // flat parentId → tree\n rowField?: string\n parentField?: string // default 'parentId'\n treeNode?: string // column key for toggler; default first column\n showLine?: boolean\n}\n```\n\n<h4 id=\"TableColumnDefinition\">TableColumnDefinition</h4>\n\nColumn definition passed to `columns`:\n\n```ts\ninterface TableColumnDefinition {\n key: string\n label: string\n width?: number\n minWidth?: number\n sortable?: boolean\n fixed?: boolean | 'left' | 'right'\n align?: 'start' | 'center' | 'end'\n render?: (row: TableItem) => unknown\n showOverflowTooltip?: boolean\n resizable?: boolean\n filterable?: boolean\n filters?: TableColumnFilter[]\n children?: TableColumnDefinition[]\n}\n```\n\n<h4 id=\"TableServerOptions\">TableServerOptions</h4>\n\nServer pagination/sort options passed to `serverOptions`, paired with `serverTotal`:\n\n```ts\ninterface TableServerOptions {\n page: number\n rowsPerPage: number\n sortBy?: string | string[]\n sortType?: 'asc' | 'desc' | ('asc' | 'desc')[]\n}\n```\n\nSee more at [API Types](/docs/types)."
|
|
27034
27811
|
}
|
|
27035
27812
|
],
|
|
27036
|
-
"markdown": "---\ntitle: Table\ncategory: 03 / DATA\ndescription: Data table with sorting, filtering, selection, pagination, frozen columns, and empty/loading states. Column width supports width / minWidth / fit.\n---\n\n# Table\n\n`MTable` displays structured row data. Define columns with `columns`, pass data with `rows`, and use built-in client-side sort, filter, pagination, and row selection—or switch to server-driven pagination. Header “select all” applies to the current page only.\n\nColumn width rules:\n\n- Columns with `width` use a fixed width\n- Columns without `width` are flexible with a `minWidth` lower bound (default `80`); when `fit` is `true` (default), remaining width is distributed proportionally\n- Horizontal scrolling appears when the total minimum width exceeds the container\n- Prefer `maxHeight` / `tableHeight` when the table body should scroll on its own; when nested under `MLayout` root scroll, fix the table height to avoid stacked scrollbars\n- For full-viewport main lists, use `MPageContent fill` + `MTable fill paginator` (body scrolls; pagination at the bottom). Skip `fill` for embedded or short tables.\n\n## Import\n\n```ts\nimport type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Selection\n\nUse `selection-mode=\"multiple\"` with `v-model:selection`, or `selection-mode=\"single\"` with `v-model:selected-item`.\n\n```vue preview src=\"./demos/Selection.en.vue\"\n```\n\n## Filter and pagination\n\nUse `search-value` / `filter-options` for client filtering. Enable `paginator` with `v-model:page` and `rows-per-page`.\n\n```vue preview src=\"./demos/FilterAndPagination.en.vue\"\n```\n\n## Expandable rows\n\nCustomize cells with `render` or `#cell-{key}`. Set `expandable` (or `expandConfig`) and provide the `#expansion` slot. In tree mode, `expandedRowKeys` controls tree nodes and cannot be used for detail expansion at the same time.\n\n```vue preview src=\"./demos/ExpandableRows.en.vue\"\n```\n\n## Fixed columns\n\nSet `fixed: 'left' | 'right'` on a column (or `fixed: true` for left).\n\n```vue preview src=\"./demos/FixedColumns.en.vue\"\n```\n\n## Column resize and header filters\n\nSet `resizable` to drag column widths (`v-model:column-widths`). Set `filterable` for a header filter; optional `filters` for checkbox options, otherwise free-text contains. **Clear** resets the draft only; **Confirm** applies to `v-model:filters`.\n\n```vue preview src=\"./demos/ResizeAndFilter.en.vue\"\n```\n\n## Virtual scroll\n\nEnable `virtual` with `maxHeight` / `tableHeight` / `fill` so the body scrolls; dev mode warns if height is missing. Expandable rows (`#expansion` / `expandConfig`) disable virtualization (dev warning when both are set).\n\n```vue preview src=\"./demos/VirtualScroll.en.vue\"\n```\n\n## Multi-header, footer, and merges\n\nUse column `children` for grouped headers; `show-footer` + `footer-method` for summaries (`footerMethod({ columns, data })` matrix or `#footer` slot); `span-method` for merges.\n\n```vue preview src=\"./demos/GridFeatures.en.vue\"\n```\n\n## Empty and loading\n\n```vue preview src=\"./demos/EmptyAndLoading.en.vue\"\n```\n\n## Tree table\n\nPass `tree-config` for hierarchical rows: nested `children`, or flat `parentId` with `transform`. Bind expand state with `v-model:expanded-row-keys`. Supports `expandAll` / `expandRowKeys`, `accordion`, `trigger`, `toggleMethod`, and lazy `loadMethod`.\n\nInstance methods: `setTreeExpand`, `setAllTreeExpand`, `toggleTreeExpand`, `isTreeExpandByRow`, `getTreeExpandRecords`, `clearTreeExpand`.\n\nWith multi-select, parent/child cascade and indeterminate are on by default (`checkbox-config.check-strictly=false`). Use `checkMethod` to disable specific rows.\n\n```vue preview src=\"./demos/Tree.en.vue\"\n```\n\n## Server mode\n\nPass `server-options` with `server-total`, and sync page / page size / sort via `v-model:server-options`.\n\n```vue preview src=\"./demos/Demo7.vue\"\n```\n\n## Breaking changes\n\n- Removed built-in cell editing: `editConfig`, column `editable`, `edit-change`, `#edit-{key}`; use `#cell-{key}` / `render` instead\n- Removed `MTreeTable` (including `morya-ui/tree-table`); use `MTable` + `treeConfig`\n- `serverItemsLength` → `serverTotal`\n- `rowsItems` → `pageSizes`\n- Removed `hideHeader`; use `showHeader` (default `true`)\n- Removed `hideRowsPerPage`; use `showRowsPerPage` (default `true`)\n- Removed: `clickEventType`, `rowsPerPageMessage`, `rowsOfPageSeparatorMessage`, `preventContextMenuRow`, `tableNodeId`\n- Events: `contextmenuRow` → `row-contextmenu`; `selectRow` / `deselectRow` / `selectAll` → `select-row` / `deselect-row` / `select-all`\n- Removed events: `updatePageItems`, `updateTotalItems`, `page` (keep `update:page`)\n- Row interaction: click and dblclick always emit (`row-click` / `row-dblclick`); context menu always `preventDefault`s and emits `row-contextmenu`\n\n## TableColumnDefinition\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `key` | `string` | Field name bound to row data. |\n| `label` | `string` | Column header text. |\n| `width` | `number` | Fixed width in px. |\n| `minWidth` | `number` | Flex column minimum width; default `80`. |\n| `sortable` | `boolean` | Enable sorting. |\n| `fixed` | `boolean \\| 'left' \\| 'right'` | Freeze column (left freeze supported). |\n| `align` | `'start' \\| 'center' \\| 'end'` | Cell alignment. |\n| `render` | `(row) => unknown` | Custom cell renderer. |\n| `showOverflowTooltip` | `boolean` | Tooltip when cell text overflows. |\n| `resizable` | `boolean` | Drag to resize column width. |\n| `filterable` | `boolean` | Show header filter trigger. |\n| `filters` | `TableColumnFilter[]` | Header filter options; omit for text filter. |\n| `children` | `TableColumnDefinition[]` | Nested columns for multi-level headers. |\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `columns` | `TableColumnDefinition[]` | — | Column definitions. |\n| `rows` | `TableItem[]` | — | Row data. |\n| `fit` | `boolean` | `true` | Flexible columns fill remaining width. |\n| `selectionMode` | `'single' \\| 'multiple' \\| null` | `null` | Row selection mode. |\n| `selection` | `TableItem[] \\| null` | `null` | Multi-select (`v-model:selection`). |\n| `selectedItem` | `TableItem \\| null` | `null` | Single-select (`v-model:selected-item`). |\n| `serverOptions` | `TableServerOptions \\| null` | `null` | Server paging/sort options. |\n| `serverTotal` | `number` | `0` | Total row count in server mode. |\n| `paginator` | `boolean` | `false` | Built-in pagination footer. |\n| `page` | `number` | `1` | Current page (`v-model:page`). |\n| `rowsPerPage` | `number` | `25` | Page size. |\n| `pageSizes` | `number[]` | `[25, 50, 100]` | Page size options. |\n| `showHeader` | `boolean` | `true` | Show table header. |\n| `showRowsPerPage` | `boolean` | `true` | Show page-size picker. |\n| `fill` | `boolean` | `false` | Fill remaining parent height (only for full-viewport main lists with `MPageContent fill`). Body scrolls; paginator stays at the bottom. Ignored when `maxHeight` / `tableHeight` is set. |\n| `treeConfig` | `TableTreeConfig \\| null` | `null` | Tree rows. |\n| `expandConfig` | `TableExpandConfig \\| null` | `null` | Detail expand (mutually exclusive with tree). |\n| `checkboxConfig` | `TableCheckboxConfig \\| null` | `null` | Multi-select options. |\n| `radioConfig` | `TableRadioConfig \\| null` | `null` | Single-select options. |\n| `striped` / `bordered` | `boolean` | `false` | Striped rows / cell borders. |\n| `highlightCurrent` | `boolean` | `false` | Highlight current row. |\n| `loading` / `emptyText` / `emptyDescription` | — | — | Loading and empty states. |\n| `maxHeight` | `number \\| null` | `null` | Scrollable body max height. |\n| `rowKey` | `string` | `'id'` | Stable row key field. |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Table density (`large`/`small` also adjust cell padding). |\n| `pt` | [RootPassThrough](/docs/types#RootPassThrough) `{ root? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |\n\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `cell-{key}` | Cell for column `{key}`; scope `{ row, value, column }` (use this for custom editors). |\n| `body-cell` | Any cell; scope `{ row, column, value }`. |\n| `expansion` | Expanded row; scope `{ row }`. |\n| `empty` / `loading` | Empty and loading placeholders. |\n| `header-{key}` | Header slot (exact key case). |\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `sort` | `{ sortField?, sortOrder? }` | Sort changed. |\n| `row-click` | `{ row, index }`, `Event` | Row clicked. |\n| `row-dblclick` | `{ row, index }`, `Event` | Row double-clicked. |\n| `row-contextmenu` | `item`, `MouseEvent` | Row context menu. |\n| `select-row` / `deselect-row` | `TableItem` | Row selection toggled. |\n| `select-all` | — | Select all on current page. |\n| `current-change` | `row \\| null, oldRow \\| null` | Current row changed. |\n| `update:selection` | `TableItem[]` | Selection v-model. |\n| `update:page` | `number` | Page v-model. |\n\n## Instance\n\nPagination, filter, selection, scroll, and expand controls via `ref`:\n\n| Method / Property | Description |\n| --- | --- |\n| `currentPageFirstIndex` | Index of the first record on the current page (`-1` when empty). |\n| `currentPageLastIndex` | Index of the last record on the current page. |\n| `clientItemsLength` | Total item count (server total in server mode). |\n| `maxPaginationNumber` | Last page number. |\n| `currentPaginationNumber` | Current page number. |\n| `isLastPage` / `isFirstPage` | Whether the current page is the last / first. |\n| `nextPage()` / `prevPage()` | Go to the next / previous page. |\n| `updatePage(page)` | Jump to a page. |\n| `rowsPerPageOptions` | Rows-per-page options. |\n| `rowsPerPageActiveOption` | Active rows-per-page value. |\n| `updateRowsPerPageActiveOption(n)` | Change rows per page. |\n| `setFilters(filters)` / `clearFilter()` | Set / clear filters. |\n| `setColumnWidths(widths)` | Set column widths (same as `v-model:column-widths`). |\n| `setHiddenColumns(keys)` | Set hidden column keys (same as `v-model:hidden-columns`). |\n| `setColumnOrder(keys)` | Set leaf column order (same as `v-model:column-order`). |\n| `clearSort()` | Clear sort. |\n| `getCheckboxRecords()` / `setCheckboxRow` / `clearCheckboxRow` / `isCheckedByCheckboxRow` / `isAllCheckboxChecked` | Selection APIs. |\n| `scrollTo(...)` / `scrollToRow(row)` | Scroll helpers. |\n| `setRowExpand` / `toggleRowExpand` / `clearRowExpand` / … | Detail expand (non-tree). |\n| `setTreeExpand` / `toggleTreeExpand` / `clearTreeExpand` / … | Tree expand. |\n\n## Types\n\n<h4 id=\"TableItem\">TableItem</h4>\n\nSee source `types.ts` for the full definition.\n\n```ts\ntype TableItem = Record<string, unknown>\n```\n\n\n<h4 id=\"TableColumnDefinition\">TableColumnDefinition</h4>\n\nColumn definition passed to `columns`:\n\n```ts\ninterface TableColumnDefinition {\n key: string\n label: string\n width?: number\n minWidth?: number\n sortable?: boolean\n fixed?: boolean | 'left' | 'right'\n align?: 'start' | 'center' | 'end'\n render?: (row: TableItem) => unknown\n filterable?: boolean\n filters?: TableColumnFilter[]\n resizable?: boolean\n children?: TableColumnDefinition[]\n showOverflowTooltip?: boolean\n}\n```\n\n<h4 id=\"TableServerOptions\">TableServerOptions</h4>\n\nServer-side paging/sorting payload for `serverOptions`, with `serverTotal`:\n\n```ts\ninterface TableServerOptions {\n page: number\n rowsPerPage: number\n sortBy?: string | string[]\n sortType?: 'asc' | 'desc' | ('asc' | 'desc')[]\n}\n```\n\n`TableItem` is `Record<string, unknown>`. See also [API types](/docs/types).\n"
|
|
27813
|
+
"markdown": "---\ntitle: Table\ncategory: 03 / DATA\ndescription: Data table with sorting, filtering, selection, pagination, fixed columns, column drag, column settings, skeleton loading and virtual scrolling. Column widths support width / minWidth / fit.\n---\n\n# Table\n\n`MTable` renders structured row data. Pass `columns` for column definitions and `rows` for data; built-in client-side sorting, filtering, pagination and row selection are included, with a server-side mode for remote sources. The header \"select all\" only applies to the current page.\n\nColumn width rules:\n\n- Columns with `width` are fixed.\n- Columns without `width` flex from `minWidth` (default `80`); when `fit` is `true` (default), remaining space is distributed proportionally.\n- Total minimum width beyond the container triggers horizontal scrolling.\n- Use `maxHeight` / `tableHeight` for body scrolling; with `MLayout` root scrolling prefer a fixed table height to avoid double scrollbars.\n- Full-viewport lists: `MPageContent fill` + `MTable fill paginator` (body scrolls, paginator pinned). Embedded tables and short pages don't need `fill`.\n\n## Import\n\n```ts\nimport type { TableColumnDefinition, TableItem, TableSortConfig, TablePassThrough } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.en.vue\"\n```\n\n## Row Selection\n\nMultiple selection uses `selection-mode=\"multiple\"` with `v-model:selection`; single selection uses `selection-mode=\"single\"` with `v-model:selected-item`. Header \"select all\" only applies to the current page.\n\n```vue preview src=\"./demos/Selection.en.vue\"\n```\n\n## Filtering & Pagination\n\nClient-side filtering via `search-value` / `filter-options`; enable `paginator` with `v-model:page` and `rows-per-page` (controlled).\n\n```vue preview src=\"./demos/FilterAndPagination.en.vue\"\n```\n\n## Fixed Columns\n\nSet `fixed: 'left' | 'right'` in the column definition (`fixed: true` equals left).\n\n```vue preview src=\"./demos/FixedColumns.en.vue\"\n```\n\n## Expandable Rows & Cell Rendering\n\nCustomize cells via `render` or `#cell-{key}`. Enable row details with `expandable` (or `expandConfig`) and provide content via `#expansion`. In tree mode `expandedRowKeys` is reserved for tree nodes and cannot also drive detail expansion.\n\n```vue preview src=\"./demos/ExpandableRows.en.vue\"\n```\n\n## Sorting (sortConfig)\n\nUse `sort-config` to configure sorting in one place: `{ field, order, multiple, must, mode }`. With `mode: 'client'` (default) the table sorts the current page itself; with `mode: 'emit'` only the `sort-change` event is emitted and the data is owned by the caller (useful for server-side sorting). Set `multiple: true` for multi-column sort and `must: true` to prevent clearing.\n\n```vue preview src=\"./demos/Sorting.en.vue\"\n```\n\n## Column Resizing & Header Filters\n\nSet `resizable` to drag column widths (`v-model:column-widths`); `filterable` adds a header filter — column `filters` becomes a multi-select, otherwise a text-contains filter. **Clear** resets the draft, **OK** commits to `v-model:filter-model` (legacy `v-model:filters` still supported).\n\n```vue preview src=\"./demos/ResizeAndFilter.en.vue\"\n```\n\n## Column Settings Panel\n\nEnable `column-setting` to show a settings button in the header corner. The popover lets users toggle column visibility, synced via `v-model:hidden-columns`. Panel copy follows `MLocale`.\n\n```vue preview src=\"./demos/ColumnSetting.en.vue\"\n```\n\n## Column Drag\n\nEnable `column-drag` to reorder leaf columns by dragging header cells. Order is synced through `v-model:column-order`. Drag-and-drop stays within a single header level and never breaks multi-level headers.\n\n```vue preview src=\"./demos/ColumnDrag.en.vue\"\n```\n\n## Skeleton Loading\n\nEnable `skeleton` for a skeleton loading state instead of a full-overlay spinner. `skeleton-rows` controls the number of placeholder rows (default `5`). Skeleton previews preserve the layout and feel much faster.\n\n```vue preview src=\"./demos/Skeleton.en.vue\"\n```\n\n## Virtual Scrolling\n\nEnable `virtual` and provide one of `maxHeight` / `tableHeight` / `fill` to form a scroll viewport; without one, the dev build warns. Expandable rows / `#expansion` / `expandConfig` are mutually exclusive with virtualization and fall back to plain rendering (with a dev warning).\n\n```vue preview src=\"./demos/VirtualScroll.en.vue\"\n```\n\n## Dynamic Row Height Virtual Scrolling\n\nBy default virtual scrolling assumes all rows have equal height (estimated by `virtual-row-height`). If your rows vary in height due to content, enable `virtual-dynamic-row-height`: the table measures each row with `ResizeObserver`, caches the result, and uses prefix sums + binary search for O(log n) positioning, keeping long lists smooth.\n\n```vue preview src=\"./demos/DynamicRowHeight.en.vue\"\n```\n\n## Multi-level Headers, Footer & Span\n\nColumns support `children` for multi-level headers; `show-footer` + `footer-method` renders totals (`footerMethod({ columns, data })` returns a row matrix, or use `#footer` for full customization); `span-method` merges cells.\n\n```vue preview src=\"./demos/GridFeatures.en.vue\"\n```\n\n## Empty & Loading\n\n```vue preview src=\"./demos/EmptyAndLoading.en.vue\"\n```\n\n## Tree Table\n\nPass `tree-config` to enable tree mode: nested `children`, or `transform` + `parentId` for flat data. Expansion state is bound with `v-model:expanded-row-keys`. Supports `expandAll` / `expandRowKeys`, `accordion`, `trigger`, `toggleMethod`, and lazy loading via `lazy` + `loadMethod`.\n\nInstance methods: `setTreeExpand`, `setAllTreeExpand`, `toggleTreeExpand`, `isTreeExpandByRow`, `getTreeExpandRecords`, `clearTreeExpand`.\n\nWith multiple selection, parent-child cascading with half-check is enabled by default (`checkbox-config.check-strictly=false`); use `checkMethod` to disable a row's checkbox.\n\n```vue preview src=\"./demos/Tree.en.vue\"\n```\n\n## Server Mode\n\nPass `server-options` and `server-total`, syncing page, rows-per-page and sort fields via `v-model:server-options`.\n\n```vue preview src=\"./demos/Demo7.vue\"\n```\n\n## Breaking changes\n\n- Built-in cell editing removed: `editConfig`, column `editable`, `edit-change`, `#edit-{key}`; use `#cell-{key}` / `render` instead.\n- `MTreeTable` removed (including `morya-ui/tree-table`); use `MTable` + `treeConfig`.\n- `serverItemsLength` → `serverTotal`; `rowsItems` → `pageSizes`.\n- `hideHeader` removed; use `showHeader` (default `true`).\n- `hideRowsPerPage` removed; use `showRowsPerPage` (default `true`).\n- Removed: `clickEventType`, `rowsPerPageMessage`, `rowsOfPageSeparatorMessage`, `preventContextMenuRow`, `tableNodeId`.\n- Events: `sortChange` → `sort-change`; `expandRow` → `expand-change`; `contextmenuRow` → `row-contextmenu`; `selectRow` / `deselectRow` / `selectAll` → `select-row` / `deselect-row` / `select-all`.\n- New event: `filter-change` (header filter commit).\n- Removed events: `updatePageItems`, `updateTotalItems`, `page` (`update:page` kept).\n- Row interactions: always support single / double click (`row-click` / `row-dblclick`); right-click always `preventDefault` and emits `row-contextmenu`.\n- Sorting props merged: `sortField` / `sortOrder` / `multiSort` / `mustSort` / `sortMode` still work, but new code should use `sortConfig: TableSortConfig`.\n- Filter v-model: `v-model:filters` still works; new code should use `v-model:filter-model`.\n\n## TableColumnDefinition\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `key` | `string` | Field name on the row. |\n| `label` | `string` | Header text. |\n| `width` | `number` | Fixed column width (px). |\n| `minWidth` | `number` | Flex column minimum width, default `80`. |\n| `sortable` | `boolean` | Sortable. |\n| `fixed` | `boolean \\| 'left' \\| 'right'` | Fixed column; `true` equals `'left'`. |\n| `align` | `'start' \\| 'center' \\| 'end'` | Cell alignment. |\n| `render` | `(row) => unknown` | Custom cell renderer. |\n| `showOverflowTooltip` | `boolean` | Show tooltip on overflow. |\n| `resizable` | `boolean` | Allow drag resizing. |\n| `filterable` | `boolean` | Show header filter. |\n| `filters` | `TableColumnFilter[]` | Header filter options; omit for text filter. |\n| `children` | `TableColumnDefinition[]` | Multi-level sub-columns. |\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `columns` | `TableColumnDefinition[]` | — | Column definitions. |\n| `rows` | `TableItem[]` | — | Row data. |\n| `fit` | `boolean` | `true` | Stretch flex columns to fill width. |\n| `selectionMode` | `'single' \\| 'multiple' \\| null` | `null` | Selection mode. |\n| `selection` | `TableItem[] \\| null` | `null` | Multiple selection (`v-model:selection`). |\n| `selectedItem` | `TableItem \\| null` | `null` | Single selection (`v-model:selected-item`). |\n| `serverOptions` | `TableServerOptions \\| null` | `null` | Server pagination/sort options. |\n| `serverTotal` | `number` | `0` | Server total count. |\n| `paginator` | `boolean` | `false` | Show built-in paginator. |\n| `page` | `number` | `1` | Current page (`v-model:page`). |\n| `rowsPerPage` | `number` | `25` | Rows per page. |\n| `pageSizes` | `number[]` | `[25, 50, 100]` | Page size options. |\n| `showHeader` | `boolean` | `true` | Show header. |\n| `showRowsPerPage` | `boolean` | `true` | Show rows-per-page selector. |\n| `fill` | `boolean` | `false` | Fill parent height (with `MPageContent fill`); body scrolls, paginator pinned. Ignored when `maxHeight` / `tableHeight` is set. |\n| `columnWidths` | `Record<string, number> \\| null` | `null` | Column widths (`v-model:column-widths`). |\n| `virtual` | `boolean` | `false` | Row virtualization (requires a height; skipped with expand rows). |\n| `virtualRowHeight` | `number` | `40` | Estimated virtual row height. |\n| `virtualDynamicRowHeight` | `boolean` | `false` | Dynamic row-height virtualization (measured & cached via `ResizeObserver`). |\n| `virtualOverscan` | `number` | `4` | Extra rows rendered above/below the viewport to avoid flicker. |\n| `hiddenColumns` | `string[] \\| null` | `null` | Hidden column keys (`v-model:hidden-columns`). |\n| `columnOrder` | `string[] \\| null` | `null` | Leaf column order (`v-model:column-order`). |\n| `columnSetting` | `boolean` | `false` | Show column settings button (visibility toggle). |\n| `columnDrag` | `boolean` | `false` | Header drag reordering. |\n| `skeleton` | `boolean` | `false` | Skeleton loading state. |\n| `skeletonRows` | `number` | `5` | Skeleton row count. |\n| `showFooter` | `boolean` | `false` | Show footer. |\n| `footerMethod` | `TableFooterMethod \\| null` | `null` | Footer data. |\n| `spanMethod` | `TableSpanMethod \\| null` | `null` | Cell span. |\n| `treeConfig` | `TableTreeConfig \\| null` | `null` | Tree rows. |\n| `expandConfig` | `TableExpandConfig \\| null` | `null` | Detail expansion (mutually exclusive with tree). |\n| `checkboxConfig` | `TableCheckboxConfig \\| null` | `null` | Multiple selection: cascade / `checkMethod` / `checkRowKeys` / `trigger` / `reserve`. |\n| `radioConfig` | `TableRadioConfig \\| null` | `null` | Single selection: `strict` / `checkMethod` / `trigger`. |\n| `expandable` | `boolean` | `false` | Show expand column (also enabled by `#expansion` or `expandConfig`). |\n| `striped` | `boolean` | `false` | Zebra rows. |\n| `bordered` | `boolean` | `false` | Cell borders. |\n| `highlightCurrent` | `boolean` | `false` | Highlight current row; pair with `v-model:current-row-key`. |\n| `rowHover` | `boolean` | `true` | Row hover highlight. |\n| `sortConfig` | `TableSortConfig \\| null` | `null` | Unified sorting config `{ field, order, multiple, must, mode }`. |\n| `sortField` | `string \\| null` | `null` | (legacy) Single-field sort. Prefer `sortConfig`. |\n| `sortOrder` | `'asc' \\| 'desc' \\| null` | `null` | (legacy) Sort direction. Prefer `sortConfig`. |\n| `multiSort` | `boolean` | `false` | (legacy) Multi-column sort. Prefer `sortConfig.multiple`. |\n| `mustSort` | `boolean` | `false` | (legacy) Disallow clearing sort. Prefer `sortConfig.must`. |\n| `sortMode` | `'client' \\| 'emit'` | `'client'` | (legacy) Sort mode. Prefer `sortConfig.mode`. |\n| `searchField` / `searchValue` | — | — | Client-side search. |\n| `filterOptions` | `TableFilterOption[]` | `null` | Structured filter criteria. |\n| `filterModel` | `Record<string, unknown> \\| null` | `null` | Header filter v-model (`update:filter-model`). |\n| `filters` | `Record<string, unknown> \\| null` | `null` | (legacy) Old filter v-model name. |\n| `loading` | `boolean` | `false` | Loading state. |\n| `emptyText` | `string` | — | Empty text. |\n| `emptyDescription` | `string` | — | Empty description. |\n| `maxHeight` | `number \\| null` | `null` | Max height, scrolls beyond. |\n| `showOverflowTooltip` | `boolean` | `false` | Global overflow tooltip. |\n| `rowKey` | `string` | `'id'` | Row unique key field. |\n| `size` | `'small' \\| 'medium' \\| 'large' \\| 'sm' \\| 'md' \\| 'lg'` | — | Density (`large`/`small` adjust cell padding). |\n| `ariaLabel` | `string` | — | — |\n| `bodyExpandRowClassName` | `TableBodyRowClassName` | — | — |\n| `bodyItemClassName` | `TableBodyItemClassName` | — | — |\n| `bodyRowClassName` | `TableBodyRowClassName` | — | — |\n| `bodyTextDirection` | `TableTextDirection` | — | — |\n| `checkboxColumnWidth` | `number \\| null` | — | — |\n| `clickRowToExpand` | `boolean` | — | — |\n| `currentRowKey` | `string \\| number \\| null` | — | — |\n| `expandColumnWidth` | `number` | — | — |\n| `expandedRowKeys` | `Array<string \\| number>` | — | — |\n| `fixedCheckbox` | `boolean` | — | — |\n| `fixedExpand` | `boolean` | — | — |\n| `fixedHeader` | `boolean` | — | — |\n| `fixedIndex` | `boolean` | — | — |\n| `headerClassName` | `string` | — | — |\n| `headerItemClassName` | `TableHeaderItemClassName` | — | — |\n| `headerTextDirection` | `TableTextDirection` | — | — |\n| `indexColumnWidth` | `number` | — | — |\n| `showIndex` | `boolean` | — | — |\n| `showIndexSymbol` | `string` | — | — |\n| `tableClassName` | `string` | — | — |\n| `tableHeight` | `number \\| null` | — | — |\n| `tableMinHeight` | `number` | — | — |\n| `pt` | `TablePassThrough` | — | Multi-part DOM pass-through: `{ root, scrollbar, thead, tbody, tfoot, pagination, emptyMessage }`. |\n\n## Slots\n\n| Slot | Description |\n| --- | --- |\n| `cell-{key}` | Cell of column `{key}`, scope `{ row, value, column }` (use it to build editors). |\n| `footer` | Custom footer. |\n| `body-cell` | Any cell, scope `{ row, column, value }`. |\n| `expansion` | Expanded row content, scope `{ row }`. |\n| `empty` | Custom empty state. |\n| `loading` | Custom loading state (ignored when `skeleton` is true). |\n| `pagination` | Custom pagination area. |\n| `body` | Custom `body` content. |\n| `body-append` | Custom `body-append` content. |\n| `body-prepend` | Custom `body-prepend` content. |\n| `customize-headers` | Custom `customize-headers` content. |\n| `header` | Custom `header` content. |\n| `header-{key}` | Header slot (case matches `columns[].key`). |\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `sort-change` | `{ sortField?, sortOrder? }` | Sort changed. |\n| `filter-change` | `Record<string, unknown> \\| null` | Header filter committed (mirrors `update:filter-model`). |\n| `expand-change` | `{ row, expanded }` | Row expansion changed (detail or tree). |\n| `row-click` | `{ row, index }`, `Event` | Row click. |\n| `row-dblclick` | `{ row, index }`, `Event` | Row double click. |\n| `row-contextmenu` | `item`, `MouseEvent` | Row right click. |\n| `select-row` | `TableItem` | Row selected. |\n| `deselect-row` | `TableItem` | Row deselected. |\n| `select-all` | — | All rows of current page selected. |\n| `current-change` | `row \\| null, oldRow \\| null` | Current row changed. |\n| `update:selection` | `TableItem[]` | Multiple selection v-model. |\n| `update:page` | `number` | Page v-model. |\n| `update:server-options` | `TableServerOptions` | Server options v-model. |\n| `update:current-row-key` | `string \\| number \\| null` | Current row key v-model. |\n| `update:expanded-row-keys` | `Array<string \\| number>` | Expanded row keys v-model. |\n| `update:filter-model` | `Record<string, unknown> \\| null` | Header filter v-model. |\n| `update:column-widths` | `Record<string, number>` | Column widths v-model. |\n| `update:hidden-columns` | `string[]` | Hidden columns v-model. |\n| `update:column-order` | `string[]` | Column order v-model. |\n| `update:selected-item` | `TableItem \\| null` | Single selection v-model. |\n\n## Instance API\n\nAccess via `ref`:\n\n| Method / Property | Description |\n| --- | --- |\n| `currentPageFirstIndex` | Index of the first record on the current page (`-1` if empty). |\n| `currentPageLastIndex` | Index of the last record on the current page. |\n| `clientItemsLength` | Total row count (server total in server mode). |\n| `maxPaginationNumber` | Maximum page number. |\n| `currentPaginationNumber` | Current page number. |\n| `isLastPage` / `isFirstPage` | Whether on the last / first page. |\n| `nextPage()` / `prevPage()` | Go to next / previous page. |\n| `updatePage(page)` | Go to a specific page. |\n| `rowsPerPageOptions` | Rows-per-page options. |\n| `rowsPerPageActiveOption` | Current rows-per-page value. |\n| `updateRowsPerPageActiveOption(n)` | Update rows-per-page. |\n| `setFilters(filters)` / `clearFilter()` | Set / clear filters. |\n| `setColumnWidths(widths)` | Set column widths (same as `v-model:column-widths`). |\n| `setHiddenColumns(keys)` | Set hidden column keys (same as `v-model:hidden-columns`). |\n| `setColumnOrder(keys)` | Set leaf column order (same as `v-model:column-order`). |\n| `clearSort()` | Clear sorting. |\n| `getCheckboxRecords()` | Currently checked rows. |\n| `setCheckboxRow(rows, checked)` | Set row checked state. |\n| `clearCheckboxRow()` | Clear all checked rows. |\n| `isCheckedByCheckboxRow(row)` | Whether a row is checked. |\n| `isAllCheckboxChecked()` | Whether all rows on the current page are checked. |\n| `getCheckboxIndeterminateRecords()` | Indeterminate (half-checked) rows in tree cascade. |\n| `scrollTo(...)` / `scrollToRow(row)` | Scroll positioning. |\n| `setRowExpand` / `setAllRowExpand` / `toggleRowExpand` / `clearRowExpand` / `isRowExpandByRow` / `getRowExpandRecords` | Detail expansion (non-tree). |\n| `setTreeExpand` / `setAllTreeExpand` / `toggleTreeExpand` / `clearTreeExpand` / `isTreeExpandByRow` / `getTreeExpandRecords` | Tree node expansion. |\n\n## Types\n\n<h4 id=\"TableItem\">TableItem</h4>\n\n```ts\ntype TableItem = Record<string, unknown>\n```\n\n<h4 id=\"TableSortConfig\">TableSortConfig</h4>\n\nUnified sort config; `field` / `order` describe the current single-column sort, `mode` chooses between internal and external sorting:\n\n```ts\ninterface TableSortConfig {\n field?: string | null\n order?: 'asc' | 'desc' | null\n multiple?: boolean\n must?: boolean\n mode?: 'client' | 'emit'\n}\n```\n\n<h4 id=\"TablePassThrough\">TablePassThrough</h4>\n\nMulti-part DOM pass-through; supports class / style / any attrs:\n\n```ts\ninterface TablePassThrough {\n root?: Record<string, unknown>\n scrollbar?: Record<string, unknown>\n thead?: Record<string, unknown>\n tbody?: Record<string, unknown>\n tfoot?: Record<string, unknown>\n pagination?: Record<string, unknown>\n emptyMessage?: Record<string, unknown>\n}\n```\n\n<h4 id=\"TableTextDirection\">TableTextDirection</h4>\n\n```ts\ntype TableTextDirection = 'left' | 'center' | 'right'\n```\n\n<h4 id=\"TableFilterOption\">TableFilterOption</h4>\n\n```ts\ntype TableFilterOption =\n | { field: string; comparison: 'between'; criteria: [number, number] }\n | { field: string; comparison: '=' | '!='; criteria: number | string }\n | { field: string; comparison: '>' | '>=' | '<' | '<='; criteria: number }\n | { field: number | string; comparison: 'in'; criteria: number[] | string[] }\n | { field: string; comparison: (value: unknown, criteria: string) => boolean; criteria: string }\n```\n\n<h4 id=\"TableHeaderItemClassName\">TableHeaderItemClassName</h4>\n\n```ts\ntype TableHeaderItemClassName = string | ((header: TableHeader, columnNumber: number) => string)\n```\n\n<h4 id=\"TableBodyRowClassName\">TableBodyRowClassName</h4>\n\n```ts\ntype TableBodyRowClassName = string | ((item: TableItem, rowNumber: number) => string)\n```\n\n<h4 id=\"TableBodyItemClassName\">TableBodyItemClassName</h4>\n\n```ts\ntype TableBodyItemClassName = string | ((column: string, rowNumber: number) => string)\n```\n\n<h4 id=\"TableTreeConfig\">TableTreeConfig</h4>\n\n```ts\ninterface TableTreeConfig {\n childrenField?: string // default 'children'\n indent?: number // default 16\n expandAll?: boolean\n accordion?: boolean\n trigger?: 'default' | 'row'\n lazy?: boolean\n hasChildField?: string // default 'hasChild'\n loadMethod?: (row: TableItem) => Promise<TableItem[]> | TableItem[]\n transform?: boolean // flat parentId → tree\n rowField?: string\n parentField?: string // default 'parentId'\n treeNode?: string // column key for toggler; default first column\n showLine?: boolean\n}\n```\n\n<h4 id=\"TableColumnDefinition\">TableColumnDefinition</h4>\n\nColumn definition passed to `columns`:\n\n```ts\ninterface TableColumnDefinition {\n key: string\n label: string\n width?: number\n minWidth?: number\n sortable?: boolean\n fixed?: boolean | 'left' | 'right'\n align?: 'start' | 'center' | 'end'\n render?: (row: TableItem) => unknown\n showOverflowTooltip?: boolean\n resizable?: boolean\n filterable?: boolean\n filters?: TableColumnFilter[]\n children?: TableColumnDefinition[]\n}\n```\n\n<h4 id=\"TableServerOptions\">TableServerOptions</h4>\n\nServer pagination/sort options passed to `serverOptions`, paired with `serverTotal`:\n\n```ts\ninterface TableServerOptions {\n page: number\n rowsPerPage: number\n sortBy?: string | string[]\n sortType?: 'asc' | 'desc' | ('asc' | 'desc')[]\n}\n```\n\nSee more at [API Types](/docs/types).\n"
|
|
27037
27814
|
}
|
|
27038
27815
|
}
|
|
27039
27816
|
},
|
|
@@ -31855,7 +32632,7 @@
|
|
|
31855
32632
|
"zh-CN": {
|
|
31856
32633
|
"title": "快速上手",
|
|
31857
32634
|
"description": "安装依赖、引入样式,并渲染第一个组件。",
|
|
31858
|
-
"markdown": "---\ntitle: 快速上手\norder: 2\ndescription: 安装依赖、引入样式,并渲染第一个组件。\n---\n\n# 快速上手\n\n> 在线文档:[morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/) · 源码:[GitHub](https://github.com/morya-space/morya-ui) · npm:[`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## 安装\n\n
|
|
32635
|
+
"markdown": "---\ntitle: 快速上手\norder: 2\ndescription: 安装依赖、引入样式,并渲染第一个组件。\n---\n\n# 快速上手\n\n> 在线文档:[morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/) · 源码:[GitHub](https://github.com/morya-space/morya-ui) · npm:[`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## 安装\n\n**从零创建新项目(推荐):**\n\n```bash\nnpx @morya-ui/setup --create my-app\n```\n\n脚手架 + 安装 + 完整接入一步到位。详见 [一键接入](/docs/setup)。\n\n**在已有应用项目中手动安装(npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\n也可以用:\n\n```bash\nnpx @morya-ui/setup app\n```\n\n会安装依赖,并尽量在入口注入样式。更多命令与选项见 [一键接入](/docs/setup)。需要 Vue 3(推荐 3.5 及以上)。主题 token、亮暗切换与动效 API 均包含在 `morya-ui` 中。Agent Skill / MCP 见 [AI 接入](/docs/ai-setup)。\n\n## 选择使用方式\n\n本库同时支持**全量**与**按需**两种消费方式,按项目需求任选其一(同一应用内建议保持一致)。\n\n| | 全量 | 按需 |\n| --- | --- | --- |\n| 典型场景 | 组件用得较多、希望快速上手 | 打包体积敏感、只用少量组件 |\n| 组件来源 | `app.use(MoryaUI)` 或 `morya-ui` 按名导入 | `morya-ui/button` 等子路径,或 Vite 自动解析 |\n| 样式 | 入口引入 `morya-ui/styles.css` | 子路径自动带入(含 theme + 依赖组件样式) |\n| JS 体积 | 全量注册会打入完整组件;按名导入可 tree-shake | 仅打入用到的组件及其依赖 |\n\n## 全量用法\n\n### 1. 插件注册(推荐的全量方式)\n\n在应用入口引入**全量样式**,并通过插件一次注册所有组件:\n\n```ts\nimport MoryaUI from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).use(MoryaUI).mount('#app')\n```\n\n模板中可直接使用 `<MButton>`、`<MInput>` 等,无需逐个 import。\n\n### 2. 按名导入 + 全量样式\n\n不注册插件、在 SFC 中按需写 import,JS 可由构建工具 tree-shake,但样式仍需全量 CSS:\n\n```ts\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).mount('#app')\n```\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton, MInput } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst name = ref('')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 1rem; max-width: 20rem\">\n <MInput v-model=\"name\" label=\"名称\" placeholder=\"输入名称\" />\n <MButton label=\"提交\" @click=\"() => undefined\" />\n </div>\n</template>\n```\n\n## 按需用法\n\n### 1. 子路径导入\n\n从 kebab-case 子路径导入(如 `button`、`input-password`、`tree-select`)。会带上组件 JS、类型声明、内部依赖与对应样式,**无需**再引 `morya-ui/styles.css`。Props 等类型从同一路径导入,例如 `import type { ButtonProps } from 'morya-ui/button'`。\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\n仅要样式时:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. 自动按需(Vite)\n\n安装 `unplugin-vue-components` 后,在 `vite.config.ts` 中配置解析器,模板里可直接写 `<MButton>`:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({\n dts: 'src/components.d.ts',\n resolvers: [MoryaUIResolver()],\n }),\n ],\n})\n```\n\n`dts` 会写出组件声明,编辑器和 `vue-tsc` 据此识别模板里的组件;该文件需落在 `tsconfig.json` 的 `include` 中。按需模式下,`createMoryaUI({ components: false })` 仍可注入全局配置而不注册组件。\n\n## 可选:应用级全局配置\n\n`createMoryaUI` 会写入全局默认值,并默认注册全部组件:\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 1100,\n }),\n )\n .mount('#app')\n```\n\n仅配置、不注册组件时使用 `components: false`。\n\n更多说明见 [全局配置](/docs/config)。\n\n## 主题 API\n\n亮暗切换等能力从同一包引入:\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { toggleTheme } = useTheme()\n```\n\n详见 [主题](/docs/theme)。\n\n## 启动本仓库文档站\n\n```bash\npnpm --filter morya-ui dev\n# http://localhost:5182\n\n# 构建静态文档站\npnpm --filter morya-ui build:docs\n```\n",
|
|
31859
32636
|
"sections": [
|
|
31860
32637
|
{
|
|
31861
32638
|
"title": "",
|
|
@@ -31865,7 +32642,7 @@
|
|
|
31865
32642
|
{
|
|
31866
32643
|
"title": "安装",
|
|
31867
32644
|
"id": "安装",
|
|
31868
|
-
"body": "
|
|
32645
|
+
"body": "**从零创建新项目(推荐):**\n\n```bash\nnpx @morya-ui/setup --create my-app\n```\n\n脚手架 + 安装 + 完整接入一步到位。详见 [一键接入](/docs/setup)。\n\n**在已有应用项目中手动安装(npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\n也可以用:\n\n```bash\nnpx @morya-ui/setup app\n```\n\n会安装依赖,并尽量在入口注入样式。更多命令与选项见 [一键接入](/docs/setup)。需要 Vue 3(推荐 3.5 及以上)。主题 token、亮暗切换与动效 API 均包含在 `morya-ui` 中。Agent Skill / MCP 见 [AI 接入](/docs/ai-setup)。"
|
|
31869
32646
|
},
|
|
31870
32647
|
{
|
|
31871
32648
|
"title": "选择使用方式",
|
|
@@ -31902,7 +32679,7 @@
|
|
|
31902
32679
|
"en-US": {
|
|
31903
32680
|
"title": "Quick start",
|
|
31904
32681
|
"description": "Install the package, import styles, and render the first component.",
|
|
31905
|
-
"markdown": "---\ntitle: Quick start\norder: 2\ndescription: Install the package, import styles, and render the first component.\n---\n\n# Quick start\n\n> Live docs: [morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/) · Source: [GitHub](https://github.com/morya-space/morya-ui) · npm: [`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## Install\n\n**In an application (npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\nOr:\n\n```bash\nnpx @morya-ui/setup app\n```\n\nThis installs the dependency and tries to inject styles at the app entry. More commands and options: [One-shot setup](/docs/setup). Requires Vue 3 (3.5+ recommended). Theme tokens, color-mode switching, and motion APIs are all included in `morya-ui`. For Agent skill / MCP, see [AI setup](/docs/ai-setup).\n\nAfter cloning this repository, run `pnpm install`. The docs playground resolves source via Vite aliases (see `playground/vite.config.ts`).\n\nTo debug from another app, use `link:` / `pnpm link` plus Vite aliases. A plain npm install always resolves `dist/`.\n\n## Choose an import mode\n\nThe library supports **full** and **on-demand** usage. Pick one per app (stay consistent within a project).\n\n| | Full | On-demand |\n| --- | --- | --- |\n| Best for | Many components, fastest setup | Bundle size, few components |\n| Components | `app.use(MoryaUI)` or named imports from `morya-ui` | `morya-ui/button` subpaths, or Vite auto-resolver |\n| Styles | Import `morya-ui/styles.css` at entry | Bundled with subpath imports (theme + deps) |\n| JS size | Full plugin bundles all components; named imports tree-shake | Only used components and their deps |\n\n## Full usage\n\n### 1. Plugin registration (recommended full mode)\n\nImport the **full stylesheet** and register all components once:\n\n```ts\nimport MoryaUI from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).use(MoryaUI).mount('#app')\n```\n\nTemplates can use `<MButton>`, `<MInput>`, etc. without per-file imports.\n\n### 2. Named imports + full CSS\n\nSkip the plugin; import components in SFCs. JS can tree-shake, but styles still need the full CSS file:\n\n```ts\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).mount('#app')\n```\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton, MInput } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst name = ref('')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 1rem; max-width: 20rem\">\n <MInput v-model=\"name\" label=\"Name\" placeholder=\"Enter a name\" />\n <MButton label=\"Submit\" @click=\"() => undefined\" />\n </div>\n</template>\n```\n\n## On-demand usage\n\n### 1. Subpath imports\n\nImport from kebab-case subpaths (e.g. `button`, `input-password`, `tree-select`). Each entry bundles component JS, type declarations, internal dependencies, and styles — **no** `morya-ui/styles.css` required. Prop types come from the same path, for example `import type { ButtonProps } from 'morya-ui/button'`.\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\nStyles only:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. Auto on-demand (Vite)\n\nWith `unplugin-vue-components`, add the resolver so templates can use `<MButton>` without manual imports:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({\n dts: 'src/components.d.ts',\n resolvers: [MoryaUIResolver()],\n }),\n ],\n})\n```\n\n`dts` writes component declarations so the editor and `vue-tsc` can resolve components used in templates. That file must be covered by `include` in `tsconfig.json`. In on-demand mode, `createMoryaUI({ components: false })` still applies global config without registering components.\n\n## Optional: app-level defaults\n\n`createMoryaUI` applies global defaults and registers all components by default:\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 1100,\n }),\n )\n .mount('#app')\n```\n\nUse `components: false` for config-only install.\n\nSee [Configuration](/docs/config) for details.\n\n## Theme API\n\nColor-mode helpers come from the same package:\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { toggleTheme } = useTheme()\n```\n\nSee [Theme](/docs/theme).\n\n## Run this docs site\n\n```bash\npnpm --filter morya-ui dev\n# http://localhost:5182\n\n# Build the static docs site\npnpm --filter morya-ui build:docs\n```\n",
|
|
32682
|
+
"markdown": "---\ntitle: Quick start\norder: 2\ndescription: Install the package, import styles, and render the first component.\n---\n\n# Quick start\n\n> Live docs: [morya-space.github.io/morya-ui](https://morya-space.github.io/morya-ui/) · Source: [GitHub](https://github.com/morya-space/morya-ui) · npm: [`morya-ui`](https://www.npmjs.com/package/morya-ui)\n\n## Install\n\n**Create a new project (recommended):**\n\n```bash\nnpx @morya-ui/setup --create my-app\n```\n\nScaffold + install + full setup in one step. See [One-shot setup](/docs/setup).\n\n**In an existing application (npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\nOr:\n\n```bash\nnpx @morya-ui/setup app\n```\n\nThis installs the dependency and tries to inject styles at the app entry. More commands and options: [One-shot setup](/docs/setup). Requires Vue 3 (3.5+ recommended). Theme tokens, color-mode switching, and motion APIs are all included in `morya-ui`. For Agent skill / MCP, see [AI setup](/docs/ai-setup).\n\nAfter cloning this repository, run `pnpm install`. The docs playground resolves source via Vite aliases (see `playground/vite.config.ts`).\n\nTo debug from another app, use `link:` / `pnpm link` plus Vite aliases. A plain npm install always resolves `dist/`.\n\n## Choose an import mode\n\nThe library supports **full** and **on-demand** usage. Pick one per app (stay consistent within a project).\n\n| | Full | On-demand |\n| --- | --- | --- |\n| Best for | Many components, fastest setup | Bundle size, few components |\n| Components | `app.use(MoryaUI)` or named imports from `morya-ui` | `morya-ui/button` subpaths, or Vite auto-resolver |\n| Styles | Import `morya-ui/styles.css` at entry | Bundled with subpath imports (theme + deps) |\n| JS size | Full plugin bundles all components; named imports tree-shake | Only used components and their deps |\n\n## Full usage\n\n### 1. Plugin registration (recommended full mode)\n\nImport the **full stylesheet** and register all components once:\n\n```ts\nimport MoryaUI from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).use(MoryaUI).mount('#app')\n```\n\nTemplates can use `<MButton>`, `<MInput>`, etc. without per-file imports.\n\n### 2. Named imports + full CSS\n\nSkip the plugin; import components in SFCs. JS can tree-shake, but styles still need the full CSS file:\n\n```ts\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App).mount('#app')\n```\n\n```vue\n<script setup lang=\"ts\">\nimport { MButton, MInput } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst name = ref('')\n</script>\n\n<template>\n <div style=\"display: grid; gap: 1rem; max-width: 20rem\">\n <MInput v-model=\"name\" label=\"Name\" placeholder=\"Enter a name\" />\n <MButton label=\"Submit\" @click=\"() => undefined\" />\n </div>\n</template>\n```\n\n## On-demand usage\n\n### 1. Subpath imports\n\nImport from kebab-case subpaths (e.g. `button`, `input-password`, `tree-select`). Each entry bundles component JS, type declarations, internal dependencies, and styles — **no** `morya-ui/styles.css` required. Prop types come from the same path, for example `import type { ButtonProps } from 'morya-ui/button'`.\n\n```ts\nimport { MButton } from 'morya-ui/button'\nimport { MInput } from 'morya-ui/input'\n```\n\nStyles only:\n\n```ts\nimport 'morya-ui/button/style'\nimport 'morya-ui/button/style.css'\n```\n\n### 2. Auto on-demand (Vite)\n\nWith `unplugin-vue-components`, add the resolver so templates can use `<MButton>` without manual imports:\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineConfig({\n plugins: [\n vue(),\n Components({\n dts: 'src/components.d.ts',\n resolvers: [MoryaUIResolver()],\n }),\n ],\n})\n```\n\n`dts` writes component declarations so the editor and `vue-tsc` can resolve components used in templates. That file must be covered by `include` in `tsconfig.json`. In on-demand mode, `createMoryaUI({ components: false })` still applies global config without registering components.\n\n## Optional: app-level defaults\n\n`createMoryaUI` applies global defaults and registers all components by default:\n\n```ts\nimport { createMoryaUI } from 'morya-ui'\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\ncreateApp(App)\n .use(\n createMoryaUI({\n appendTo: 'body',\n size: 'small',\n zIndex: 1100,\n }),\n )\n .mount('#app')\n```\n\nUse `components: false` for config-only install.\n\nSee [Configuration](/docs/config) for details.\n\n## Theme API\n\nColor-mode helpers come from the same package:\n\n```ts\nimport { useTheme } from 'morya-ui'\n\nconst { toggleTheme } = useTheme()\n```\n\nSee [Theme](/docs/theme).\n\n## Run this docs site\n\n```bash\npnpm --filter morya-ui dev\n# http://localhost:5182\n\n# Build the static docs site\npnpm --filter morya-ui build:docs\n```\n",
|
|
31906
32683
|
"sections": [
|
|
31907
32684
|
{
|
|
31908
32685
|
"title": "",
|
|
@@ -31912,7 +32689,7 @@
|
|
|
31912
32689
|
{
|
|
31913
32690
|
"title": "Install",
|
|
31914
32691
|
"id": "install",
|
|
31915
|
-
"body": "**In an application (npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\nOr:\n\n```bash\nnpx @morya-ui/setup app\n```\n\nThis installs the dependency and tries to inject styles at the app entry. More commands and options: [One-shot setup](/docs/setup). Requires Vue 3 (3.5+ recommended). Theme tokens, color-mode switching, and motion APIs are all included in `morya-ui`. For Agent skill / MCP, see [AI setup](/docs/ai-setup).\n\nAfter cloning this repository, run `pnpm install`. The docs playground resolves source via Vite aliases (see `playground/vite.config.ts`).\n\nTo debug from another app, use `link:` / `pnpm link` plus Vite aliases. A plain npm install always resolves `dist/`."
|
|
32692
|
+
"body": "**Create a new project (recommended):**\n\n```bash\nnpx @morya-ui/setup --create my-app\n```\n\nScaffold + install + full setup in one step. See [One-shot setup](/docs/setup).\n\n**In an existing application (npm / pnpm / yarn):**\n\n```bash\npnpm add morya-ui\n```\n\nOr:\n\n```bash\nnpx @morya-ui/setup app\n```\n\nThis installs the dependency and tries to inject styles at the app entry. More commands and options: [One-shot setup](/docs/setup). Requires Vue 3 (3.5+ recommended). Theme tokens, color-mode switching, and motion APIs are all included in `morya-ui`. For Agent skill / MCP, see [AI setup](/docs/ai-setup).\n\nAfter cloning this repository, run `pnpm install`. The docs playground resolves source via Vite aliases (see `playground/vite.config.ts`).\n\nTo debug from another app, use `link:` / `pnpm link` plus Vite aliases. A plain npm install always resolves `dist/`."
|
|
31916
32693
|
},
|
|
31917
32694
|
{
|
|
31918
32695
|
"title": "Choose an import mode",
|
|
@@ -31959,22 +32736,27 @@
|
|
|
31959
32736
|
"zh-CN": {
|
|
31960
32737
|
"title": "一键接入",
|
|
31961
32738
|
"description": "用 @morya-ui/setup 安装组件库,并按需写入样式、Agent 配置与 MCP。",
|
|
31962
|
-
"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 规则、便携 `AGENTS.md` 与多编辑器 MCP。手写安装见 [快速上手](/docs/quick-start);AI 生成页面的约定见 [AI 接入](/docs/ai-setup)。\n\n##
|
|
32739
|
+
"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 规则、便携 `AGENTS.md` 与多编辑器 MCP。手写安装见 [快速上手](/docs/quick-start);AI 生成页面的约定见 [AI 接入](/docs/ai-setup)。\n\n## 快速开始\n\n### 在现有项目中配置\n\n在业务项目根目录执行:\n\n```bash\nnpx @morya-ui/setup\n```\n\n### 从零创建新项目\n\n```bash\nnpx @morya-ui/setup --create my-admin\n```\n\n会从 create-vite 脚手架出 `./my-admin`,安装依赖,然后自动执行完整接入(组件库 + AI 配置 + MCP + 样式)。\n\n### 交互模式\n\n在终端(TTY)中裸跑 `npx @morya-ui/setup`,CLI 会按顺序询问:\n\n1. **做什么** — 配置当前项目,还是创建新项目\n2. **项目名** — 仅创建时(带校验)\n3. **包管理器** — 仅创建时(标出自动探测结果)\n4. **create-vite 模板** — `vue-ts` vs `vue`\n5. **可选 Agent Skills** — `full` / `ai` 模式\n\n每个提示都有合理默认值,直接回车即可。传 `--yes`(或在 CI 等非 TTY 环境)跳过全部提示。\n\n## 命令\n\n默认会:\n\n1. 将 `morya-ui`(以及项目中已有的 `@morya-ui/*`,如 `@morya-ui/nuxt`)升级到 npm `latest`(按锁文件选用 pnpm / yarn / npm)\n2. 复制 `DESIGN.md`、`AGENTS.md`、Agent Skill、Cursor rules 与检查脚本\n3. 合并 MCP 配置(Cursor / VS Code / Zed + 根目录 `.mcp.json`),接入 [`@morya-ui/mcp@latest`](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# 只写部分编辑器的 MCP(仍会写 .mcp.json)\nnpx @morya-ui/setup ai --editors=cursor,vscode\n\n# 收窄 Skill 目标 agents(默认:cursor, github-copilot, zed, claude-code, windsurf)\nnpx @morya-ui/setup ai --agents=github-copilot,zed\n\n# companion 装到 skills CLI 支持的全部 agents(目录会很多)\nnpx @morya-ui/setup ai --agents=all\n\n# 只刷新 AI 模板 / MCP,不改动依赖\nnpx @morya-ui/setup ai --skip-install\n```\n\n在 TTY 下,`full` / `ai` 会提示勾选可选 Agent Skill(必选 `morya-ui-pages` 始终写入)。可选 companion 通过 [skills CLI](https://skills.sh/) 安装**最新版**,并同步到默认 5 个 skill agents。完成后若写入了 MCP,请 **重启编辑器或重载 MCP**。Zed 需信任 worktree 后才会加载项目 skills。生成页面前让 Agent 先读 `DESIGN.md`(及 `AGENTS.md`)。\n\n### 创建新项目\n\n```bash\n# 交互式:询问项目名、包管理器、模板\nnpx @morya-ui/setup --create\n\n# 显式指定\nnpx @morya-ui/setup --create my-admin\nnpx @morya-ui/setup --create my-admin --template vue\nnpx @morya-ui/setup --create my-admin --pm npm\n\n# CI / 非交互:全走默认值\nnpx @morya-ui/setup --create my-admin --yes\n```\n\n`--create` 会自动完成:create-vite 脚手架 → `<pm> install` → 完整接入流程(相当于在新项目里再跑一次 `npx @morya-ui/setup`)。\n\n## 选项\n\n| Flag | 说明 |\n| --- | --- |\n| `--create <name>` | 从 create-vite 脚手架新项目,然后执行完整接入 |\n| `--template <tpl>` | create-vite 模板:`vue-ts`(默认)或 `vue`;仅配合 `--create` |\n| `--cwd <dir>` | 目标项目根(默认当前目录);配合 `--create` 时为父目录 |\n| `--pm pnpm\\|yarn\\|npm` | 指定包管理器 |\n| `--skills <list>` | 逗号分隔的 skill id,或 `all`(跳过交互提示) |\n| `--editors <list>` | MCP 目标:`cursor`、`vscode`、`zed` 或 `all`(默认三者;始终另写 `.mcp.json`) |\n| `--agents <list>` | Skill agents:`cursor`、`github-copilot`、`zed`、`claude-code`、`windsurf`(默认),或 `all` |\n| `--yes` / `-y` | 跳过全部交互提示,使用默认值(CI 友好) |\n| `--force` | 覆盖已有模板文件、`morya-ui` MCP 条目与 skill 目录链接 |\n| `--dry-run` | 只打印将要执行的操作 |\n| `--skip-install` | 不安装 / 升级 `morya-ui` 与 `@morya-ui/*` |\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 会始终拉取最新版。执行时默认会把相关依赖升到最新;需要跳过时加 `--skip-install`。\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.md` | 编辑器无关的常驻清单(VS Code / Zed / CLI 等) |\n| `.agents/skills/morya-ui-pages/` | 页面生成 Agent Skill(见 [Agent Skill](/docs/agent-skill)) |\n| `.agents/skills/<optional>/` | 勾选时由 skills CLI 写入的最新 companion |\n| `.claude/skills/`、`.windsurf/skills/`、`.github/skills/` | 从 `.agents/skills` 同步的镜像(Claude Code / Windsurf / Copilot) |\n| `.cursor/rules/` | Cursor 常驻规则 |\n| `scripts/check-raw-colors.mjs` | 裸色值扫描 |\n| `.cursor/mcp.json` | Cursor MCP |\n| `.vscode/mcp.json` | VS Code MCP |\n| `.zed/settings.json` | Zed `context_servers`(合并,不覆盖其它设置) |\n| `.mcp.json` | 便携 MCP(Agent Host / 跨工具发现) |\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- 依赖:默认将 `morya-ui@latest` 以及项目中已有的 `@morya-ui/*` 升到最新(可用 `--skip-install` 跳过)\n- 模板文件与 `.cursor/rules/*`:目标已存在则跳过(除非 `--force`)\n- Companion skills(skills CLI):勾选时始终安装/更新为最新版\n- MCP 配置:合并其它 server / 设置;已有 `morya-ui` 条目则跳过(除非 `--force`);新建或强制覆盖时使用 `@morya-ui/mcp@latest`\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",
|
|
31963
32740
|
"sections": [
|
|
31964
32741
|
{
|
|
31965
32742
|
"title": "",
|
|
31966
32743
|
"id": "overview",
|
|
31967
32744
|
"body": "# 一键接入\n\n[`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) 用于在业务 Vue 项目中接入 `morya-ui`:安装依赖、注入样式,并可一并写入 Agent Skill、Cursor 规则、便携 `AGENTS.md` 与多编辑器 MCP。手写安装见 [快速上手](/docs/quick-start);AI 生成页面的约定见 [AI 接入](/docs/ai-setup)。"
|
|
31968
32745
|
},
|
|
32746
|
+
{
|
|
32747
|
+
"title": "快速开始",
|
|
32748
|
+
"id": "快速开始",
|
|
32749
|
+
"body": "### 在现有项目中配置\n\n在业务项目根目录执行:\n\n```bash\nnpx @morya-ui/setup\n```\n\n### 从零创建新项目\n\n```bash\nnpx @morya-ui/setup --create my-admin\n```\n\n会从 create-vite 脚手架出 `./my-admin`,安装依赖,然后自动执行完整接入(组件库 + AI 配置 + MCP + 样式)。\n\n### 交互模式\n\n在终端(TTY)中裸跑 `npx @morya-ui/setup`,CLI 会按顺序询问:\n\n1. **做什么** — 配置当前项目,还是创建新项目\n2. **项目名** — 仅创建时(带校验)\n3. **包管理器** — 仅创建时(标出自动探测结果)\n4. **create-vite 模板** — `vue-ts` vs `vue`\n5. **可选 Agent Skills** — `full` / `ai` 模式\n\n每个提示都有合理默认值,直接回车即可。传 `--yes`(或在 CI 等非 TTY 环境)跳过全部提示。"
|
|
32750
|
+
},
|
|
31969
32751
|
{
|
|
31970
32752
|
"title": "命令",
|
|
31971
32753
|
"id": "命令",
|
|
31972
|
-
"body": "
|
|
32754
|
+
"body": "默认会:\n\n1. 将 `morya-ui`(以及项目中已有的 `@morya-ui/*`,如 `@morya-ui/nuxt`)升级到 npm `latest`(按锁文件选用 pnpm / yarn / npm)\n2. 复制 `DESIGN.md`、`AGENTS.md`、Agent Skill、Cursor rules 与检查脚本\n3. 合并 MCP 配置(Cursor / VS Code / Zed + 根目录 `.mcp.json`),接入 [`@morya-ui/mcp@latest`](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# 只写部分编辑器的 MCP(仍会写 .mcp.json)\nnpx @morya-ui/setup ai --editors=cursor,vscode\n\n# 收窄 Skill 目标 agents(默认:cursor, github-copilot, zed, claude-code, windsurf)\nnpx @morya-ui/setup ai --agents=github-copilot,zed\n\n# companion 装到 skills CLI 支持的全部 agents(目录会很多)\nnpx @morya-ui/setup ai --agents=all\n\n# 只刷新 AI 模板 / MCP,不改动依赖\nnpx @morya-ui/setup ai --skip-install\n```\n\n在 TTY 下,`full` / `ai` 会提示勾选可选 Agent Skill(必选 `morya-ui-pages` 始终写入)。可选 companion 通过 [skills CLI](https://skills.sh/) 安装**最新版**,并同步到默认 5 个 skill agents。完成后若写入了 MCP,请 **重启编辑器或重载 MCP**。Zed 需信任 worktree 后才会加载项目 skills。生成页面前让 Agent 先读 `DESIGN.md`(及 `AGENTS.md`)。\n\n### 创建新项目\n\n```bash\n# 交互式:询问项目名、包管理器、模板\nnpx @morya-ui/setup --create\n\n# 显式指定\nnpx @morya-ui/setup --create my-admin\nnpx @morya-ui/setup --create my-admin --template vue\nnpx @morya-ui/setup --create my-admin --pm npm\n\n# CI / 非交互:全走默认值\nnpx @morya-ui/setup --create my-admin --yes\n```\n\n`--create` 会自动完成:create-vite 脚手架 → `<pm> install` → 完整接入流程(相当于在新项目里再跑一次 `npx @morya-ui/setup`)。"
|
|
31973
32755
|
},
|
|
31974
32756
|
{
|
|
31975
32757
|
"title": "选项",
|
|
31976
32758
|
"id": "选项",
|
|
31977
|
-
"body": "| Flag | 说明 |\n| --- | --- |\n| `--cwd <dir>` |
|
|
32759
|
+
"body": "| Flag | 说明 |\n| --- | --- |\n| `--create <name>` | 从 create-vite 脚手架新项目,然后执行完整接入 |\n| `--template <tpl>` | create-vite 模板:`vue-ts`(默认)或 `vue`;仅配合 `--create` |\n| `--cwd <dir>` | 目标项目根(默认当前目录);配合 `--create` 时为父目录 |\n| `--pm pnpm\\|yarn\\|npm` | 指定包管理器 |\n| `--skills <list>` | 逗号分隔的 skill id,或 `all`(跳过交互提示) |\n| `--editors <list>` | MCP 目标:`cursor`、`vscode`、`zed` 或 `all`(默认三者;始终另写 `.mcp.json`) |\n| `--agents <list>` | Skill agents:`cursor`、`github-copilot`、`zed`、`claude-code`、`windsurf`(默认),或 `all` |\n| `--yes` / `-y` | 跳过全部交互提示,使用默认值(CI 友好) |\n| `--force` | 覆盖已有模板文件、`morya-ui` MCP 条目与 skill 目录链接 |\n| `--dry-run` | 只打印将要执行的操作 |\n| `--skip-install` | 不安装 / 升级 `morya-ui` 与 `@morya-ui/*` |\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 会始终拉取最新版。执行时默认会把相关依赖升到最新;需要跳过时加 `--skip-install`。\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```"
|
|
31978
32760
|
},
|
|
31979
32761
|
{
|
|
31980
32762
|
"title": "会落到项目里的内容",
|
|
@@ -31996,22 +32778,27 @@
|
|
|
31996
32778
|
"en-US": {
|
|
31997
32779
|
"title": "One-shot setup",
|
|
31998
32780
|
"description": "Use @morya-ui/setup to install the library and optionally write styles, Agent config, and MCP.",
|
|
31999
|
-
"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, portable `AGENTS.md`, and multi-editor MCP. For manual install see [Quick start](/docs/quick-start). For AI page-generation workflow see [AI setup](/docs/ai-setup).\n\n##
|
|
32781
|
+
"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, portable `AGENTS.md`, and multi-editor MCP. For manual install see [Quick start](/docs/quick-start). For AI page-generation workflow see [AI setup](/docs/ai-setup).\n\n## Quick start\n\n### Configure an existing project\n\nFrom the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\n### Create a new project from scratch\n\n```bash\nnpx @morya-ui/setup --create my-admin\n```\n\nScaffolds `./my-admin` via create-vite, installs dependencies, then applies the full setup (library + AI pack + MCP + styles) inside it.\n\n### Interactive mode\n\nRun without arguments in a terminal (TTY) and the CLI prompts for:\n\n1. **What to do** — configure current project, or create a new one\n2. **Project name** — when creating (with validation)\n3. **Package manager** — when creating (auto-detected default highlighted)\n4. **create-vite template** — `vue-ts` vs `vue`\n5. **Optional Agent skills** — `full` / `ai` modes\n\nEvery prompt has a sensible default — press Enter to accept. Pass `--yes` (or run in a non-TTY environment like CI) to skip all prompts and use defaults.\n\n## Commands\n\nBy default this will:\n\n1. Install / upgrade `morya-ui` and any existing `@morya-ui/*` (e.g. `@morya-ui/nuxt`) to npm `latest` (pnpm / yarn / npm from the lockfile)\n2. Copy `DESIGN.md`, `AGENTS.md`, Agent skill, Cursor rules, and check scripts\n3. Merge MCP configs (Cursor / VS Code / Zed + root `.mcp.json`) for [`@morya-ui/mcp@latest`](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# Upgrade deps + styles only\nnpx @morya-ui/setup app\n\n# Upgrade deps + AI config + MCP (skips styles injection)\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# Subset of MCP editor targets (still writes .mcp.json)\nnpx @morya-ui/setup ai --editors=cursor,vscode\n\n# Narrow skill agents (default: cursor, github-copilot, zed, claude-code, windsurf)\nnpx @morya-ui/setup ai --agents=github-copilot,zed\n\n# Install companions to every skills-CLI agent (many dirs)\nnpx @morya-ui/setup ai --agents=all\n\n# Refresh AI template / MCP without touching dependencies\nnpx @morya-ui/setup ai --skip-install\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/) for the default five skill agents, and mirrored into agent-specific dirs. If MCP was written, **restart your editor or reload MCP**. Zed may require trusting the worktree before project skills load. Have the agent read `DESIGN.md` (and `AGENTS.md`) before generating pages.\n\n### Create a new project\n\n```bash\n# Interactive: prompts for name, package manager, template\nnpx @morya-ui/setup --create\n\n# Explicit\nnpx @morya-ui/setup --create my-admin\nnpx @morya-ui/setup --create my-admin --template vue\nnpx @morya-ui/setup --create my-admin --pm npm\n\n# CI / non-interactive: all defaults\nnpx @morya-ui/setup --create my-admin --yes\n```\n\n`--create` runs: create-vite scaffold → `<pm> install` → full setup (equivalent to running `npx @morya-ui/setup` inside the new project).\n\n## Options\n\n| Flag | Meaning |\n| --- | --- |\n| `--create <name>` | Scaffold a new project via create-vite, then run the full setup inside it |\n| `--template <tpl>` | create-vite template: `vue-ts` (default) or `vue`; only used with `--create` |\n| `--cwd <dir>` | Target project root (default: cwd); with `--create`, the parent directory |\n| `--pm pnpm\\|yarn\\|npm` | Package manager |\n| `--skills <list>` | Comma-separated skill ids, or `all` (skips the prompt) |\n| `--editors <list>` | MCP targets: `cursor`, `vscode`, `zed`, or `all` (default: all three; always also writes `.mcp.json`) |\n| `--agents <list>` | Skill agents: `cursor`, `github-copilot`, `zed`, `claude-code`, `windsurf` (default), or `all` |\n| `--yes` / `-y` | Skip all interactive prompts and use defaults (CI-friendly) |\n| `--force` | Overwrite existing template files, MCP `morya-ui` entry, and skill-dir links |\n| `--dry-run` | Print actions only |\n| `--skip-install` | Skip install / upgrade of `morya-ui` and `@morya-ui/*` |\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. Dependencies are bumped to latest by default; pass `--skip-install` to leave them alone.\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.md` | Portable always-on checklist (VS Code / Zed / CLI agents) |\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| `.claude/skills/`, `.windsurf/skills/`, `.github/skills/` | Mirrors from `.agents/skills` (Claude Code / Windsurf / Copilot) |\n| `.cursor/rules/` | Cursor always-on rules |\n| `scripts/check-raw-colors.mjs` | Raw color scan |\n| `.cursor/mcp.json` | Cursor MCP |\n| `.vscode/mcp.json` | VS Code MCP |\n| `.zed/settings.json` | Zed `context_servers` (merged; other settings kept) |\n| `.mcp.json` | Portable MCP (Agent Host / cross-tool discovery) |\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- Dependencies: always install / upgrade `morya-ui@latest` and any existing `@morya-ui/*` to `@latest` unless `--skip-install`\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- MCP configs: merge other servers / settings; skip an existing `morya-ui` entry unless `--force`; new or forced entries use `@morya-ui/mcp@latest`\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",
|
|
32000
32782
|
"sections": [
|
|
32001
32783
|
{
|
|
32002
32784
|
"title": "",
|
|
32003
32785
|
"id": "overview",
|
|
32004
32786
|
"body": "# One-shot setup\n\n[`@morya-ui/setup`](https://www.npmjs.com/package/@morya-ui/setup) onboards a consumer Vue app to `morya-ui`: install the dependency, inject styles, and optionally write the Agent skill, Cursor rules, portable `AGENTS.md`, and multi-editor MCP. For manual install see [Quick start](/docs/quick-start). For AI page-generation workflow see [AI setup](/docs/ai-setup)."
|
|
32005
32787
|
},
|
|
32788
|
+
{
|
|
32789
|
+
"title": "Quick start",
|
|
32790
|
+
"id": "quick-start",
|
|
32791
|
+
"body": "### Configure an existing project\n\nFrom the app project root:\n\n```bash\nnpx @morya-ui/setup\n```\n\n### Create a new project from scratch\n\n```bash\nnpx @morya-ui/setup --create my-admin\n```\n\nScaffolds `./my-admin` via create-vite, installs dependencies, then applies the full setup (library + AI pack + MCP + styles) inside it.\n\n### Interactive mode\n\nRun without arguments in a terminal (TTY) and the CLI prompts for:\n\n1. **What to do** — configure current project, or create a new one\n2. **Project name** — when creating (with validation)\n3. **Package manager** — when creating (auto-detected default highlighted)\n4. **create-vite template** — `vue-ts` vs `vue`\n5. **Optional Agent skills** — `full` / `ai` modes\n\nEvery prompt has a sensible default — press Enter to accept. Pass `--yes` (or run in a non-TTY environment like CI) to skip all prompts and use defaults."
|
|
32792
|
+
},
|
|
32006
32793
|
{
|
|
32007
32794
|
"title": "Commands",
|
|
32008
32795
|
"id": "commands",
|
|
32009
|
-
"body": "
|
|
32796
|
+
"body": "By default this will:\n\n1. Install / upgrade `morya-ui` and any existing `@morya-ui/*` (e.g. `@morya-ui/nuxt`) to npm `latest` (pnpm / yarn / npm from the lockfile)\n2. Copy `DESIGN.md`, `AGENTS.md`, Agent skill, Cursor rules, and check scripts\n3. Merge MCP configs (Cursor / VS Code / Zed + root `.mcp.json`) for [`@morya-ui/mcp@latest`](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# Upgrade deps + styles only\nnpx @morya-ui/setup app\n\n# Upgrade deps + AI config + MCP (skips styles injection)\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# Subset of MCP editor targets (still writes .mcp.json)\nnpx @morya-ui/setup ai --editors=cursor,vscode\n\n# Narrow skill agents (default: cursor, github-copilot, zed, claude-code, windsurf)\nnpx @morya-ui/setup ai --agents=github-copilot,zed\n\n# Install companions to every skills-CLI agent (many dirs)\nnpx @morya-ui/setup ai --agents=all\n\n# Refresh AI template / MCP without touching dependencies\nnpx @morya-ui/setup ai --skip-install\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/) for the default five skill agents, and mirrored into agent-specific dirs. If MCP was written, **restart your editor or reload MCP**. Zed may require trusting the worktree before project skills load. Have the agent read `DESIGN.md` (and `AGENTS.md`) before generating pages.\n\n### Create a new project\n\n```bash\n# Interactive: prompts for name, package manager, template\nnpx @morya-ui/setup --create\n\n# Explicit\nnpx @morya-ui/setup --create my-admin\nnpx @morya-ui/setup --create my-admin --template vue\nnpx @morya-ui/setup --create my-admin --pm npm\n\n# CI / non-interactive: all defaults\nnpx @morya-ui/setup --create my-admin --yes\n```\n\n`--create` runs: create-vite scaffold → `<pm> install` → full setup (equivalent to running `npx @morya-ui/setup` inside the new project)."
|
|
32010
32797
|
},
|
|
32011
32798
|
{
|
|
32012
32799
|
"title": "Options",
|
|
32013
32800
|
"id": "options",
|
|
32014
|
-
"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| `--editors <list>` | MCP targets: `cursor`, `vscode`, `zed`, or `all` (default: all three; always also writes `.mcp.json`) |\n| `--agents <list>` | Skill agents: `cursor`, `github-copilot`, `zed`, `claude-code`, `windsurf` (default), or `all` |\n| `--yes` / `-y` |
|
|
32801
|
+
"body": "| Flag | Meaning |\n| --- | --- |\n| `--create <name>` | Scaffold a new project via create-vite, then run the full setup inside it |\n| `--template <tpl>` | create-vite template: `vue-ts` (default) or `vue`; only used with `--create` |\n| `--cwd <dir>` | Target project root (default: cwd); with `--create`, the parent directory |\n| `--pm pnpm\\|yarn\\|npm` | Package manager |\n| `--skills <list>` | Comma-separated skill ids, or `all` (skips the prompt) |\n| `--editors <list>` | MCP targets: `cursor`, `vscode`, `zed`, or `all` (default: all three; always also writes `.mcp.json`) |\n| `--agents <list>` | Skill agents: `cursor`, `github-copilot`, `zed`, `claude-code`, `windsurf` (default), or `all` |\n| `--yes` / `-y` | Skip all interactive prompts and use defaults (CI-friendly) |\n| `--force` | Overwrite existing template files, MCP `morya-ui` entry, and skill-dir links |\n| `--dry-run` | Print actions only |\n| `--skip-install` | Skip install / upgrade of `morya-ui` and `@morya-ui/*` |\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. Dependencies are bumped to latest by default; pass `--skip-install` to leave them alone.\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```"
|
|
32015
32802
|
},
|
|
32016
32803
|
{
|
|
32017
32804
|
"title": "What lands in the project",
|
|
@@ -32957,24 +33744,24 @@
|
|
|
32957
33744
|
"zh-CN": {
|
|
32958
33745
|
"title": "API 类型",
|
|
32959
33746
|
"description": "文档 Props 里常见类型名的结构与含义。",
|
|
32960
|
-
"markdown": "---\ntitle: API 类型\norder: 8\ndescription: 文档 Props 里常见类型名的结构与含义。\n---\n\n# API 类型\n\n组件文档 Props 表里出现的类型名,在这里查具体结构。包入口也导出同名类型,可在业务代码里 `import type { … } from 'morya-ui'`(以各组件 `types.ts` 为准)。\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\n单个 DOM 节点上要合并的属性 bag。`pt.<part>` 的值就是这个类型。\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\n常用键:`class`、`style`、`data-*`、`onClick` / `onKeydown`(Vue 事件监听写法)、以及该节点合法的原生 HTML 属性。\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\n单根容器(Card、Dialog 遮罩、Tabs 等):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch(可见根是 `<label>`,hidden input 单独一段):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // 一般是 label\n input?: PassThroughPart // 原生 input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\n表单字段(Input、Select、DatePicker 等):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // 外层 .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // 触发器 / 组合控件(Select 等)\n input?: PassThroughPart // 原生 input / textarea\n}\n```\n\n具体组件支持哪些键,见该组件文档的 **类型** 或 **pt** 小节。\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) 在 `FieldPassThrough` 基础上多了前后缀等:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) 在 `RootPassThrough` 上增加分隔条与面板:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\n分隔条外观也可用 `resizeTriggerClass` / `resizeTriggerStyle`,内容用 `#resize-trigger`(别名 `#gutter`)。\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\n控件尺寸,多数表单 / 按钮组件的 `size` prop:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` 为兼容别名;未传时通常继承 [ConfigProvider](/docs/config) 的 `size`。\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n输入框视觉变体:\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonType\">ButtonType</h3>\n\n按钮类型糖([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\n按钮颜色轴(Button、ConfirmDialog `acceptColor`、Dialog `positiveColor` 等):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\n按钮变体轴:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\n浮层 Teleport 挂载目标(Dialog、Select 菜单、Toast 等):\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'`(默认):挂到 document.body \n- `'self'`:不 Teleport,就地渲染 \n- 也常见 `appendTo: false`(运行时兼容,同 `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\n关闭 / 确认前的拦截函数。返回 `false`(含 Promise 解析为 `false`)则**不继续**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\n用于 Dialog `beforeClose`、`onPositiveClick`,ConfirmDialog / ConfirmPopup 的 `beforeAccept` 等。\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) 选项项:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) 选项分组(混入 `options` 渲染分组标题行):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\n单选为标量;`multiple` 时为数组。\n\n<h3 id=\"IconName\">IconName</h3>\n\n[`MIcon`](/components/Icon) / [`Button`](/components/Button) 的 `icon` / `name` 使用的注册名,例如 `'search'`、`'chevron-down'`。完整列表见 Icon 文档注册表。\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nMenu / Dropdown / ContextMenu 等导航项的公共字段:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MToneType\">MToneType</h3>\n\n显示 / 反馈组件的语义色基集:\n\n```ts\ntype MToneType =\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MTagType\">MTagType</h3>\n\nTag / Badge / Chip / Status:`MToneType` 加上品牌色 `primary`。\n\n```ts\ntype MTagType = MToneType | 'primary'\n```\n\n<h3 id=\"MToastType\">MToastType</h3>\n\nMessage / Toast / Timeline 的语义色:\n\n```ts\ntype MToastType =\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'secondary'\n | 'contrast'\n```\n\n---\n\n更细的组件专属类型(如 `TableServerOptions`、`MenuItem`)写在对应组件页 **类型** 小节;这里只列跨组件复用的名字。\n",
|
|
33747
|
+
"markdown": "---\ntitle: API 类型\norder: 8\ndescription: 文档 Props 里常见类型名的结构与含义。\n---\n\n# API 类型\n\n组件文档 Props 表里出现的类型名,在这里查具体结构。包入口也导出同名类型,可在业务代码里 `import type { … } from 'morya-ui'`(以各组件 `types.ts` 为准)。\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\n单个 DOM 节点上要合并的属性 bag。`pt.<part>` 的值就是这个类型。\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\n常用键:`class`、`style`、`data-*`、`onClick` / `onKeydown`(Vue 事件监听写法)、以及该节点合法的原生 HTML 属性。\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\n单根容器(Card、Dialog 遮罩、Tabs 等):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch(可见根是 `<label>`,hidden input 单独一段):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // 一般是 label\n input?: PassThroughPart // 原生 input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\n表单字段(Input、Select、DatePicker 等):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // 外层 .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // 触发器 / 组合控件(Select 等)\n input?: PassThroughPart // 原生 input / textarea\n}\n```\n\n具体组件支持哪些键,见该组件文档的 **类型** 或 **pt** 小节。\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) 在 `FieldPassThrough` 基础上多了前后缀等:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) 在 `RootPassThrough` 上增加分隔条与面板:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\n分隔条外观也可用 `resizeTriggerClass` / `resizeTriggerStyle`,内容用 `#resize-trigger`(别名 `#gutter`)。\n\n<h3 id=\"OrderListPassThrough\">OrderListPassThrough</h3>\n\n[`OrderList`](/components/order-list) 在 `RootPassThrough` 上增加按钮组与列表项:\n\n```ts\ntype OrderListPassThrough = RootPassThrough & {\n controls?: PassThroughPart // 左侧按钮组\n list?: PassThroughPart // 滚动列表\n item?: PassThroughPart // 单个列表项\n handle?: PassThroughPart // 拖拽手柄\n label?: PassThroughPart // 项文本容器\n}\n```\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\n控件尺寸,多数表单 / 按钮组件的 `size` prop:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` 为兼容别名;未传时通常继承 [ConfigProvider](/docs/config) 的 `size`。\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n输入框视觉变体:\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonType\">ButtonType</h3>\n\n按钮类型糖([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\n按钮颜色轴(Button、ConfirmDialog `acceptColor`、Dialog `positiveColor` 等):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\n按钮变体轴:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\n浮层 Teleport 挂载目标(Dialog、Select 菜单、Toast 等):\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'`(默认):挂到 document.body \n- `'self'`:不 Teleport,就地渲染 \n- 也常见 `appendTo: false`(运行时兼容,同 `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\n关闭 / 确认前的拦截函数。返回 `false`(含 Promise 解析为 `false`)则**不继续**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\n用于 Dialog `beforeClose`、`onPositiveClick`,ConfirmDialog / ConfirmPopup 的 `beforeAccept` 等。\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) 选项项:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) 选项分组(混入 `options` 渲染分组标题行):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\n单选为标量;`multiple` 时为数组。\n\n<h3 id=\"IconName\">IconName</h3>\n\n[`MIcon`](/components/Icon) / [`Button`](/components/Button) 的 `icon` / `name` 使用的注册名,例如 `'search'`、`'chevron-down'`。完整列表见 Icon 文档注册表。\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nMenu / Dropdown / ContextMenu 等导航项的公共字段:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MToneType\">MToneType</h3>\n\n显示 / 反馈组件的语义色基集:\n\n```ts\ntype MToneType =\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MTagType\">MTagType</h3>\n\nTag / Badge / Chip / Status:`MToneType` 加上品牌色 `primary`。\n\n```ts\ntype MTagType = MToneType | 'primary'\n```\n\n<h3 id=\"MToastType\">MToastType</h3>\n\nMessage / Toast / Timeline 的语义色:\n\n```ts\ntype MToastType =\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'secondary'\n | 'contrast'\n```\n\n---\n\n更细的组件专属类型(如 `TableServerOptions`、`MenuItem`)写在对应组件页 **类型** 小节;这里只列跨组件复用的名字。\n",
|
|
32961
33748
|
"sections": [
|
|
32962
33749
|
{
|
|
32963
33750
|
"title": "",
|
|
32964
33751
|
"id": "overview",
|
|
32965
|
-
"body": "# API 类型\n\n组件文档 Props 表里出现的类型名,在这里查具体结构。包入口也导出同名类型,可在业务代码里 `import type { … } from 'morya-ui'`(以各组件 `types.ts` 为准)。\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\n单个 DOM 节点上要合并的属性 bag。`pt.<part>` 的值就是这个类型。\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\n常用键:`class`、`style`、`data-*`、`onClick` / `onKeydown`(Vue 事件监听写法)、以及该节点合法的原生 HTML 属性。\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\n单根容器(Card、Dialog 遮罩、Tabs 等):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch(可见根是 `<label>`,hidden input 单独一段):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // 一般是 label\n input?: PassThroughPart // 原生 input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\n表单字段(Input、Select、DatePicker 等):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // 外层 .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // 触发器 / 组合控件(Select 等)\n input?: PassThroughPart // 原生 input / textarea\n}\n```\n\n具体组件支持哪些键,见该组件文档的 **类型** 或 **pt** 小节。\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) 在 `FieldPassThrough` 基础上多了前后缀等:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) 在 `RootPassThrough` 上增加分隔条与面板:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\n分隔条外观也可用 `resizeTriggerClass` / `resizeTriggerStyle`,内容用 `#resize-trigger`(别名 `#gutter`)。\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\n控件尺寸,多数表单 / 按钮组件的 `size` prop:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` 为兼容别名;未传时通常继承 [ConfigProvider](/docs/config) 的 `size`。\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n输入框视觉变体:\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonType\">ButtonType</h3>\n\n按钮类型糖([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\n按钮颜色轴(Button、ConfirmDialog `acceptColor`、Dialog `positiveColor` 等):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\n按钮变体轴:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\n浮层 Teleport 挂载目标(Dialog、Select 菜单、Toast 等):\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'`(默认):挂到 document.body \n- `'self'`:不 Teleport,就地渲染 \n- 也常见 `appendTo: false`(运行时兼容,同 `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\n关闭 / 确认前的拦截函数。返回 `false`(含 Promise 解析为 `false`)则**不继续**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\n用于 Dialog `beforeClose`、`onPositiveClick`,ConfirmDialog / ConfirmPopup 的 `beforeAccept` 等。\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) 选项项:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) 选项分组(混入 `options` 渲染分组标题行):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\n单选为标量;`multiple` 时为数组。\n\n<h3 id=\"IconName\">IconName</h3>\n\n[`MIcon`](/components/Icon) / [`Button`](/components/Button) 的 `icon` / `name` 使用的注册名,例如 `'search'`、`'chevron-down'`。完整列表见 Icon 文档注册表。\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nMenu / Dropdown / ContextMenu 等导航项的公共字段:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MToneType\">MToneType</h3>\n\n显示 / 反馈组件的语义色基集:\n\n```ts\ntype MToneType =\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MTagType\">MTagType</h3>\n\nTag / Badge / Chip / Status:`MToneType` 加上品牌色 `primary`。\n\n```ts\ntype MTagType = MToneType | 'primary'\n```\n\n<h3 id=\"MToastType\">MToastType</h3>\n\nMessage / Toast / Timeline 的语义色:\n\n```ts\ntype MToastType =\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'secondary'\n | 'contrast'\n```\n\n---\n\n更细的组件专属类型(如 `TableServerOptions`、`MenuItem`)写在对应组件页 **类型** 小节;这里只列跨组件复用的名字。"
|
|
33752
|
+
"body": "# API 类型\n\n组件文档 Props 表里出现的类型名,在这里查具体结构。包入口也导出同名类型,可在业务代码里 `import type { … } from 'morya-ui'`(以各组件 `types.ts` 为准)。\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\n单个 DOM 节点上要合并的属性 bag。`pt.<part>` 的值就是这个类型。\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\n常用键:`class`、`style`、`data-*`、`onClick` / `onKeydown`(Vue 事件监听写法)、以及该节点合法的原生 HTML 属性。\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\n单根容器(Card、Dialog 遮罩、Tabs 等):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch(可见根是 `<label>`,hidden input 单独一段):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // 一般是 label\n input?: PassThroughPart // 原生 input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\n表单字段(Input、Select、DatePicker 等):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // 外层 .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // 触发器 / 组合控件(Select 等)\n input?: PassThroughPart // 原生 input / textarea\n}\n```\n\n具体组件支持哪些键,见该组件文档的 **类型** 或 **pt** 小节。\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) 在 `FieldPassThrough` 基础上多了前后缀等:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) 在 `RootPassThrough` 上增加分隔条与面板:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\n分隔条外观也可用 `resizeTriggerClass` / `resizeTriggerStyle`,内容用 `#resize-trigger`(别名 `#gutter`)。\n\n<h3 id=\"OrderListPassThrough\">OrderListPassThrough</h3>\n\n[`OrderList`](/components/order-list) 在 `RootPassThrough` 上增加按钮组与列表项:\n\n```ts\ntype OrderListPassThrough = RootPassThrough & {\n controls?: PassThroughPart // 左侧按钮组\n list?: PassThroughPart // 滚动列表\n item?: PassThroughPart // 单个列表项\n handle?: PassThroughPart // 拖拽手柄\n label?: PassThroughPart // 项文本容器\n}\n```\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\n控件尺寸,多数表单 / 按钮组件的 `size` prop:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` 为兼容别名;未传时通常继承 [ConfigProvider](/docs/config) 的 `size`。\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n输入框视觉变体:\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonType\">ButtonType</h3>\n\n按钮类型糖([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\n按钮颜色轴(Button、ConfirmDialog `acceptColor`、Dialog `positiveColor` 等):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\n按钮变体轴:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\n浮层 Teleport 挂载目标(Dialog、Select 菜单、Toast 等):\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'`(默认):挂到 document.body \n- `'self'`:不 Teleport,就地渲染 \n- 也常见 `appendTo: false`(运行时兼容,同 `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\n关闭 / 确认前的拦截函数。返回 `false`(含 Promise 解析为 `false`)则**不继续**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\n用于 Dialog `beforeClose`、`onPositiveClick`,ConfirmDialog / ConfirmPopup 的 `beforeAccept` 等。\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) 选项项:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) 选项分组(混入 `options` 渲染分组标题行):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\n单选为标量;`multiple` 时为数组。\n\n<h3 id=\"IconName\">IconName</h3>\n\n[`MIcon`](/components/Icon) / [`Button`](/components/Button) 的 `icon` / `name` 使用的注册名,例如 `'search'`、`'chevron-down'`。完整列表见 Icon 文档注册表。\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nMenu / Dropdown / ContextMenu 等导航项的公共字段:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MToneType\">MToneType</h3>\n\n显示 / 反馈组件的语义色基集:\n\n```ts\ntype MToneType =\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MTagType\">MTagType</h3>\n\nTag / Badge / Chip / Status:`MToneType` 加上品牌色 `primary`。\n\n```ts\ntype MTagType = MToneType | 'primary'\n```\n\n<h3 id=\"MToastType\">MToastType</h3>\n\nMessage / Toast / Timeline 的语义色:\n\n```ts\ntype MToastType =\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'secondary'\n | 'contrast'\n```\n\n---\n\n更细的组件专属类型(如 `TableServerOptions`、`MenuItem`)写在对应组件页 **类型** 小节;这里只列跨组件复用的名字。"
|
|
32966
33753
|
}
|
|
32967
33754
|
]
|
|
32968
33755
|
},
|
|
32969
33756
|
"en-US": {
|
|
32970
33757
|
"title": "API types",
|
|
32971
33758
|
"description": "Shapes behind type names in component Props tables.",
|
|
32972
|
-
"markdown": "---\ntitle: API types\norder: 8\ndescription: Shapes behind type names in component Props tables.\n---\n\n# API types\n\nLook up structures for names that appear in Props tables. The package re-exports the same names as TypeScript types (`import type { … } from 'morya-ui'`), per component `types.ts`.\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\nAttribute bag merged onto one DOM node—the value of `pt.<part>`.\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\nCommon keys: `class`, `style`, `data-*`, `onClick` / `onKeydown`, and valid native attributes for that element.\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\nSingle-root containers (Card, Dialog backdrop, Tabs, …):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch (visible `<label>` root + hidden input):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // usually the label\n input?: PassThroughPart // native input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\nForm fields (Input, Select, DatePicker, …):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // outer .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // trigger / composite control\n input?: PassThroughPart // native input / textarea\n}\n```\n\nWhich keys a component accepts is listed on that component’s **Types** or **pt** section.\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) extends `FieldPassThrough` with affixes:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) extends `RootPassThrough` with gutter and panes:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\nGutter look can also use `resizeTriggerClass` / `resizeTriggerStyle`; content goes in `#resize-trigger` (alias `#gutter`).\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\nControl size for many form / button props:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` are legacy aliases. Omitted `size` usually inherits [ConfigProvider](/docs/config).\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonType\">ButtonType</h3>\n\nButton type sugar ([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\nButton color axis (Button, ConfirmDialog `acceptColor`, Dialog `positiveColor`, …):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\nButton variant axis:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\nOverlay Teleport target:\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'` (default) \n- `'self'` — render in place (no Teleport) \n- `false` is accepted at runtime (same idea as `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\nGuard before close / confirm. Return `false` (including from a Promise) to **abort**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\nUsed by Dialog `beforeClose`, ConfirmDialog `beforeAccept`, and similar.\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) option row:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) option group (mix into `options` to render a group header row):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\nScalar when single-select; array when `multiple`.\n\n<h3 id=\"IconName\">IconName</h3>\n\nRegistered icon id for [`MIcon`](/components/Icon) / [`Button`](/components/Button), e.g. `'search'`. See the Icon registry.\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nShared fields for Menu / Dropdown / ContextMenu items:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MToneType\">MToneType</h3>\n\nBase semantic tones for display / feedback components:\n\n```ts\ntype MToneType =\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MTagType\">MTagType</h3>\n\nTag / Badge / Chip / Status: `MToneType` plus brand `primary`.\n\n```ts\ntype MTagType = MToneType | 'primary'\n```\n\n<h3 id=\"MToastType\">MToastType</h3>\n\nMessage / Toast / Timeline tones:\n\n```ts\ntype MToastType =\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'secondary'\n | 'contrast'\n```\n\n---\n\nComponent-only types (`TableServerOptions`, `MenuItem`, …) live under each component’s **Types** section; this page is for shared names only.\n",
|
|
33759
|
+
"markdown": "---\ntitle: API types\norder: 8\ndescription: Shapes behind type names in component Props tables.\n---\n\n# API types\n\nLook up structures for names that appear in Props tables. The package re-exports the same names as TypeScript types (`import type { … } from 'morya-ui'`), per component `types.ts`.\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\nAttribute bag merged onto one DOM node—the value of `pt.<part>`.\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\nCommon keys: `class`, `style`, `data-*`, `onClick` / `onKeydown`, and valid native attributes for that element.\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\nSingle-root containers (Card, Dialog backdrop, Tabs, …):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch (visible `<label>` root + hidden input):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // usually the label\n input?: PassThroughPart // native input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\nForm fields (Input, Select, DatePicker, …):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // outer .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // trigger / composite control\n input?: PassThroughPart // native input / textarea\n}\n```\n\nWhich keys a component accepts is listed on that component’s **Types** or **pt** section.\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) extends `FieldPassThrough` with affixes:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) extends `RootPassThrough` with gutter and panes:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\nGutter look can also use `resizeTriggerClass` / `resizeTriggerStyle`; content goes in `#resize-trigger` (alias `#gutter`).\n\n<h3 id=\"OrderListPassThrough\">OrderListPassThrough</h3>\n\n[`OrderList`](/components/order-list) extends `RootPassThrough` with the button group and list items:\n\n```ts\ntype OrderListPassThrough = RootPassThrough & {\n controls?: PassThroughPart // left button group\n list?: PassThroughPart // scrollable list\n item?: PassThroughPart // single item\n handle?: PassThroughPart // drag handle\n label?: PassThroughPart // item label container\n}\n```\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\nControl size for many form / button props:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` are legacy aliases. Omitted `size` usually inherits [ConfigProvider](/docs/config).\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonType\">ButtonType</h3>\n\nButton type sugar ([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\nButton color axis (Button, ConfirmDialog `acceptColor`, Dialog `positiveColor`, …):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\nButton variant axis:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\nOverlay Teleport target:\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'` (default) \n- `'self'` — render in place (no Teleport) \n- `false` is accepted at runtime (same idea as `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\nGuard before close / confirm. Return `false` (including from a Promise) to **abort**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\nUsed by Dialog `beforeClose`, ConfirmDialog `beforeAccept`, and similar.\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) option row:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) option group (mix into `options` to render a group header row):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\nScalar when single-select; array when `multiple`.\n\n<h3 id=\"IconName\">IconName</h3>\n\nRegistered icon id for [`MIcon`](/components/Icon) / [`Button`](/components/Button), e.g. `'search'`. See the Icon registry.\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nShared fields for Menu / Dropdown / ContextMenu items:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MToneType\">MToneType</h3>\n\nBase semantic tones for display / feedback components:\n\n```ts\ntype MToneType =\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MTagType\">MTagType</h3>\n\nTag / Badge / Chip / Status: `MToneType` plus brand `primary`.\n\n```ts\ntype MTagType = MToneType | 'primary'\n```\n\n<h3 id=\"MToastType\">MToastType</h3>\n\nMessage / Toast / Timeline tones:\n\n```ts\ntype MToastType =\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'secondary'\n | 'contrast'\n```\n\n---\n\nComponent-only types (`TableServerOptions`, `MenuItem`, …) live under each component’s **Types** section; this page is for shared names only.\n",
|
|
32973
33760
|
"sections": [
|
|
32974
33761
|
{
|
|
32975
33762
|
"title": "",
|
|
32976
33763
|
"id": "overview",
|
|
32977
|
-
"body": "# API types\n\nLook up structures for names that appear in Props tables. The package re-exports the same names as TypeScript types (`import type { … } from 'morya-ui'`), per component `types.ts`.\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\nAttribute bag merged onto one DOM node—the value of `pt.<part>`.\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\nCommon keys: `class`, `style`, `data-*`, `onClick` / `onKeydown`, and valid native attributes for that element.\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\nSingle-root containers (Card, Dialog backdrop, Tabs, …):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch (visible `<label>` root + hidden input):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // usually the label\n input?: PassThroughPart // native input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\nForm fields (Input, Select, DatePicker, …):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // outer .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // trigger / composite control\n input?: PassThroughPart // native input / textarea\n}\n```\n\nWhich keys a component accepts is listed on that component’s **Types** or **pt** section.\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) extends `FieldPassThrough` with affixes:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) extends `RootPassThrough` with gutter and panes:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\nGutter look can also use `resizeTriggerClass` / `resizeTriggerStyle`; content goes in `#resize-trigger` (alias `#gutter`).\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\nControl size for many form / button props:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` are legacy aliases. Omitted `size` usually inherits [ConfigProvider](/docs/config).\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonType\">ButtonType</h3>\n\nButton type sugar ([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\nButton color axis (Button, ConfirmDialog `acceptColor`, Dialog `positiveColor`, …):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\nButton variant axis:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\nOverlay Teleport target:\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'` (default) \n- `'self'` — render in place (no Teleport) \n- `false` is accepted at runtime (same idea as `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\nGuard before close / confirm. Return `false` (including from a Promise) to **abort**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\nUsed by Dialog `beforeClose`, ConfirmDialog `beforeAccept`, and similar.\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) option row:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) option group (mix into `options` to render a group header row):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\nScalar when single-select; array when `multiple`.\n\n<h3 id=\"IconName\">IconName</h3>\n\nRegistered icon id for [`MIcon`](/components/Icon) / [`Button`](/components/Button), e.g. `'search'`. See the Icon registry.\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nShared fields for Menu / Dropdown / ContextMenu items:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MToneType\">MToneType</h3>\n\nBase semantic tones for display / feedback components:\n\n```ts\ntype MToneType =\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MTagType\">MTagType</h3>\n\nTag / Badge / Chip / Status: `MToneType` plus brand `primary`.\n\n```ts\ntype MTagType = MToneType | 'primary'\n```\n\n<h3 id=\"MToastType\">MToastType</h3>\n\nMessage / Toast / Timeline tones:\n\n```ts\ntype MToastType =\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'secondary'\n | 'contrast'\n```\n\n---\n\nComponent-only types (`TableServerOptions`, `MenuItem`, …) live under each component’s **Types** section; this page is for shared names only."
|
|
33764
|
+
"body": "# API types\n\nLook up structures for names that appear in Props tables. The package re-exports the same names as TypeScript types (`import type { … } from 'morya-ui'`), per component `types.ts`.\n\n<h3 id=\"PassThroughPart\">PassThroughPart</h3>\n\nAttribute bag merged onto one DOM node—the value of `pt.<part>`.\n\n```ts\ntype PassThroughPart = Record<string, unknown>\n```\n\nCommon keys: `class`, `style`, `data-*`, `onClick` / `onKeydown`, and valid native attributes for that element.\n\n<h3 id=\"RootPassThrough\">RootPassThrough</h3>\n\nSingle-root containers (Card, Dialog backdrop, Tabs, …):\n\n```ts\ninterface RootPassThrough {\n root?: PassThroughPart\n}\n```\n\n<h3 id=\"ControlPassThrough\">ControlPassThrough</h3>\n\nCheckbox / Radio / Switch (visible `<label>` root + hidden input):\n\n```ts\ninterface ControlPassThrough {\n root?: PassThroughPart // usually the label\n input?: PassThroughPart // native input\n}\n```\n\n<h3 id=\"FieldPassThrough\">FieldPassThrough</h3>\n\nForm fields (Input, Select, DatePicker, …):\n\n```ts\ninterface FieldPassThrough {\n root?: PassThroughPart // outer .m-*-field\n label?: PassThroughPart\n control?: PassThroughPart // trigger / composite control\n input?: PassThroughPart // native input / textarea\n}\n```\n\nWhich keys a component accepts is listed on that component’s **Types** or **pt** section.\n\n<h3 id=\"InputPassThrough\">InputPassThrough</h3>\n\n[`Input`](/components/Input) extends `FieldPassThrough` with affixes:\n\n```ts\ntype InputPassThrough = FieldPassThrough & {\n prefix?: PassThroughPart\n suffix?: PassThroughPart\n help?: PassThroughPart\n count?: PassThroughPart\n}\n```\n\n<h3 id=\"SplitterPassThrough\">SplitterPassThrough</h3>\n\n[`Splitter`](/components/Splitter) extends `RootPassThrough` with gutter and panes:\n\n```ts\ntype SplitterPassThrough = RootPassThrough & {\n gutter?: PassThroughPart\n panel1?: PassThroughPart\n panel2?: PassThroughPart\n}\n```\n\nGutter look can also use `resizeTriggerClass` / `resizeTriggerStyle`; content goes in `#resize-trigger` (alias `#gutter`).\n\n<h3 id=\"OrderListPassThrough\">OrderListPassThrough</h3>\n\n[`OrderList`](/components/order-list) extends `RootPassThrough` with the button group and list items:\n\n```ts\ntype OrderListPassThrough = RootPassThrough & {\n controls?: PassThroughPart // left button group\n list?: PassThroughPart // scrollable list\n item?: PassThroughPart // single item\n handle?: PassThroughPart // drag handle\n label?: PassThroughPart // item label container\n}\n```\n\n<h3 id=\"MSizeInput\">MSizeInput</h3>\n\nControl size for many form / button props:\n\n```ts\ntype MSizeInput = 'small' | 'medium' | 'large' | 'sm' | 'md' | 'lg'\n```\n\n`sm` / `md` / `lg` are legacy aliases. Omitted `size` usually inherits [ConfigProvider](/docs/config).\n\n<h3 id=\"MInputVariant\">MInputVariant</h3>\n\n```ts\ntype MInputVariant = 'outlined' | 'filled'\n```\n\n<h3 id=\"ButtonType\">ButtonType</h3>\n\nButton type sugar ([`Button`](/components/Button)):\n\n```ts\ntype ButtonType = 'default' | 'primary' | 'dashed' | 'link' | 'text'\n```\n\n<h3 id=\"ButtonColor\">ButtonColor</h3>\n\nButton color axis (Button, ConfirmDialog `acceptColor`, Dialog `positiveColor`, …):\n\n```ts\ntype ButtonColor =\n | 'default'\n | 'primary'\n | 'danger'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'contrast'\n | 'link'\n```\n\n<h3 id=\"ButtonVariant\">ButtonVariant</h3>\n\nButton variant axis:\n\n```ts\ntype ButtonVariant = 'solid' | 'outlined' | 'dashed' | 'filled' | 'text' | 'link'\n```\n\n<h3 id=\"MAppendTo\">MAppendTo</h3>\n\nOverlay Teleport target:\n\n```ts\ntype MAppendTo = string | HTMLElement | 'self'\n```\n\n- `'body'` (default) \n- `'self'` — render in place (no Teleport) \n- `false` is accepted at runtime (same idea as `'self'`)\n\n<h3 id=\"AsyncGuard\">AsyncGuard</h3>\n\nGuard before close / confirm. Return `false` (including from a Promise) to **abort**:\n\n```ts\ntype AsyncGuard<T extends unknown[] = []> = (\n ...args: T\n) => unknown | Promise<unknown>\n```\n\nUsed by Dialog `beforeClose`, ConfirmDialog `beforeAccept`, and similar.\n\n<h3 id=\"SelectOption\">SelectOption</h3>\n\n[`Select`](/components/Select) option row:\n\n```ts\ninterface SelectOption {\n label: string\n value: string | number\n disabled?: boolean\n}\n```\n\n<h3 id=\"SelectOptionGroup\">SelectOptionGroup</h3>\n\n[`Select`](/components/Select) option group (mix into `options` to render a group header row):\n\n```ts\ninterface SelectOptionGroup {\n label: string\n items: SelectOption[]\n}\n```\n\n<h3 id=\"SelectModelValue\">SelectModelValue</h3>\n\n```ts\ntype SelectValue = string | number\ntype SelectModelValue = SelectValue | SelectValue[] | undefined\n```\n\nScalar when single-select; array when `multiple`.\n\n<h3 id=\"IconName\">IconName</h3>\n\nRegistered icon id for [`MIcon`](/components/Icon) / [`Button`](/components/Button), e.g. `'search'`. See the Icon registry.\n\n<h3 id=\"MenuNodeBase\">MenuNodeBase</h3>\n\nShared fields for Menu / Dropdown / ContextMenu items:\n\n```ts\ninterface MenuNodeBase {\n key?: string\n label?: string\n value?: string\n icon?: string\n disabled?: boolean\n separator?: boolean\n shortcut?: string\n command?: () => void\n items?: MenuNodeBase[]\n}\n```\n\n<h3 id=\"MToneType\">MToneType</h3>\n\nBase semantic tones for display / feedback components:\n\n```ts\ntype MToneType =\n | 'secondary'\n | 'success'\n | 'info'\n | 'warning'\n | 'help'\n | 'danger'\n | 'contrast'\n```\n\n<h3 id=\"MTagType\">MTagType</h3>\n\nTag / Badge / Chip / Status: `MToneType` plus brand `primary`.\n\n```ts\ntype MTagType = MToneType | 'primary'\n```\n\n<h3 id=\"MToastType\">MToastType</h3>\n\nMessage / Toast / Timeline tones:\n\n```ts\ntype MToastType =\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'\n | 'secondary'\n | 'contrast'\n```\n\n---\n\nComponent-only types (`TableServerOptions`, `MenuItem`, …) live under each component’s **Types** section; this page is for shared names only."
|
|
32978
33765
|
}
|
|
32979
33766
|
]
|
|
32980
33767
|
}
|