@morya-ui/mcp 0.4.4 → 0.5.0
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/LICENSE +21 -21
- package/README.md +154 -154
- package/bin/morya-ui-mcp.js +2 -2
- package/data/catalog.json +1368 -413
- package/data/example-coverage.json +78 -73
- package/data/golden-pages/dashboard-page.vue +161 -161
- package/data/golden-pages/detail-page.vue +147 -147
- package/data/golden-pages/empty-state.vue +56 -56
- package/data/golden-pages/form-in-dialog.vue +166 -166
- package/data/golden-pages/form-page.vue +107 -107
- package/data/golden-pages/landing-page.vue +382 -382
- package/data/golden-pages/list-page-dense.vue +168 -168
- package/data/golden-pages/list-page-rail.vue +272 -272
- package/data/golden-pages/list-page.vue +222 -222
- package/data/golden-pages/login-page.vue +244 -244
- package/data/golden-pages/result-page.vue +84 -84
- package/data/golden-pages/settings-page.vue +163 -163
- package/data/golden-pages/wizard-form.vue +167 -167
- package/dist/decisions.js +1299 -6
- package/dist/page-snippets.js +669 -669
- package/dist/style-shells.js +153 -153
- package/dist/tools.js +192 -192
- package/package.json +1 -1
package/data/catalog.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-10-
|
|
2
|
+
"generatedAt": "2026-10-13T08:55:20.652Z",
|
|
3
3
|
"library": {
|
|
4
4
|
"name": "morya-ui",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.5.0"
|
|
6
6
|
},
|
|
7
7
|
"mcp": {
|
|
8
8
|
"name": "@morya-ui/mcp",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.5.0"
|
|
10
10
|
},
|
|
11
11
|
"components": [
|
|
12
12
|
{
|
|
@@ -4414,6 +4414,419 @@
|
|
|
4414
4414
|
}
|
|
4415
4415
|
}
|
|
4416
4416
|
},
|
|
4417
|
+
{
|
|
4418
|
+
"id": "ColorPicker",
|
|
4419
|
+
"name": "ColorPicker",
|
|
4420
|
+
"exportName": "MColorPicker",
|
|
4421
|
+
"category": "02 / FORM",
|
|
4422
|
+
"description": "颜色选择器,支持面板取色、透明度与预设色板。",
|
|
4423
|
+
"descriptionEn": "Color picker with panel, alpha, and preset swatches.",
|
|
4424
|
+
"import": "import { MColorPicker } from 'morya-ui'",
|
|
4425
|
+
"props": [
|
|
4426
|
+
{
|
|
4427
|
+
"name": "modelValue",
|
|
4428
|
+
"type": "string",
|
|
4429
|
+
"default": "'#1677ff'",
|
|
4430
|
+
"description": "当前颜色值(hex)或 CSS 渐变字符串。"
|
|
4431
|
+
},
|
|
4432
|
+
{
|
|
4433
|
+
"name": "gradient",
|
|
4434
|
+
"type": "boolean",
|
|
4435
|
+
"default": "false",
|
|
4436
|
+
"description": "启用渐变色模式。"
|
|
4437
|
+
},
|
|
4438
|
+
{
|
|
4439
|
+
"name": "disabled",
|
|
4440
|
+
"type": "boolean",
|
|
4441
|
+
"default": "false",
|
|
4442
|
+
"description": "禁用。"
|
|
4443
|
+
},
|
|
4444
|
+
{
|
|
4445
|
+
"name": "disabledAlpha",
|
|
4446
|
+
"type": "boolean",
|
|
4447
|
+
"default": "false",
|
|
4448
|
+
"description": "禁用透明度调节。"
|
|
4449
|
+
},
|
|
4450
|
+
{
|
|
4451
|
+
"name": "allowClear",
|
|
4452
|
+
"type": "boolean",
|
|
4453
|
+
"default": "false",
|
|
4454
|
+
"description": "显示清空按钮。"
|
|
4455
|
+
},
|
|
4456
|
+
{
|
|
4457
|
+
"name": "format",
|
|
4458
|
+
"type": "'hex' | 'rgb' | 'hsb'",
|
|
4459
|
+
"default": "'hex'",
|
|
4460
|
+
"description": "显示格式。"
|
|
4461
|
+
},
|
|
4462
|
+
{
|
|
4463
|
+
"name": "presets",
|
|
4464
|
+
"type": "ColorPickerPreset[]",
|
|
4465
|
+
"default": "—",
|
|
4466
|
+
"description": "预设色板。"
|
|
4467
|
+
},
|
|
4468
|
+
{
|
|
4469
|
+
"name": "showText",
|
|
4470
|
+
"type": "boolean",
|
|
4471
|
+
"default": "false",
|
|
4472
|
+
"description": "在触发器中显示颜色文本。"
|
|
4473
|
+
},
|
|
4474
|
+
{
|
|
4475
|
+
"name": "size",
|
|
4476
|
+
"type": "MSizeInput",
|
|
4477
|
+
"default": "—",
|
|
4478
|
+
"description": "尺寸。"
|
|
4479
|
+
},
|
|
4480
|
+
{
|
|
4481
|
+
"name": "placement",
|
|
4482
|
+
"type": "ColorPickerPlacement",
|
|
4483
|
+
"default": "'bottom-start'",
|
|
4484
|
+
"description": "弹层位置。"
|
|
4485
|
+
},
|
|
4486
|
+
{
|
|
4487
|
+
"name": "teleport",
|
|
4488
|
+
"type": "boolean",
|
|
4489
|
+
"default": "true",
|
|
4490
|
+
"description": "是否 teleport 到 body。"
|
|
4491
|
+
},
|
|
4492
|
+
{
|
|
4493
|
+
"name": "appendTo",
|
|
4494
|
+
"type": "MAppendTo",
|
|
4495
|
+
"default": "'body'",
|
|
4496
|
+
"description": "挂载目标。"
|
|
4497
|
+
},
|
|
4498
|
+
{
|
|
4499
|
+
"name": "transition",
|
|
4500
|
+
"type": "MotionPresetId | false",
|
|
4501
|
+
"default": "—",
|
|
4502
|
+
"description": "过渡动画。"
|
|
4503
|
+
},
|
|
4504
|
+
{
|
|
4505
|
+
"name": "pt",
|
|
4506
|
+
"type": "FieldPassThrough",
|
|
4507
|
+
"default": "—",
|
|
4508
|
+
"description": "DOM 透传。"
|
|
4509
|
+
},
|
|
4510
|
+
{
|
|
4511
|
+
"name": "label",
|
|
4512
|
+
"type": "string",
|
|
4513
|
+
"description": "分组标签。"
|
|
4514
|
+
},
|
|
4515
|
+
{
|
|
4516
|
+
"name": "colors",
|
|
4517
|
+
"type": "string[]",
|
|
4518
|
+
"description": "颜色数组。"
|
|
4519
|
+
},
|
|
4520
|
+
{
|
|
4521
|
+
"name": "defaultOpen",
|
|
4522
|
+
"type": "boolean",
|
|
4523
|
+
"description": "默认展开。"
|
|
4524
|
+
}
|
|
4525
|
+
],
|
|
4526
|
+
"events": [
|
|
4527
|
+
{
|
|
4528
|
+
"name": "update:modelValue",
|
|
4529
|
+
"payload": "string",
|
|
4530
|
+
"description": "颜色变化。"
|
|
4531
|
+
},
|
|
4532
|
+
{
|
|
4533
|
+
"name": "change",
|
|
4534
|
+
"payload": "string",
|
|
4535
|
+
"description": "颜色变化(同 `update:modelValue`)。"
|
|
4536
|
+
},
|
|
4537
|
+
{
|
|
4538
|
+
"name": "clear",
|
|
4539
|
+
"payload": "—",
|
|
4540
|
+
"description": "点击清空。"
|
|
4541
|
+
},
|
|
4542
|
+
{
|
|
4543
|
+
"name": "show",
|
|
4544
|
+
"payload": "—",
|
|
4545
|
+
"description": "面板打开。"
|
|
4546
|
+
},
|
|
4547
|
+
{
|
|
4548
|
+
"name": "hide",
|
|
4549
|
+
"payload": "—",
|
|
4550
|
+
"description": "面板关闭。"
|
|
4551
|
+
}
|
|
4552
|
+
],
|
|
4553
|
+
"slots": [
|
|
4554
|
+
{
|
|
4555
|
+
"name": "—",
|
|
4556
|
+
"description": "暂无自定义插槽。"
|
|
4557
|
+
}
|
|
4558
|
+
],
|
|
4559
|
+
"methods": [
|
|
4560
|
+
{
|
|
4561
|
+
"name": "open",
|
|
4562
|
+
"description": "打开颜色选择面板。"
|
|
4563
|
+
},
|
|
4564
|
+
{
|
|
4565
|
+
"name": "close",
|
|
4566
|
+
"description": "关闭颜色选择面板。"
|
|
4567
|
+
},
|
|
4568
|
+
{
|
|
4569
|
+
"name": "toggle",
|
|
4570
|
+
"description": "切换颜色选择面板的显示状态。"
|
|
4571
|
+
}
|
|
4572
|
+
],
|
|
4573
|
+
"examples": [
|
|
4574
|
+
{
|
|
4575
|
+
"id": "引入-1",
|
|
4576
|
+
"section": "引入",
|
|
4577
|
+
"sectionId": "引入",
|
|
4578
|
+
"lang": "ts",
|
|
4579
|
+
"preview": false,
|
|
4580
|
+
"code": "import { MColorPicker } from \"morya-ui\";",
|
|
4581
|
+
"locale": "zh-CN"
|
|
4582
|
+
},
|
|
4583
|
+
{
|
|
4584
|
+
"id": "基础用法-1",
|
|
4585
|
+
"section": "基础用法",
|
|
4586
|
+
"sectionId": "基础用法",
|
|
4587
|
+
"lang": "vue",
|
|
4588
|
+
"preview": true,
|
|
4589
|
+
"code": "<script setup lang=\"ts\">\nimport { MColorPicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#1677ff')\n</script>\n\n<template>\n <MColorPicker v-model=\"color\" />\n</template>",
|
|
4590
|
+
"locale": "zh-CN"
|
|
4591
|
+
},
|
|
4592
|
+
{
|
|
4593
|
+
"id": "预设色板-1",
|
|
4594
|
+
"section": "预设色板",
|
|
4595
|
+
"sectionId": "预设色板",
|
|
4596
|
+
"lang": "vue",
|
|
4597
|
+
"preview": true,
|
|
4598
|
+
"code": "<script setup lang=\"ts\">\nimport { MColorPicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#1677ff')\n</script>\n\n<template>\n <MColorPicker\n v-model=\"color\"\n :presets=\"[\n { label: 'Recommended', colors: ['#1677ff', '#52c41a', '#faad14', '#f5222d', '#722ed1'] },\n ]\"\n />\n</template>",
|
|
4599
|
+
"locale": "zh-CN"
|
|
4600
|
+
},
|
|
4601
|
+
{
|
|
4602
|
+
"id": "显示文本与清空-1",
|
|
4603
|
+
"section": "显示文本与清空",
|
|
4604
|
+
"sectionId": "显示文本与清空",
|
|
4605
|
+
"lang": "vue",
|
|
4606
|
+
"preview": true,
|
|
4607
|
+
"code": "<script setup lang=\"ts\">\nimport { MColorPicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#1677ff')\n</script>\n\n<template>\n <MColorPicker v-model=\"color\" show-text allow-clear />\n</template>",
|
|
4608
|
+
"locale": "zh-CN"
|
|
4609
|
+
},
|
|
4610
|
+
{
|
|
4611
|
+
"id": "渐变色-1",
|
|
4612
|
+
"section": "渐变色",
|
|
4613
|
+
"sectionId": "渐变色",
|
|
4614
|
+
"lang": "vue",
|
|
4615
|
+
"preview": true,
|
|
4616
|
+
"code": "<script setup lang=\"ts\">\nimport { MColorPicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#1677ff')\n</script>\n\n<template>\n <MColorPicker v-model=\"color\" gradient />\n</template>",
|
|
4617
|
+
"locale": "zh-CN"
|
|
4618
|
+
},
|
|
4619
|
+
{
|
|
4620
|
+
"id": "渐变值绑定-1",
|
|
4621
|
+
"section": "渐变值绑定",
|
|
4622
|
+
"sectionId": "渐变值绑定",
|
|
4623
|
+
"lang": "vue",
|
|
4624
|
+
"preview": true,
|
|
4625
|
+
"code": "<script setup lang=\"ts\">\nimport { MColorPicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('linear-gradient(90deg, #1677ff 0%, #ff4d4f 100%)')\n</script>\n\n<template>\n <MColorPicker v-model=\"color\" gradient show-text />\n</template>",
|
|
4626
|
+
"locale": "zh-CN"
|
|
4627
|
+
},
|
|
4628
|
+
{
|
|
4629
|
+
"id": "import-1",
|
|
4630
|
+
"section": "Import",
|
|
4631
|
+
"sectionId": "import",
|
|
4632
|
+
"lang": "ts",
|
|
4633
|
+
"preview": false,
|
|
4634
|
+
"code": "import { MColorPicker } from \"morya-ui\";",
|
|
4635
|
+
"locale": "en-US"
|
|
4636
|
+
},
|
|
4637
|
+
{
|
|
4638
|
+
"id": "basic-1",
|
|
4639
|
+
"section": "Basic",
|
|
4640
|
+
"sectionId": "basic",
|
|
4641
|
+
"lang": "vue",
|
|
4642
|
+
"preview": true,
|
|
4643
|
+
"code": "<script setup lang=\"ts\">\nimport { MColorPicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#1677ff')\n</script>\n\n<template>\n <MColorPicker v-model=\"color\" />\n</template>",
|
|
4644
|
+
"locale": "en-US"
|
|
4645
|
+
},
|
|
4646
|
+
{
|
|
4647
|
+
"id": "presets-1",
|
|
4648
|
+
"section": "Presets",
|
|
4649
|
+
"sectionId": "presets",
|
|
4650
|
+
"lang": "vue",
|
|
4651
|
+
"preview": true,
|
|
4652
|
+
"code": "<script setup lang=\"ts\">\nimport { MColorPicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#1677ff')\n</script>\n\n<template>\n <MColorPicker\n v-model=\"color\"\n :presets=\"[\n { label: 'Recommended', colors: ['#1677ff', '#52c41a', '#faad14', '#f5222d', '#722ed1'] },\n ]\"\n />\n</template>",
|
|
4653
|
+
"locale": "en-US"
|
|
4654
|
+
},
|
|
4655
|
+
{
|
|
4656
|
+
"id": "show-text-and-clear-1",
|
|
4657
|
+
"section": "Show text and clear",
|
|
4658
|
+
"sectionId": "show-text-and-clear",
|
|
4659
|
+
"lang": "vue",
|
|
4660
|
+
"preview": true,
|
|
4661
|
+
"code": "<script setup lang=\"ts\">\nimport { MColorPicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#1677ff')\n</script>\n\n<template>\n <MColorPicker v-model=\"color\" show-text allow-clear />\n</template>",
|
|
4662
|
+
"locale": "en-US"
|
|
4663
|
+
},
|
|
4664
|
+
{
|
|
4665
|
+
"id": "gradient-1",
|
|
4666
|
+
"section": "Gradient",
|
|
4667
|
+
"sectionId": "gradient",
|
|
4668
|
+
"lang": "vue",
|
|
4669
|
+
"preview": true,
|
|
4670
|
+
"code": "<script setup lang=\"ts\">\nimport { MColorPicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#1677ff')\n</script>\n\n<template>\n <MColorPicker v-model=\"color\" gradient />\n</template>",
|
|
4671
|
+
"locale": "en-US"
|
|
4672
|
+
},
|
|
4673
|
+
{
|
|
4674
|
+
"id": "gradient-value-binding-1",
|
|
4675
|
+
"section": "Gradient Value Binding",
|
|
4676
|
+
"sectionId": "gradient-value-binding",
|
|
4677
|
+
"lang": "vue",
|
|
4678
|
+
"preview": true,
|
|
4679
|
+
"code": "<script setup lang=\"ts\">\nimport { MColorPicker } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('linear-gradient(90deg, #1677ff 0%, #ff4d4f 100%)')\n</script>\n\n<template>\n <MColorPicker v-model=\"color\" gradient show-text />\n</template>",
|
|
4680
|
+
"locale": "en-US"
|
|
4681
|
+
}
|
|
4682
|
+
],
|
|
4683
|
+
"locales": {
|
|
4684
|
+
"zh-CN": {
|
|
4685
|
+
"title": "ColorPicker",
|
|
4686
|
+
"description": "颜色选择器,支持面板取色、透明度与预设色板。",
|
|
4687
|
+
"sections": [
|
|
4688
|
+
{
|
|
4689
|
+
"id": "overview",
|
|
4690
|
+
"title": "",
|
|
4691
|
+
"body": "# ColorPicker\n\n颜色选择器,支持 HSB 面板取色、透明度调节、预设色板与多种格式显示。"
|
|
4692
|
+
},
|
|
4693
|
+
{
|
|
4694
|
+
"id": "何时使用",
|
|
4695
|
+
"title": "何时使用",
|
|
4696
|
+
"body": "- 需要完整的颜色选择体验,而非仅输入 hex。\n- 需要调节透明度(alpha)时。\n- 需要提供预设色板供用户快速选择时。"
|
|
4697
|
+
},
|
|
4698
|
+
{
|
|
4699
|
+
"id": "引入",
|
|
4700
|
+
"title": "引入",
|
|
4701
|
+
"body": "```ts\nimport { MColorPicker } from \"morya-ui\";\n```"
|
|
4702
|
+
},
|
|
4703
|
+
{
|
|
4704
|
+
"id": "基础用法",
|
|
4705
|
+
"title": "基础用法",
|
|
4706
|
+
"body": "```vue preview src=\"./demos/Basic.vue\"\n```"
|
|
4707
|
+
},
|
|
4708
|
+
{
|
|
4709
|
+
"id": "预设色板",
|
|
4710
|
+
"title": "预设色板",
|
|
4711
|
+
"body": "```vue preview src=\"./demos/Presets.vue\"\n```"
|
|
4712
|
+
},
|
|
4713
|
+
{
|
|
4714
|
+
"id": "显示文本与清空",
|
|
4715
|
+
"title": "显示文本与清空",
|
|
4716
|
+
"body": "```vue preview src=\"./demos/ShowText.vue\"\n```"
|
|
4717
|
+
},
|
|
4718
|
+
{
|
|
4719
|
+
"id": "渐变色",
|
|
4720
|
+
"title": "渐变色",
|
|
4721
|
+
"body": "启用 `gradient` 后支持线性/径向渐变编辑,可添加/删除/拖拽色标。\n\n```vue preview src=\"./demos/Gradient.vue\"\n```"
|
|
4722
|
+
},
|
|
4723
|
+
{
|
|
4724
|
+
"id": "渐变值绑定",
|
|
4725
|
+
"title": "渐变值绑定",
|
|
4726
|
+
"body": "```vue preview src=\"./demos/GradientValue.vue\"\n```"
|
|
4727
|
+
},
|
|
4728
|
+
{
|
|
4729
|
+
"id": "props",
|
|
4730
|
+
"title": "Props",
|
|
4731
|
+
"body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `string` | `'#1677ff'` | 当前颜色值(hex)或 CSS 渐变字符串。 |\n| `gradient` | `boolean` | `false` | 启用渐变色模式。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `disabledAlpha` | `boolean` | `false` | 禁用透明度调节。 |\n| `allowClear` | `boolean` | `false` | 显示清空按钮。 |\n| `format` | `'hex' \\| 'rgb' \\| 'hsb'` | `'hex'` | 显示格式。 |\n| `presets` | `ColorPickerPreset[]` | — | 预设色板。 |\n| `showText` | `boolean` | `false` | 在触发器中显示颜色文本。 |\n| `size` | `MSizeInput` | — | 尺寸。 |\n| `placement` | `ColorPickerPlacement` | `'bottom-start'` | 弹层位置。 |\n| `teleport` | `boolean` | `true` | 是否 teleport 到 body。 |\n| `appendTo` | `MAppendTo` | `'body'` | 挂载目标。 |\n| `transition` | `MotionPresetId \\| false` | — | 过渡动画。 |\n| `pt` | `FieldPassThrough` | — | DOM 透传。 |"
|
|
4732
|
+
},
|
|
4733
|
+
{
|
|
4734
|
+
"id": "events",
|
|
4735
|
+
"title": "Events",
|
|
4736
|
+
"body": "| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `string` | 颜色变化。 |\n| `change` | `string` | 颜色变化(同 `update:modelValue`)。 |\n| `clear` | — | 点击清空。 |\n| `show` | — | 面板打开。 |\n| `hide` | — | 面板关闭。 |"
|
|
4737
|
+
},
|
|
4738
|
+
{
|
|
4739
|
+
"id": "colorpickerpreset",
|
|
4740
|
+
"title": "ColorPickerPreset",
|
|
4741
|
+
"body": "| 参数 | 类型 | 说明 |\n| --- | --- | --- |\n| `label` | `string` | 分组标签。 |\n| `colors` | `string[]` | 颜色数组。 |\n| `defaultOpen` | `boolean` | 默认展开。 |"
|
|
4742
|
+
},
|
|
4743
|
+
{
|
|
4744
|
+
"id": "slots",
|
|
4745
|
+
"title": "Slots",
|
|
4746
|
+
"body": "| 插槽名 | 说明 |\n| --- | --- |\n| — | 暂无自定义插槽。 |"
|
|
4747
|
+
},
|
|
4748
|
+
{
|
|
4749
|
+
"id": "methods",
|
|
4750
|
+
"title": "Methods",
|
|
4751
|
+
"body": "| 方法名 | 说明 |\n| --- | --- |\n| `open` | 打开颜色选择面板。 |\n| `close` | 关闭颜色选择面板。 |\n| `toggle` | 切换颜色选择面板的显示状态。 |"
|
|
4752
|
+
}
|
|
4753
|
+
],
|
|
4754
|
+
"markdown": "---\ntitle: ColorPicker\ncategory: 02 / FORM\ndescription: 颜色选择器,支持面板取色、透明度与预设色板。\n---\n\n# ColorPicker\n\n颜色选择器,支持 HSB 面板取色、透明度调节、预设色板与多种格式显示。\n\n## 何时使用\n\n- 需要完整的颜色选择体验,而非仅输入 hex。\n- 需要调节透明度(alpha)时。\n- 需要提供预设色板供用户快速选择时。\n\n## 引入\n\n```ts\nimport { MColorPicker } from \"morya-ui\";\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## 预设色板\n\n```vue preview src=\"./demos/Presets.vue\"\n```\n\n## 显示文本与清空\n\n```vue preview src=\"./demos/ShowText.vue\"\n```\n\n## 渐变色\n\n启用 `gradient` 后支持线性/径向渐变编辑,可添加/删除/拖拽色标。\n\n```vue preview src=\"./demos/Gradient.vue\"\n```\n\n## 渐变值绑定\n\n```vue preview src=\"./demos/GradientValue.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `string` | `'#1677ff'` | 当前颜色值(hex)或 CSS 渐变字符串。 |\n| `gradient` | `boolean` | `false` | 启用渐变色模式。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `disabledAlpha` | `boolean` | `false` | 禁用透明度调节。 |\n| `allowClear` | `boolean` | `false` | 显示清空按钮。 |\n| `format` | `'hex' \\| 'rgb' \\| 'hsb'` | `'hex'` | 显示格式。 |\n| `presets` | `ColorPickerPreset[]` | — | 预设色板。 |\n| `showText` | `boolean` | `false` | 在触发器中显示颜色文本。 |\n| `size` | `MSizeInput` | — | 尺寸。 |\n| `placement` | `ColorPickerPlacement` | `'bottom-start'` | 弹层位置。 |\n| `teleport` | `boolean` | `true` | 是否 teleport 到 body。 |\n| `appendTo` | `MAppendTo` | `'body'` | 挂载目标。 |\n| `transition` | `MotionPresetId \\| false` | — | 过渡动画。 |\n| `pt` | `FieldPassThrough` | — | DOM 透传。 |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `string` | 颜色变化。 |\n| `change` | `string` | 颜色变化(同 `update:modelValue`)。 |\n| `clear` | — | 点击清空。 |\n| `show` | — | 面板打开。 |\n| `hide` | — | 面板关闭。 |\n\n## ColorPickerPreset\n\n| 参数 | 类型 | 说明 |\n| --- | --- | --- |\n| `label` | `string` | 分组标签。 |\n| `colors` | `string[]` | 颜色数组。 |\n| `defaultOpen` | `boolean` | 默认展开。 |\n\n## Slots\n\n| 插槽名 | 说明 |\n| --- | --- |\n| — | 暂无自定义插槽。 |\n\n## Methods\n\n| 方法名 | 说明 |\n| --- | --- |\n| `open` | 打开颜色选择面板。 |\n| `close` | 关闭颜色选择面板。 |\n| `toggle` | 切换颜色选择面板的显示状态。 |\n"
|
|
4755
|
+
},
|
|
4756
|
+
"en-US": {
|
|
4757
|
+
"title": "ColorPicker",
|
|
4758
|
+
"description": "Color picker with panel, alpha, and preset swatches.",
|
|
4759
|
+
"sections": [
|
|
4760
|
+
{
|
|
4761
|
+
"id": "overview",
|
|
4762
|
+
"title": "",
|
|
4763
|
+
"body": "# ColorPicker\n\nColor picker with HSB panel, alpha slider, preset swatches, and multiple display formats."
|
|
4764
|
+
},
|
|
4765
|
+
{
|
|
4766
|
+
"id": "when-to-use",
|
|
4767
|
+
"title": "When to use",
|
|
4768
|
+
"body": "- When you need a full color picking experience, not just hex input.\n- When you need alpha channel support.\n- When you want to provide preset color palettes."
|
|
4769
|
+
},
|
|
4770
|
+
{
|
|
4771
|
+
"id": "import",
|
|
4772
|
+
"title": "Import",
|
|
4773
|
+
"body": "```ts\nimport { MColorPicker } from \"morya-ui\";\n```"
|
|
4774
|
+
},
|
|
4775
|
+
{
|
|
4776
|
+
"id": "basic",
|
|
4777
|
+
"title": "Basic",
|
|
4778
|
+
"body": "```vue preview src=\"./demos/Basic.vue\"\n```"
|
|
4779
|
+
},
|
|
4780
|
+
{
|
|
4781
|
+
"id": "presets",
|
|
4782
|
+
"title": "Presets",
|
|
4783
|
+
"body": "```vue preview src=\"./demos/Presets.vue\"\n```"
|
|
4784
|
+
},
|
|
4785
|
+
{
|
|
4786
|
+
"id": "show-text-and-clear",
|
|
4787
|
+
"title": "Show text and clear",
|
|
4788
|
+
"body": "```vue preview src=\"./demos/ShowText.vue\"\n```"
|
|
4789
|
+
},
|
|
4790
|
+
{
|
|
4791
|
+
"id": "gradient",
|
|
4792
|
+
"title": "Gradient",
|
|
4793
|
+
"body": "Enable `gradient` for linear/radial gradient editing with draggable color stops.\n\n```vue preview src=\"./demos/Gradient.vue\"\n```"
|
|
4794
|
+
},
|
|
4795
|
+
{
|
|
4796
|
+
"id": "gradient-value-binding",
|
|
4797
|
+
"title": "Gradient Value Binding",
|
|
4798
|
+
"body": "```vue preview src=\"./demos/GradientValue.vue\"\n```"
|
|
4799
|
+
},
|
|
4800
|
+
{
|
|
4801
|
+
"id": "props",
|
|
4802
|
+
"title": "Props",
|
|
4803
|
+
"body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `string` | `'#1677ff'` | Current color value (hex) or CSS gradient string. |\n| `gradient` | `boolean` | `false` | Enable gradient mode. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `disabledAlpha` | `boolean` | `false` | Disable alpha channel. |\n| `allowClear` | `boolean` | `false` | Show clear button. |\n| `format` | `'hex' \\| 'rgb' \\| 'hsb'` | `'hex'` | Display format. |\n| `presets` | `ColorPickerPreset[]` | — | Preset color palettes. |\n| `showText` | `boolean` | `false` | Show color text in trigger. |\n| `size` | `MSizeInput` | — | Size. |\n| `placement` | `ColorPickerPlacement` | `'bottom-start'` | Popup placement. |\n| `teleport` | `boolean` | `true` | Teleport to body. |\n| `appendTo` | `MAppendTo` | `'body'` | Mount target. |\n| `transition` | `MotionPresetId \\| false` | — | Transition. |\n| `pt` | `FieldPassThrough` | — | DOM pass-through. |"
|
|
4804
|
+
},
|
|
4805
|
+
{
|
|
4806
|
+
"id": "events",
|
|
4807
|
+
"title": "Events",
|
|
4808
|
+
"body": "| Event | Payload | Description |\n| --- | --- | --- |\n| `update:modelValue` | `string` | Color changed. |\n| `change` | `string` | Color changed. |\n| `clear` | — | Clear clicked. |\n| `show` | — | Panel opened. |\n| `hide` | — | Panel closed. |"
|
|
4809
|
+
},
|
|
4810
|
+
{
|
|
4811
|
+
"id": "colorpickerpreset",
|
|
4812
|
+
"title": "ColorPickerPreset",
|
|
4813
|
+
"body": "| Prop | Type | Description |\n| --- | --- | --- |\n| `label` | `string` | Group label. |\n| `colors` | `string[]` | Color array. |\n| `defaultOpen` | `boolean` | Default expanded. |"
|
|
4814
|
+
},
|
|
4815
|
+
{
|
|
4816
|
+
"id": "slots",
|
|
4817
|
+
"title": "Slots",
|
|
4818
|
+
"body": "| Name | Description |\n| --- | --- |\n| — | No custom slots yet. |"
|
|
4819
|
+
},
|
|
4820
|
+
{
|
|
4821
|
+
"id": "methods",
|
|
4822
|
+
"title": "Methods",
|
|
4823
|
+
"body": "| Method | Description |\n| --- | --- |\n| `open` | Open the color picker panel. |\n| `close` | Close the color picker panel. |\n| `toggle` | Toggle the color picker panel visibility. |"
|
|
4824
|
+
}
|
|
4825
|
+
],
|
|
4826
|
+
"markdown": "---\ntitle: ColorPicker\ncategory: 02 / FORM\ndescription: Color picker with panel, alpha, and preset swatches.\n---\n\n# ColorPicker\n\nColor picker with HSB panel, alpha slider, preset swatches, and multiple display formats.\n\n## When to use\n\n- When you need a full color picking experience, not just hex input.\n- When you need alpha channel support.\n- When you want to provide preset color palettes.\n\n## Import\n\n```ts\nimport { MColorPicker } from \"morya-ui\";\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Presets\n\n```vue preview src=\"./demos/Presets.vue\"\n```\n\n## Show text and clear\n\n```vue preview src=\"./demos/ShowText.vue\"\n```\n\n## Gradient\n\nEnable `gradient` for linear/radial gradient editing with draggable color stops.\n\n```vue preview src=\"./demos/Gradient.vue\"\n```\n\n## Gradient Value Binding\n\n```vue preview src=\"./demos/GradientValue.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `modelValue` | `string` | `'#1677ff'` | Current color value (hex) or CSS gradient string. |\n| `gradient` | `boolean` | `false` | Enable gradient mode. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `disabledAlpha` | `boolean` | `false` | Disable alpha channel. |\n| `allowClear` | `boolean` | `false` | Show clear button. |\n| `format` | `'hex' \\| 'rgb' \\| 'hsb'` | `'hex'` | Display format. |\n| `presets` | `ColorPickerPreset[]` | — | Preset color palettes. |\n| `showText` | `boolean` | `false` | Show color text in trigger. |\n| `size` | `MSizeInput` | — | Size. |\n| `placement` | `ColorPickerPlacement` | `'bottom-start'` | Popup placement. |\n| `teleport` | `boolean` | `true` | Teleport to body. |\n| `appendTo` | `MAppendTo` | `'body'` | Mount target. |\n| `transition` | `MotionPresetId \\| false` | — | Transition. |\n| `pt` | `FieldPassThrough` | — | DOM pass-through. |\n\n## Events\n\n| Event | Payload | Description |\n| --- | --- | --- |\n| `update:modelValue` | `string` | Color changed. |\n| `change` | `string` | Color changed. |\n| `clear` | — | Clear clicked. |\n| `show` | — | Panel opened. |\n| `hide` | — | Panel closed. |\n\n## ColorPickerPreset\n\n| Prop | Type | Description |\n| --- | --- | --- |\n| `label` | `string` | Group label. |\n| `colors` | `string[]` | Color array. |\n| `defaultOpen` | `boolean` | Default expanded. |\n\n## Slots\n\n| Name | Description |\n| --- | --- |\n| — | No custom slots yet. |\n\n## Methods\n\n| Method | Description |\n| --- | --- |\n| `open` | Open the color picker panel. |\n| `close` | Close the color picker panel. |\n| `toggle` | Toggle the color picker panel visibility. |\n"
|
|
4827
|
+
}
|
|
4828
|
+
}
|
|
4829
|
+
},
|
|
4417
4830
|
{
|
|
4418
4831
|
"id": "CommandMenu",
|
|
4419
4832
|
"name": "CommandMenu",
|
|
@@ -6106,7 +6519,31 @@
|
|
|
6106
6519
|
"name": "shortcuts",
|
|
6107
6520
|
"type": "DatePickerShortcut[]",
|
|
6108
6521
|
"default": "[]",
|
|
6109
|
-
"description": "
|
|
6522
|
+
"description": "面板快捷选项;与当前值匹配时高亮。"
|
|
6523
|
+
},
|
|
6524
|
+
{
|
|
6525
|
+
"name": "status",
|
|
6526
|
+
"type": "'default' | 'warning' | 'error'",
|
|
6527
|
+
"default": "'default'",
|
|
6528
|
+
"description": "视觉警示;`invalid` / `errorMessage` 自动视为 `error`。"
|
|
6529
|
+
},
|
|
6530
|
+
{
|
|
6531
|
+
"name": "needConfirm",
|
|
6532
|
+
"type": "boolean",
|
|
6533
|
+
"default": "false",
|
|
6534
|
+
"description": "选择后仅写入 draft,按「确认」提交、「取消」回滚。"
|
|
6535
|
+
},
|
|
6536
|
+
{
|
|
6537
|
+
"name": "multiple",
|
|
6538
|
+
"type": "boolean",
|
|
6539
|
+
"default": "false",
|
|
6540
|
+
"description": "多选日期(仅 `type='date'`);`modelValue` 为 `string[]`。"
|
|
6541
|
+
},
|
|
6542
|
+
{
|
|
6543
|
+
"name": "mask",
|
|
6544
|
+
"type": "boolean",
|
|
6545
|
+
"default": "false",
|
|
6546
|
+
"description": "输入框可编辑,按 `format` 自动补分隔符;Enter 提交,Esc/失焦回滚。"
|
|
6110
6547
|
},
|
|
6111
6548
|
{
|
|
6112
6549
|
"name": "fluid",
|
|
@@ -6206,6 +6643,14 @@
|
|
|
6206
6643
|
{
|
|
6207
6644
|
"name": "trigger",
|
|
6208
6645
|
"description": "自定义触发器 `{ value, open }`。"
|
|
6646
|
+
},
|
|
6647
|
+
{
|
|
6648
|
+
"name": "footer",
|
|
6649
|
+
"description": "面板底部自定义操作区,作用域 `{ close }`。`need-confirm` 时若未提供则显示默认「取消/确认」。"
|
|
6650
|
+
},
|
|
6651
|
+
{
|
|
6652
|
+
"name": "cell",
|
|
6653
|
+
"description": "自定义日期单元格,作用域 `{ date, inMonth, selected, inRange, rangeStart, rangeEnd, isToday, disabled }`。"
|
|
6209
6654
|
}
|
|
6210
6655
|
],
|
|
6211
6656
|
"methods": [],
|
|
@@ -6309,6 +6754,123 @@
|
|
|
6309
6754
|
"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
6755
|
"locale": "zh-CN"
|
|
6311
6756
|
},
|
|
6757
|
+
{
|
|
6758
|
+
"id": "范围快捷键-1",
|
|
6759
|
+
"section": "范围快捷键",
|
|
6760
|
+
"sectionId": "范围快捷键",
|
|
6761
|
+
"lang": "vue",
|
|
6762
|
+
"preview": true,
|
|
6763
|
+
"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>",
|
|
6764
|
+
"locale": "zh-CN"
|
|
6765
|
+
},
|
|
6766
|
+
{
|
|
6767
|
+
"id": "自定义格式-1",
|
|
6768
|
+
"section": "自定义格式",
|
|
6769
|
+
"sectionId": "自定义格式",
|
|
6770
|
+
"lang": "vue",
|
|
6771
|
+
"preview": true,
|
|
6772
|
+
"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>",
|
|
6773
|
+
"locale": "zh-CN"
|
|
6774
|
+
},
|
|
6775
|
+
{
|
|
6776
|
+
"id": "日期时间-1",
|
|
6777
|
+
"section": "日期时间",
|
|
6778
|
+
"sectionId": "日期时间",
|
|
6779
|
+
"lang": "vue",
|
|
6780
|
+
"preview": true,
|
|
6781
|
+
"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>",
|
|
6782
|
+
"locale": "zh-CN"
|
|
6783
|
+
},
|
|
6784
|
+
{
|
|
6785
|
+
"id": "自定义触发器-1",
|
|
6786
|
+
"section": "自定义触发器",
|
|
6787
|
+
"sectionId": "自定义触发器",
|
|
6788
|
+
"lang": "vue",
|
|
6789
|
+
"preview": true,
|
|
6790
|
+
"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>",
|
|
6791
|
+
"locale": "zh-CN"
|
|
6792
|
+
},
|
|
6793
|
+
{
|
|
6794
|
+
"id": "禁用区间-1",
|
|
6795
|
+
"section": "禁用区间",
|
|
6796
|
+
"sectionId": "禁用区间",
|
|
6797
|
+
"lang": "vue",
|
|
6798
|
+
"preview": true,
|
|
6799
|
+
"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>",
|
|
6800
|
+
"locale": "zh-CN"
|
|
6801
|
+
},
|
|
6802
|
+
{
|
|
6803
|
+
"id": "内联面板-1",
|
|
6804
|
+
"section": "内联面板",
|
|
6805
|
+
"sectionId": "内联面板",
|
|
6806
|
+
"lang": "vue",
|
|
6807
|
+
"preview": true,
|
|
6808
|
+
"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>",
|
|
6809
|
+
"locale": "zh-CN"
|
|
6810
|
+
},
|
|
6811
|
+
{
|
|
6812
|
+
"id": "状态-status-1",
|
|
6813
|
+
"section": "状态(status)",
|
|
6814
|
+
"sectionId": "状态-status",
|
|
6815
|
+
"lang": "vue",
|
|
6816
|
+
"preview": true,
|
|
6817
|
+
"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>",
|
|
6818
|
+
"locale": "zh-CN"
|
|
6819
|
+
},
|
|
6820
|
+
{
|
|
6821
|
+
"id": "页脚与自定义单元格-1",
|
|
6822
|
+
"section": "页脚与自定义单元格",
|
|
6823
|
+
"sectionId": "页脚与自定义单元格",
|
|
6824
|
+
"lang": "vue",
|
|
6825
|
+
"preview": true,
|
|
6826
|
+
"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>",
|
|
6827
|
+
"locale": "zh-CN"
|
|
6828
|
+
},
|
|
6829
|
+
{
|
|
6830
|
+
"id": "needconfirm-确认提交-1",
|
|
6831
|
+
"section": "needConfirm 确认提交",
|
|
6832
|
+
"sectionId": "needconfirm-确认提交",
|
|
6833
|
+
"lang": "vue",
|
|
6834
|
+
"preview": true,
|
|
6835
|
+
"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>",
|
|
6836
|
+
"locale": "zh-CN"
|
|
6837
|
+
},
|
|
6838
|
+
{
|
|
6839
|
+
"id": "多选日期-1",
|
|
6840
|
+
"section": "多选日期",
|
|
6841
|
+
"sectionId": "多选日期",
|
|
6842
|
+
"lang": "vue",
|
|
6843
|
+
"preview": true,
|
|
6844
|
+
"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>",
|
|
6845
|
+
"locale": "zh-CN"
|
|
6846
|
+
},
|
|
6847
|
+
{
|
|
6848
|
+
"id": "多选实战-排班-1",
|
|
6849
|
+
"section": "多选实战:排班",
|
|
6850
|
+
"sectionId": "多选实战-排班",
|
|
6851
|
+
"lang": "vue",
|
|
6852
|
+
"preview": true,
|
|
6853
|
+
"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>",
|
|
6854
|
+
"locale": "zh-CN"
|
|
6855
|
+
},
|
|
6856
|
+
{
|
|
6857
|
+
"id": "表单集成-1",
|
|
6858
|
+
"section": "表单集成",
|
|
6859
|
+
"sectionId": "表单集成",
|
|
6860
|
+
"lang": "vue",
|
|
6861
|
+
"preview": true,
|
|
6862
|
+
"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>",
|
|
6863
|
+
"locale": "zh-CN"
|
|
6864
|
+
},
|
|
6865
|
+
{
|
|
6866
|
+
"id": "输入掩码-1",
|
|
6867
|
+
"section": "输入掩码",
|
|
6868
|
+
"sectionId": "输入掩码",
|
|
6869
|
+
"lang": "vue",
|
|
6870
|
+
"preview": true,
|
|
6871
|
+
"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>",
|
|
6872
|
+
"locale": "zh-CN"
|
|
6873
|
+
},
|
|
6312
6874
|
{
|
|
6313
6875
|
"id": "类型-1",
|
|
6314
6876
|
"section": "类型",
|
|
@@ -6417,6 +6979,123 @@
|
|
|
6417
6979
|
"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
6980
|
"locale": "en-US"
|
|
6419
6981
|
},
|
|
6982
|
+
{
|
|
6983
|
+
"id": "range-shortcuts-1",
|
|
6984
|
+
"section": "Range Shortcuts",
|
|
6985
|
+
"sectionId": "range-shortcuts",
|
|
6986
|
+
"lang": "vue",
|
|
6987
|
+
"preview": true,
|
|
6988
|
+
"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>",
|
|
6989
|
+
"locale": "en-US"
|
|
6990
|
+
},
|
|
6991
|
+
{
|
|
6992
|
+
"id": "custom-format-1",
|
|
6993
|
+
"section": "Custom Format",
|
|
6994
|
+
"sectionId": "custom-format",
|
|
6995
|
+
"lang": "vue",
|
|
6996
|
+
"preview": true,
|
|
6997
|
+
"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>",
|
|
6998
|
+
"locale": "en-US"
|
|
6999
|
+
},
|
|
7000
|
+
{
|
|
7001
|
+
"id": "datetime-1",
|
|
7002
|
+
"section": "Datetime",
|
|
7003
|
+
"sectionId": "datetime",
|
|
7004
|
+
"lang": "vue",
|
|
7005
|
+
"preview": true,
|
|
7006
|
+
"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>",
|
|
7007
|
+
"locale": "en-US"
|
|
7008
|
+
},
|
|
7009
|
+
{
|
|
7010
|
+
"id": "custom-trigger-1",
|
|
7011
|
+
"section": "Custom Trigger",
|
|
7012
|
+
"sectionId": "custom-trigger",
|
|
7013
|
+
"lang": "vue",
|
|
7014
|
+
"preview": true,
|
|
7015
|
+
"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>",
|
|
7016
|
+
"locale": "en-US"
|
|
7017
|
+
},
|
|
7018
|
+
{
|
|
7019
|
+
"id": "disabled-ranges-1",
|
|
7020
|
+
"section": "Disabled Ranges",
|
|
7021
|
+
"sectionId": "disabled-ranges",
|
|
7022
|
+
"lang": "vue",
|
|
7023
|
+
"preview": true,
|
|
7024
|
+
"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>",
|
|
7025
|
+
"locale": "en-US"
|
|
7026
|
+
},
|
|
7027
|
+
{
|
|
7028
|
+
"id": "inline-panel-1",
|
|
7029
|
+
"section": "Inline Panel",
|
|
7030
|
+
"sectionId": "inline-panel",
|
|
7031
|
+
"lang": "vue",
|
|
7032
|
+
"preview": true,
|
|
7033
|
+
"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>",
|
|
7034
|
+
"locale": "en-US"
|
|
7035
|
+
},
|
|
7036
|
+
{
|
|
7037
|
+
"id": "status-1",
|
|
7038
|
+
"section": "Status",
|
|
7039
|
+
"sectionId": "status",
|
|
7040
|
+
"lang": "vue",
|
|
7041
|
+
"preview": true,
|
|
7042
|
+
"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>",
|
|
7043
|
+
"locale": "en-US"
|
|
7044
|
+
},
|
|
7045
|
+
{
|
|
7046
|
+
"id": "footer-custom-cell-1",
|
|
7047
|
+
"section": "Footer & Custom Cell",
|
|
7048
|
+
"sectionId": "footer-custom-cell",
|
|
7049
|
+
"lang": "vue",
|
|
7050
|
+
"preview": true,
|
|
7051
|
+
"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>",
|
|
7052
|
+
"locale": "en-US"
|
|
7053
|
+
},
|
|
7054
|
+
{
|
|
7055
|
+
"id": "needconfirm-1",
|
|
7056
|
+
"section": "needConfirm",
|
|
7057
|
+
"sectionId": "needconfirm",
|
|
7058
|
+
"lang": "vue",
|
|
7059
|
+
"preview": true,
|
|
7060
|
+
"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>",
|
|
7061
|
+
"locale": "en-US"
|
|
7062
|
+
},
|
|
7063
|
+
{
|
|
7064
|
+
"id": "multiple-dates-1",
|
|
7065
|
+
"section": "Multiple Dates",
|
|
7066
|
+
"sectionId": "multiple-dates",
|
|
7067
|
+
"lang": "vue",
|
|
7068
|
+
"preview": true,
|
|
7069
|
+
"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>",
|
|
7070
|
+
"locale": "en-US"
|
|
7071
|
+
},
|
|
7072
|
+
{
|
|
7073
|
+
"id": "multiple-in-practice-shift-planning-1",
|
|
7074
|
+
"section": "Multiple in Practice: Shift Planning",
|
|
7075
|
+
"sectionId": "multiple-in-practice-shift-planning",
|
|
7076
|
+
"lang": "vue",
|
|
7077
|
+
"preview": true,
|
|
7078
|
+
"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>",
|
|
7079
|
+
"locale": "en-US"
|
|
7080
|
+
},
|
|
7081
|
+
{
|
|
7082
|
+
"id": "form-integration-1",
|
|
7083
|
+
"section": "Form Integration",
|
|
7084
|
+
"sectionId": "form-integration",
|
|
7085
|
+
"lang": "vue",
|
|
7086
|
+
"preview": true,
|
|
7087
|
+
"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>",
|
|
7088
|
+
"locale": "en-US"
|
|
7089
|
+
},
|
|
7090
|
+
{
|
|
7091
|
+
"id": "input-mask-1",
|
|
7092
|
+
"section": "Input Mask",
|
|
7093
|
+
"sectionId": "input-mask",
|
|
7094
|
+
"lang": "vue",
|
|
7095
|
+
"preview": true,
|
|
7096
|
+
"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>",
|
|
7097
|
+
"locale": "en-US"
|
|
7098
|
+
},
|
|
6420
7099
|
{
|
|
6421
7100
|
"id": "types-1",
|
|
6422
7101
|
"section": "Types",
|
|
@@ -6497,10 +7176,80 @@
|
|
|
6497
7176
|
"title": "Shortcuts",
|
|
6498
7177
|
"body": "```vue preview src=\"./demos/Shortcuts.zh.vue\"\n```"
|
|
6499
7178
|
},
|
|
7179
|
+
{
|
|
7180
|
+
"id": "范围快捷键",
|
|
7181
|
+
"title": "范围快捷键",
|
|
7182
|
+
"body": "`shortcuts` 在 `daterange` / `datetimerange` 下更强大:返回 `[start, end]` 元组即可一键选定区间。与当前值匹配的快捷键会自动高亮。\n\n```vue preview src=\"./demos/RangeShortcuts.zh.vue\"\n```"
|
|
7183
|
+
},
|
|
7184
|
+
{
|
|
7185
|
+
"id": "自定义格式",
|
|
7186
|
+
"title": "自定义格式",
|
|
7187
|
+
"body": "`format` 仅控制显示,提交值仍按 `type` 约定(`YYYY-MM-DD` 等)。支持任意 `YYYY` / `MM` / `DD` / `HH` / `mm` / `ss` 组合与自由文本。\n\n```vue preview src=\"./demos/Format.zh.vue\"\n```"
|
|
7188
|
+
},
|
|
7189
|
+
{
|
|
7190
|
+
"id": "日期时间",
|
|
7191
|
+
"title": "日期时间",
|
|
7192
|
+
"body": "`datetime` 与 `datetimerange` 把日历与时间列放在同一面板;`show-seconds` 含秒;`need-confirm` 让用户从容完成两步选择后再提交。\n\n```vue preview src=\"./demos/Datetime.zh.vue\"\n```"
|
|
7193
|
+
},
|
|
7194
|
+
{
|
|
7195
|
+
"id": "自定义触发器",
|
|
7196
|
+
"title": "自定义触发器",
|
|
7197
|
+
"body": "`#trigger` 插槽完全接管触发元素,作用域 `{ value, open }`。适合按钮、图标或复合排版。\n\n```vue preview src=\"./demos/CustomTrigger.zh.vue\"\n```"
|
|
7198
|
+
},
|
|
7199
|
+
{
|
|
7200
|
+
"id": "禁用区间",
|
|
7201
|
+
"title": "禁用区间",
|
|
7202
|
+
"body": "`min-date` / `max-date` 之外的日期会在日历中置灰禁用。两者可单独或组合使用。\n\n```vue preview src=\"./demos/DisabledDates.zh.vue\"\n```"
|
|
7203
|
+
},
|
|
7204
|
+
{
|
|
7205
|
+
"id": "内联面板",
|
|
7206
|
+
"title": "内联面板",
|
|
7207
|
+
"body": "`:teleport=\"false\"` + `append-to=\"self\"` 让面板嵌入文档流,不浮出层叠上下文,适合卡片、抽屉或复合表单内嵌。\n\n```vue preview src=\"./demos/InlinePanel.zh.vue\"\n```"
|
|
7208
|
+
},
|
|
7209
|
+
{
|
|
7210
|
+
"id": "面板模式切换",
|
|
7211
|
+
"title": "面板模式切换",
|
|
7212
|
+
"body": "点击面板头部的月份/年份标签,可在 日 → 月 → 年 三个子面板间循环切换,方便快速跳到目标年份/月份再回到日视图。"
|
|
7213
|
+
},
|
|
7214
|
+
{
|
|
7215
|
+
"id": "状态-status",
|
|
7216
|
+
"title": "状态(status)",
|
|
7217
|
+
"body": "`status` 提供 `'warning'` 与 `'error'` 两种视觉警示(`invalid` / `errorMessage` 会自动落到 `error`)。`warning` 通常配合 `helpText` 表达温和提醒,不阻断提交。\n\n```vue preview src=\"./demos/Status.zh.vue\"\n```"
|
|
7218
|
+
},
|
|
7219
|
+
{
|
|
7220
|
+
"id": "页脚与自定义单元格",
|
|
7221
|
+
"title": "页脚与自定义单元格",
|
|
7222
|
+
"body": "`#footer` 插槽在面板底部渲染操作区(作用域 `{ close }`);`#cell` 插槽自定义日期单元格内容(作用域含 `date / inMonth / selected / inRange / rangeStart / rangeEnd / isToday / disabled`),适合加节假日标记、日程点、自定义排版。\n\n```vue preview src=\"./demos/FooterAndCell.zh.vue\"\n```"
|
|
7223
|
+
},
|
|
7224
|
+
{
|
|
7225
|
+
"id": "needconfirm-确认提交",
|
|
7226
|
+
"title": "needConfirm 确认提交",
|
|
7227
|
+
"body": "`need-confirm` 启用后,选择值只写入暂存 draft,点击「确认」才提交并关闭,「取消」回滚。适合 `datetime` / `datetimerange` / `time` 等需要多步操作的场景。\n\n```vue preview src=\"./demos/NeedConfirm.zh.vue\"\n```"
|
|
7228
|
+
},
|
|
7229
|
+
{
|
|
7230
|
+
"id": "多选日期",
|
|
7231
|
+
"title": "多选日期",
|
|
7232
|
+
"body": "`multiple` 仅在 `type='date'` 下生效。`modelValue` 变为 `string[]`,每次点击切换选中,面板保持打开。\n\n```vue preview src=\"./demos/Multiple.zh.vue\"\n```"
|
|
7233
|
+
},
|
|
7234
|
+
{
|
|
7235
|
+
"id": "多选实战-排班",
|
|
7236
|
+
"title": "多选实战:排班",
|
|
7237
|
+
"body": "多选配合 `MTag` 展示所选日期,直观易读。\n\n```vue preview src=\"./demos/WorkSchedule.zh.vue\"\n```"
|
|
7238
|
+
},
|
|
7239
|
+
{
|
|
7240
|
+
"id": "表单集成",
|
|
7241
|
+
"title": "表单集成",
|
|
7242
|
+
"body": "结合 `required` / `error-message` / `min-date`,实现一个完整的项目日期范围校验表单。\n\n```vue preview src=\"./demos/FormIntegration.zh.vue\"\n```"
|
|
7243
|
+
},
|
|
7244
|
+
{
|
|
7245
|
+
"id": "输入掩码",
|
|
7246
|
+
"title": "输入掩码",
|
|
7247
|
+
"body": "`mask` 让输入框可编辑,按 `format` 自动插入 `-` `/` `:` 分隔符;`Enter` 提交,`Esc` 或失焦回滚。仅 `date` / `datetime` / `time` 类型支持。\n\n```vue preview src=\"./demos/Mask.zh.vue\"\n```"
|
|
7248
|
+
},
|
|
6500
7249
|
{
|
|
6501
7250
|
"id": "props",
|
|
6502
7251
|
"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[]` | `[]` |
|
|
7252
|
+
"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
7253
|
},
|
|
6505
7254
|
{
|
|
6506
7255
|
"id": "events",
|
|
@@ -6510,7 +7259,7 @@
|
|
|
6510
7259
|
{
|
|
6511
7260
|
"id": "slots",
|
|
6512
7261
|
"title": "Slots",
|
|
6513
|
-
"body": "| 插槽名 | 说明
|
|
7262
|
+
"body": "| 插槽名 | 说明 |\n| --------- | --------------------------------------------------------------------------------------------------------------------------------- |\n| `trigger` | 自定义触发器 `{ value, open }`。 |\n| `footer` | 面板底部自定义操作区,作用域 `{ close }`。`need-confirm` 时若未提供则显示默认「取消/确认」。 |\n| `cell` | 自定义日期单元格,作用域 `{ date, inMonth, selected, inRange, rangeStart, rangeEnd, isToday, disabled }`。 |"
|
|
6514
7263
|
},
|
|
6515
7264
|
{
|
|
6516
7265
|
"id": "类型",
|
|
@@ -6523,7 +7272,7 @@
|
|
|
6523
7272
|
"body": "用 `type` 区分日期/范围/时间模式(含 `daterange`、`datetime`、`time` 等)。"
|
|
6524
7273
|
}
|
|
6525
7274
|
],
|
|
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"
|
|
7275
|
+
"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
7276
|
},
|
|
6528
7277
|
"en-US": {
|
|
6529
7278
|
"title": "DatePicker",
|
|
@@ -6594,10 +7343,80 @@
|
|
|
6594
7343
|
"title": "Shortcuts",
|
|
6595
7344
|
"body": "```vue preview src=\"./demos/Shortcuts.en.vue\"\n```"
|
|
6596
7345
|
},
|
|
7346
|
+
{
|
|
7347
|
+
"id": "range-shortcuts",
|
|
7348
|
+
"title": "Range Shortcuts",
|
|
7349
|
+
"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```"
|
|
7350
|
+
},
|
|
7351
|
+
{
|
|
7352
|
+
"id": "custom-format",
|
|
7353
|
+
"title": "Custom Format",
|
|
7354
|
+
"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```"
|
|
7355
|
+
},
|
|
7356
|
+
{
|
|
7357
|
+
"id": "datetime",
|
|
7358
|
+
"title": "Datetime",
|
|
7359
|
+
"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```"
|
|
7360
|
+
},
|
|
7361
|
+
{
|
|
7362
|
+
"id": "custom-trigger",
|
|
7363
|
+
"title": "Custom Trigger",
|
|
7364
|
+
"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```"
|
|
7365
|
+
},
|
|
7366
|
+
{
|
|
7367
|
+
"id": "disabled-ranges",
|
|
7368
|
+
"title": "Disabled Ranges",
|
|
7369
|
+
"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```"
|
|
7370
|
+
},
|
|
7371
|
+
{
|
|
7372
|
+
"id": "inline-panel",
|
|
7373
|
+
"title": "Inline Panel",
|
|
7374
|
+
"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```"
|
|
7375
|
+
},
|
|
7376
|
+
{
|
|
7377
|
+
"id": "panel-mode-cycling",
|
|
7378
|
+
"title": "Panel Mode Cycling",
|
|
7379
|
+
"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."
|
|
7380
|
+
},
|
|
7381
|
+
{
|
|
7382
|
+
"id": "status",
|
|
7383
|
+
"title": "Status",
|
|
7384
|
+
"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```"
|
|
7385
|
+
},
|
|
7386
|
+
{
|
|
7387
|
+
"id": "footer-custom-cell",
|
|
7388
|
+
"title": "Footer & Custom Cell",
|
|
7389
|
+
"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```"
|
|
7390
|
+
},
|
|
7391
|
+
{
|
|
7392
|
+
"id": "needconfirm",
|
|
7393
|
+
"title": "needConfirm",
|
|
7394
|
+
"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```"
|
|
7395
|
+
},
|
|
7396
|
+
{
|
|
7397
|
+
"id": "multiple-dates",
|
|
7398
|
+
"title": "Multiple Dates",
|
|
7399
|
+
"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```"
|
|
7400
|
+
},
|
|
7401
|
+
{
|
|
7402
|
+
"id": "multiple-in-practice-shift-planning",
|
|
7403
|
+
"title": "Multiple in Practice: Shift Planning",
|
|
7404
|
+
"body": "Combine `multiple` with `MTag` to display picked days in a friendly, readable way.\n\n```vue preview src=\"./demos/WorkSchedule.en.vue\"\n```"
|
|
7405
|
+
},
|
|
7406
|
+
{
|
|
7407
|
+
"id": "form-integration",
|
|
7408
|
+
"title": "Form Integration",
|
|
7409
|
+
"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```"
|
|
7410
|
+
},
|
|
7411
|
+
{
|
|
7412
|
+
"id": "input-mask",
|
|
7413
|
+
"title": "Input Mask",
|
|
7414
|
+
"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```"
|
|
7415
|
+
},
|
|
6597
7416
|
{
|
|
6598
7417
|
"id": "props",
|
|
6599
7418
|
"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.
|
|
7419
|
+
"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
7420
|
},
|
|
6602
7421
|
{
|
|
6603
7422
|
"id": "events",
|
|
@@ -6607,7 +7426,7 @@
|
|
|
6607
7426
|
{
|
|
6608
7427
|
"id": "slots",
|
|
6609
7428
|
"title": "Slots",
|
|
6610
|
-
"body": "| Slot | Description
|
|
7429
|
+
"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
7430
|
},
|
|
6612
7431
|
{
|
|
6613
7432
|
"id": "types",
|
|
@@ -6620,7 +7439,7 @@
|
|
|
6620
7439
|
"body": "Date, range, and time modes are selected via `type` (`daterange`, `datetime`, `time`, etc.)."
|
|
6621
7440
|
}
|
|
6622
7441
|
],
|
|
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"
|
|
7442
|
+
"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
7443
|
}
|
|
6625
7444
|
}
|
|
6626
7445
|
},
|
|
@@ -12709,241 +13528,6 @@
|
|
|
12709
13528
|
}
|
|
12710
13529
|
}
|
|
12711
13530
|
},
|
|
12712
|
-
{
|
|
12713
|
-
"id": "InputColor",
|
|
12714
|
-
"name": "InputColor",
|
|
12715
|
-
"exportName": "MInputColor",
|
|
12716
|
-
"category": "02 / FORM",
|
|
12717
|
-
"description": "颜色选择,支持色板与十六进制文本。",
|
|
12718
|
-
"descriptionEn": "Color picker with a palette and hexadecimal text input.",
|
|
12719
|
-
"import": "import { MInputColor } from 'morya-ui'",
|
|
12720
|
-
"props": [
|
|
12721
|
-
{
|
|
12722
|
-
"name": "modelValue",
|
|
12723
|
-
"type": "string",
|
|
12724
|
-
"default": "'#000000'",
|
|
12725
|
-
"description": "十六进制颜色。"
|
|
12726
|
-
},
|
|
12727
|
-
{
|
|
12728
|
-
"name": "swatches",
|
|
12729
|
-
"type": "string[]",
|
|
12730
|
-
"default": "—",
|
|
12731
|
-
"description": "快捷色板。"
|
|
12732
|
-
},
|
|
12733
|
-
{
|
|
12734
|
-
"name": "disabled",
|
|
12735
|
-
"type": "boolean",
|
|
12736
|
-
"default": "false",
|
|
12737
|
-
"description": "禁用。"
|
|
12738
|
-
},
|
|
12739
|
-
{
|
|
12740
|
-
"name": "id",
|
|
12741
|
-
"type": "string",
|
|
12742
|
-
"default": "—",
|
|
12743
|
-
"description": "色板 input id。"
|
|
12744
|
-
},
|
|
12745
|
-
{
|
|
12746
|
-
"name": "invalid",
|
|
12747
|
-
"type": "boolean",
|
|
12748
|
-
"default": "—",
|
|
12749
|
-
"description": "—"
|
|
12750
|
-
},
|
|
12751
|
-
{
|
|
12752
|
-
"name": "label",
|
|
12753
|
-
"type": "string",
|
|
12754
|
-
"default": "—",
|
|
12755
|
-
"description": "—"
|
|
12756
|
-
},
|
|
12757
|
-
{
|
|
12758
|
-
"name": "size",
|
|
12759
|
-
"type": "[MSizeInput](/docs/types#MSizeInput)",
|
|
12760
|
-
"default": "—",
|
|
12761
|
-
"description": "—"
|
|
12762
|
-
},
|
|
12763
|
-
{
|
|
12764
|
-
"name": "pt",
|
|
12765
|
-
"type": "[FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }",
|
|
12766
|
-
"default": "—",
|
|
12767
|
-
"description": "DOM 透传,见 [样式与 attrs](/docs/attrs)."
|
|
12768
|
-
}
|
|
12769
|
-
],
|
|
12770
|
-
"events": [
|
|
12771
|
-
{
|
|
12772
|
-
"name": "update:modelValue",
|
|
12773
|
-
"payload": "string",
|
|
12774
|
-
"description": "颜色变化。"
|
|
12775
|
-
}
|
|
12776
|
-
],
|
|
12777
|
-
"slots": [
|
|
12778
|
-
{
|
|
12779
|
-
"name": "trigger",
|
|
12780
|
-
"description": "自定义颜色触发器。"
|
|
12781
|
-
}
|
|
12782
|
-
],
|
|
12783
|
-
"methods": [],
|
|
12784
|
-
"examples": [
|
|
12785
|
-
{
|
|
12786
|
-
"id": "引入-1",
|
|
12787
|
-
"section": "引入",
|
|
12788
|
-
"sectionId": "引入",
|
|
12789
|
-
"lang": "ts",
|
|
12790
|
-
"preview": false,
|
|
12791
|
-
"code": "import { MInputColor } from \"morya-ui\";",
|
|
12792
|
-
"locale": "zh-CN"
|
|
12793
|
-
},
|
|
12794
|
-
{
|
|
12795
|
-
"id": "基础用法-1",
|
|
12796
|
-
"section": "基础用法",
|
|
12797
|
-
"sectionId": "基础用法",
|
|
12798
|
-
"lang": "vue",
|
|
12799
|
-
"preview": true,
|
|
12800
|
-
"code": "<script setup lang=\"ts\">\nimport { MInputColor } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#2563eb')\n</script>\n\n<template>\n <MInputColor v-model=\"color\" />\n</template>",
|
|
12801
|
-
"locale": "zh-CN"
|
|
12802
|
-
},
|
|
12803
|
-
{
|
|
12804
|
-
"id": "swatches-1",
|
|
12805
|
-
"section": "Swatches",
|
|
12806
|
-
"sectionId": "swatches",
|
|
12807
|
-
"lang": "vue",
|
|
12808
|
-
"preview": true,
|
|
12809
|
-
"code": "<script setup lang=\"ts\">\nimport { MInputColor } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#2563eb')\n</script>\n\n<template>\n <MInputColor v-model=\"color\" :swatches=\"['#2563eb', '#16a34a', '#dc2626']\" />\n</template>",
|
|
12810
|
-
"locale": "zh-CN"
|
|
12811
|
-
},
|
|
12812
|
-
{
|
|
12813
|
-
"id": "import-1",
|
|
12814
|
-
"section": "Import",
|
|
12815
|
-
"sectionId": "import",
|
|
12816
|
-
"lang": "ts",
|
|
12817
|
-
"preview": false,
|
|
12818
|
-
"code": "import { MInputColor } from \"morya-ui\";",
|
|
12819
|
-
"locale": "en-US"
|
|
12820
|
-
},
|
|
12821
|
-
{
|
|
12822
|
-
"id": "basic-1",
|
|
12823
|
-
"section": "Basic",
|
|
12824
|
-
"sectionId": "basic",
|
|
12825
|
-
"lang": "vue",
|
|
12826
|
-
"preview": true,
|
|
12827
|
-
"code": "<script setup lang=\"ts\">\nimport { MInputColor } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#2563eb')\n</script>\n\n<template>\n <MInputColor v-model=\"color\" />\n</template>",
|
|
12828
|
-
"locale": "en-US"
|
|
12829
|
-
},
|
|
12830
|
-
{
|
|
12831
|
-
"id": "swatches-1",
|
|
12832
|
-
"section": "Swatches",
|
|
12833
|
-
"sectionId": "swatches",
|
|
12834
|
-
"lang": "vue",
|
|
12835
|
-
"preview": true,
|
|
12836
|
-
"code": "<script setup lang=\"ts\">\nimport { MInputColor } from 'morya-ui'\nimport { ref } from 'vue'\n\nconst color = ref('#2563eb')\n</script>\n\n<template>\n <MInputColor v-model=\"color\" :swatches=\"['#2563eb', '#16a34a', '#dc2626']\" />\n</template>",
|
|
12837
|
-
"locale": "en-US"
|
|
12838
|
-
}
|
|
12839
|
-
],
|
|
12840
|
-
"locales": {
|
|
12841
|
-
"zh-CN": {
|
|
12842
|
-
"title": "InputColor",
|
|
12843
|
-
"description": "颜色选择,支持色板与十六进制文本。",
|
|
12844
|
-
"sections": [
|
|
12845
|
-
{
|
|
12846
|
-
"id": "overview",
|
|
12847
|
-
"title": "",
|
|
12848
|
-
"body": "# InputColor\n\n通过原生色板与文本框编辑 hex 颜色。"
|
|
12849
|
-
},
|
|
12850
|
-
{
|
|
12851
|
-
"id": "何时使用",
|
|
12852
|
-
"title": "何时使用",
|
|
12853
|
-
"body": "- 表单需要选择或输入十六进制颜色时。\n- 需要预设色块(`swatches`)即可,不需要完整独立取色面板。"
|
|
12854
|
-
},
|
|
12855
|
-
{
|
|
12856
|
-
"id": "引入",
|
|
12857
|
-
"title": "引入",
|
|
12858
|
-
"body": "```ts\nimport { MInputColor } from \"morya-ui\";\n```"
|
|
12859
|
-
},
|
|
12860
|
-
{
|
|
12861
|
-
"id": "基础用法",
|
|
12862
|
-
"title": "基础用法",
|
|
12863
|
-
"body": "```vue preview src=\"./demos/Basic.vue\"\n```"
|
|
12864
|
-
},
|
|
12865
|
-
{
|
|
12866
|
-
"id": "swatches",
|
|
12867
|
-
"title": "Swatches",
|
|
12868
|
-
"body": "`swatches` 提供快捷色板。\n\n```vue preview src=\"./demos/Swatches.vue\"\n```"
|
|
12869
|
-
},
|
|
12870
|
-
{
|
|
12871
|
-
"id": "props",
|
|
12872
|
-
"title": "Props",
|
|
12873
|
-
"body": "| 参数 | 类型 | 默认值 | 说明 |\n| ------------ | -------------------------------------------------------------------------------------- | ----------- | ----------------------------------------- |\n| `modelValue` | `string` | `'#000000'` | 十六进制颜色。 |\n| `swatches` | `string[]` | — | 快捷色板。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `id` | `string` | — | 色板 input id。 |\n| `invalid` | `boolean` | — | — |\n| `label` | `string` | — | — |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | — |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |"
|
|
12874
|
-
},
|
|
12875
|
-
{
|
|
12876
|
-
"id": "events",
|
|
12877
|
-
"title": "Events",
|
|
12878
|
-
"body": "| 事件名 | 参数 | 说明 |\n| ------------------- | -------- | ---------- |\n| `update:modelValue` | `string` | 颜色变化。 |"
|
|
12879
|
-
},
|
|
12880
|
-
{
|
|
12881
|
-
"id": "功能边界",
|
|
12882
|
-
"title": "功能边界",
|
|
12883
|
-
"body": "选色实现是**原生色板 + hex 文本 + 可选 swatches**,不是完整的面板级取色体验。"
|
|
12884
|
-
},
|
|
12885
|
-
{
|
|
12886
|
-
"id": "slots",
|
|
12887
|
-
"title": "Slots",
|
|
12888
|
-
"body": "| 插槽名 | 说明 |\n| --------- | ------------------ |\n| `trigger` | 自定义颜色触发器。 |"
|
|
12889
|
-
}
|
|
12890
|
-
],
|
|
12891
|
-
"markdown": "---\ntitle: InputColor\ncategory: 02 / FORM\ndescription: 颜色选择,支持色板与十六进制文本。\n---\n\n# InputColor\n\n通过原生色板与文本框编辑 hex 颜色。\n\n## 何时使用\n\n- 表单需要选择或输入十六进制颜色时。\n- 需要预设色块(`swatches`)即可,不需要完整独立取色面板。\n\n## 引入\n\n```ts\nimport { MInputColor } from \"morya-ui\";\n```\n\n## 基础用法\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Swatches\n\n`swatches` 提供快捷色板。\n\n```vue preview src=\"./demos/Swatches.vue\"\n```\n\n## Props\n\n| 参数 | 类型 | 默认值 | 说明 |\n| ------------ | -------------------------------------------------------------------------------------- | ----------- | ----------------------------------------- |\n| `modelValue` | `string` | `'#000000'` | 十六进制颜色。 |\n| `swatches` | `string[]` | — | 快捷色板。 |\n| `disabled` | `boolean` | `false` | 禁用。 |\n| `id` | `string` | — | 色板 input id。 |\n| `invalid` | `boolean` | — | — |\n| `label` | `string` | — | — |\n| `size` | [MSizeInput](/docs/types#MSizeInput) | — | — |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | DOM 透传,见 [样式与 attrs](/docs/attrs). |\n\n## Events\n\n| 事件名 | 参数 | 说明 |\n| ------------------- | -------- | ---------- |\n| `update:modelValue` | `string` | 颜色变化。 |\n\n## 功能边界\n\n选色实现是**原生色板 + hex 文本 + 可选 swatches**,不是完整的面板级取色体验。\n\n## Slots\n\n| 插槽名 | 说明 |\n| --------- | ------------------ |\n| `trigger` | 自定义颜色触发器。 |\n"
|
|
12892
|
-
},
|
|
12893
|
-
"en-US": {
|
|
12894
|
-
"title": "InputColor",
|
|
12895
|
-
"description": "Color picker with a palette and hexadecimal text input.",
|
|
12896
|
-
"sections": [
|
|
12897
|
-
{
|
|
12898
|
-
"id": "overview",
|
|
12899
|
-
"title": "",
|
|
12900
|
-
"body": "# InputColor\n\nEdit hex colors with the native color picker and a text field."
|
|
12901
|
-
},
|
|
12902
|
-
{
|
|
12903
|
-
"id": "when-to-use",
|
|
12904
|
-
"title": "When to use",
|
|
12905
|
-
"body": "- Use when a form needs a hex color value.\n- Prefer this when native picker + optional `swatches` is enough; not a full standalone color panel."
|
|
12906
|
-
},
|
|
12907
|
-
{
|
|
12908
|
-
"id": "import",
|
|
12909
|
-
"title": "Import",
|
|
12910
|
-
"body": "```ts\nimport { MInputColor } from \"morya-ui\";\n```"
|
|
12911
|
-
},
|
|
12912
|
-
{
|
|
12913
|
-
"id": "basic",
|
|
12914
|
-
"title": "Basic",
|
|
12915
|
-
"body": "```vue preview src=\"./demos/Basic.vue\"\n```"
|
|
12916
|
-
},
|
|
12917
|
-
{
|
|
12918
|
-
"id": "swatches",
|
|
12919
|
-
"title": "Swatches",
|
|
12920
|
-
"body": "`swatches` provides a row of preset colors.\n\n```vue preview src=\"./demos/Swatches.vue\"\n```"
|
|
12921
|
-
},
|
|
12922
|
-
{
|
|
12923
|
-
"id": "props",
|
|
12924
|
-
"title": "Props",
|
|
12925
|
-
"body": "| Prop | Type | Default | Description |\n| ------------ | -------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------- |\n| `modelValue` | `string` | `'#000000'` | Hexadecimal color. |\n| `swatches` | `string[]` | — | Preset color chips. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `id` | `string` | — | Color input id. |\n| `pt` | [FieldPassThrough](/docs/types#FieldPassThrough) `{ root?, label?, control?, input? }` | — | Pass-through; see [Styling & attrs](/docs/attrs). |"
|
|
12926
|
-
},
|
|
12927
|
-
{
|
|
12928
|
-
"id": "events",
|
|
12929
|
-
"title": "Events",
|
|
12930
|
-
"body": "| Event | Prop | Description |\n| ------------------- | -------- | -------------- |\n| `update:modelValue` | `string` | Color changed. |"
|
|
12931
|
-
},
|
|
12932
|
-
{
|
|
12933
|
-
"id": "boundaries",
|
|
12934
|
-
"title": "Boundaries",
|
|
12935
|
-
"body": "A **native picker + hex text + optional swatches**, not a full panel-level color experience."
|
|
12936
|
-
},
|
|
12937
|
-
{
|
|
12938
|
-
"id": "slots",
|
|
12939
|
-
"title": "Slots",
|
|
12940
|
-
"body": "| Slot | Description |\n| --------- | --------------------- |\n| `trigger` | Custom color trigger. |"
|
|
12941
|
-
}
|
|
12942
|
-
],
|
|
12943
|
-
"markdown": "---\ntitle: InputColor\ncategory: 02 / FORM\ndescription: Color picker with a palette and hexadecimal text input.\n---\n\n# InputColor\n\nEdit hex colors with the native color picker and a text field.\n\n## When to use\n\n- Use when a form needs a hex color value.\n- Prefer this when native picker + optional `swatches` is enough; not a full standalone color panel.\n\n## Import\n\n```ts\nimport { MInputColor } from \"morya-ui\";\n```\n\n## Basic\n\n```vue preview src=\"./demos/Basic.vue\"\n```\n\n## Swatches\n\n`swatches` provides a row of preset colors.\n\n```vue preview src=\"./demos/Swatches.vue\"\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| ------------ | -------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------- |\n| `modelValue` | `string` | `'#000000'` | Hexadecimal color. |\n| `swatches` | `string[]` | — | Preset color chips. |\n| `disabled` | `boolean` | `false` | Disabled. |\n| `id` | `string` | — | Color input id. |\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` | Color changed. |\n\n## Boundaries\n\nA **native picker + hex text + optional swatches**, not a full panel-level color experience.\n\n## Slots\n\n| Slot | Description |\n| --------- | --------------------- |\n| `trigger` | Custom color trigger. |\n"
|
|
12944
|
-
}
|
|
12945
|
-
}
|
|
12946
|
-
},
|
|
12947
13531
|
{
|
|
12948
13532
|
"id": "InputGroup",
|
|
12949
13533
|
"name": "InputGroup",
|
|
@@ -17783,7 +18367,7 @@
|
|
|
17783
18367
|
"exportName": "MOrderList",
|
|
17784
18368
|
"category": "03 / DATA",
|
|
17785
18369
|
"description": "列表拖拽与上下按钮排序。",
|
|
17786
|
-
"descriptionEn": "Reorder a list with drag
|
|
18370
|
+
"descriptionEn": "Reorder a list with drag handles and up/down buttons.",
|
|
17787
18371
|
"import": "import { MOrderList } from 'morya-ui'",
|
|
17788
18372
|
"props": [
|
|
17789
18373
|
{
|
|
@@ -17792,6 +18376,12 @@
|
|
|
17792
18376
|
"default": "[]",
|
|
17793
18377
|
"description": "列表数据。"
|
|
17794
18378
|
},
|
|
18379
|
+
{
|
|
18380
|
+
"name": "selection",
|
|
18381
|
+
"type": "number | null",
|
|
18382
|
+
"default": "—",
|
|
18383
|
+
"description": "受控选中下标,配合 `v-model:selection`。"
|
|
18384
|
+
},
|
|
17795
18385
|
{
|
|
17796
18386
|
"name": "dataKey",
|
|
17797
18387
|
"type": "string",
|
|
@@ -17810,15 +18400,21 @@
|
|
|
17810
18400
|
"default": "true",
|
|
17811
18401
|
"description": "是否启用拖拽。"
|
|
17812
18402
|
},
|
|
18403
|
+
{
|
|
18404
|
+
"name": "disabled",
|
|
18405
|
+
"type": "boolean",
|
|
18406
|
+
"default": "false",
|
|
18407
|
+
"description": "禁用全部交互(按钮、拖拽、选中)。"
|
|
18408
|
+
},
|
|
17813
18409
|
{
|
|
17814
18410
|
"name": "emptyMessage",
|
|
17815
18411
|
"type": "string",
|
|
17816
18412
|
"default": "—",
|
|
17817
|
-
"description": "
|
|
18413
|
+
"description": "空态文案,默认取 locale `emptyMessage`。"
|
|
17818
18414
|
},
|
|
17819
18415
|
{
|
|
17820
18416
|
"name": "pt",
|
|
17821
|
-
"type": "[
|
|
18417
|
+
"type": "[OrderListPassThrough](/docs/types#OrderListPassThrough)",
|
|
17822
18418
|
"default": "—",
|
|
17823
18419
|
"description": "DOM 透传,见 [样式与 attrs](/docs/attrs)."
|
|
17824
18420
|
}
|
|
@@ -17827,22 +18423,27 @@
|
|
|
17827
18423
|
{
|
|
17828
18424
|
"name": "update:modelValue",
|
|
17829
18425
|
"payload": "unknown[]",
|
|
17830
|
-
"description": "
|
|
18426
|
+
"description": "顺序变化后的新数组。"
|
|
18427
|
+
},
|
|
18428
|
+
{
|
|
18429
|
+
"name": "update:selection",
|
|
18430
|
+
"payload": "number | null",
|
|
18431
|
+
"description": "选中下标变化。"
|
|
17831
18432
|
},
|
|
17832
18433
|
{
|
|
17833
18434
|
"name": "reorder",
|
|
17834
|
-
"payload": "
|
|
17835
|
-
"description": "
|
|
18435
|
+
"payload": "{ item, from, to }",
|
|
18436
|
+
"description": "单次移动的详情(移动项、原下标、新下标)。"
|
|
17836
18437
|
}
|
|
17837
18438
|
],
|
|
17838
18439
|
"slots": [
|
|
17839
18440
|
{
|
|
17840
18441
|
"name": "item",
|
|
17841
|
-
"description": "`{ item, index }` 自定义项。"
|
|
18442
|
+
"description": "`{ item, index, selected, dragging }` 自定义项。"
|
|
17842
18443
|
},
|
|
17843
18444
|
{
|
|
17844
18445
|
"name": "empty",
|
|
17845
|
-
"description": "
|
|
18446
|
+
"description": "自定义空态内容。"
|
|
17846
18447
|
}
|
|
17847
18448
|
],
|
|
17848
18449
|
"methods": [],
|
|
@@ -17865,6 +18466,24 @@
|
|
|
17865
18466
|
"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
18467
|
"locale": "zh-CN"
|
|
17867
18468
|
},
|
|
18469
|
+
{
|
|
18470
|
+
"id": "禁用-1",
|
|
18471
|
+
"section": "禁用",
|
|
18472
|
+
"sectionId": "禁用",
|
|
18473
|
+
"lang": "vue",
|
|
18474
|
+
"preview": true,
|
|
18475
|
+
"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>",
|
|
18476
|
+
"locale": "zh-CN"
|
|
18477
|
+
},
|
|
18478
|
+
{
|
|
18479
|
+
"id": "自定义项-1",
|
|
18480
|
+
"section": "自定义项",
|
|
18481
|
+
"sectionId": "自定义项",
|
|
18482
|
+
"lang": "vue",
|
|
18483
|
+
"preview": true,
|
|
18484
|
+
"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>",
|
|
18485
|
+
"locale": "zh-CN"
|
|
18486
|
+
},
|
|
17868
18487
|
{
|
|
17869
18488
|
"id": "import-1",
|
|
17870
18489
|
"section": "Import",
|
|
@@ -17882,6 +18501,24 @@
|
|
|
17882
18501
|
"preview": true,
|
|
17883
18502
|
"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
18503
|
"locale": "en-US"
|
|
18504
|
+
},
|
|
18505
|
+
{
|
|
18506
|
+
"id": "disabled-1",
|
|
18507
|
+
"section": "Disabled",
|
|
18508
|
+
"sectionId": "disabled",
|
|
18509
|
+
"lang": "vue",
|
|
18510
|
+
"preview": true,
|
|
18511
|
+
"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>",
|
|
18512
|
+
"locale": "en-US"
|
|
18513
|
+
},
|
|
18514
|
+
{
|
|
18515
|
+
"id": "custom-item-1",
|
|
18516
|
+
"section": "Custom item",
|
|
18517
|
+
"sectionId": "custom-item",
|
|
18518
|
+
"lang": "vue",
|
|
18519
|
+
"preview": true,
|
|
18520
|
+
"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>",
|
|
18521
|
+
"locale": "en-US"
|
|
17885
18522
|
}
|
|
17886
18523
|
],
|
|
17887
18524
|
"locales": {
|
|
@@ -17892,7 +18529,7 @@
|
|
|
17892
18529
|
{
|
|
17893
18530
|
"id": "overview",
|
|
17894
18531
|
"title": "",
|
|
17895
|
-
"body": "# OrderList\n\n支持拖拽手柄重排(原生 HTML5 DnD
|
|
18532
|
+
"body": "# OrderList\n\n支持拖拽手柄重排(原生 HTML5 DnD,无外部拖拽库),并保留上下/置顶/置底按钮作为键盘友好备选。"
|
|
17896
18533
|
},
|
|
17897
18534
|
{
|
|
17898
18535
|
"id": "引入",
|
|
@@ -17904,32 +18541,52 @@
|
|
|
17904
18541
|
"title": "基础用法",
|
|
17905
18542
|
"body": "```vue preview src=\"./demos/Basic.zh.vue\"\n```"
|
|
17906
18543
|
},
|
|
18544
|
+
{
|
|
18545
|
+
"id": "禁用",
|
|
18546
|
+
"title": "禁用",
|
|
18547
|
+
"body": "```vue preview src=\"./demos/Disabled.zh.vue\"\n```"
|
|
18548
|
+
},
|
|
18549
|
+
{
|
|
18550
|
+
"id": "自定义项",
|
|
18551
|
+
"title": "自定义项",
|
|
18552
|
+
"body": "通过 `#item` 插槽自定义渲染,作用域含 `{ item, index, selected, dragging }`。\n\n```vue preview src=\"./demos/CustomItem.zh.vue\"\n```"
|
|
18553
|
+
},
|
|
18554
|
+
{
|
|
18555
|
+
"id": "键盘操作",
|
|
18556
|
+
"title": "键盘操作",
|
|
18557
|
+
"body": "| 按键 | 说明 |\n| --- | --- |\n| `↑` / `↓` | 移动选中项高亮。 |\n| `Ctrl/⌘ + ↑` / `Ctrl/⌘ + ↓` | 将选中项上移 / 下移一位。 |\n| `Ctrl/⌘ + Home` / `Ctrl/⌘ + End` | 将选中项置顶 / 置底。 |\n| `Home` / `End` | 高亮首项 / 末项。 |"
|
|
18558
|
+
},
|
|
17907
18559
|
{
|
|
17908
18560
|
"id": "props",
|
|
17909
18561
|
"title": "Props",
|
|
17910
|
-
"body": "| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `modelValue` | `unknown[]` | `[]` | 列表数据。 |\n| `dataKey` | `string` | — | 对象项的唯一键。 |\n| `listStyle` | `string \\| object` | — | 列表样式。 |\n| `dragdrop` | `boolean` | `true` | 是否启用拖拽。 |\n| `emptyMessage` | `string` | — |
|
|
18562
|
+
"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
18563
|
},
|
|
17912
18564
|
{
|
|
17913
18565
|
"id": "slots",
|
|
17914
18566
|
"title": "Slots",
|
|
17915
|
-
"body": "| 插槽 | 说明 |\n| --- | --- |\n| `item` | `{ item, index }` 自定义项。 |\n| `empty` |
|
|
18567
|
+
"body": "| 插槽 | 说明 |\n| --- | --- |\n| `item` | `{ item, index, selected, dragging }` 自定义项。 |\n| `empty` | 自定义空态内容。 |"
|
|
17916
18568
|
},
|
|
17917
18569
|
{
|
|
17918
18570
|
"id": "events",
|
|
17919
18571
|
"title": "Events",
|
|
17920
|
-
"body": "| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `unknown[]` |
|
|
18572
|
+
"body": "| 事件名 | 参数 | 说明 |\n| --- | --- | --- |\n| `update:modelValue` | `unknown[]` | 顺序变化后的新数组。 |\n| `update:selection` | `number \\| null` | 选中下标变化。 |\n| `reorder` | `{ item, from, to }` | 单次移动的详情(移动项、原下标、新下标)。 |"
|
|
18573
|
+
},
|
|
18574
|
+
{
|
|
18575
|
+
"id": "无障碍",
|
|
18576
|
+
"title": "无障碍",
|
|
18577
|
+
"body": "- 列表为 `role=\"listbox\"`,项为 `role=\"option\"`,选中项同步 `aria-selected`。\n- 拖拽仅在手柄 `pointerdown` 后启动,避免误触;键盘可完整完成所有排序操作。\n- `disabled` 时列表标记 `aria-disabled`,项不可聚焦、不可拖拽。"
|
|
17921
18578
|
}
|
|
17922
18579
|
],
|
|
17923
|
-
"markdown": "---\ntitle: OrderList\ncategory: 03 / DATA\ndescription: 列表拖拽与上下按钮排序。\n---\n\n# OrderList\n\n支持拖拽手柄重排(原生 HTML5 DnD
|
|
18580
|
+
"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
18581
|
},
|
|
17925
18582
|
"en-US": {
|
|
17926
18583
|
"title": "OrderList",
|
|
17927
|
-
"description": "Reorder a list with drag
|
|
18584
|
+
"description": "Reorder a list with drag handles and up/down buttons.",
|
|
17928
18585
|
"sections": [
|
|
17929
18586
|
{
|
|
17930
18587
|
"id": "overview",
|
|
17931
18588
|
"title": "",
|
|
17932
|
-
"body": "# OrderList\n\nReorder with
|
|
18589
|
+
"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
18590
|
},
|
|
17934
18591
|
{
|
|
17935
18592
|
"id": "import",
|
|
@@ -17941,23 +18598,43 @@
|
|
|
17941
18598
|
"title": "Basic",
|
|
17942
18599
|
"body": "```vue preview src=\"./demos/Basic.en.vue\"\n```"
|
|
17943
18600
|
},
|
|
18601
|
+
{
|
|
18602
|
+
"id": "disabled",
|
|
18603
|
+
"title": "Disabled",
|
|
18604
|
+
"body": "```vue preview src=\"./demos/Disabled.en.vue\"\n```"
|
|
18605
|
+
},
|
|
18606
|
+
{
|
|
18607
|
+
"id": "custom-item",
|
|
18608
|
+
"title": "Custom item",
|
|
18609
|
+
"body": "Customize rendering via the `#item` slot with scope `{ item, index, selected, dragging }`.\n\n```vue preview src=\"./demos/CustomItem.en.vue\"\n```"
|
|
18610
|
+
},
|
|
18611
|
+
{
|
|
18612
|
+
"id": "keyboard",
|
|
18613
|
+
"title": "Keyboard",
|
|
18614
|
+
"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. |"
|
|
18615
|
+
},
|
|
17944
18616
|
{
|
|
17945
18617
|
"id": "props",
|
|
17946
18618
|
"title": "Props",
|
|
17947
|
-
"body": "|
|
|
18619
|
+
"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
18620
|
},
|
|
17949
18621
|
{
|
|
17950
18622
|
"id": "slots",
|
|
17951
18623
|
"title": "Slots",
|
|
17952
|
-
"body": "| Slot | Description |\n| --- | --- |\n| `item` | `{ item, index }` custom item. |"
|
|
18624
|
+
"body": "| Slot | Description |\n| --- | --- |\n| `item` | `{ item, index, selected, dragging }` custom item. |\n| `empty` | Custom empty content. |"
|
|
17953
18625
|
},
|
|
17954
18626
|
{
|
|
17955
18627
|
"id": "events",
|
|
17956
18628
|
"title": "Events",
|
|
17957
|
-
"body": "| Event |
|
|
18629
|
+
"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). |"
|
|
18630
|
+
},
|
|
18631
|
+
{
|
|
18632
|
+
"id": "accessibility",
|
|
18633
|
+
"title": "Accessibility",
|
|
18634
|
+
"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
18635
|
}
|
|
17959
18636
|
],
|
|
17960
|
-
"markdown": "---\ntitle: OrderList\ncategory: 03 / DATA\ndescription: Reorder a list with drag
|
|
18637
|
+
"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
18638
|
}
|
|
17962
18639
|
}
|
|
17963
18640
|
},
|
|
@@ -25743,8 +26420,8 @@
|
|
|
25743
26420
|
"name": "Table",
|
|
25744
26421
|
"exportName": "MTable",
|
|
25745
26422
|
"category": "03 / DATA",
|
|
25746
|
-
"description": "
|
|
25747
|
-
"descriptionEn": "Data table with sorting, filtering, selection, pagination,
|
|
26423
|
+
"description": "数据表格。支持排序、筛选、选择、分页、固定列、列拖拽、列设置、骨架屏与虚拟滚动。列宽支持 width / minWidth / fit。",
|
|
26424
|
+
"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
26425
|
"import": "import { MTable } from 'morya-ui'",
|
|
25749
26426
|
"props": [
|
|
25750
26427
|
{
|
|
@@ -25855,6 +26532,18 @@
|
|
|
25855
26532
|
"default": "40",
|
|
25856
26533
|
"description": "虚拟行高估算。"
|
|
25857
26534
|
},
|
|
26535
|
+
{
|
|
26536
|
+
"name": "virtualDynamicRowHeight",
|
|
26537
|
+
"type": "boolean",
|
|
26538
|
+
"default": "false",
|
|
26539
|
+
"description": "动态行高虚拟滚动(实测行高缓存,配合 `ResizeObserver`)。"
|
|
26540
|
+
},
|
|
26541
|
+
{
|
|
26542
|
+
"name": "virtualOverscan",
|
|
26543
|
+
"type": "number",
|
|
26544
|
+
"default": "4",
|
|
26545
|
+
"description": "虚拟滚动上下额外渲染的行数,减少白屏闪烁。"
|
|
26546
|
+
},
|
|
25858
26547
|
{
|
|
25859
26548
|
"name": "hiddenColumns",
|
|
25860
26549
|
"type": "string[] | null",
|
|
@@ -25867,6 +26556,30 @@
|
|
|
25867
26556
|
"default": "null",
|
|
25868
26557
|
"description": "叶列顺序(`v-model:column-order`)。"
|
|
25869
26558
|
},
|
|
26559
|
+
{
|
|
26560
|
+
"name": "columnSetting",
|
|
26561
|
+
"type": "boolean",
|
|
26562
|
+
"default": "false",
|
|
26563
|
+
"description": "显示列设置按钮(显示/隐藏列)。"
|
|
26564
|
+
},
|
|
26565
|
+
{
|
|
26566
|
+
"name": "columnDrag",
|
|
26567
|
+
"type": "boolean",
|
|
26568
|
+
"default": "false",
|
|
26569
|
+
"description": "表头拖拽排序。"
|
|
26570
|
+
},
|
|
26571
|
+
{
|
|
26572
|
+
"name": "skeleton",
|
|
26573
|
+
"type": "boolean",
|
|
26574
|
+
"default": "false",
|
|
26575
|
+
"description": "骨架屏加载态。"
|
|
26576
|
+
},
|
|
26577
|
+
{
|
|
26578
|
+
"name": "skeletonRows",
|
|
26579
|
+
"type": "number",
|
|
26580
|
+
"default": "5",
|
|
26581
|
+
"description": "骨架屏行数。"
|
|
26582
|
+
},
|
|
25870
26583
|
{
|
|
25871
26584
|
"name": "showFooter",
|
|
25872
26585
|
"type": "boolean",
|
|
@@ -25939,23 +26652,41 @@
|
|
|
25939
26652
|
"default": "true",
|
|
25940
26653
|
"description": "行 hover 高亮。"
|
|
25941
26654
|
},
|
|
26655
|
+
{
|
|
26656
|
+
"name": "sortConfig",
|
|
26657
|
+
"type": "TableSortConfig | null",
|
|
26658
|
+
"default": "null",
|
|
26659
|
+
"description": "统一排序配置 `{ field, order, multiple, must, mode }`。"
|
|
26660
|
+
},
|
|
25942
26661
|
{
|
|
25943
26662
|
"name": "sortField",
|
|
25944
|
-
"type": "
|
|
25945
|
-
"default": "
|
|
25946
|
-
"description": "
|
|
26663
|
+
"type": "string | null",
|
|
26664
|
+
"default": "null",
|
|
26665
|
+
"description": "(兼容)单字段排序。建议用 `sortConfig`。"
|
|
25947
26666
|
},
|
|
25948
26667
|
{
|
|
25949
26668
|
"name": "sortOrder",
|
|
25950
|
-
"type": "
|
|
25951
|
-
"default": "
|
|
25952
|
-
"description": "
|
|
26669
|
+
"type": "'asc' | 'desc' | null",
|
|
26670
|
+
"default": "null",
|
|
26671
|
+
"description": "(兼容)单字段排序方向。建议用 `sortConfig`。"
|
|
26672
|
+
},
|
|
26673
|
+
{
|
|
26674
|
+
"name": "multiSort",
|
|
26675
|
+
"type": "boolean",
|
|
26676
|
+
"default": "false",
|
|
26677
|
+
"description": "(兼容)多列排序。建议用 `sortConfig.multiple`。"
|
|
26678
|
+
},
|
|
26679
|
+
{
|
|
26680
|
+
"name": "mustSort",
|
|
26681
|
+
"type": "boolean",
|
|
26682
|
+
"default": "false",
|
|
26683
|
+
"description": "(兼容)禁止取消排序。建议用 `sortConfig.must`。"
|
|
25953
26684
|
},
|
|
25954
26685
|
{
|
|
25955
26686
|
"name": "sortMode",
|
|
25956
26687
|
"type": "'client' | 'emit'",
|
|
25957
26688
|
"default": "'client'",
|
|
25958
|
-
"description": "
|
|
26689
|
+
"description": "(兼容)排序模式。建议用 `sortConfig.mode`。"
|
|
25959
26690
|
},
|
|
25960
26691
|
{
|
|
25961
26692
|
"name": "searchField",
|
|
@@ -25975,6 +26706,18 @@
|
|
|
25975
26706
|
"default": "null",
|
|
25976
26707
|
"description": "结构化筛选条件。"
|
|
25977
26708
|
},
|
|
26709
|
+
{
|
|
26710
|
+
"name": "filterModel",
|
|
26711
|
+
"type": "Record<string, unknown> | null",
|
|
26712
|
+
"default": "null",
|
|
26713
|
+
"description": "列筛选 v-model(与 `update:filter-model` 配合)。"
|
|
26714
|
+
},
|
|
26715
|
+
{
|
|
26716
|
+
"name": "filters",
|
|
26717
|
+
"type": "Record<string, unknown> | null",
|
|
26718
|
+
"default": "null",
|
|
26719
|
+
"description": "(兼容)旧筛选 v-model 名。"
|
|
26720
|
+
},
|
|
25978
26721
|
{
|
|
25979
26722
|
"name": "loading",
|
|
25980
26723
|
"type": "boolean",
|
|
@@ -26077,12 +26820,6 @@
|
|
|
26077
26820
|
"default": "—",
|
|
26078
26821
|
"description": "—"
|
|
26079
26822
|
},
|
|
26080
|
-
{
|
|
26081
|
-
"name": "filters",
|
|
26082
|
-
"type": "Record<string, unknown> | null",
|
|
26083
|
-
"default": "—",
|
|
26084
|
-
"description": "—"
|
|
26085
|
-
},
|
|
26086
26823
|
{
|
|
26087
26824
|
"name": "fixedCheckbox",
|
|
26088
26825
|
"type": "boolean",
|
|
@@ -26131,18 +26868,6 @@
|
|
|
26131
26868
|
"default": "—",
|
|
26132
26869
|
"description": "—"
|
|
26133
26870
|
},
|
|
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
26871
|
{
|
|
26147
26872
|
"name": "showIndex",
|
|
26148
26873
|
"type": "boolean",
|
|
@@ -26175,17 +26900,27 @@
|
|
|
26175
26900
|
},
|
|
26176
26901
|
{
|
|
26177
26902
|
"name": "pt",
|
|
26178
|
-
"type": "
|
|
26903
|
+
"type": "TablePassThrough",
|
|
26179
26904
|
"default": "—",
|
|
26180
|
-
"description": "DOM
|
|
26905
|
+
"description": "多部分 DOM 透传:`{ root, scrollbar, thead, tbody, tfoot, pagination, emptyMessage }`。"
|
|
26181
26906
|
}
|
|
26182
26907
|
],
|
|
26183
26908
|
"events": [
|
|
26184
26909
|
{
|
|
26185
|
-
"name": "sort",
|
|
26910
|
+
"name": "sort-change",
|
|
26186
26911
|
"payload": "{ sortField?, sortOrder? }",
|
|
26187
26912
|
"description": "排序变化。"
|
|
26188
26913
|
},
|
|
26914
|
+
{
|
|
26915
|
+
"name": "filter-change",
|
|
26916
|
+
"payload": "Record<string, unknown> | null",
|
|
26917
|
+
"description": "列筛选提交(与 `update:filter-model` 同步)。"
|
|
26918
|
+
},
|
|
26919
|
+
{
|
|
26920
|
+
"name": "expand-change",
|
|
26921
|
+
"payload": "{ row, expanded }",
|
|
26922
|
+
"description": "行展开状态变化(详情展开或树节点展开)。"
|
|
26923
|
+
},
|
|
26189
26924
|
{
|
|
26190
26925
|
"name": "row-click",
|
|
26191
26926
|
"payload": "{ row, index }`, `Event",
|
|
@@ -26221,11 +26956,6 @@
|
|
|
26221
26956
|
"payload": "row | null, oldRow | null",
|
|
26222
26957
|
"description": "当前高亮行变化。"
|
|
26223
26958
|
},
|
|
26224
|
-
{
|
|
26225
|
-
"name": "expand",
|
|
26226
|
-
"payload": "{ row, expanded }",
|
|
26227
|
-
"description": "行展开。"
|
|
26228
|
-
},
|
|
26229
26959
|
{
|
|
26230
26960
|
"name": "update:selection",
|
|
26231
26961
|
"payload": "TableItem[]",
|
|
@@ -26247,39 +26977,34 @@
|
|
|
26247
26977
|
"description": "当前行键 v-model。"
|
|
26248
26978
|
},
|
|
26249
26979
|
{
|
|
26250
|
-
"name": "
|
|
26251
|
-
"payload": "
|
|
26252
|
-
"description": "
|
|
26253
|
-
},
|
|
26254
|
-
{
|
|
26255
|
-
"name": "update:expandedRowKeys",
|
|
26256
|
-
"payload": "—",
|
|
26257
|
-
"description": "—"
|
|
26980
|
+
"name": "update:expanded-row-keys",
|
|
26981
|
+
"payload": "Array<string | number>",
|
|
26982
|
+
"description": "树/详情展开键 v-model。"
|
|
26258
26983
|
},
|
|
26259
26984
|
{
|
|
26260
|
-
"name": "update:
|
|
26261
|
-
"payload": "
|
|
26262
|
-
"description": "
|
|
26985
|
+
"name": "update:filter-model",
|
|
26986
|
+
"payload": "Record<string, unknown> | null",
|
|
26987
|
+
"description": "列筛选 v-model。"
|
|
26263
26988
|
},
|
|
26264
26989
|
{
|
|
26265
|
-
"name": "update:
|
|
26990
|
+
"name": "update:column-widths",
|
|
26266
26991
|
"payload": "Record<string, number>",
|
|
26267
26992
|
"description": "列宽 v-model。"
|
|
26268
26993
|
},
|
|
26269
26994
|
{
|
|
26270
|
-
"name": "update:
|
|
26995
|
+
"name": "update:hidden-columns",
|
|
26271
26996
|
"payload": "string[]",
|
|
26272
26997
|
"description": "隐藏列 v-model。"
|
|
26273
26998
|
},
|
|
26274
26999
|
{
|
|
26275
|
-
"name": "update:
|
|
27000
|
+
"name": "update:column-order",
|
|
26276
27001
|
"payload": "string[]",
|
|
26277
27002
|
"description": "列顺序 v-model。"
|
|
26278
27003
|
},
|
|
26279
27004
|
{
|
|
26280
|
-
"name": "update:
|
|
26281
|
-
"payload": "
|
|
26282
|
-
"description": "
|
|
27005
|
+
"name": "update:selected-item",
|
|
27006
|
+
"payload": "TableItem | null",
|
|
27007
|
+
"description": "单选 v-model。"
|
|
26283
27008
|
}
|
|
26284
27009
|
],
|
|
26285
27010
|
"slots": [
|
|
@@ -26305,7 +27030,7 @@
|
|
|
26305
27030
|
},
|
|
26306
27031
|
{
|
|
26307
27032
|
"name": "loading",
|
|
26308
|
-
"description": "
|
|
27033
|
+
"description": "自定义加载态(`skeleton` 为 true 时不生效)。"
|
|
26309
27034
|
},
|
|
26310
27035
|
{
|
|
26311
27036
|
"name": "pagination",
|
|
@@ -26501,7 +27226,7 @@
|
|
|
26501
27226
|
"sectionId": "引入",
|
|
26502
27227
|
"lang": "ts",
|
|
26503
27228
|
"preview": false,
|
|
26504
|
-
"code": "import type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'",
|
|
27229
|
+
"code": "import type { TableColumnDefinition, TableItem, TableSortConfig, TablePassThrough } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'",
|
|
26505
27230
|
"locale": "zh-CN"
|
|
26506
27231
|
},
|
|
26507
27232
|
{
|
|
@@ -26549,6 +27274,15 @@
|
|
|
26549
27274
|
"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
27275
|
"locale": "zh-CN"
|
|
26551
27276
|
},
|
|
27277
|
+
{
|
|
27278
|
+
"id": "排序-sortconfig-1",
|
|
27279
|
+
"section": "排序(sortConfig)",
|
|
27280
|
+
"sectionId": "排序-sortconfig",
|
|
27281
|
+
"lang": "vue",
|
|
27282
|
+
"preview": true,
|
|
27283
|
+
"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>",
|
|
27284
|
+
"locale": "zh-CN"
|
|
27285
|
+
},
|
|
26552
27286
|
{
|
|
26553
27287
|
"id": "列宽拖拽与表头筛选-1",
|
|
26554
27288
|
"section": "列宽拖拽与表头筛选",
|
|
@@ -26558,6 +27292,33 @@
|
|
|
26558
27292
|
"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
27293
|
"locale": "zh-CN"
|
|
26560
27294
|
},
|
|
27295
|
+
{
|
|
27296
|
+
"id": "列设置面板-1",
|
|
27297
|
+
"section": "列设置面板",
|
|
27298
|
+
"sectionId": "列设置面板",
|
|
27299
|
+
"lang": "vue",
|
|
27300
|
+
"preview": true,
|
|
27301
|
+
"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>",
|
|
27302
|
+
"locale": "zh-CN"
|
|
27303
|
+
},
|
|
27304
|
+
{
|
|
27305
|
+
"id": "列拖拽排序-1",
|
|
27306
|
+
"section": "列拖拽排序",
|
|
27307
|
+
"sectionId": "列拖拽排序",
|
|
27308
|
+
"lang": "vue",
|
|
27309
|
+
"preview": true,
|
|
27310
|
+
"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>",
|
|
27311
|
+
"locale": "zh-CN"
|
|
27312
|
+
},
|
|
27313
|
+
{
|
|
27314
|
+
"id": "骨架屏加载-1",
|
|
27315
|
+
"section": "骨架屏加载",
|
|
27316
|
+
"sectionId": "骨架屏加载",
|
|
27317
|
+
"lang": "vue",
|
|
27318
|
+
"preview": true,
|
|
27319
|
+
"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>",
|
|
27320
|
+
"locale": "zh-CN"
|
|
27321
|
+
},
|
|
26561
27322
|
{
|
|
26562
27323
|
"id": "虚拟滚动-1",
|
|
26563
27324
|
"section": "虚拟滚动",
|
|
@@ -26567,6 +27328,15 @@
|
|
|
26567
27328
|
"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
27329
|
"locale": "zh-CN"
|
|
26569
27330
|
},
|
|
27331
|
+
{
|
|
27332
|
+
"id": "动态行高虚拟滚动-1",
|
|
27333
|
+
"section": "动态行高虚拟滚动",
|
|
27334
|
+
"sectionId": "动态行高虚拟滚动",
|
|
27335
|
+
"lang": "vue",
|
|
27336
|
+
"preview": true,
|
|
27337
|
+
"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>",
|
|
27338
|
+
"locale": "zh-CN"
|
|
27339
|
+
},
|
|
26570
27340
|
{
|
|
26571
27341
|
"id": "多级表头-表尾与合并-1",
|
|
26572
27342
|
"section": "多级表头、表尾与合并",
|
|
@@ -26618,7 +27388,7 @@
|
|
|
26618
27388
|
"sectionId": "类型",
|
|
26619
27389
|
"lang": "ts",
|
|
26620
27390
|
"preview": false,
|
|
26621
|
-
"code": "
|
|
27391
|
+
"code": "interface TableSortConfig {\n field?: string | null\n order?: 'asc' | 'desc' | null\n multiple?: boolean\n must?: boolean\n mode?: 'client' | 'emit'\n}",
|
|
26622
27392
|
"locale": "zh-CN"
|
|
26623
27393
|
},
|
|
26624
27394
|
{
|
|
@@ -26627,7 +27397,7 @@
|
|
|
26627
27397
|
"sectionId": "类型",
|
|
26628
27398
|
"lang": "ts",
|
|
26629
27399
|
"preview": false,
|
|
26630
|
-
"code": "
|
|
27400
|
+
"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
27401
|
"locale": "zh-CN"
|
|
26632
27402
|
},
|
|
26633
27403
|
{
|
|
@@ -26636,7 +27406,7 @@
|
|
|
26636
27406
|
"sectionId": "类型",
|
|
26637
27407
|
"lang": "ts",
|
|
26638
27408
|
"preview": false,
|
|
26639
|
-
"code": "type
|
|
27409
|
+
"code": "type TableTextDirection = 'left' | 'center' | 'right'",
|
|
26640
27410
|
"locale": "zh-CN"
|
|
26641
27411
|
},
|
|
26642
27412
|
{
|
|
@@ -26645,7 +27415,7 @@
|
|
|
26645
27415
|
"sectionId": "类型",
|
|
26646
27416
|
"lang": "ts",
|
|
26647
27417
|
"preview": false,
|
|
26648
|
-
"code": "type
|
|
27418
|
+
"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
27419
|
"locale": "zh-CN"
|
|
26650
27420
|
},
|
|
26651
27421
|
{
|
|
@@ -26654,7 +27424,7 @@
|
|
|
26654
27424
|
"sectionId": "类型",
|
|
26655
27425
|
"lang": "ts",
|
|
26656
27426
|
"preview": false,
|
|
26657
|
-
"code": "type
|
|
27427
|
+
"code": "type TableHeaderItemClassName = string | ((header: TableHeader, columnNumber: number) => string)",
|
|
26658
27428
|
"locale": "zh-CN"
|
|
26659
27429
|
},
|
|
26660
27430
|
{
|
|
@@ -26663,7 +27433,7 @@
|
|
|
26663
27433
|
"sectionId": "类型",
|
|
26664
27434
|
"lang": "ts",
|
|
26665
27435
|
"preview": false,
|
|
26666
|
-
"code": "
|
|
27436
|
+
"code": "type TableBodyRowClassName = string | ((item: TableItem, rowNumber: number) => string)",
|
|
26667
27437
|
"locale": "zh-CN"
|
|
26668
27438
|
},
|
|
26669
27439
|
{
|
|
@@ -26672,7 +27442,7 @@
|
|
|
26672
27442
|
"sectionId": "类型",
|
|
26673
27443
|
"lang": "ts",
|
|
26674
27444
|
"preview": false,
|
|
26675
|
-
"code": "
|
|
27445
|
+
"code": "type TableBodyItemClassName = string | ((column: string, rowNumber: number) => string)",
|
|
26676
27446
|
"locale": "zh-CN"
|
|
26677
27447
|
},
|
|
26678
27448
|
{
|
|
@@ -26681,6 +27451,24 @@
|
|
|
26681
27451
|
"sectionId": "类型",
|
|
26682
27452
|
"lang": "ts",
|
|
26683
27453
|
"preview": false,
|
|
27454
|
+
"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}",
|
|
27455
|
+
"locale": "zh-CN"
|
|
27456
|
+
},
|
|
27457
|
+
{
|
|
27458
|
+
"id": "类型-10",
|
|
27459
|
+
"section": "类型",
|
|
27460
|
+
"sectionId": "类型",
|
|
27461
|
+
"lang": "ts",
|
|
27462
|
+
"preview": false,
|
|
27463
|
+
"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}",
|
|
27464
|
+
"locale": "zh-CN"
|
|
27465
|
+
},
|
|
27466
|
+
{
|
|
27467
|
+
"id": "类型-11",
|
|
27468
|
+
"section": "类型",
|
|
27469
|
+
"sectionId": "类型",
|
|
27470
|
+
"lang": "ts",
|
|
27471
|
+
"preview": false,
|
|
26684
27472
|
"code": "interface TableServerOptions {\n page: number\n rowsPerPage: number\n sortBy?: string | string[]\n sortType?: 'asc' | 'desc' | ('asc' | 'desc')[]\n}",
|
|
26685
27473
|
"locale": "zh-CN"
|
|
26686
27474
|
},
|
|
@@ -26690,7 +27478,7 @@
|
|
|
26690
27478
|
"sectionId": "import",
|
|
26691
27479
|
"lang": "ts",
|
|
26692
27480
|
"preview": false,
|
|
26693
|
-
"code": "import type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'",
|
|
27481
|
+
"code": "import type { TableColumnDefinition, TableItem, TableSortConfig, TablePassThrough } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'",
|
|
26694
27482
|
"locale": "en-US"
|
|
26695
27483
|
},
|
|
26696
27484
|
{
|
|
@@ -26703,72 +27491,117 @@
|
|
|
26703
27491
|
"locale": "en-US"
|
|
26704
27492
|
},
|
|
26705
27493
|
{
|
|
26706
|
-
"id": "selection-1",
|
|
26707
|
-
"section": "Selection",
|
|
26708
|
-
"sectionId": "selection",
|
|
27494
|
+
"id": "row-selection-1",
|
|
27495
|
+
"section": "Row Selection",
|
|
27496
|
+
"sectionId": "row-selection",
|
|
26709
27497
|
"lang": "vue",
|
|
26710
27498
|
"preview": true,
|
|
26711
27499
|
"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
27500
|
"locale": "en-US"
|
|
26713
27501
|
},
|
|
26714
27502
|
{
|
|
26715
|
-
"id": "
|
|
26716
|
-
"section": "
|
|
26717
|
-
"sectionId": "
|
|
27503
|
+
"id": "filtering-pagination-1",
|
|
27504
|
+
"section": "Filtering & Pagination",
|
|
27505
|
+
"sectionId": "filtering-pagination",
|
|
26718
27506
|
"lang": "vue",
|
|
26719
27507
|
"preview": true,
|
|
26720
27508
|
"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
27509
|
"locale": "en-US"
|
|
26722
27510
|
},
|
|
26723
27511
|
{
|
|
26724
|
-
"id": "
|
|
26725
|
-
"section": "
|
|
26726
|
-
"sectionId": "
|
|
27512
|
+
"id": "fixed-columns-1",
|
|
27513
|
+
"section": "Fixed Columns",
|
|
27514
|
+
"sectionId": "fixed-columns",
|
|
27515
|
+
"lang": "vue",
|
|
27516
|
+
"preview": true,
|
|
27517
|
+
"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>",
|
|
27518
|
+
"locale": "en-US"
|
|
27519
|
+
},
|
|
27520
|
+
{
|
|
27521
|
+
"id": "expandable-rows-cell-rendering-1",
|
|
27522
|
+
"section": "Expandable Rows & Cell Rendering",
|
|
27523
|
+
"sectionId": "expandable-rows-cell-rendering",
|
|
26727
27524
|
"lang": "vue",
|
|
26728
27525
|
"preview": true,
|
|
26729
27526
|
"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
27527
|
"locale": "en-US"
|
|
26731
27528
|
},
|
|
26732
27529
|
{
|
|
26733
|
-
"id": "
|
|
26734
|
-
"section": "
|
|
26735
|
-
"sectionId": "
|
|
27530
|
+
"id": "sorting-sortconfig-1",
|
|
27531
|
+
"section": "Sorting (sortConfig)",
|
|
27532
|
+
"sectionId": "sorting-sortconfig",
|
|
26736
27533
|
"lang": "vue",
|
|
26737
27534
|
"preview": true,
|
|
26738
|
-
"code": "<script setup lang=\"ts\">\nimport { MTable } from 'morya-ui'\n\nconst columns = [\n { key: 'name', label: '
|
|
27535
|
+
"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
27536
|
"locale": "en-US"
|
|
26740
27537
|
},
|
|
26741
27538
|
{
|
|
26742
|
-
"id": "column-
|
|
26743
|
-
"section": "Column
|
|
26744
|
-
"sectionId": "column-
|
|
27539
|
+
"id": "column-resizing-header-filters-1",
|
|
27540
|
+
"section": "Column Resizing & Header Filters",
|
|
27541
|
+
"sectionId": "column-resizing-header-filters",
|
|
26745
27542
|
"lang": "vue",
|
|
26746
27543
|
"preview": true,
|
|
26747
27544
|
"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
27545
|
"locale": "en-US"
|
|
26749
27546
|
},
|
|
26750
27547
|
{
|
|
26751
|
-
"id": "
|
|
26752
|
-
"section": "
|
|
26753
|
-
"sectionId": "
|
|
27548
|
+
"id": "column-settings-panel-1",
|
|
27549
|
+
"section": "Column Settings Panel",
|
|
27550
|
+
"sectionId": "column-settings-panel",
|
|
27551
|
+
"lang": "vue",
|
|
27552
|
+
"preview": true,
|
|
27553
|
+
"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>",
|
|
27554
|
+
"locale": "en-US"
|
|
27555
|
+
},
|
|
27556
|
+
{
|
|
27557
|
+
"id": "column-drag-1",
|
|
27558
|
+
"section": "Column Drag",
|
|
27559
|
+
"sectionId": "column-drag",
|
|
27560
|
+
"lang": "vue",
|
|
27561
|
+
"preview": true,
|
|
27562
|
+
"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>",
|
|
27563
|
+
"locale": "en-US"
|
|
27564
|
+
},
|
|
27565
|
+
{
|
|
27566
|
+
"id": "skeleton-loading-1",
|
|
27567
|
+
"section": "Skeleton Loading",
|
|
27568
|
+
"sectionId": "skeleton-loading",
|
|
27569
|
+
"lang": "vue",
|
|
27570
|
+
"preview": true,
|
|
27571
|
+
"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>",
|
|
27572
|
+
"locale": "en-US"
|
|
27573
|
+
},
|
|
27574
|
+
{
|
|
27575
|
+
"id": "virtual-scrolling-1",
|
|
27576
|
+
"section": "Virtual Scrolling",
|
|
27577
|
+
"sectionId": "virtual-scrolling",
|
|
26754
27578
|
"lang": "vue",
|
|
26755
27579
|
"preview": true,
|
|
26756
27580
|
"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
27581
|
"locale": "en-US"
|
|
26758
27582
|
},
|
|
26759
27583
|
{
|
|
26760
|
-
"id": "
|
|
26761
|
-
"section": "
|
|
26762
|
-
"sectionId": "
|
|
27584
|
+
"id": "dynamic-row-height-virtual-scrolling-1",
|
|
27585
|
+
"section": "Dynamic Row Height Virtual Scrolling",
|
|
27586
|
+
"sectionId": "dynamic-row-height-virtual-scrolling",
|
|
27587
|
+
"lang": "vue",
|
|
27588
|
+
"preview": true,
|
|
27589
|
+
"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>",
|
|
27590
|
+
"locale": "en-US"
|
|
27591
|
+
},
|
|
27592
|
+
{
|
|
27593
|
+
"id": "multi-level-headers-footer-span-1",
|
|
27594
|
+
"section": "Multi-level Headers, Footer & Span",
|
|
27595
|
+
"sectionId": "multi-level-headers-footer-span",
|
|
26763
27596
|
"lang": "vue",
|
|
26764
27597
|
"preview": true,
|
|
26765
27598
|
"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
27599
|
"locale": "en-US"
|
|
26767
27600
|
},
|
|
26768
27601
|
{
|
|
26769
|
-
"id": "empty-
|
|
26770
|
-
"section": "Empty
|
|
26771
|
-
"sectionId": "empty-
|
|
27602
|
+
"id": "empty-loading-1",
|
|
27603
|
+
"section": "Empty & Loading",
|
|
27604
|
+
"sectionId": "empty-loading",
|
|
26772
27605
|
"lang": "vue",
|
|
26773
27606
|
"preview": true,
|
|
26774
27607
|
"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 +27609,7 @@
|
|
|
26776
27609
|
},
|
|
26777
27610
|
{
|
|
26778
27611
|
"id": "tree-table-1",
|
|
26779
|
-
"section": "Tree
|
|
27612
|
+
"section": "Tree Table",
|
|
26780
27613
|
"sectionId": "tree-table",
|
|
26781
27614
|
"lang": "vue",
|
|
26782
27615
|
"preview": true,
|
|
@@ -26785,7 +27618,7 @@
|
|
|
26785
27618
|
},
|
|
26786
27619
|
{
|
|
26787
27620
|
"id": "server-mode-1",
|
|
26788
|
-
"section": "Server
|
|
27621
|
+
"section": "Server Mode",
|
|
26789
27622
|
"sectionId": "server-mode",
|
|
26790
27623
|
"lang": "vue",
|
|
26791
27624
|
"preview": true,
|
|
@@ -26807,7 +27640,7 @@
|
|
|
26807
27640
|
"sectionId": "types",
|
|
26808
27641
|
"lang": "ts",
|
|
26809
27642
|
"preview": false,
|
|
26810
|
-
"code": "interface
|
|
27643
|
+
"code": "interface TableSortConfig {\n field?: string | null\n order?: 'asc' | 'desc' | null\n multiple?: boolean\n must?: boolean\n mode?: 'client' | 'emit'\n}",
|
|
26811
27644
|
"locale": "en-US"
|
|
26812
27645
|
},
|
|
26813
27646
|
{
|
|
@@ -26816,6 +27649,78 @@
|
|
|
26816
27649
|
"sectionId": "types",
|
|
26817
27650
|
"lang": "ts",
|
|
26818
27651
|
"preview": false,
|
|
27652
|
+
"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}",
|
|
27653
|
+
"locale": "en-US"
|
|
27654
|
+
},
|
|
27655
|
+
{
|
|
27656
|
+
"id": "types-4",
|
|
27657
|
+
"section": "Types",
|
|
27658
|
+
"sectionId": "types",
|
|
27659
|
+
"lang": "ts",
|
|
27660
|
+
"preview": false,
|
|
27661
|
+
"code": "type TableTextDirection = 'left' | 'center' | 'right'",
|
|
27662
|
+
"locale": "en-US"
|
|
27663
|
+
},
|
|
27664
|
+
{
|
|
27665
|
+
"id": "types-5",
|
|
27666
|
+
"section": "Types",
|
|
27667
|
+
"sectionId": "types",
|
|
27668
|
+
"lang": "ts",
|
|
27669
|
+
"preview": false,
|
|
27670
|
+
"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 }",
|
|
27671
|
+
"locale": "en-US"
|
|
27672
|
+
},
|
|
27673
|
+
{
|
|
27674
|
+
"id": "types-6",
|
|
27675
|
+
"section": "Types",
|
|
27676
|
+
"sectionId": "types",
|
|
27677
|
+
"lang": "ts",
|
|
27678
|
+
"preview": false,
|
|
27679
|
+
"code": "type TableHeaderItemClassName = string | ((header: TableHeader, columnNumber: number) => string)",
|
|
27680
|
+
"locale": "en-US"
|
|
27681
|
+
},
|
|
27682
|
+
{
|
|
27683
|
+
"id": "types-7",
|
|
27684
|
+
"section": "Types",
|
|
27685
|
+
"sectionId": "types",
|
|
27686
|
+
"lang": "ts",
|
|
27687
|
+
"preview": false,
|
|
27688
|
+
"code": "type TableBodyRowClassName = string | ((item: TableItem, rowNumber: number) => string)",
|
|
27689
|
+
"locale": "en-US"
|
|
27690
|
+
},
|
|
27691
|
+
{
|
|
27692
|
+
"id": "types-8",
|
|
27693
|
+
"section": "Types",
|
|
27694
|
+
"sectionId": "types",
|
|
27695
|
+
"lang": "ts",
|
|
27696
|
+
"preview": false,
|
|
27697
|
+
"code": "type TableBodyItemClassName = string | ((column: string, rowNumber: number) => string)",
|
|
27698
|
+
"locale": "en-US"
|
|
27699
|
+
},
|
|
27700
|
+
{
|
|
27701
|
+
"id": "types-9",
|
|
27702
|
+
"section": "Types",
|
|
27703
|
+
"sectionId": "types",
|
|
27704
|
+
"lang": "ts",
|
|
27705
|
+
"preview": false,
|
|
27706
|
+
"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}",
|
|
27707
|
+
"locale": "en-US"
|
|
27708
|
+
},
|
|
27709
|
+
{
|
|
27710
|
+
"id": "types-10",
|
|
27711
|
+
"section": "Types",
|
|
27712
|
+
"sectionId": "types",
|
|
27713
|
+
"lang": "ts",
|
|
27714
|
+
"preview": false,
|
|
27715
|
+
"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}",
|
|
27716
|
+
"locale": "en-US"
|
|
27717
|
+
},
|
|
27718
|
+
{
|
|
27719
|
+
"id": "types-11",
|
|
27720
|
+
"section": "Types",
|
|
27721
|
+
"sectionId": "types",
|
|
27722
|
+
"lang": "ts",
|
|
27723
|
+
"preview": false,
|
|
26819
27724
|
"code": "interface TableServerOptions {\n page: number\n rowsPerPage: number\n sortBy?: string | string[]\n sortType?: 'asc' | 'desc' | ('asc' | 'desc')[]\n}",
|
|
26820
27725
|
"locale": "en-US"
|
|
26821
27726
|
}
|
|
@@ -26823,7 +27728,7 @@
|
|
|
26823
27728
|
"locales": {
|
|
26824
27729
|
"zh-CN": {
|
|
26825
27730
|
"title": "Table",
|
|
26826
|
-
"description": "
|
|
27731
|
+
"description": "数据表格。支持排序、筛选、选择、分页、固定列、列拖拽、列设置、骨架屏与虚拟滚动。列宽支持 width / minWidth / fit。",
|
|
26827
27732
|
"sections": [
|
|
26828
27733
|
{
|
|
26829
27734
|
"id": "overview",
|
|
@@ -26833,7 +27738,7 @@
|
|
|
26833
27738
|
{
|
|
26834
27739
|
"id": "引入",
|
|
26835
27740
|
"title": "引入",
|
|
26836
|
-
"body": "```ts\nimport type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```"
|
|
27741
|
+
"body": "```ts\nimport type { TableColumnDefinition, TableItem, TableSortConfig, TablePassThrough } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```"
|
|
26837
27742
|
},
|
|
26838
27743
|
{
|
|
26839
27744
|
"id": "基础用法",
|
|
@@ -26860,16 +27765,41 @@
|
|
|
26860
27765
|
"title": "展开行与列渲染",
|
|
26861
27766
|
"body": "列可通过 `render` 或 `#cell-{key}` 自定义单元格。展开行设置 `expandable`(或 `expandConfig`),详情由 `#expansion` 提供。树模式下 `expandedRowKeys` 用于树节点展开,不可同时用于详情展开。\n\n```vue preview src=\"./demos/ExpandableRows.zh.vue\"\n```"
|
|
26862
27767
|
},
|
|
27768
|
+
{
|
|
27769
|
+
"id": "排序-sortconfig",
|
|
27770
|
+
"title": "排序(sortConfig)",
|
|
27771
|
+
"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```"
|
|
27772
|
+
},
|
|
26863
27773
|
{
|
|
26864
27774
|
"id": "列宽拖拽与表头筛选",
|
|
26865
27775
|
"title": "列宽拖拽与表头筛选",
|
|
26866
|
-
"body": "列设置 `resizable` 可拖拽改宽(`v-model:column-widths`);`filterable`
|
|
27776
|
+
"body": "列设置 `resizable` 可拖拽改宽(`v-model:column-widths`);`filterable` 显示表头筛选,列定义里的 `filters` 为多选选项,省略则为文本包含筛选。面板内 **清除** 仅重置草稿,**确认** 后才写入 `v-model:filter-model`(旧 prop 名 `filters` 仍兼容)。\n\n```vue preview src=\"./demos/ResizeAndFilter.zh.vue\"\n```"
|
|
27777
|
+
},
|
|
27778
|
+
{
|
|
27779
|
+
"id": "列设置面板",
|
|
27780
|
+
"title": "列设置面板",
|
|
27781
|
+
"body": "开启 `column-setting` 在表头右上角显示「列设置」按钮,弹出面板可勾选显示/隐藏列,配合 `v-model:hidden-columns` 持久化。面板文案随 `MLocale` 切换。\n\n```vue preview src=\"./demos/ColumnSetting.zh.vue\"\n```"
|
|
27782
|
+
},
|
|
27783
|
+
{
|
|
27784
|
+
"id": "列拖拽排序",
|
|
27785
|
+
"title": "列拖拽排序",
|
|
27786
|
+
"body": "开启 `column-drag` 后,拖拽表头单元格可调整叶列顺序,顺序由 `v-model:column-order` 同步。拖放仅在同一层级内进行,不会破坏多级表头结构。\n\n```vue preview src=\"./demos/ColumnDrag.zh.vue\"\n```"
|
|
27787
|
+
},
|
|
27788
|
+
{
|
|
27789
|
+
"id": "骨架屏加载",
|
|
27790
|
+
"title": "骨架屏加载",
|
|
27791
|
+
"body": "通过 `skeleton` 启用骨架屏加载态,替代整页遮罩 spinner;`skeleton-rows` 控制骨架行数(默认 `5`)。骨架屏会让用户提前感知表格布局,加载体验更好。\n\n```vue preview src=\"./demos/Skeleton.zh.vue\"\n```"
|
|
26867
27792
|
},
|
|
26868
27793
|
{
|
|
26869
27794
|
"id": "虚拟滚动",
|
|
26870
27795
|
"title": "虚拟滚动",
|
|
26871
27796
|
"body": "开启 `virtual`,并提供 `maxHeight` / `tableHeight` / `fill` 之一以形成滚动视口;缺高度时开发环境会 `console.warn`。展开行 / `#expansion` / `expandConfig` 与虚拟滚动互斥,会自动降级为普通渲染(开发环境会提示)。\n\n```vue preview src=\"./demos/VirtualScroll.zh.vue\"\n```"
|
|
26872
27797
|
},
|
|
27798
|
+
{
|
|
27799
|
+
"id": "动态行高虚拟滚动",
|
|
27800
|
+
"title": "动态行高虚拟滚动",
|
|
27801
|
+
"body": "默认虚拟滚动要求所有行等高(由 `virtual-row-height` 估算)。如果某些行由于内容差异存在不同高度,可开启 `virtual-dynamic-row-height`:表格会通过 `ResizeObserver` 实测每行高度并缓存,配合前缀和 + 二分查找实现 O(log n) 滚动定位,长列表下滚动仍保持流畅。\n\n```vue preview src=\"./demos/DynamicRowHeight.zh.vue\"\n```"
|
|
27802
|
+
},
|
|
26873
27803
|
{
|
|
26874
27804
|
"id": "多级表头-表尾与合并",
|
|
26875
27805
|
"title": "多级表头、表尾与合并",
|
|
@@ -26893,7 +27823,7 @@
|
|
|
26893
27823
|
{
|
|
26894
27824
|
"id": "breaking-changes",
|
|
26895
27825
|
"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`"
|
|
27826
|
+
"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
27827
|
},
|
|
26898
27828
|
{
|
|
26899
27829
|
"id": "tablecolumndefinition",
|
|
@@ -26903,17 +27833,17 @@
|
|
|
26903
27833
|
{
|
|
26904
27834
|
"id": "props",
|
|
26905
27835
|
"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`
|
|
27836
|
+
"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
27837
|
},
|
|
26908
27838
|
{
|
|
26909
27839
|
"id": "slots",
|
|
26910
27840
|
"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` |
|
|
27841
|
+
"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
27842
|
},
|
|
26913
27843
|
{
|
|
26914
27844
|
"id": "events",
|
|
26915
27845
|
"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| `
|
|
27846
|
+
"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
27847
|
},
|
|
26918
27848
|
{
|
|
26919
27849
|
"id": "实例方法",
|
|
@@ -26923,24 +27853,24 @@
|
|
|
26923
27853
|
{
|
|
26924
27854
|
"id": "类型",
|
|
26925
27855
|
"title": "类型",
|
|
26926
|
-
"body": "<h4 id=\"TableItem\">TableItem</h4>\n\n
|
|
27856
|
+
"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
27857
|
}
|
|
26928
27858
|
],
|
|
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"
|
|
27859
|
+
"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
27860
|
},
|
|
26931
27861
|
"en-US": {
|
|
26932
27862
|
"title": "Table",
|
|
26933
|
-
"description": "Data table with sorting, filtering, selection, pagination,
|
|
27863
|
+
"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
27864
|
"sections": [
|
|
26935
27865
|
{
|
|
26936
27866
|
"id": "overview",
|
|
26937
27867
|
"title": "",
|
|
26938
|
-
"body": "# Table\n\n`MTable`
|
|
27868
|
+
"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
27869
|
},
|
|
26940
27870
|
{
|
|
26941
27871
|
"id": "import",
|
|
26942
27872
|
"title": "Import",
|
|
26943
|
-
"body": "```ts\nimport type { TableColumnDefinition, TableItem } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```"
|
|
27873
|
+
"body": "```ts\nimport type { TableColumnDefinition, TableItem, TableSortConfig, TablePassThrough } from 'morya-ui'\nimport { MTable, MTag } from 'morya-ui'\n```"
|
|
26944
27874
|
},
|
|
26945
27875
|
{
|
|
26946
27876
|
"id": "basic",
|
|
@@ -26948,92 +27878,117 @@
|
|
|
26948
27878
|
"body": "```vue preview src=\"./demos/Basic.en.vue\"\n```"
|
|
26949
27879
|
},
|
|
26950
27880
|
{
|
|
26951
|
-
"id": "selection",
|
|
26952
|
-
"title": "Selection",
|
|
26953
|
-
"body": "
|
|
27881
|
+
"id": "row-selection",
|
|
27882
|
+
"title": "Row Selection",
|
|
27883
|
+
"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
27884
|
},
|
|
26955
27885
|
{
|
|
26956
|
-
"id": "
|
|
26957
|
-
"title": "
|
|
26958
|
-
"body": "
|
|
27886
|
+
"id": "filtering-pagination",
|
|
27887
|
+
"title": "Filtering & Pagination",
|
|
27888
|
+
"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
27889
|
},
|
|
26960
27890
|
{
|
|
26961
|
-
"id": "
|
|
26962
|
-
"title": "
|
|
26963
|
-
"body": "
|
|
27891
|
+
"id": "fixed-columns",
|
|
27892
|
+
"title": "Fixed Columns",
|
|
27893
|
+
"body": "Set `fixed: 'left' | 'right'` in the column definition (`fixed: true` equals left).\n\n```vue preview src=\"./demos/FixedColumns.en.vue\"\n```"
|
|
26964
27894
|
},
|
|
26965
27895
|
{
|
|
26966
|
-
"id": "
|
|
26967
|
-
"title": "
|
|
26968
|
-
"body": "
|
|
27896
|
+
"id": "expandable-rows-cell-rendering",
|
|
27897
|
+
"title": "Expandable Rows & Cell Rendering",
|
|
27898
|
+
"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```"
|
|
27899
|
+
},
|
|
27900
|
+
{
|
|
27901
|
+
"id": "sorting-sortconfig",
|
|
27902
|
+
"title": "Sorting (sortConfig)",
|
|
27903
|
+
"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```"
|
|
27904
|
+
},
|
|
27905
|
+
{
|
|
27906
|
+
"id": "column-resizing-header-filters",
|
|
27907
|
+
"title": "Column Resizing & Header Filters",
|
|
27908
|
+
"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```"
|
|
26969
27909
|
},
|
|
26970
27910
|
{
|
|
26971
|
-
"id": "column-
|
|
26972
|
-
"title": "Column
|
|
26973
|
-
"body": "
|
|
27911
|
+
"id": "column-settings-panel",
|
|
27912
|
+
"title": "Column Settings Panel",
|
|
27913
|
+
"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```"
|
|
26974
27914
|
},
|
|
26975
27915
|
{
|
|
26976
|
-
"id": "
|
|
26977
|
-
"title": "
|
|
26978
|
-
"body": "Enable `
|
|
27916
|
+
"id": "column-drag",
|
|
27917
|
+
"title": "Column Drag",
|
|
27918
|
+
"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```"
|
|
26979
27919
|
},
|
|
26980
27920
|
{
|
|
26981
|
-
"id": "
|
|
26982
|
-
"title": "
|
|
26983
|
-
"body": "
|
|
27921
|
+
"id": "skeleton-loading",
|
|
27922
|
+
"title": "Skeleton Loading",
|
|
27923
|
+
"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```"
|
|
26984
27924
|
},
|
|
26985
27925
|
{
|
|
26986
|
-
"id": "
|
|
26987
|
-
"title": "
|
|
27926
|
+
"id": "virtual-scrolling",
|
|
27927
|
+
"title": "Virtual Scrolling",
|
|
27928
|
+
"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```"
|
|
27929
|
+
},
|
|
27930
|
+
{
|
|
27931
|
+
"id": "dynamic-row-height-virtual-scrolling",
|
|
27932
|
+
"title": "Dynamic Row Height Virtual Scrolling",
|
|
27933
|
+
"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```"
|
|
27934
|
+
},
|
|
27935
|
+
{
|
|
27936
|
+
"id": "multi-level-headers-footer-span",
|
|
27937
|
+
"title": "Multi-level Headers, Footer & Span",
|
|
27938
|
+
"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```"
|
|
27939
|
+
},
|
|
27940
|
+
{
|
|
27941
|
+
"id": "empty-loading",
|
|
27942
|
+
"title": "Empty & Loading",
|
|
26988
27943
|
"body": "```vue preview src=\"./demos/EmptyAndLoading.en.vue\"\n```"
|
|
26989
27944
|
},
|
|
26990
27945
|
{
|
|
26991
27946
|
"id": "tree-table",
|
|
26992
|
-
"title": "Tree
|
|
26993
|
-
"body": "Pass `tree-config`
|
|
27947
|
+
"title": "Tree Table",
|
|
27948
|
+
"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
27949
|
},
|
|
26995
27950
|
{
|
|
26996
27951
|
"id": "server-mode",
|
|
26997
|
-
"title": "Server
|
|
26998
|
-
"body": "Pass `server-options`
|
|
27952
|
+
"title": "Server Mode",
|
|
27953
|
+
"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
27954
|
},
|
|
27000
27955
|
{
|
|
27001
27956
|
"id": "breaking-changes",
|
|
27002
27957
|
"title": "Breaking changes",
|
|
27003
|
-
"body": "-
|
|
27958
|
+
"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
27959
|
},
|
|
27005
27960
|
{
|
|
27006
27961
|
"id": "tablecolumndefinition",
|
|
27007
27962
|
"title": "TableColumnDefinition",
|
|
27008
|
-
"body": "| Field | Type | Description |\n| --- | --- | --- |\n| `key` | `string` | Field name
|
|
27963
|
+
"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
27964
|
},
|
|
27010
27965
|
{
|
|
27011
27966
|
"id": "props",
|
|
27012
27967
|
"title": "Props",
|
|
27013
|
-
"body": "| Prop | Type | Default | Description |\n| --- | --- | --- | --- |\n| `columns` | `TableColumnDefinition[]` | — | Column definitions. |\n| `rows` | `TableItem[]` | — | Row data. |\n| `fit` | `boolean` | `true` |
|
|
27968
|
+
"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
27969
|
},
|
|
27015
27970
|
{
|
|
27016
27971
|
"id": "slots",
|
|
27017
27972
|
"title": "Slots",
|
|
27018
|
-
"body": "| Slot | Description |\n| --- | --- |\n| `cell-{key}` | Cell
|
|
27973
|
+
"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
27974
|
},
|
|
27020
27975
|
{
|
|
27021
27976
|
"id": "events",
|
|
27022
27977
|
"title": "Events",
|
|
27023
|
-
"body": "| Event | Payload | Description |\n| --- | --- | --- |\n| `sort` | `{ sortField?, sortOrder? }` | Sort changed. |\n| `row-click` | `{ row, index }`, `Event` | Row
|
|
27978
|
+
"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
27979
|
},
|
|
27025
27980
|
{
|
|
27026
|
-
"id": "instance",
|
|
27027
|
-
"title": "Instance",
|
|
27028
|
-
"body": "
|
|
27981
|
+
"id": "instance-api",
|
|
27982
|
+
"title": "Instance API",
|
|
27983
|
+
"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
27984
|
},
|
|
27030
27985
|
{
|
|
27031
27986
|
"id": "types",
|
|
27032
27987
|
"title": "Types",
|
|
27033
|
-
"body": "<h4 id=\"TableItem\">TableItem</h4>\n\
|
|
27988
|
+
"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
27989
|
}
|
|
27035
27990
|
],
|
|
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"
|
|
27991
|
+
"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
27992
|
}
|
|
27038
27993
|
}
|
|
27039
27994
|
},
|
|
@@ -32601,7 +33556,7 @@
|
|
|
32601
33556
|
"zh-CN": {
|
|
32602
33557
|
"title": "主题",
|
|
32603
33558
|
"description": "亮暗主题、设计令牌与内容密度。",
|
|
32604
|
-
"markdown": "---\ntitle: 主题\norder: 5\ndescription: 亮暗主题、设计令牌与内容密度。\n---\n\n# 主题\n\n主题能力内置于 `morya-ui`。组件只消费语义化 CSS 变量(`--m-*`),不自行维护第二套色板。\n\n引入 `morya-ui/styles.css` 时已包含这些变量;主题 JS API(`useTheme` 等)从同一包导入。\n\n## 亮 / 暗色\n\n```ts\nimport { useTheme } from \"morya-ui\";\n\nconst { isDark, setTheme, toggleTheme } = useTheme();\n\nsetTheme(\"light\"); // 或 'dark'\ntoggleTheme();\n```\n\n文档站右上角的按钮调用的就是同一套 API。主题偏好会写到 `document.documentElement` 的 `data-theme`。\n\n## 设计令牌\n\n常用变量示例见 [设计令牌](/docs/design-tokens) 完整列表(支持搜索与分类)。\n\n| Token | 用途 |\n| ----------------------------------------------------------------- | --------------------------------------------- |\n| `--m-color-primary` | 品牌主色 |\n| `--m-color-surface` | 页面底色 |\n| `--m-color-text` | 正文 |\n| `--m-color-border` | 分割线 / 描边 |\n| `--m-radius-sm/md/lg` | 圆角阶梯 |\n| `--m-space-*` | 间距阶梯 |\n| `--m-font-size-xs/sm/md/lg` | 组件正文字号阶梯 |\n| `--m-opacity-disabled` | 禁用态透明度 |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | 浮层层叠(Config `zIndex` 会写 `--m-z-base`) |\n| `--m-menu-min-width` / `--m-control-affix-*` | 菜单最小宽、输入清除区尺寸 |\n\n动效相关 token(`--m-motion-*`)见 [动效](/docs/motion)。\n\n## 内容密度\n\n```ts\nimport { useDensity } from \"morya-ui\";\n\nconst { preference, setDensity } = useDensity();\nsetDensity(\"compact\"); // 'compact' | 'comfortable' | 'spacious'\n```\n\n也会写到 `document.documentElement` 的 `data-m-density`,并缩放 `--m-space-*` 与 `--m-control-height-*`。 \n应用级可用 `createMoryaUI({ density: 'compact' })` 或 `<MConfigProvider density=\"compact\">`。\n\n在组件页侧栏「主题」可临时改主色、圆角与密度,用于本地预览。完整交互页见 [主题编辑器](/theme-editor)(可导出 `createTheme` / CSS)。\n\n## 控件尺寸与聚焦\n\n默认控件高度采用 compact 节奏:\n\n| Size | 高度 | 字号 |\n| --------------- | ------------------------------------ | ------ |\n| `small` | `28px`(`--m-control-height-small`) | `14px` |\n| 默认 / `medium` | `34px` | `14px` |\n| `large` | `40px` | `15px` |\n\n聚焦样式为 **主色描边 + 2px 淡色光晕**(非外扩 outline ring):\n\n```css\nborder-color: var(--m-color-primary-hover);\nbox-shadow: var(--m-focus-shadow); /* 0 0 0 2px primary@20% */\n```\n\n相关 token:`--m-radius-control`、`--m-control-padding-x-*`、`--m-button-padding-x-*`、`--m-focus-shadow` / `--m-focus-shadow-danger`。\n\n## createTheme\n\n从 seed 推导完整 `--m-*` 并应用到文档或作用域元素:\n\n```ts\nimport { createTheme } from \"morya-ui\";\n\nconst theme = createTheme({\n seed: { colorPrimary: \"#0b6e4f\", borderRadius: 8 },\n // algorithm: 'dark' | 'compact' | ['dark', 'compact']\n});\n\ntheme.apply(); // 写到 :root(或传入元素做局部主题)\n// const dispose = theme.inject() // 写入 <style data-m-theme>(组件级覆盖需要)\n```\n\n在线调色与导出片段:[主题编辑器](/theme-editor)。\n\n## 与 ConfigProvider\n\n主题切换是「视觉层」;`MConfigProvider` / `createMoryaUI` 负责尺寸、文案、浮层挂载等「行为默认值」。二者可同时使用,详见 [全局配置](/docs/config)。\n\n进出场与 `useMotion` 见 [动效](/docs/motion)。\n",
|
|
33559
|
+
"markdown": "---\ntitle: 主题\norder: 5\ndescription: 亮暗主题、设计令牌与内容密度。\n---\n\n# 主题\n\n主题能力内置于 `morya-ui`。组件只消费语义化 CSS 变量(`--m-*`),不自行维护第二套色板。\n\n引入 `morya-ui/styles.css` 时已包含这些变量;主题 JS API(`useTheme` 等)从同一包导入。\n\n## 亮 / 暗色\n\n```ts\nimport { useTheme } from \"morya-ui\";\n\nconst { isDark, setTheme, toggleTheme } = useTheme();\n\nsetTheme(\"light\"); // 或 'dark'\ntoggleTheme();\n```\n\n文档站右上角的按钮调用的就是同一套 API。主题偏好会写到 `document.documentElement` 的 `data-theme`。\n\n## 设计令牌\n\n常用变量示例见 [设计令牌](/docs/design-tokens) 完整列表(支持搜索与分类)。\n\n| Token | 用途 |\n| ----------------------------------------------------------------- | --------------------------------------------- |\n| `--m-color-primary` | 品牌主色 |\n| `--m-color-surface` | 页面底色 |\n| `--m-color-text` | 正文 |\n| `--m-color-border` | 分割线 / 描边 |\n| `--m-radius-sm/md/lg` | 圆角阶梯 |\n| `--m-space-*` | 间距阶梯 |\n| `--m-font-size-xs/sm/md/lg` | 组件正文字号阶梯 |\n| `--m-opacity-disabled` | 禁用态透明度 |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | 浮层层叠(Config `zIndex` 会写 `--m-z-base`) |\n| `--m-overlay-menu-min-width` / `--m-control-affix-*` | 菜单最小宽、输入清除区尺寸 |\n\n动效相关 token(`--m-motion-*`)见 [动效](/docs/motion)。\n\n## 内容密度\n\n```ts\nimport { useDensity } from \"morya-ui\";\n\nconst { preference, setDensity } = useDensity();\nsetDensity(\"compact\"); // 'compact' | 'comfortable' | 'spacious'\n```\n\n也会写到 `document.documentElement` 的 `data-m-density`,并缩放 `--m-space-*` 与 `--m-control-height-*`。 \n应用级可用 `createMoryaUI({ density: 'compact' })` 或 `<MConfigProvider density=\"compact\">`。\n\n在组件页侧栏「主题」可临时改主色、圆角与密度,用于本地预览。完整交互页见 [主题编辑器](/theme-editor)(可导出 `createTheme` / CSS)。\n\n## 控件尺寸与聚焦\n\n默认控件高度采用 compact 节奏:\n\n| Size | 高度 | 字号 |\n| --------------- | ------------------------------------ | ------ |\n| `small` | `28px`(`--m-control-height-small`) | `14px` |\n| 默认 / `medium` | `34px` | `14px` |\n| `large` | `40px` | `15px` |\n\n聚焦样式为 **主色描边 + 2px 淡色光晕**(非外扩 outline ring):\n\n```css\nborder-color: var(--m-color-primary-hover);\nbox-shadow: var(--m-focus-shadow); /* 0 0 0 2px primary@20% */\n```\n\n相关 token:`--m-radius-control`、`--m-control-padding-x-*`、`--m-button-padding-x-*`、`--m-focus-shadow` / `--m-focus-shadow-danger`。\n\n## createTheme\n\n从 seed 推导完整 `--m-*` 并应用到文档或作用域元素:\n\n```ts\nimport { createTheme } from \"morya-ui\";\n\nconst theme = createTheme({\n seed: { colorPrimary: \"#0b6e4f\", borderRadius: 8 },\n // algorithm: 'dark' | 'compact' | ['dark', 'compact']\n});\n\ntheme.apply(); // 写到 :root(或传入元素做局部主题)\n// const dispose = theme.inject() // 写入 <style data-m-theme>(组件级覆盖需要)\n```\n\n在线调色与导出片段:[主题编辑器](/theme-editor)。\n\n## 与 ConfigProvider\n\n主题切换是「视觉层」;`MConfigProvider` / `createMoryaUI` 负责尺寸、文案、浮层挂载等「行为默认值」。二者可同时使用,详见 [全局配置](/docs/config)。\n\n进出场与 `useMotion` 见 [动效](/docs/motion)。\n",
|
|
32605
33560
|
"sections": [
|
|
32606
33561
|
{
|
|
32607
33562
|
"title": "",
|
|
@@ -32616,7 +33571,7 @@
|
|
|
32616
33571
|
{
|
|
32617
33572
|
"title": "设计令牌",
|
|
32618
33573
|
"id": "设计令牌",
|
|
32619
|
-
"body": "常用变量示例见 [设计令牌](/docs/design-tokens) 完整列表(支持搜索与分类)。\n\n| Token | 用途 |\n| ----------------------------------------------------------------- | --------------------------------------------- |\n| `--m-color-primary` | 品牌主色 |\n| `--m-color-surface` | 页面底色 |\n| `--m-color-text` | 正文 |\n| `--m-color-border` | 分割线 / 描边 |\n| `--m-radius-sm/md/lg` | 圆角阶梯 |\n| `--m-space-*` | 间距阶梯 |\n| `--m-font-size-xs/sm/md/lg` | 组件正文字号阶梯 |\n| `--m-opacity-disabled` | 禁用态透明度 |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | 浮层层叠(Config `zIndex` 会写 `--m-z-base`) |\n| `--m-menu-min-width` / `--m-control-affix-*` | 菜单最小宽、输入清除区尺寸 |\n\n动效相关 token(`--m-motion-*`)见 [动效](/docs/motion)。"
|
|
33574
|
+
"body": "常用变量示例见 [设计令牌](/docs/design-tokens) 完整列表(支持搜索与分类)。\n\n| Token | 用途 |\n| ----------------------------------------------------------------- | --------------------------------------------- |\n| `--m-color-primary` | 品牌主色 |\n| `--m-color-surface` | 页面底色 |\n| `--m-color-text` | 正文 |\n| `--m-color-border` | 分割线 / 描边 |\n| `--m-radius-sm/md/lg` | 圆角阶梯 |\n| `--m-space-*` | 间距阶梯 |\n| `--m-font-size-xs/sm/md/lg` | 组件正文字号阶梯 |\n| `--m-opacity-disabled` | 禁用态透明度 |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | 浮层层叠(Config `zIndex` 会写 `--m-z-base`) |\n| `--m-overlay-menu-min-width` / `--m-control-affix-*` | 菜单最小宽、输入清除区尺寸 |\n\n动效相关 token(`--m-motion-*`)见 [动效](/docs/motion)。"
|
|
32620
33575
|
},
|
|
32621
33576
|
{
|
|
32622
33577
|
"title": "内容密度",
|
|
@@ -32643,7 +33598,7 @@
|
|
|
32643
33598
|
"en-US": {
|
|
32644
33599
|
"title": "Theme",
|
|
32645
33600
|
"description": "Light and dark themes, design tokens, and density.",
|
|
32646
|
-
"markdown": "---\ntitle: Theme\norder: 5\ndescription: Light and dark themes, design tokens, and density.\n---\n\n# Theme\n\nTheme support is built into `morya-ui`. Components consume semantic CSS variables (`--m-*`) and do not keep a second palette.\n\nImporting `morya-ui/styles.css` already includes these variables. Theme JS APIs (`useTheme` and friends) come from the same package.\n\n## Light / dark\n\n```ts\nimport { useTheme } from \"morya-ui\";\n\nconst { isDark, setTheme, toggleTheme } = useTheme();\n\nsetTheme(\"light\"); // or 'dark'\ntoggleTheme();\n```\n\nThe button at the top-right of the docs site uses the same API. The preference is written to `data-theme` on `document.documentElement`.\n\n## Design tokens\n\nSee the full [Design tokens](/docs/design-tokens) catalog (searchable, grouped by category).\n\n| Token | Use |\n| ----------------------------------------------------------------- | ----------------------------------------------- |\n| `--m-color-primary` | Brand color |\n| `--m-color-surface` | Page background |\n| `--m-color-text` | Body text |\n| `--m-color-border` | Dividers / strokes |\n| `--m-radius-sm/md/lg` | Radius scale |\n| `--m-space-*` | Spacing scale |\n| `--m-font-size-xs/sm/md/lg` | Component type scale |\n| `--m-opacity-disabled` | Disabled opacity |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | Overlay stacking (`zIndex` writes `--m-z-base`) |\n| `--m-menu-min-width` / `--m-control-affix-*` | Menu min width, input clear-button size |\n\nMotion tokens (`--m-motion-*`) are covered in [Motion](/docs/motion).\n\n## Density\n\n```ts\nimport { useDensity } from \"morya-ui\";\n\nconst { preference, setDensity } = useDensity();\nsetDensity(\"compact\"); // 'compact' | 'comfortable' | 'spacious'\n```\n\nThis writes `data-m-density` on `document.documentElement` and scales `--m-space-*` plus `--m-control-height-*`. \nAt the app level use `createMoryaUI({ density: 'compact' })` or `<MConfigProvider density=\"compact\">`.\n\nThe Components page sidebar Theme panel can temporarily change accent, radius, and density for local preview. Full interactive page: [Theme editor](/theme-editor) (exports `createTheme` / CSS).\n\n## Control size and focus\n\nDefault control heights follow a compact rhythm:\n\n| Size | Height | Font size |\n| ------------------ | ----------------------------------- | --------- |\n| `small` | `28px` (`--m-control-height-small`) | `14px` |\n| Default / `medium` | `34px` | `14px` |\n| `large` | `40px` | `15px` |\n\nFocus uses a **brand border + 2px tinted glow** (not an outset outline ring):\n\n```css\nborder-color: var(--m-color-primary-hover);\nbox-shadow: var(--m-focus-shadow); /* 0 0 0 2px primary@20% */\n```\n\nRelated tokens: `--m-radius-control`, `--m-control-padding-x-*`, `--m-button-padding-x-*`, `--m-focus-shadow` / `--m-focus-shadow-danger`.\n\n## createTheme\n\nDerive the full `--m-*` set from a seed and apply it to the document or a scoped element:\n\n```ts\nimport { createTheme } from \"morya-ui\";\n\nconst theme = createTheme({\n seed: { colorPrimary: \"#0b6e4f\", borderRadius: 8 },\n // algorithm: 'dark' | 'compact' | ['dark', 'compact']\n});\n\ntheme.apply(); // write onto :root (or pass an element for scoped theming)\n// const dispose = theme.inject() // <style data-m-theme> (needed for component overrides)\n```\n\nLive tuning and export snippets: [Theme editor](/theme-editor).\n\n## With ConfigProvider\n\nTheme switching is the visual layer. `MConfigProvider` / `createMoryaUI` own size, copy, overlay mount, and other behavioral defaults. Use both together; see [Configuration](/docs/config).\n\nEnter/exit presets and `useMotion` live under [Motion](/docs/motion).\n",
|
|
33601
|
+
"markdown": "---\ntitle: Theme\norder: 5\ndescription: Light and dark themes, design tokens, and density.\n---\n\n# Theme\n\nTheme support is built into `morya-ui`. Components consume semantic CSS variables (`--m-*`) and do not keep a second palette.\n\nImporting `morya-ui/styles.css` already includes these variables. Theme JS APIs (`useTheme` and friends) come from the same package.\n\n## Light / dark\n\n```ts\nimport { useTheme } from \"morya-ui\";\n\nconst { isDark, setTheme, toggleTheme } = useTheme();\n\nsetTheme(\"light\"); // or 'dark'\ntoggleTheme();\n```\n\nThe button at the top-right of the docs site uses the same API. The preference is written to `data-theme` on `document.documentElement`.\n\n## Design tokens\n\nSee the full [Design tokens](/docs/design-tokens) catalog (searchable, grouped by category).\n\n| Token | Use |\n| ----------------------------------------------------------------- | ----------------------------------------------- |\n| `--m-color-primary` | Brand color |\n| `--m-color-surface` | Page background |\n| `--m-color-text` | Body text |\n| `--m-color-border` | Dividers / strokes |\n| `--m-radius-sm/md/lg` | Radius scale |\n| `--m-space-*` | Spacing scale |\n| `--m-font-size-xs/sm/md/lg` | Component type scale |\n| `--m-opacity-disabled` | Disabled opacity |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | Overlay stacking (`zIndex` writes `--m-z-base`) |\n| `--m-overlay-menu-min-width` / `--m-control-affix-*` | Menu min width, input clear-button size |\n\nMotion tokens (`--m-motion-*`) are covered in [Motion](/docs/motion).\n\n## Density\n\n```ts\nimport { useDensity } from \"morya-ui\";\n\nconst { preference, setDensity } = useDensity();\nsetDensity(\"compact\"); // 'compact' | 'comfortable' | 'spacious'\n```\n\nThis writes `data-m-density` on `document.documentElement` and scales `--m-space-*` plus `--m-control-height-*`. \nAt the app level use `createMoryaUI({ density: 'compact' })` or `<MConfigProvider density=\"compact\">`.\n\nThe Components page sidebar Theme panel can temporarily change accent, radius, and density for local preview. Full interactive page: [Theme editor](/theme-editor) (exports `createTheme` / CSS).\n\n## Control size and focus\n\nDefault control heights follow a compact rhythm:\n\n| Size | Height | Font size |\n| ------------------ | ----------------------------------- | --------- |\n| `small` | `28px` (`--m-control-height-small`) | `14px` |\n| Default / `medium` | `34px` | `14px` |\n| `large` | `40px` | `15px` |\n\nFocus uses a **brand border + 2px tinted glow** (not an outset outline ring):\n\n```css\nborder-color: var(--m-color-primary-hover);\nbox-shadow: var(--m-focus-shadow); /* 0 0 0 2px primary@20% */\n```\n\nRelated tokens: `--m-radius-control`, `--m-control-padding-x-*`, `--m-button-padding-x-*`, `--m-focus-shadow` / `--m-focus-shadow-danger`.\n\n## createTheme\n\nDerive the full `--m-*` set from a seed and apply it to the document or a scoped element:\n\n```ts\nimport { createTheme } from \"morya-ui\";\n\nconst theme = createTheme({\n seed: { colorPrimary: \"#0b6e4f\", borderRadius: 8 },\n // algorithm: 'dark' | 'compact' | ['dark', 'compact']\n});\n\ntheme.apply(); // write onto :root (or pass an element for scoped theming)\n// const dispose = theme.inject() // <style data-m-theme> (needed for component overrides)\n```\n\nLive tuning and export snippets: [Theme editor](/theme-editor).\n\n## With ConfigProvider\n\nTheme switching is the visual layer. `MConfigProvider` / `createMoryaUI` own size, copy, overlay mount, and other behavioral defaults. Use both together; see [Configuration](/docs/config).\n\nEnter/exit presets and `useMotion` live under [Motion](/docs/motion).\n",
|
|
32647
33602
|
"sections": [
|
|
32648
33603
|
{
|
|
32649
33604
|
"title": "",
|
|
@@ -32658,7 +33613,7 @@
|
|
|
32658
33613
|
{
|
|
32659
33614
|
"title": "Design tokens",
|
|
32660
33615
|
"id": "design-tokens",
|
|
32661
|
-
"body": "See the full [Design tokens](/docs/design-tokens) catalog (searchable, grouped by category).\n\n| Token | Use |\n| ----------------------------------------------------------------- | ----------------------------------------------- |\n| `--m-color-primary` | Brand color |\n| `--m-color-surface` | Page background |\n| `--m-color-text` | Body text |\n| `--m-color-border` | Dividers / strokes |\n| `--m-radius-sm/md/lg` | Radius scale |\n| `--m-space-*` | Spacing scale |\n| `--m-font-size-xs/sm/md/lg` | Component type scale |\n| `--m-opacity-disabled` | Disabled opacity |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | Overlay stacking (`zIndex` writes `--m-z-base`) |\n| `--m-menu-min-width` / `--m-control-affix-*` | Menu min width, input clear-button size |\n\nMotion tokens (`--m-motion-*`) are covered in [Motion](/docs/motion)."
|
|
33616
|
+
"body": "See the full [Design tokens](/docs/design-tokens) catalog (searchable, grouped by category).\n\n| Token | Use |\n| ----------------------------------------------------------------- | ----------------------------------------------- |\n| `--m-color-primary` | Brand color |\n| `--m-color-surface` | Page background |\n| `--m-color-text` | Body text |\n| `--m-color-border` | Dividers / strokes |\n| `--m-radius-sm/md/lg` | Radius scale |\n| `--m-space-*` | Spacing scale |\n| `--m-font-size-xs/sm/md/lg` | Component type scale |\n| `--m-opacity-disabled` | Disabled opacity |\n| `--m-z-base` / `--m-z-overlay` / `--m-z-dropdown` / `--m-z-toast` | Overlay stacking (`zIndex` writes `--m-z-base`) |\n| `--m-overlay-menu-min-width` / `--m-control-affix-*` | Menu min width, input clear-button size |\n\nMotion tokens (`--m-motion-*`) are covered in [Motion](/docs/motion)."
|
|
32662
33617
|
},
|
|
32663
33618
|
{
|
|
32664
33619
|
"title": "Density",
|
|
@@ -32967,24 +33922,24 @@
|
|
|
32967
33922
|
"zh-CN": {
|
|
32968
33923
|
"title": "API 类型",
|
|
32969
33924
|
"description": "文档 Props 里常见类型名的结构与含义。",
|
|
32970
|
-
"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",
|
|
33925
|
+
"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",
|
|
32971
33926
|
"sections": [
|
|
32972
33927
|
{
|
|
32973
33928
|
"title": "",
|
|
32974
33929
|
"id": "overview",
|
|
32975
|
-
"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`)写在对应组件页 **类型** 小节;这里只列跨组件复用的名字。"
|
|
33930
|
+
"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`)写在对应组件页 **类型** 小节;这里只列跨组件复用的名字。"
|
|
32976
33931
|
}
|
|
32977
33932
|
]
|
|
32978
33933
|
},
|
|
32979
33934
|
"en-US": {
|
|
32980
33935
|
"title": "API types",
|
|
32981
33936
|
"description": "Shapes behind type names in component Props tables.",
|
|
32982
|
-
"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",
|
|
33937
|
+
"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",
|
|
32983
33938
|
"sections": [
|
|
32984
33939
|
{
|
|
32985
33940
|
"title": "",
|
|
32986
33941
|
"id": "overview",
|
|
32987
|
-
"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."
|
|
33942
|
+
"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."
|
|
32988
33943
|
}
|
|
32989
33944
|
]
|
|
32990
33945
|
}
|
|
@@ -33125,7 +34080,7 @@
|
|
|
33125
34080
|
"zh-CN": {
|
|
33126
34081
|
"title": "SSR 与服务端框架",
|
|
33127
34082
|
"description": "在 Nuxt、Astro、Vite SSR 等环境中使用 Morya UI。",
|
|
33128
|
-
"markdown": "---\ntitle: SSR 与服务端框架\norder: 10\ndescription: 在 Nuxt、Astro、Vite SSR 等环境中使用 Morya UI。\n---\n\n# SSR 与服务端框架\n\nMorya UI 面向 **Vue 3** 的 SSR 场景做了兼容(推荐 3.5 及以上):服务端不会访问 `document` / `window`,组件实例 id 在服务端与客户端保持一致,命令式 API(`toast` / `message` / `confirm`)在服务端自动跳过。\n\n以下框架均可接入;按场景选择 **全量 SSR** 或 **客户端 Islands**。\n\n## 通用约定\n\n| 项 | 建议 |\n| --- | --- |\n| 样式 | 在应用入口或框架配置中引入 `morya-ui/styles.css` |\n| 主题 | 优先用根级 **`MConfigProvider`** 设置 `theme` / `density`,避免在 SSR 阶段单独调用 `useTheme()` 写 `document` |\n| 命令式反馈 | `toast()`、`message()`、`confirm()` 仅在浏览器执行;SSR 期间调用不会报错,但不会渲染 |\n| 按需导入 | 配合 `morya-ui/resolver` 与 `unplugin-vue-components` 减小体积 |\n| 浮层 | Dialog / Select / Tooltip 等使用 Vue `Teleport`;SSR 可输出占位,交互在客户端水合后生效 |\n\n## Nuxt 3\n\n推荐使用官方模块 **`@morya-ui/nuxt`**(同仓库 `packages/nuxt`)。\n\n### 安装\n\n```bash\npnpm add morya-ui @morya-ui/nuxt\npnpm add -D unplugin-vue-components\n```\n\n### 配置\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\n// nuxt.config.ts\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineNuxtConfig({\n modules: ['@morya-ui/nuxt'],\n vite: {\n plugins: [\n Components({\n resolvers: [MoryaUIResolver()],\n }),\n ],\n },\n})\n```\n\n模块默认会:\n\n- 引入 `morya-ui/styles.css`\n- 将 `morya-ui` 加入 `build.transpile`\n- 在客户端注册 overlay 上下文(供 `toast` / `message` 使用)\n\n### 根布局\n\n```vue\n<!-- app.vue -->\n<script setup lang=\"ts\">\nconst theme = ref<'light' | 'dark'>('light')\n</script>\n\n<template>\n <MConfigProvider :theme=\"theme\" density=\"comfortable\">\n <NuxtPage />\n </MConfigProvider>\n</template>\n```\n\n按需导入时无需 `app.use(MoryaUI)`;若需全量注册,可在 `plugins/morya-ui.client.ts` 中 `nuxtApp.vueApp.use(MoryaUI)`。\n\n### 仅客户端组件\n\n极少数依赖浏览器专有 API 的场景(如自定义 `appendTo` 到尚未存在的节点),可用 Nuxt 的 `<ClientOnly>` 包裹。\n\n## Astro + Vue\n\n适合 **静态页 + Vue 岛**(管理后台、控制台嵌入营销站)。\n\n### 安装\n\n```bash\npnpm add morya-ui\nnpx astro add vue\n```\n\n### 在 Vue 岛中使用\n\n```astro\n---\n// src/pages/admin.astro\nimport AdminShell from '../components/AdminShell.vue'\n---\n<AdminShell client:load />\n```\n\n```vue\n<!-- src/components/AdminShell.vue -->\n<script setup lang=\"ts\">\nimport { MButton, MConfigProvider } from 'morya-ui'\nimport 'morya-ui/styles.css'\n</script>\n\n<template>\n <MConfigProvider theme=\"light\">\n <MButton label=\"Hello\" />\n </MConfigProvider>\n</template>\n```\n\n- 交互型后台推荐 `client:load` 或 `client:only`\n- 纯展示块可用 `client:visible` 延迟水合\n- Astro 本身不做 Vue SSR 时,无需处理 hydration id 问题\n\n## Vite SSR(含自定义服务端)\n\n```ts\nimport { MConfigProvider } from 'morya-ui/config-provider'\n// main.server.ts / entry-server.ts\nimport { createSSRApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\nexport function createApp() {\n const app = createSSRApp(App)\n return { app }\n}\n```\n\n客户端入口可注册 overlay 插件:\n\n```ts\n// entry-client.ts\nimport { createMoryaUI } from 'morya-ui'\n\ncreateApp(/* ... */)\n .use(createMoryaUI({ components: false }))\n .mount('#app')\n```\n\n构建时确保 `morya-ui` 进入 `ssr.noExternal`(或 `ssr: { noExternal: ['morya-ui'] }`),以便正确处理 `.vue` 与 CSS 副作用。\n\n## 其他 Vue SSR 方案\n\n| 方案 | 说明 |\n| --- | --- |\n| **
|
|
34083
|
+
"markdown": "---\ntitle: SSR 与服务端框架\norder: 10\ndescription: 在 Nuxt、Astro、Vite SSR 等环境中使用 Morya UI。\n---\n\n# SSR 与服务端框架\n\nMorya UI 面向 **Vue 3** 的 SSR 场景做了兼容(推荐 3.5 及以上):服务端不会访问 `document` / `window`,组件实例 id 在服务端与客户端保持一致,命令式 API(`toast` / `message` / `confirm`)在服务端自动跳过。\n\n以下框架均可接入;按场景选择 **全量 SSR** 或 **客户端 Islands**。\n\n## 通用约定\n\n| 项 | 建议 |\n| --- | --- |\n| 样式 | 在应用入口或框架配置中引入 `morya-ui/styles.css` |\n| 主题 | 优先用根级 **`MConfigProvider`** 设置 `theme` / `density`,避免在 SSR 阶段单独调用 `useTheme()` 写 `document` |\n| 命令式反馈 | `toast()`、`message()`、`confirm()` 仅在浏览器执行;SSR 期间调用不会报错,但不会渲染 |\n| 按需导入 | 配合 `morya-ui/resolver` 与 `unplugin-vue-components` 减小体积 |\n| 浮层 | Dialog / Select / Tooltip 等使用 Vue `Teleport`;SSR 可输出占位,交互在客户端水合后生效 |\n\n## Nuxt 3\n\n推荐使用官方模块 **`@morya-ui/nuxt`**(同仓库 `packages/nuxt`)。\n\n### 安装\n\n```bash\npnpm add morya-ui @morya-ui/nuxt\npnpm add -D unplugin-vue-components\n```\n\n### 配置\n\n```ts\nimport { MoryaUIResolver } from 'morya-ui/resolver'\n// nuxt.config.ts\nimport Components from 'unplugin-vue-components/vite'\n\nexport default defineNuxtConfig({\n modules: ['@morya-ui/nuxt'],\n vite: {\n plugins: [\n Components({\n resolvers: [MoryaUIResolver()],\n }),\n ],\n },\n})\n```\n\n模块默认会:\n\n- 引入 `morya-ui/styles.css`\n- 将 `morya-ui` 加入 `build.transpile`\n- 在客户端注册 overlay 上下文(供 `toast` / `message` 使用)\n\n### 根布局\n\n```vue\n<!-- app.vue -->\n<script setup lang=\"ts\">\nconst theme = ref<'light' | 'dark'>('light')\n</script>\n\n<template>\n <MConfigProvider :theme=\"theme\" density=\"comfortable\">\n <NuxtPage />\n </MConfigProvider>\n</template>\n```\n\n按需导入时无需 `app.use(MoryaUI)`;若需全量注册,可在 `plugins/morya-ui.client.ts` 中 `nuxtApp.vueApp.use(MoryaUI)`。\n\n### 仅客户端组件\n\n极少数依赖浏览器专有 API 的场景(如自定义 `appendTo` 到尚未存在的节点),可用 Nuxt 的 `<ClientOnly>` 包裹。\n\n## Astro + Vue\n\n适合 **静态页 + Vue 岛**(管理后台、控制台嵌入营销站)。\n\n### 安装\n\n```bash\npnpm add morya-ui\nnpx astro add vue\n```\n\n### 在 Vue 岛中使用\n\n```astro\n---\n// src/pages/admin.astro\nimport AdminShell from '../components/AdminShell.vue'\n---\n<AdminShell client:load />\n```\n\n```vue\n<!-- src/components/AdminShell.vue -->\n<script setup lang=\"ts\">\nimport { MButton, MConfigProvider } from 'morya-ui'\nimport 'morya-ui/styles.css'\n</script>\n\n<template>\n <MConfigProvider theme=\"light\">\n <MButton label=\"Hello\" />\n </MConfigProvider>\n</template>\n```\n\n- 交互型后台推荐 `client:load` 或 `client:only`\n- 纯展示块可用 `client:visible` 延迟水合\n- Astro 本身不做 Vue SSR 时,无需处理 hydration id 问题\n\n## Vite SSR(含自定义服务端)\n\n```ts\nimport { MConfigProvider } from 'morya-ui/config-provider'\n// main.server.ts / entry-server.ts\nimport { createSSRApp } from 'vue'\nimport App from './App.vue'\nimport 'morya-ui/styles.css'\n\nexport function createApp() {\n const app = createSSRApp(App)\n return { app }\n}\n```\n\n客户端入口可注册 overlay 插件:\n\n```ts\n// entry-client.ts\nimport { createMoryaUI } from 'morya-ui'\n\ncreateApp(/* ... */)\n .use(createMoryaUI({ components: false }))\n .mount('#app')\n```\n\n构建时确保 `morya-ui` 进入 `ssr.noExternal`(或 `ssr: { noExternal: ['morya-ui'] }`),以便正确处理 `.vue` 与 CSS 副作用。\n\n## 其他 Vue SSR 方案\n\n| 方案 | 说明 |\n| --- | --- |\n| **vite-plugin-ssr / vike** | 与 Vite SSR 相同:服务端渲染 + 客户端 `createMoryaUI({ components: false })` |\n| **Inertia + Vue SSR** | 根组件包 `MConfigProvider`;命令式 API 仅在 `onMounted` 后调用 |\n\n## 已知限制\n\n- **不支持 Vue 2**;SSR 仅适用于 Vue 3。\n- **IE** 不在支持范围内(与 Vue 3 一致)。\n- 主题 `localStorage` 持久化仅在浏览器生效;SSR 首屏使用 `MConfigProvider` 或 cookie 同步主题可避免闪动。\n- 全量 E2E SSR 回归仍在完善;若遇到 hydration 警告,请提供最小复现并 [提 Issue](https://github.com/morya-space/morya-ui/issues)。\n\n## 下一步\n\n- [快速上手](/docs/quick-start):安装与导入方式\n- [全局配置](/docs/config):`MConfigProvider`\n- [主题](/docs/theme):亮暗色与 token\n",
|
|
33129
34084
|
"sections": [
|
|
33130
34085
|
{
|
|
33131
34086
|
"title": "",
|
|
@@ -33155,7 +34110,7 @@
|
|
|
33155
34110
|
{
|
|
33156
34111
|
"title": "其他 Vue SSR 方案",
|
|
33157
34112
|
"id": "其他-vue-ssr-方案",
|
|
33158
|
-
"body": "| 方案 | 说明 |\n| --- | --- |\n| **
|
|
34113
|
+
"body": "| 方案 | 说明 |\n| --- | --- |\n| **vite-plugin-ssr / vike** | 与 Vite SSR 相同:服务端渲染 + 客户端 `createMoryaUI({ components: false })` |\n| **Inertia + Vue SSR** | 根组件包 `MConfigProvider`;命令式 API 仅在 `onMounted` 后调用 |"
|
|
33159
34114
|
},
|
|
33160
34115
|
{
|
|
33161
34116
|
"title": "已知限制",
|