@chenzy-design/svelte 0.2.1 → 0.3.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.
Files changed (241) hide show
  1. package/dist/anchor/Anchor.svelte +1 -1
  2. package/dist/anchor/meta.d.ts +1 -1
  3. package/dist/anchor/meta.js +1 -1
  4. package/dist/autocomplete/AutoComplete.svelte +10 -10
  5. package/dist/avatar/Avatar.svelte +12 -7
  6. package/dist/avatar/AvatarGroup.svelte +2 -2
  7. package/dist/avatar/context.d.ts +1 -1
  8. package/dist/avatar/context.d.ts.map +1 -1
  9. package/dist/avatar/meta.d.ts +2 -2
  10. package/dist/avatar/meta.d.ts.map +1 -1
  11. package/dist/avatar/meta.js +3 -1
  12. package/dist/badge/Badge.svelte +5 -5
  13. package/dist/banner/Banner.svelte +1 -1
  14. package/dist/breadcrumb/Breadcrumb.svelte +9 -8
  15. package/dist/breadcrumb/meta.d.ts +1 -1
  16. package/dist/breadcrumb/meta.js +1 -1
  17. package/dist/button/Button.svelte +289 -55
  18. package/dist/button/Button.svelte.d.ts +20 -4
  19. package/dist/button/Button.svelte.d.ts.map +1 -1
  20. package/dist/button/ButtonGroup.svelte +107 -0
  21. package/dist/button/ButtonGroup.svelte.d.ts +21 -0
  22. package/dist/button/ButtonGroup.svelte.d.ts.map +1 -0
  23. package/dist/button/SplitButtonGroup.svelte +127 -0
  24. package/dist/button/SplitButtonGroup.svelte.d.ts +35 -0
  25. package/dist/button/SplitButtonGroup.svelte.d.ts.map +1 -0
  26. package/dist/button/context.d.ts +14 -0
  27. package/dist/button/context.d.ts.map +1 -0
  28. package/dist/button/context.js +14 -0
  29. package/dist/button/index.d.ts +3 -0
  30. package/dist/button/index.d.ts.map +1 -1
  31. package/dist/button/index.js +3 -0
  32. package/dist/button/meta.d.ts +173 -4
  33. package/dist/button/meta.d.ts.map +1 -1
  34. package/dist/button/meta.js +58 -9
  35. package/dist/calendar/Calendar.svelte +16 -16
  36. package/dist/card/Card.svelte +10 -10
  37. package/dist/card/Card.svelte.d.ts +1 -1
  38. package/dist/card/Card.svelte.d.ts.map +1 -1
  39. package/dist/card/CardMeta.svelte +6 -6
  40. package/dist/card/CardMeta.svelte.d.ts +1 -1
  41. package/dist/card/CardMeta.svelte.d.ts.map +1 -1
  42. package/dist/card/index.d.ts +8 -0
  43. package/dist/card/index.d.ts.map +1 -0
  44. package/dist/card/meta.d.ts +1 -1
  45. package/dist/card/meta.d.ts.map +1 -1
  46. package/dist/card/meta.js +4 -0
  47. package/dist/carousel/Carousel.svelte +14 -14
  48. package/dist/carousel/meta.d.ts +1 -1
  49. package/dist/carousel/meta.js +2 -2
  50. package/dist/cascader/Cascader.svelte +18 -10
  51. package/dist/checkbox/Checkbox.svelte +19 -5
  52. package/dist/checkbox/Checkbox.svelte.d.ts +3 -0
  53. package/dist/checkbox/Checkbox.svelte.d.ts.map +1 -1
  54. package/dist/checkbox/CheckboxGroup.svelte +1 -1
  55. package/dist/checkbox/meta.d.ts +15 -0
  56. package/dist/checkbox/meta.d.ts.map +1 -1
  57. package/dist/checkbox/meta.js +3 -0
  58. package/dist/collapse/Collapse.svelte +6 -2
  59. package/dist/collapse/meta.d.ts +1 -1
  60. package/dist/collapse/meta.js +2 -2
  61. package/dist/color-picker/ColorPicker.svelte +69 -33
  62. package/dist/color-picker/ColorPicker.svelte.d.ts +13 -0
  63. package/dist/color-picker/ColorPicker.svelte.d.ts.map +1 -1
  64. package/dist/color-picker/meta.d.ts +30 -0
  65. package/dist/color-picker/meta.d.ts.map +1 -1
  66. package/dist/color-picker/meta.js +6 -0
  67. package/dist/components.d.ts +25 -9
  68. package/dist/components.json +986 -76
  69. package/dist/date-picker/DatePicker.svelte +43 -42
  70. package/dist/date-picker/RangePicker.svelte +10 -10
  71. package/dist/descriptions/Descriptions.svelte +7 -3
  72. package/dist/divider/Divider.svelte +1 -1
  73. package/dist/drawer/Drawer.svelte +1 -1
  74. package/dist/dropdown/Dropdown.svelte +6 -5
  75. package/dist/dropdown/DropdownDivider.svelte +1 -1
  76. package/dist/dropdown/DropdownItem.svelte +1 -1
  77. package/dist/dropdown/DropdownItemNode.svelte +4 -4
  78. package/dist/dropdown/DropdownSubMenu.svelte +2 -2
  79. package/dist/dropdown/DropdownTitle.svelte +1 -1
  80. package/dist/dropdown/meta.d.ts +1 -1
  81. package/dist/dropdown/meta.js +1 -1
  82. package/dist/empty/Empty.svelte +1 -0
  83. package/dist/form/Field.svelte +14 -14
  84. package/dist/form/Form.svelte +2 -2
  85. package/dist/form/FormCascader.svelte +6 -6
  86. package/dist/form/FormCheckbox.svelte +6 -6
  87. package/dist/form/FormDatePicker.svelte +5 -5
  88. package/dist/form/FormLabel.svelte +2 -2
  89. package/dist/form/FormRadio.svelte +5 -5
  90. package/dist/form/FormRating.svelte +7 -7
  91. package/dist/form/FormSection.svelte +2 -2
  92. package/dist/form/FormSelect.svelte +12 -12
  93. package/dist/form/FormSlider.svelte +10 -10
  94. package/dist/form/FormSwitch.svelte +5 -5
  95. package/dist/form/FormTagInput.svelte +5 -5
  96. package/dist/form/FormTreeSelect.svelte +7 -7
  97. package/dist/form/FormUpload.svelte +10 -10
  98. package/dist/highlight/Highlight.svelte +2 -2
  99. package/dist/highlight/meta.d.ts +1 -1
  100. package/dist/highlight/meta.d.ts.map +1 -1
  101. package/dist/highlight/meta.js +6 -1
  102. package/dist/image/ImagePreview.svelte +7 -7
  103. package/dist/image/meta.d.ts +1 -1
  104. package/dist/image/meta.js +1 -1
  105. package/dist/index.d.ts +2 -1
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +2 -1
  108. package/dist/input/Input.svelte +14 -7
  109. package/dist/input-number/InputNumber.svelte +25 -19
  110. package/dist/layout/Content.svelte +17 -3
  111. package/dist/layout/Content.svelte.d.ts +6 -0
  112. package/dist/layout/Content.svelte.d.ts.map +1 -1
  113. package/dist/layout/Footer.svelte +22 -5
  114. package/dist/layout/Footer.svelte.d.ts +6 -0
  115. package/dist/layout/Footer.svelte.d.ts.map +1 -1
  116. package/dist/layout/Header.svelte +20 -3
  117. package/dist/layout/Header.svelte.d.ts +6 -0
  118. package/dist/layout/Header.svelte.d.ts.map +1 -1
  119. package/dist/layout/Layout.svelte +15 -2
  120. package/dist/layout/Layout.svelte.d.ts +6 -0
  121. package/dist/layout/Layout.svelte.d.ts.map +1 -1
  122. package/dist/layout/Sider.svelte +29 -4
  123. package/dist/layout/Sider.svelte.d.ts +8 -0
  124. package/dist/layout/Sider.svelte.d.ts.map +1 -1
  125. package/dist/layout/meta.d.ts +88 -0
  126. package/dist/layout/meta.d.ts.map +1 -1
  127. package/dist/layout/meta.js +22 -5
  128. package/dist/list/List.svelte +3 -3
  129. package/dist/list/ListItem.svelte +5 -5
  130. package/dist/list/ListMeta.svelte +1 -1
  131. package/dist/list/meta.d.ts +1 -1
  132. package/dist/list/meta.js +2 -2
  133. package/dist/menu/Menu.svelte +119 -38
  134. package/dist/menu/Menu.svelte.d.ts +16 -1
  135. package/dist/menu/Menu.svelte.d.ts.map +1 -1
  136. package/dist/menu/MenuPopupNode.svelte +37 -37
  137. package/dist/menu/MenuPopupNode.svelte.d.ts +1 -1
  138. package/dist/menu/MenuPopupNode.svelte.d.ts.map +1 -1
  139. package/dist/menu/meta.d.ts +21 -1
  140. package/dist/menu/meta.d.ts.map +1 -1
  141. package/dist/menu/meta.js +6 -1
  142. package/dist/menu/types.d.ts +6 -0
  143. package/dist/menu/types.d.ts.map +1 -1
  144. package/dist/modal/ConfirmModal.svelte +1 -1
  145. package/dist/modal/Modal.svelte +1 -1
  146. package/dist/nav/Nav.svelte +293 -0
  147. package/dist/nav/Nav.svelte.d.ts +75 -0
  148. package/dist/nav/Nav.svelte.d.ts.map +1 -0
  149. package/dist/nav/NavFooter.svelte +82 -0
  150. package/dist/nav/NavFooter.svelte.d.ts +14 -0
  151. package/dist/nav/NavFooter.svelte.d.ts.map +1 -0
  152. package/dist/nav/NavHeader.svelte +66 -0
  153. package/dist/nav/NavHeader.svelte.d.ts +18 -0
  154. package/dist/nav/NavHeader.svelte.d.ts.map +1 -0
  155. package/dist/nav/NavItem.svelte +68 -0
  156. package/dist/nav/NavItem.svelte.d.ts +28 -0
  157. package/dist/nav/NavItem.svelte.d.ts.map +1 -0
  158. package/dist/nav/NavSub.svelte +57 -0
  159. package/dist/nav/NavSub.svelte.d.ts +18 -0
  160. package/dist/nav/NavSub.svelte.d.ts.map +1 -0
  161. package/dist/nav/context.d.ts +31 -0
  162. package/dist/nav/context.d.ts.map +1 -0
  163. package/dist/nav/context.js +15 -0
  164. package/dist/nav/index.d.ts +20 -0
  165. package/dist/nav/index.d.ts.map +1 -0
  166. package/dist/nav/index.js +18 -0
  167. package/dist/nav/meta.d.ts +296 -0
  168. package/dist/nav/meta.d.ts.map +1 -0
  169. package/dist/nav/meta.js +119 -0
  170. package/dist/nav/types.d.ts +52 -0
  171. package/dist/nav/types.d.ts.map +1 -0
  172. package/dist/nav/types.js +31 -0
  173. package/dist/notification/NotificationItem.svelte +5 -5
  174. package/dist/notification/meta.d.ts +1 -1
  175. package/dist/notification/meta.d.ts.map +1 -1
  176. package/dist/notification/meta.js +1 -0
  177. package/dist/overflow-list/OverflowList.svelte +4 -4
  178. package/dist/pagination/Pagination.svelte +5 -5
  179. package/dist/popconfirm/Popconfirm.svelte +10 -14
  180. package/dist/popconfirm/Popconfirm.svelte.d.ts.map +1 -1
  181. package/dist/popconfirm/meta.d.ts +1 -1
  182. package/dist/popconfirm/meta.d.ts.map +1 -1
  183. package/dist/popconfirm/meta.js +1 -0
  184. package/dist/popover/Popover.svelte +13 -13
  185. package/dist/progress/Progress.svelte +1 -1
  186. package/dist/radio/Radio.svelte +58 -11
  187. package/dist/radio/Radio.svelte.d.ts +11 -0
  188. package/dist/radio/Radio.svelte.d.ts.map +1 -1
  189. package/dist/radio/RadioGroup.svelte +1 -1
  190. package/dist/radio/meta.d.ts +54 -1
  191. package/dist/radio/meta.d.ts.map +1 -1
  192. package/dist/radio/meta.js +12 -1
  193. package/dist/rating/Rating.svelte +20 -4
  194. package/dist/rating/Rating.svelte.d.ts +5 -0
  195. package/dist/rating/Rating.svelte.d.ts.map +1 -1
  196. package/dist/rating/meta.d.ts +25 -0
  197. package/dist/rating/meta.d.ts.map +1 -1
  198. package/dist/rating/meta.js +5 -0
  199. package/dist/scroll-list/ScrollColumn.svelte +1 -1
  200. package/dist/select/Select.svelte +26 -18
  201. package/dist/side-sheet/SideSheet.svelte +4 -4
  202. package/dist/slider/Slider.svelte +93 -17
  203. package/dist/slider/Slider.svelte.d.ts +20 -0
  204. package/dist/slider/Slider.svelte.d.ts.map +1 -1
  205. package/dist/slider/meta.d.ts +36 -1
  206. package/dist/slider/meta.d.ts.map +1 -1
  207. package/dist/slider/meta.js +8 -1
  208. package/dist/steps/Steps.svelte +7 -7
  209. package/dist/steps/meta.d.ts +1 -1
  210. package/dist/steps/meta.js +1 -1
  211. package/dist/switch/Switch.svelte +6 -6
  212. package/dist/switch/meta.d.ts +1 -1
  213. package/dist/switch/meta.js +1 -1
  214. package/dist/table/Table.svelte +17 -17
  215. package/dist/tabs/Tabs.svelte +12 -12
  216. package/dist/tabs/meta.d.ts +1 -1
  217. package/dist/tabs/meta.js +1 -1
  218. package/dist/tag/Tag.svelte +4 -2
  219. package/dist/tag/meta.d.ts +1 -1
  220. package/dist/tag/meta.d.ts.map +1 -1
  221. package/dist/tag/meta.js +2 -0
  222. package/dist/tag-input/TagInput.svelte +25 -14
  223. package/dist/textarea/TextArea.svelte +8 -8
  224. package/dist/time-picker/TimePicker.svelte +16 -16
  225. package/dist/timeline/Timeline.svelte +3 -3
  226. package/dist/timeline/meta.d.ts +1 -1
  227. package/dist/timeline/meta.js +1 -1
  228. package/dist/toast/ToastItem.svelte +2 -1
  229. package/dist/toast/meta.d.ts +1 -1
  230. package/dist/toast/meta.d.ts.map +1 -1
  231. package/dist/toast/meta.js +1 -0
  232. package/dist/tooltip/Tooltip.svelte +1 -1
  233. package/dist/transfer/Transfer.svelte +19 -19
  234. package/dist/tree/Tree.svelte +7 -6
  235. package/dist/tree-select/TreeSelect.svelte +20 -11
  236. package/dist/typography/TypographyBase.svelte +21 -12
  237. package/dist/typography/meta.d.ts +1 -1
  238. package/dist/typography/meta.d.ts.map +1 -1
  239. package/dist/typography/meta.js +3 -1
  240. package/dist/upload/Upload.svelte +44 -41
  241. package/package.json +3 -3
@@ -19,6 +19,7 @@
19
19
  import MenuPopupNode from './MenuPopupNode.svelte';
20
20
  import { deriveMenuSemantics, isDivider, isGroup } from './types.js';
21
21
  import type { Snippet } from 'svelte';
22
+ import type { Placement } from '@chenzy-design/core';
22
23
  import type { MenuItemDef, MenuItemNode, MenuKey, MenuPurpose } from './types.js';
23
24
 
24
25
  type Mode = 'vertical' | 'inline' | 'horizontal';
@@ -28,7 +29,7 @@
28
29
 
29
30
  interface TooltipProps {
30
31
  content?: string;
31
- position?: string;
32
+ position?: Placement;
32
33
  theme?: 'dark' | 'light';
33
34
  mouseEnterDelay?: number;
34
35
  mouseLeaveDelay?: number;
@@ -43,6 +44,20 @@
43
44
  defaultOpenKeys?: MenuKey[];
44
45
  size?: Size;
45
46
  inlineIndent?: number;
47
+ /**
48
+ * 缩进限制(默认 true):仅一级导航缩进,深层子项不按层级累加缩进。
49
+ * 设为 false 时按 level × inlineIndent 逐级缩进。仅 inline 模式有意义。
50
+ */
51
+ limitIndent?: boolean;
52
+ /**
53
+ * 含子菜单项的展开箭头位置(默认 'right'):'left' 置于 label 前、'right' 置于末尾。
54
+ * 仅 inline 模式(内联展开的 SubMenu title)生效。
55
+ */
56
+ toggleIconPosition?: 'left' | 'right';
57
+ /** 自定义展开箭头图标(Snippet,替代默认三角形)。 */
58
+ expandIcon?: Snippet;
59
+ /** 子菜单展开/浮层动画开关(默认 true)。false 时去除展开过渡与浮层动画。 */
60
+ motion?: boolean;
46
61
  /** inline 模式下折叠为图标轨:仅显图标、容器变窄,有子菜单的项 hover 向右弹浮层 */
47
62
  inlineCollapsed?: boolean;
48
63
  /** 多选模式:点击叶子项 toggle 其选中态,selectedKeys 可含多项同时高亮(默认单选) */
@@ -104,6 +119,10 @@
104
119
  defaultOpenKeys = [],
105
120
  size = 'default',
106
121
  inlineIndent = 24,
122
+ limitIndent = true,
123
+ toggleIconPosition = 'right',
124
+ expandIcon,
125
+ motion = true,
107
126
  inlineCollapsed = false,
108
127
  multiple = false,
109
128
  triggerSubMenuAction,
@@ -379,7 +398,8 @@
379
398
 
380
399
  {#snippet renderItems(list: MenuItemDef[], level: number)}
381
400
  {#each list as item, i (item.key ?? `__cd-menu-${level}-${i}`)}
382
- {@const indent = `calc(var(--cd-menu-item-padding) + ${level} * ${inlineIndent}px)`}
401
+ {@const indentLevel = limitIndent ? Math.min(level, 1) : level}
402
+ {@const indent = `calc(var(--cd-menu-item-padding) + ${indentLevel} * ${inlineIndent}px)`}
383
403
  {#if isDivider(item)}
384
404
  <li class="cd-menu__divider" role={sem.navigation ? undefined : 'separator'}></li>
385
405
  {:else if isGroup(item)}
@@ -428,20 +448,41 @@
428
448
  }
429
449
  }}
430
450
  >
451
+ {#if toggleIconPosition === 'left'}
452
+ <span
453
+ class="cd-menu__arrow cd-menu__arrow--left"
454
+ class:cd-menu__arrow--open={open}
455
+ aria-hidden="true"
456
+ >
457
+ {#if expandIcon}{@render expandIcon()}{:else}
458
+ <svg viewBox="0 0 16 16" width="10" height="10" focusable="false">
459
+ <path fill="currentColor" d="M6 4l4 4-4 4V4Z" />
460
+ </svg>
461
+ {/if}
462
+ </span>
463
+ {/if}
431
464
  {#if item.icon}<span class="cd-menu__icon" aria-hidden="true">{@render item.icon()}</span>{/if}
432
465
  <span class="cd-menu__label">{item.label}</span>
433
- <span
434
- class="cd-menu__arrow"
435
- class:cd-menu__arrow--open={open}
436
- aria-hidden="true"
437
- >
438
- <svg viewBox="0 0 16 16" width="10" height="10" focusable="false">
439
- <path fill="currentColor" d="M6 4l4 4-4 4V4Z" />
440
- </svg>
441
- </span>
466
+ {#if toggleIconPosition === 'right'}
467
+ <span
468
+ class="cd-menu__arrow"
469
+ class:cd-menu__arrow--open={open}
470
+ aria-hidden="true"
471
+ >
472
+ {#if expandIcon}{@render expandIcon()}{:else}
473
+ <svg viewBox="0 0 16 16" width="10" height="10" focusable="false">
474
+ <path fill="currentColor" d="M6 4l4 4-4 4V4Z" />
475
+ </svg>
476
+ {/if}
477
+ </span>
478
+ {/if}
442
479
  </button>
443
480
  {#if open}
444
- <ul class="cd-menu__sub" role={sem.subListRole}>
481
+ <ul
482
+ class="cd-menu__sub"
483
+ class:cd-menu__sub--motion={motion}
484
+ role={sem.subListRole}
485
+ >
445
486
  {@render renderItems(item.children ?? [], level + 1)}
446
487
  </ul>
447
488
  {/if}
@@ -461,7 +502,12 @@
461
502
  aria-current={selected ? 'page' : undefined}
462
503
  aria-disabled={isItemDisabled(item) || undefined}
463
504
  style="padding-inline-start: {indent}"
464
- onclick={() => selectLeaf(item)}
505
+ onclick={(e) => {
506
+ item.onClick?.(e);
507
+ selectLeaf(item);
508
+ }}
509
+ onmouseenter={item.onMouseEnter}
510
+ onmouseleave={item.onMouseLeave}
465
511
  >
466
512
  {#if item.icon}<span class="cd-menu__icon" aria-hidden="true">{@render item.icon()}</span>{/if}
467
513
  <span class="cd-menu__label">{item.label}</span>
@@ -484,7 +530,12 @@
484
530
  aria-disabled={isItemDisabled(item) || undefined}
485
531
  disabled={isItemDisabled(item) || undefined}
486
532
  style="padding-inline-start: {indent}"
487
- onclick={() => selectLeaf(item)}
533
+ onclick={(e) => {
534
+ item.onClick?.(e);
535
+ selectLeaf(item);
536
+ }}
537
+ onmouseenter={item.onMouseEnter}
538
+ onmouseleave={item.onMouseLeave}
488
539
  >
489
540
  {#if item.icon}<span class="cd-menu__icon" aria-hidden="true">{@render item.icon()}</span>{/if}
490
541
  <span class="cd-menu__label">{item.label}</span>
@@ -535,8 +586,8 @@
535
586
  {destroyOnHide}
536
587
  {getPopupContainer}
537
588
  parentDisabled={disabled}
538
- {tooltipProps}
539
- {renderWrapper}
589
+ {...(tooltipProps !== undefined ? { tooltipProps } : {})}
590
+ {...(renderWrapper !== undefined ? { renderWrapper } : {})}
540
591
  onSelectLeaf={selectLeaf}
541
592
  onCloseAll={() => {}}
542
593
  />
@@ -555,7 +606,7 @@
555
606
  {destroyOnHide}
556
607
  {getPopupContainer}
557
608
  parentDisabled={disabled}
558
- {renderWrapper}
609
+ {...(renderWrapper !== undefined ? { renderWrapper } : {})}
559
610
  onSelectLeaf={selectLeaf}
560
611
  onCloseAll={() => {}}
561
612
  />
@@ -606,13 +657,29 @@
606
657
  .cd-menu--horizontal > :global(.cd-menu__item) {
607
658
  display: flex;
608
659
  }
660
+ /* 水平导航配色对齐 Semi:默认项文字浅(text-2)、hover 文字变深(text-1) 且无背景、
661
+ 选中文字最深(text-0) + 无背景块、无下划线(Semi 顶部导航选中态仅靠文字深浅区分)。 */
609
662
  .cd-menu--horizontal > :global(.cd-menu__item) > :global(.cd-menu__link),
610
663
  .cd-menu--horizontal > :global(.cd-menu__item) > :global(.cd-menu__title) {
611
664
  inline-size: auto;
665
+ background: transparent;
666
+ color: var(--cd-color-text-2);
667
+ }
668
+ .cd-menu--horizontal > :global(.cd-menu__item) > :global(.cd-menu__link:hover),
669
+ .cd-menu--horizontal > :global(.cd-menu__item) > :global(.cd-menu__title:hover) {
670
+ background: transparent;
671
+ color: var(--cd-color-text-1);
672
+ }
673
+ .cd-menu--horizontal > :global(.cd-menu__item) > :global(.cd-menu__link--selected) {
674
+ background: transparent;
675
+ color: var(--cd-color-text-0);
612
676
  }
613
677
  /* 折叠图标轨:容器收窄到仅容图标 + padding */
678
+ /* 折叠图标轨:撑满容器宽度(如 Nav/Sider 的折叠宽度),使图标居中、选中背景填满。
679
+ min 用 token 兜底,避免容器未限宽时塌成 0。 */
614
680
  .cd-menu--collapsed {
615
- inline-size: var(--cd-menu-collapsed-width, calc(var(--cd-menu-item-height) + var(--cd-spacing-2)));
681
+ inline-size: 100%;
682
+ min-inline-size: var(--cd-menu-collapsed-width, calc(var(--cd-menu-item-height) + var(--cd-spacing-tight)));
616
683
  }
617
684
  .cd-menu__item {
618
685
  margin: 0;
@@ -623,10 +690,29 @@
623
690
  padding: 0;
624
691
  list-style: none;
625
692
  }
693
+ /* motion=true 时内联子菜单展开动画(淡入 + 轻微下移);motion=false 关闭 */
694
+ .cd-menu__sub--motion {
695
+ animation: cd-menu-sub-in var(--cd-motion-duration-fast) var(--cd-motion-ease-standard) both;
696
+ }
697
+ @keyframes cd-menu-sub-in {
698
+ from {
699
+ opacity: 0;
700
+ transform: translateY(-4px);
701
+ }
702
+ to {
703
+ opacity: 1;
704
+ transform: translateY(0);
705
+ }
706
+ }
707
+ @media (prefers-reduced-motion: reduce) {
708
+ .cd-menu__sub--motion {
709
+ animation: none;
710
+ }
711
+ }
626
712
  /* 分隔符:水平细线,不可交互 */
627
713
  .cd-menu__divider {
628
714
  block-size: 1px;
629
- margin-block: var(--cd-spacing-1);
715
+ margin-block: var(--cd-spacing-extra-tight);
630
716
  background: var(--cd-menu-border-color, var(--cd-color-border));
631
717
  }
632
718
  /* 分组:始终展开的分区标题 + 组内项列表 */
@@ -641,7 +727,7 @@
641
727
  block-size: var(--cd-menu-item-height);
642
728
  padding-inline: var(--cd-menu-item-padding);
643
729
  color: var(--cd-menu-item-color-disabled);
644
- font-size: var(--cd-font-size-1);
730
+ font-size: var(--cd-font-size-small);
645
731
  cursor: default;
646
732
  user-select: none;
647
733
  }
@@ -649,7 +735,7 @@
649
735
  .cd-menu__title {
650
736
  display: flex;
651
737
  align-items: center;
652
- gap: var(--cd-spacing-2);
738
+ gap: var(--cd-spacing-tight);
653
739
  inline-size: 100%;
654
740
  block-size: var(--cd-menu-item-height);
655
741
  padding-inline: var(--cd-menu-item-padding);
@@ -659,16 +745,17 @@
659
745
  font: inherit;
660
746
  text-align: start;
661
747
  cursor: pointer;
748
+ border-radius: var(--cd-menu-item-radius);
662
749
  transition: background var(--cd-motion-duration-fast)
663
750
  var(--cd-motion-ease-standard);
664
751
  }
665
752
  .cd-menu--small .cd-menu__link,
666
753
  .cd-menu--small .cd-menu__title {
667
- font-size: var(--cd-font-size-1);
754
+ font-size: var(--cd-font-size-small);
668
755
  }
669
756
  .cd-menu--large .cd-menu__link,
670
757
  .cd-menu--large .cd-menu__title {
671
- font-size: var(--cd-font-size-3);
758
+ font-size: var(--cd-font-size-header-6);
672
759
  }
673
760
  .cd-menu__link:hover,
674
761
  .cd-menu__title:hover {
@@ -679,39 +766,29 @@
679
766
  outline: none;
680
767
  box-shadow: var(--cd-focus-ring);
681
768
  }
769
+ /* 对齐 Semi:选中态深色文字 + 蓝底块,无左侧指示条,靠蓝底/蓝图标区分 */
682
770
  .cd-menu__link--selected {
683
771
  position: relative;
684
772
  color: var(--cd-menu-item-color-selected);
685
773
  background: var(--cd-menu-item-bg-selected);
686
774
  }
687
- .cd-menu__link--selected::before {
688
- content: '';
689
- position: absolute;
690
- inset-block: 0;
691
- inset-inline-start: 0;
692
- inline-size: 3px;
693
- background: var(--cd-menu-item-indicator);
775
+ .cd-menu__link--selected :global(.cd-menu__icon) {
776
+ color: var(--cd-menu-item-icon-color-selected);
694
777
  }
695
778
  .cd-menu__link[aria-disabled='true'],
696
779
  .cd-menu__title[aria-disabled='true'] {
697
780
  color: var(--cd-menu-item-color-disabled);
698
781
  cursor: not-allowed;
699
782
  }
700
- /* 校验态:用 token 着色选中指示条与选中文字(表单内菜单少见场景)。
783
+ /* 校验态:用 token 着色选中文字(表单内菜单少见场景)。
701
784
  选中叶子可能由子组件 MenuPopupNode 渲染(vertical/horizontal/collapsed 浮层模式),
702
785
  故用 :global 穿透 scoped 边界匹配后代 link。 */
703
786
  .cd-menu--warning :global(.cd-menu__link--selected) {
704
787
  color: var(--cd-menu-color-warning, var(--cd-color-warning));
705
788
  }
706
- .cd-menu--warning :global(.cd-menu__link--selected::before) {
707
- background: var(--cd-menu-color-warning, var(--cd-color-warning));
708
- }
709
789
  .cd-menu--error :global(.cd-menu__link--selected) {
710
790
  color: var(--cd-menu-color-danger, var(--cd-color-danger));
711
791
  }
712
- .cd-menu--error :global(.cd-menu__link--selected::before) {
713
- background: var(--cd-menu-color-danger, var(--cd-color-danger));
714
- }
715
792
  .cd-menu__label {
716
793
  flex: 1 1 auto;
717
794
  overflow: hidden;
@@ -734,7 +811,7 @@
734
811
  flex: 0 0 auto;
735
812
  inline-size: 1rem;
736
813
  block-size: 1rem;
737
- color: var(--cd-menu-item-color-selected);
814
+ color: var(--cd-menu-item-icon-color-selected);
738
815
  opacity: 0;
739
816
  }
740
817
  .cd-menu__check--on {
@@ -752,6 +829,10 @@
752
829
  .cd-menu__arrow--open {
753
830
  transform: rotate(90deg);
754
831
  }
832
+ /* toggleIconPosition='left':箭头置于 label 前,与后续内容留出间距 */
833
+ .cd-menu__arrow--left {
834
+ margin-inline-end: var(--cd-spacing-extra-tight);
835
+ }
755
836
  @media (prefers-reduced-motion: reduce) {
756
837
  .cd-menu__link,
757
838
  .cd-menu__title,
@@ -1,4 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
+ import type { Placement } from '@chenzy-design/core';
2
3
  import type { MenuItemDef, MenuItemNode, MenuKey, MenuPurpose } from './types.js';
3
4
  type Mode = 'vertical' | 'inline' | 'horizontal';
4
5
  type Size = 'small' | 'default' | 'large';
@@ -6,7 +7,7 @@ type Status = 'default' | 'warning' | 'error';
6
7
  type TriggerSubMenuAction = 'hover' | 'click';
7
8
  interface TooltipProps {
8
9
  content?: string;
9
- position?: string;
10
+ position?: Placement;
10
11
  theme?: 'dark' | 'light';
11
12
  mouseEnterDelay?: number;
12
13
  mouseLeaveDelay?: number;
@@ -20,6 +21,20 @@ interface Props {
20
21
  defaultOpenKeys?: MenuKey[];
21
22
  size?: Size;
22
23
  inlineIndent?: number;
24
+ /**
25
+ * 缩进限制(默认 true):仅一级导航缩进,深层子项不按层级累加缩进。
26
+ * 设为 false 时按 level × inlineIndent 逐级缩进。仅 inline 模式有意义。
27
+ */
28
+ limitIndent?: boolean;
29
+ /**
30
+ * 含子菜单项的展开箭头位置(默认 'right'):'left' 置于 label 前、'right' 置于末尾。
31
+ * 仅 inline 模式(内联展开的 SubMenu title)生效。
32
+ */
33
+ toggleIconPosition?: 'left' | 'right';
34
+ /** 自定义展开箭头图标(Snippet,替代默认三角形)。 */
35
+ expandIcon?: Snippet;
36
+ /** 子菜单展开/浮层动画开关(默认 true)。false 时去除展开过渡与浮层动画。 */
37
+ motion?: boolean;
23
38
  /** inline 模式下折叠为图标轨:仅显图标、容器变窄,有子菜单的项 hover 向右弹浮层 */
24
39
  inlineCollapsed?: boolean;
25
40
  /** 多选模式:点击叶子项 toggle 其选中态,selectedKeys 可含多项同时高亮(默认单选) */
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.svelte.d.ts","sourceRoot":"","sources":["../../src/menu/Menu.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGhF,KAAK,IAAI,GAAG,UAAU,GAAG,QAAQ,GAAG,YAAY,CAAC;AACjD,KAAK,IAAI,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAC1C,KAAK,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAC9C,KAAK,oBAAoB,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9C,UAAU,YAAY;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,KAAK;IACb,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,6BAA6B;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;IACzD;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;CACtE;AA6ZH,QAAA,MAAM,IAAI,2CAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"Menu.svelte.d.ts","sourceRoot":"","sources":["../../src/menu/Menu.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGhF,KAAK,IAAI,GAAG,UAAU,GAAG,QAAQ,GAAG,YAAY,CAAC;AACjD,KAAK,IAAI,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAC1C,KAAK,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAC9C,KAAK,oBAAoB,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9C,UAAU,YAAY;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,KAAK;IACb,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACtC,kCAAkC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gDAAgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,6BAA6B;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;IACzD;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;CACtE;AAsbH,QAAA,MAAM,IAAI,2CAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
@@ -17,7 +17,7 @@
17
17
 
18
18
  interface TooltipProps {
19
19
  content?: string;
20
- position?: string;
20
+ position?: Placement;
21
21
  theme?: 'dark' | 'light';
22
22
  mouseEnterDelay?: number;
23
23
  mouseLeaveDelay?: number;
@@ -87,6 +87,20 @@
87
87
  // 整体 disabled(parentDisabled)叠加单项 disabled。
88
88
  const itemDisabled = $derived(parentDisabled || !!node.disabled);
89
89
 
90
+ // 折叠 Tooltip 的可选透传项:exactOptionalPropertyTypes 下不能把 undefined 显式传给
91
+ // 值域不含 undefined 的可选 prop,故仅在有值时纳入(content/placement 始终有兜底另传)。
92
+ const tooltipPass = $derived({
93
+ content: tooltipProps?.content ?? node.label,
94
+ placement: tooltipProps?.position ?? ('right' as Placement),
95
+ ...(tooltipProps?.theme !== undefined ? { theme: tooltipProps.theme } : {}),
96
+ ...(tooltipProps?.mouseEnterDelay !== undefined
97
+ ? { mouseEnterDelay: tooltipProps.mouseEnterDelay }
98
+ : {}),
99
+ ...(tooltipProps?.mouseLeaveDelay !== undefined
100
+ ? { mouseLeaveDelay: tooltipProps.mouseLeaveDelay }
101
+ : {}),
102
+ });
103
+
90
104
  let titleEl = $state<HTMLButtonElement | null>(null);
91
105
  let open = $state(false);
92
106
 
@@ -189,8 +203,8 @@
189
203
  {getPopupContainer}
190
204
  {parentDisabled}
191
205
  {destroyOnHide}
192
- {tooltipProps}
193
- {renderWrapper}
206
+ {...(tooltipProps !== undefined ? { tooltipProps } : {})}
207
+ {...(renderWrapper !== undefined ? { renderWrapper } : {})}
194
208
  {onSelectLeaf}
195
209
  {onCloseAll}
196
210
  {openDelay}
@@ -238,13 +252,7 @@
238
252
  </button>
239
253
  {/snippet}
240
254
  {#if collapsed}
241
- <Tooltip
242
- content={tooltipProps?.content ?? node.label}
243
- placement={tooltipProps?.position ?? 'right'}
244
- theme={tooltipProps?.theme}
245
- mouseEnterDelay={tooltipProps?.mouseEnterDelay}
246
- mouseLeaveDelay={tooltipProps?.mouseLeaveDelay}
247
- >
255
+ <Tooltip {...tooltipPass}>
248
256
  {@render titleButton()}
249
257
  </Tooltip>
250
258
  {:else}
@@ -273,7 +281,7 @@
273
281
  {destroyOnHide}
274
282
  parentDisabled={parentDisabled}
275
283
  {onSelectLeaf}
276
- {renderWrapper}
284
+ {...(renderWrapper !== undefined ? { renderWrapper } : {})}
277
285
  onCloseAll={() => {
278
286
  closeNow();
279
287
  onCloseAll();
@@ -308,13 +316,7 @@
308
316
  </a>
309
317
  {/snippet}
310
318
  {#if collapsed}
311
- <Tooltip
312
- content={tooltipProps?.content ?? node.label}
313
- placement={tooltipProps?.position ?? 'right'}
314
- theme={tooltipProps?.theme}
315
- mouseEnterDelay={tooltipProps?.mouseEnterDelay}
316
- mouseLeaveDelay={tooltipProps?.mouseLeaveDelay}
317
- >
319
+ <Tooltip {...tooltipPass}>
318
320
  {#if renderWrapper}
319
321
  {@render renderWrapper({ item: node, children: leafLink })}
320
322
  {:else}
@@ -353,13 +355,7 @@
353
355
  </button>
354
356
  {/snippet}
355
357
  {#if collapsed}
356
- <Tooltip
357
- content={tooltipProps?.content ?? node.label}
358
- placement={tooltipProps?.position ?? 'right'}
359
- theme={tooltipProps?.theme}
360
- mouseEnterDelay={tooltipProps?.mouseEnterDelay}
361
- mouseLeaveDelay={tooltipProps?.mouseLeaveDelay}
362
- >
358
+ <Tooltip {...tooltipPass}>
363
359
  {#if renderWrapper}
364
360
  {@render renderWrapper({ item: node, children: leafButton })}
365
361
  {:else}
@@ -384,7 +380,7 @@
384
380
  /* 分隔符:水平细线,不可交互 */
385
381
  .cd-menu__divider {
386
382
  block-size: 1px;
387
- margin-block: var(--cd-spacing-1);
383
+ margin-block: var(--cd-spacing-extra-tight);
388
384
  background: var(--cd-menu-border-color, var(--cd-color-border));
389
385
  }
390
386
  /* 分组:始终展开的分区标题 + 组内项 */
@@ -399,7 +395,7 @@
399
395
  block-size: var(--cd-menu-item-height);
400
396
  padding-inline: var(--cd-menu-item-padding);
401
397
  color: var(--cd-menu-item-color-disabled);
402
- font-size: var(--cd-font-size-1);
398
+ font-size: var(--cd-font-size-small);
403
399
  cursor: default;
404
400
  user-select: none;
405
401
  }
@@ -407,7 +403,7 @@
407
403
  .cd-menu__title {
408
404
  display: flex;
409
405
  align-items: center;
410
- gap: var(--cd-spacing-2);
406
+ gap: var(--cd-spacing-tight);
411
407
  inline-size: 100%;
412
408
  block-size: var(--cd-menu-item-height);
413
409
  padding-inline: var(--cd-menu-item-padding);
@@ -437,18 +433,14 @@
437
433
  outline: none;
438
434
  box-shadow: var(--cd-focus-ring);
439
435
  }
436
+ /* 对齐 Semi:选中态深色文字 + 蓝底块,无左侧指示条 */
440
437
  .cd-menu__link--selected {
441
438
  position: relative;
442
439
  color: var(--cd-menu-item-color-selected);
443
440
  background: var(--cd-menu-item-bg-selected);
444
441
  }
445
- .cd-menu__link--selected::before {
446
- content: '';
447
- position: absolute;
448
- inset-block: 0;
449
- inset-inline-start: 0;
450
- inline-size: 3px;
451
- background: var(--cd-menu-item-indicator);
442
+ .cd-menu__link--selected :global(.cd-menu__icon) {
443
+ color: var(--cd-menu-item-icon-color-selected);
452
444
  }
453
445
  .cd-menu__link[aria-disabled='true'],
454
446
  .cd-menu__title[aria-disabled='true'] {
@@ -480,6 +472,14 @@
480
472
  gap: 0;
481
473
  padding-inline: 0;
482
474
  }
475
+ /* 折叠态项被 Tooltip 包裹,其触发器默认 inline-block 会收缩到图标宽度,
476
+ 导致选中背景/点击区只有 16px。强制 Tooltip 链路撑满 li 宽度,
477
+ 使图标居中、选中背景填满整条图标轨。 */
478
+ .cd-menu__item :global(.cd-tooltip),
479
+ .cd-menu__item :global(.cd-tooltip__trigger) {
480
+ display: block;
481
+ inline-size: 100%;
482
+ }
483
483
  .cd-menu__check {
484
484
  display: inline-flex;
485
485
  align-items: center;
@@ -487,7 +487,7 @@
487
487
  flex: 0 0 auto;
488
488
  inline-size: 1rem;
489
489
  block-size: 1rem;
490
- color: var(--cd-menu-item-color-selected);
490
+ color: var(--cd-menu-item-icon-color-selected);
491
491
  opacity: 0;
492
492
  }
493
493
  .cd-menu__check--on {
@@ -506,7 +506,7 @@
506
506
  padding: 0;
507
507
  list-style: none;
508
508
  min-inline-size: 8rem;
509
- padding-block: var(--cd-spacing-1);
509
+ padding-block: var(--cd-spacing-extra-tight);
510
510
  background: var(--cd-menu-bg);
511
511
  border-radius: var(--cd-select-dropdown-radius, 6px);
512
512
  box-shadow: var(--cd-select-dropdown-shadow, 0 4px 12px rgba(0, 0, 0, 0.12));
@@ -3,7 +3,7 @@ import type { Placement } from '@chenzy-design/core';
3
3
  import type { MenuItemDef, MenuItemNode, MenuKey } from './types.js';
4
4
  interface TooltipProps {
5
5
  content?: string;
6
- position?: string;
6
+ position?: Placement;
7
7
  theme?: 'dark' | 'light';
8
8
  mouseEnterDelay?: number;
9
9
  mouseLeaveDelay?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"MenuPopupNode.svelte.d.ts","sourceRoot":"","sources":["../../src/menu/MenuPopupNode.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAKnE,UAAU,YAAY;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,KAAK;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,gDAAgD;IAChD,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;IACtC,YAAY,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAC3C,sBAAsB;IACtB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IACvE,4CAA4C;IAC5C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iDAAiD;IACjD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;CACtE;AA0OH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"MenuPopupNode.svelte.d.ts","sourceRoot":"","sources":["../../src/menu/MenuPopupNode.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAKnE,UAAU,YAAY;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,KAAK;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,gDAAgD;IAChD,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;IACtC,YAAY,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAC3C,sBAAsB;IACtB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IACvE,4CAA4C;IAC5C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iDAAiD;IACjD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;CACtE;AAwPH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -43,6 +43,26 @@ export declare const meta: {
43
43
  readonly type: "number";
44
44
  readonly default: "24";
45
45
  readonly desc: "子级缩进像素";
46
+ }, {
47
+ readonly name: "limitIndent";
48
+ readonly type: "boolean";
49
+ readonly default: "true";
50
+ readonly desc: "仅一级缩进;false 时逐级缩进";
51
+ }, {
52
+ readonly name: "toggleIconPosition";
53
+ readonly type: "'left'|'right'";
54
+ readonly default: "'right'";
55
+ readonly desc: "inline 子菜单箭头位置";
56
+ }, {
57
+ readonly name: "expandIcon";
58
+ readonly type: "Snippet";
59
+ readonly default: "undefined";
60
+ readonly desc: "自定义展开箭头图标";
61
+ }, {
62
+ readonly name: "motion";
63
+ readonly type: "boolean";
64
+ readonly default: "true";
65
+ readonly desc: "子菜单展开动画开关";
46
66
  }, {
47
67
  readonly name: "inlineCollapsed";
48
68
  readonly type: "boolean";
@@ -122,6 +142,6 @@ export declare const meta: {
122
142
  readonly keyboard: readonly ["Tab", "Enter", "Space"];
123
143
  readonly notes: readonly ["ul[role=menu] > li[role=none] > button[role=menuitem] 结构", "SubMenu 标题 aria-haspopup=true + aria-expanded 反映展开态", "选中叶子项 aria-current=true(单选);multiple 下叶子项 role=menuitemcheckbox + aria-checked", "禁用项 aria-disabled=true 且原生 disabled", "divider 渲染 li[role=separator],不可聚焦不可选;键盘导航天然跳过(非 menuitem)", "group 渲染组标题(不可点击)+ ul[role=group][aria-label=分组名],组内项正常 menuitem 可选;组标题不可聚焦故键盘跳过", "purpose='navigation':<nav aria-label> landmark 包裹原生 ul>li>a(去除 menu/menuitem/separator/group 等 role),含 href 叶子为 <a href>,当前项 aria-current=page;用浏览器原生链接 + Tab 键序导航,不接管 ←→ roving", "purpose='menu'(默认):role=menu/menubar + menuitem,叶子 button + onClick,行为完全向后兼容;role 集合由 deriveMenuSemantics(purpose, mode, multiple) 纯函数派生(红线 #2)"];
124
144
  };
125
- readonly tokens: readonly ["--cd-menu-bg", "--cd-menu-item-height", "--cd-menu-item-padding", "--cd-menu-item-color", "--cd-menu-item-color-selected", "--cd-menu-item-color-disabled", "--cd-menu-item-bg-hover", "--cd-menu-item-bg-selected", "--cd-menu-item-indicator", "--cd-menu-submenu-arrow-color", "--cd-focus-ring", "--cd-motion-*"];
145
+ readonly tokens: readonly ["--cd-menu-bg", "--cd-menu-item-height", "--cd-menu-item-padding", "--cd-menu-item-radius", "--cd-menu-item-color", "--cd-menu-item-color-selected", "--cd-menu-item-icon-color-selected", "--cd-menu-item-color-disabled", "--cd-menu-item-bg-hover", "--cd-menu-item-bg-selected", "--cd-menu-submenu-arrow-color", "--cd-focus-ring", "--cd-motion-*"];
126
146
  };
127
147
  //# sourceMappingURL=meta.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/menu/meta.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoIP,CAAC"}
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/menu/meta.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyIP,CAAC"}
package/dist/menu/meta.js CHANGED
@@ -35,6 +35,10 @@ export const meta = {
35
35
  { name: 'defaultOpenKeys', type: '(string|number)[]', default: '[]' },
36
36
  { name: 'size', type: "'small'|'default'|'large'", default: 'default' },
37
37
  { name: 'inlineIndent', type: 'number', default: '24', desc: '子级缩进像素' },
38
+ { name: 'limitIndent', type: 'boolean', default: 'true', desc: '仅一级缩进;false 时逐级缩进' },
39
+ { name: 'toggleIconPosition', type: "'left'|'right'", default: "'right'", desc: 'inline 子菜单箭头位置' },
40
+ { name: 'expandIcon', type: 'Snippet', default: 'undefined', desc: '自定义展开箭头图标' },
41
+ { name: 'motion', type: 'boolean', default: 'true', desc: '子菜单展开动画开关' },
38
42
  {
39
43
  name: 'inlineCollapsed',
40
44
  type: 'boolean',
@@ -123,12 +127,13 @@ export const meta = {
123
127
  '--cd-menu-bg',
124
128
  '--cd-menu-item-height',
125
129
  '--cd-menu-item-padding',
130
+ '--cd-menu-item-radius',
126
131
  '--cd-menu-item-color',
127
132
  '--cd-menu-item-color-selected',
133
+ '--cd-menu-item-icon-color-selected',
128
134
  '--cd-menu-item-color-disabled',
129
135
  '--cd-menu-item-bg-hover',
130
136
  '--cd-menu-item-bg-selected',
131
- '--cd-menu-item-indicator',
132
137
  '--cd-menu-submenu-arrow-color',
133
138
  '--cd-focus-ring',
134
139
  '--cd-motion-*',
@@ -20,6 +20,12 @@ export interface MenuItemNode {
20
20
  target?: string;
21
21
  /** 链接 rel(如 'noopener noreferrer');仅 navigation + href 渲染 `<a>` 时透传。 */
22
22
  rel?: string;
23
+ /** 项级点击回调(叶子项;在 Menu onSelect 之外额外触发)。 */
24
+ onClick?: (e: MouseEvent) => void;
25
+ /** 项级鼠标移入回调。 */
26
+ onMouseEnter?: (e: MouseEvent) => void;
27
+ /** 项级鼠标移出回调。 */
28
+ onMouseLeave?: (e: MouseEvent) => void;
23
29
  }
24
30
  /**
25
31
  * 分隔符项:渲染为一条水平分隔线,不可选不可聚焦(role=separator)。
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/menu/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,iBAAiB;AACjB,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEtC,uCAAuC;AACvC,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,eAAe,GAAG,aAAa,CAAC;AAEzE,iBAAiB;AACjB,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,IAAI,eAAe,CAEpE;AAED,gBAAgB;AAChB,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,IAAI,aAAa,CAEhE;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,YAAY,CAAC;AAEhD,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACzC,0DAA0D;IAC1D,QAAQ,EAAE,UAAU,GAAG,kBAAkB,GAAG,SAAS,CAAC;IACtD,iDAAiD;IACjD,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAC;IACzC,6CAA6C;IAC7C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,+DAA+D;IAC/D,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,8CAA8C;IAC9C,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,YAAY,EAC1C,QAAQ,EAAE,OAAO,GAChB,aAAa,CAqBf"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/menu/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,iBAAiB;AACjB,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEtC,uCAAuC;AACvC,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,gBAAgB;IAChB,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACvC,gBAAgB;IAChB,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,eAAe,GAAG,aAAa,CAAC;AAEzE,iBAAiB;AACjB,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,IAAI,eAAe,CAEpE;AAED,gBAAgB;AAChB,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,IAAI,aAAa,CAEhE;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,YAAY,CAAC;AAEhD,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACzC,0DAA0D;IAC1D,QAAQ,EAAE,UAAU,GAAG,kBAAkB,GAAG,SAAS,CAAC;IACtD,iDAAiD;IACjD,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAC;IACzC,6CAA6C;IAC7C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,+DAA+D;IAC/D,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,8CAA8C;IAC9C,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,YAAY,EAC1C,QAAQ,EAAE,OAAO,GAChB,aAAa,CAqBf"}
@@ -144,7 +144,7 @@
144
144
  <style>
145
145
  .cd-confirm-modal__body {
146
146
  display: flex;
147
- gap: var(--cd-spacing-3);
147
+ gap: var(--cd-spacing-base-tight);
148
148
  align-items: flex-start;
149
149
  }
150
150
  .cd-confirm-modal__icon {