@greypan/web-ui 12.0.1 → 12.2.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 (164) hide show
  1. package/README.CN.md +4 -0
  2. package/README.md +4 -0
  3. package/dist/assets/menu-portal.js +1 -1
  4. package/dist/assets/menu-portal.js.map +1 -1
  5. package/dist/assets/toast-containers.js +1 -1
  6. package/dist/assets/toast-containers.js.map +1 -1
  7. package/dist/components/autocomplete/index.d.ts +5 -0
  8. package/dist/components/autocomplete/index.d.ts.map +1 -1
  9. package/dist/components/autocomplete/index.js +18 -2
  10. package/dist/components/autocomplete/index.js.map +1 -1
  11. package/dist/components/autocomplete/style.js +1 -1
  12. package/dist/components/autocomplete/style.js.map +1 -1
  13. package/dist/components/back-top/style.js +1 -1
  14. package/dist/components/back-top/style.js.map +1 -1
  15. package/dist/components/button-group/style.js +1 -1
  16. package/dist/components/button-group/style.js.map +1 -1
  17. package/dist/components/dialog/index.d.ts +5 -1
  18. package/dist/components/dialog/index.d.ts.map +1 -1
  19. package/dist/components/dialog/index.js +16 -4
  20. package/dist/components/dialog/index.js.map +1 -1
  21. package/dist/components/dialog/style.js +1 -1
  22. package/dist/components/dialog/style.js.map +1 -1
  23. package/dist/components/drawer/index.d.ts +11 -0
  24. package/dist/components/drawer/index.d.ts.map +1 -1
  25. package/dist/components/drawer/index.js +23 -1
  26. package/dist/components/drawer/index.js.map +1 -1
  27. package/dist/components/drawer/page-shift.js +113 -0
  28. package/dist/components/drawer/page-shift.js.map +1 -0
  29. package/dist/components/dropdown/index.js +1 -1
  30. package/dist/components/grouped-text/grouping.d.ts +25 -0
  31. package/dist/components/grouped-text/grouping.d.ts.map +1 -0
  32. package/dist/components/grouped-text/grouping.js +147 -0
  33. package/dist/components/grouped-text/grouping.js.map +1 -0
  34. package/dist/components/grouped-text/index.d.ts +36 -0
  35. package/dist/components/grouped-text/index.d.ts.map +1 -0
  36. package/dist/components/grouped-text/index.js +28 -0
  37. package/dist/components/grouped-text/index.js.map +1 -0
  38. package/dist/components/grouped-text/style.js +5 -0
  39. package/dist/components/grouped-text/style.js.map +1 -0
  40. package/dist/components/icon/index.d.ts +1 -1
  41. package/dist/components/icon/index.d.ts.map +1 -1
  42. package/dist/components/index.d.ts +6 -2
  43. package/dist/components/index.d.ts.map +1 -1
  44. package/dist/components/index.js +4 -1
  45. package/dist/components/layout/index.d.ts +8 -0
  46. package/dist/components/layout/index.d.ts.map +1 -1
  47. package/dist/components/layout/index.js +24 -13
  48. package/dist/components/layout/index.js.map +1 -1
  49. package/dist/components/layout/style.js +1 -1
  50. package/dist/components/layout/style.js.map +1 -1
  51. package/dist/components/middle-ellipsis/index.js +1 -1
  52. package/dist/components/popover/index.d.ts +5 -2
  53. package/dist/components/popover/index.d.ts.map +1 -1
  54. package/dist/components/popover/index.js +32 -21
  55. package/dist/components/popover/index.js.map +1 -1
  56. package/dist/components/popover/style.js +1 -1
  57. package/dist/components/popover/style.js.map +1 -1
  58. package/dist/components/progress/index.d.ts +30 -0
  59. package/dist/components/progress/index.d.ts.map +1 -0
  60. package/dist/components/progress/index.js +103 -0
  61. package/dist/components/progress/index.js.map +1 -0
  62. package/dist/components/progress/style.js +5 -0
  63. package/dist/components/progress/style.js.map +1 -0
  64. package/dist/components/segmented-trigger/index.d.ts +2 -0
  65. package/dist/components/segmented-trigger/index.d.ts.map +1 -1
  66. package/dist/components/segmented-trigger/index.js +7 -0
  67. package/dist/components/segmented-trigger/index.js.map +1 -1
  68. package/dist/components/select/index.d.ts +13 -0
  69. package/dist/components/select/index.d.ts.map +1 -1
  70. package/dist/components/select/index.js +41 -3
  71. package/dist/components/select/index.js.map +1 -1
  72. package/dist/components/select/style.js +1 -1
  73. package/dist/components/select/style.js.map +1 -1
  74. package/dist/components/shake/index.d.ts +43 -0
  75. package/dist/components/shake/index.d.ts.map +1 -0
  76. package/dist/components/shake/index.js +103 -0
  77. package/dist/components/shake/index.js.map +1 -0
  78. package/dist/components/spinner/index.d.ts +0 -3
  79. package/dist/components/spinner/index.d.ts.map +1 -1
  80. package/dist/components/spinner/index.js +5 -20
  81. package/dist/components/spinner/index.js.map +1 -1
  82. package/dist/components/spinner/style.js +1 -1
  83. package/dist/components/spinner/style.js.map +1 -1
  84. package/dist/components/theme/style.js +1 -1
  85. package/dist/components/theme/style.js.map +1 -1
  86. package/dist/components/tooltip/index.d.ts +8 -0
  87. package/dist/components/tooltip/index.d.ts.map +1 -1
  88. package/dist/components/tooltip/index.js +60 -10
  89. package/dist/components/tooltip/index.js.map +1 -1
  90. package/dist/components/tooltip/style.js +1 -1
  91. package/dist/components/tooltip/style.js.map +1 -1
  92. package/dist/icons/generated/ant-design-sync-outlined.d.ts +7 -0
  93. package/dist/icons/generated/ant-design-sync-outlined.d.ts.map +1 -0
  94. package/dist/icons/generated/ant-design-sync-outlined.js +9 -0
  95. package/dist/icons/generated/ant-design-sync-outlined.js.map +1 -0
  96. package/dist/icons/generated/ic-baseline-phonelink.d.ts +7 -0
  97. package/dist/icons/generated/ic-baseline-phonelink.d.ts.map +1 -0
  98. package/dist/icons/generated/ic-baseline-phonelink.js +9 -0
  99. package/dist/icons/generated/ic-baseline-phonelink.js.map +1 -0
  100. package/dist/icons/generated/ic-outline-motion-photos-off.d.ts +7 -0
  101. package/dist/icons/generated/ic-outline-motion-photos-off.d.ts.map +1 -0
  102. package/dist/icons/generated/ic-outline-motion-photos-off.js +9 -0
  103. package/dist/icons/generated/ic-outline-motion-photos-off.js.map +1 -0
  104. package/dist/icons/generated/ic-outline-motion-photos-on.d.ts +7 -0
  105. package/dist/icons/generated/ic-outline-motion-photos-on.d.ts.map +1 -0
  106. package/dist/icons/generated/ic-outline-motion-photos-on.js +9 -0
  107. package/dist/icons/generated/ic-outline-motion-photos-on.js.map +1 -0
  108. package/dist/icons/generated/ic-round-menu-open.d.ts +7 -0
  109. package/dist/icons/generated/ic-round-menu-open.d.ts.map +1 -0
  110. package/dist/icons/generated/ic-round-menu-open.js +9 -0
  111. package/dist/icons/generated/ic-round-menu-open.js.map +1 -0
  112. package/dist/icons/generated/lucide-accessibility.d.ts +7 -0
  113. package/dist/icons/generated/lucide-accessibility.d.ts.map +1 -0
  114. package/dist/icons/generated/lucide-accessibility.js +9 -0
  115. package/dist/icons/generated/lucide-accessibility.js.map +1 -0
  116. package/dist/icons/generated/lucide-boxes.d.ts +7 -0
  117. package/dist/icons/generated/lucide-boxes.d.ts.map +1 -0
  118. package/dist/icons/generated/lucide-boxes.js +9 -0
  119. package/dist/icons/generated/lucide-boxes.js.map +1 -0
  120. package/dist/icons/generated/lucide-contrast.d.ts +7 -0
  121. package/dist/icons/generated/lucide-contrast.d.ts.map +1 -0
  122. package/dist/icons/generated/lucide-contrast.js +9 -0
  123. package/dist/icons/generated/lucide-contrast.js.map +1 -0
  124. package/dist/icons/generated/lucide-keyboard.d.ts +7 -0
  125. package/dist/icons/generated/lucide-keyboard.d.ts.map +1 -0
  126. package/dist/icons/generated/lucide-keyboard.js +9 -0
  127. package/dist/icons/generated/lucide-keyboard.js.map +1 -0
  128. package/dist/icons/generated/lucide-languages.d.ts +7 -0
  129. package/dist/icons/generated/lucide-languages.d.ts.map +1 -0
  130. package/dist/icons/generated/lucide-languages.js +9 -0
  131. package/dist/icons/generated/lucide-languages.js.map +1 -0
  132. package/dist/icons/generated/lucide-list.d.ts +7 -0
  133. package/dist/icons/generated/lucide-list.d.ts.map +1 -0
  134. package/dist/icons/generated/lucide-list.js +9 -0
  135. package/dist/icons/generated/lucide-list.js.map +1 -0
  136. package/dist/icons/generated/lucide-moon.d.ts +7 -0
  137. package/dist/icons/generated/lucide-moon.d.ts.map +1 -0
  138. package/dist/icons/generated/lucide-moon.js +9 -0
  139. package/dist/icons/generated/lucide-moon.js.map +1 -0
  140. package/dist/icons/generated/lucide-sparkles.d.ts +7 -0
  141. package/dist/icons/generated/lucide-sparkles.d.ts.map +1 -0
  142. package/dist/icons/generated/lucide-sparkles.js +9 -0
  143. package/dist/icons/generated/lucide-sparkles.js.map +1 -0
  144. package/dist/icons/generated/lucide-sun.d.ts +7 -0
  145. package/dist/icons/generated/lucide-sun.d.ts.map +1 -0
  146. package/dist/icons/generated/lucide-sun.js +9 -0
  147. package/dist/icons/generated/lucide-sun.js.map +1 -0
  148. package/dist/icons/generated/tabler-brand-typescript.d.ts +7 -0
  149. package/dist/icons/generated/tabler-brand-typescript.d.ts.map +1 -0
  150. package/dist/icons/generated/tabler-brand-typescript.js +9 -0
  151. package/dist/icons/generated/tabler-brand-typescript.js.map +1 -0
  152. package/dist/icons/index.d.ts +87 -72
  153. package/dist/icons/index.js +16 -1
  154. package/dist/shared/locale/builtin-labels.js +2 -1
  155. package/dist/shared/locale/builtin-labels.js.map +1 -1
  156. package/dist/shared/overlay/anchored-panel.js +2 -2
  157. package/dist/shared/overlay/anchored-panel.js.map +1 -1
  158. package/dist/shared/overlay/presence.js +2 -2
  159. package/dist/shared/overlay/presence.js.map +1 -1
  160. package/dist/shared/overlay/trigger-props.d.ts +10 -0
  161. package/dist/shared/overlay/trigger-props.d.ts.map +1 -0
  162. package/dist/shared/overlay/trigger-props.js +42 -0
  163. package/dist/shared/overlay/trigger-props.js.map +1 -0
  164. package/package.json +4 -2
@@ -9,6 +9,7 @@ import lucide_chevron_up_default from "./generated/lucide-chevron-up.js";
9
9
  import lucide_chevron_down_default from "./generated/lucide-chevron-down.js";
10
10
  import lucide_plus_default from "./generated/lucide-plus.js";
11
11
  import lucide_minus_default from "./generated/lucide-minus.js";
12
+ import lucide_moon_default from "./generated/lucide-moon.js";
12
13
  import lucide_search_default from "./generated/lucide-search.js";
13
14
  import lucide_x_default from "./generated/lucide-x.js";
14
15
  import lucide_file_default from "./generated/lucide-file.js";
@@ -32,6 +33,7 @@ import heroicons_check_16_solid_default from "./generated/heroicons-check-16-sol
32
33
  import lucide_user_default from "./generated/lucide-user.js";
33
34
  import heroicons_x_mark_16_solid_default from "./generated/heroicons-x-mark-16-solid.js";
34
35
  import lucide_star_default from "./generated/lucide-star.js";
36
+ import lucide_sun_default from "./generated/lucide-sun.js";
35
37
  import lucide_heart_default from "./generated/lucide-heart.js";
36
38
  import lucide_bell_default from "./generated/lucide-bell.js";
37
39
  import lucide_mail_default from "./generated/lucide-mail.js";
@@ -44,6 +46,7 @@ import lucide_file_text_default from "./generated/lucide-file-text.js";
44
46
  import lucide_film_default from "./generated/lucide-film.js";
45
47
  import lucide_folder_open_default from "./generated/lucide-folder-open.js";
46
48
  import lucide_layout_grid_default from "./generated/lucide-layout-grid.js";
49
+ import lucide_list_default from "./generated/lucide-list.js";
47
50
  import lucide_music_default from "./generated/lucide-music.js";
48
51
  import lucide_package_default from "./generated/lucide-package.js";
49
52
  import lucide_pencil_default from "./generated/lucide-pencil.js";
@@ -72,4 +75,16 @@ import bi_check_lg_default from "./generated/bi-check-lg.js";
72
75
  import akar_icons_circle_check_default from "./generated/akar-icons-circle-check.js";
73
76
  import fluent_tag_search_24_regular_default from "./generated/fluent-tag-search-24-regular.js";
74
77
  import mdi_tag_search_outline_default from "./generated/mdi-tag-search-outline.js";
75
- export { akar_icons_check_default as akarIconsCheck, akar_icons_circle_check_default as akarIconsCircleCheck, andrsrxn_inbox_default as andrsrxnInbox, bi_check_default as biCheck, bi_check_lg_default as biCheckLg, fluent_tag_search_24_regular_default as fluentTagSearch24Regular, heroicons_bars_arrow_down_16_solid_default as heroiconsBarsArrowDown16Solid, heroicons_bars_arrow_up_16_solid_default as heroiconsBarsArrowUp16Solid, heroicons_check_16_solid_default as heroiconsCheck16Solid, heroicons_x_mark_16_solid_default as heroiconsXMark16Solid, jam_close_circle_f_default as jamCloseCircleF, lucide_arrow_down_to_line_default as lucideArrowDownToLine, lucide_arrow_up_to_line_default as lucideArrowUpToLine, lucide_bell_default as lucideBell, lucide_check_default as lucideCheck, lucide_chevron_down_default as lucideChevronDown, lucide_chevron_left_default as lucideChevronLeft, lucide_chevron_right_default as lucideChevronRight, lucide_chevron_up_default as lucideChevronUp, lucide_circle_alert_default as lucideCircleAlert, lucide_clapperboard_default as lucideClapperboard, lucide_clipboard_paste_default as lucideClipboardPaste, lucide_code_default as lucideCode, lucide_copy_default as lucideCopy, lucide_download_default as lucideDownload, lucide_ellipsis_vertical_default as lucideEllipsisVertical, lucide_external_link_default as lucideExternalLink, lucide_eye_default as lucideEye, lucide_file_default as lucideFile, lucide_file_text_default as lucideFileText, lucide_film_default as lucideFilm, lucide_folder_default as lucideFolder, lucide_folder_open_default as lucideFolderOpen, lucide_globe_default as lucideGlobe, lucide_headphones_default as lucideHeadphones, lucide_heart_default as lucideHeart, lucide_image_default as lucideImage, lucide_inbox_default as lucideInbox, lucide_info_default as lucideInfo, lucide_layout_grid_default as lucideLayoutGrid, lucide_link_default as lucideLink, lucide_list_filter_default as lucideListFilter, lucide_list_restart_default as lucideListRestart, lucide_loader_circle_default as lucideLoaderCircle, lucide_mail_default as lucideMail, lucide_minus_default as lucideMinus, lucide_music_default as lucideMusic, lucide_package_default as lucidePackage, lucide_pen_line_default as lucidePenLine, lucide_pencil_default as lucidePencil, lucide_play_default as lucidePlay, lucide_plus_default as lucidePlus, lucide_printer_default as lucidePrinter, lucide_redo_2_default as lucideRedo2, lucide_refresh_cw_default as lucideRefreshCw, lucide_scissors_default as lucideScissors, lucide_search_default as lucideSearch, lucide_settings_default as lucideSettings, lucide_sliders_horizontal_default as lucideSlidersHorizontal, lucide_star_default as lucideStar, lucide_tag_default as lucideTag, lucide_tags_default as lucideTags, lucide_trash_2_default as lucideTrash2, lucide_triangle_alert_default as lucideTriangleAlert, lucide_undo_2_default as lucideUndo2, lucide_upload_default as lucideUpload, lucide_user_default as lucideUser, lucide_wrench_default as lucideWrench, lucide_x_default as lucideX, mdi_tag_search_outline_default as mdiTagSearchOutline, ooui_close_default as oouiClose, radix_icons_panel_left_minimized_default as radixIconsPanelLeftMinimized, radix_icons_reset_default as radixIconsReset, tabler_sort_ascending_letters_default as tablerSortAscendingLetters };
78
+ import lucide_accessibility_default from "./generated/lucide-accessibility.js";
79
+ import lucide_boxes_default from "./generated/lucide-boxes.js";
80
+ import lucide_keyboard_default from "./generated/lucide-keyboard.js";
81
+ import lucide_sparkles_default from "./generated/lucide-sparkles.js";
82
+ import tabler_brand_typescript_default from "./generated/tabler-brand-typescript.js";
83
+ import ic_outline_motion_photos_on_default from "./generated/ic-outline-motion-photos-on.js";
84
+ import ic_outline_motion_photos_off_default from "./generated/ic-outline-motion-photos-off.js";
85
+ import lucide_contrast_default from "./generated/lucide-contrast.js";
86
+ import lucide_languages_default from "./generated/lucide-languages.js";
87
+ import ant_design_sync_outlined_default from "./generated/ant-design-sync-outlined.js";
88
+ import ic_baseline_phonelink_default from "./generated/ic-baseline-phonelink.js";
89
+ import ic_round_menu_open_default from "./generated/ic-round-menu-open.js";
90
+ export { akar_icons_check_default as akarIconsCheck, akar_icons_circle_check_default as akarIconsCircleCheck, andrsrxn_inbox_default as andrsrxnInbox, ant_design_sync_outlined_default as antDesignSyncOutlined, bi_check_default as biCheck, bi_check_lg_default as biCheckLg, fluent_tag_search_24_regular_default as fluentTagSearch24Regular, heroicons_bars_arrow_down_16_solid_default as heroiconsBarsArrowDown16Solid, heroicons_bars_arrow_up_16_solid_default as heroiconsBarsArrowUp16Solid, heroicons_check_16_solid_default as heroiconsCheck16Solid, heroicons_x_mark_16_solid_default as heroiconsXMark16Solid, ic_baseline_phonelink_default as icBaselinePhonelink, ic_outline_motion_photos_off_default as icOutlineMotionPhotosOff, ic_outline_motion_photos_on_default as icOutlineMotionPhotosOn, ic_round_menu_open_default as icRoundMenuOpen, jam_close_circle_f_default as jamCloseCircleF, lucide_accessibility_default as lucideAccessibility, lucide_arrow_down_to_line_default as lucideArrowDownToLine, lucide_arrow_up_to_line_default as lucideArrowUpToLine, lucide_bell_default as lucideBell, lucide_boxes_default as lucideBoxes, lucide_check_default as lucideCheck, lucide_chevron_down_default as lucideChevronDown, lucide_chevron_left_default as lucideChevronLeft, lucide_chevron_right_default as lucideChevronRight, lucide_chevron_up_default as lucideChevronUp, lucide_circle_alert_default as lucideCircleAlert, lucide_clapperboard_default as lucideClapperboard, lucide_clipboard_paste_default as lucideClipboardPaste, lucide_code_default as lucideCode, lucide_contrast_default as lucideContrast, lucide_copy_default as lucideCopy, lucide_download_default as lucideDownload, lucide_ellipsis_vertical_default as lucideEllipsisVertical, lucide_external_link_default as lucideExternalLink, lucide_eye_default as lucideEye, lucide_file_default as lucideFile, lucide_file_text_default as lucideFileText, lucide_film_default as lucideFilm, lucide_folder_default as lucideFolder, lucide_folder_open_default as lucideFolderOpen, lucide_globe_default as lucideGlobe, lucide_headphones_default as lucideHeadphones, lucide_heart_default as lucideHeart, lucide_image_default as lucideImage, lucide_inbox_default as lucideInbox, lucide_info_default as lucideInfo, lucide_keyboard_default as lucideKeyboard, lucide_languages_default as lucideLanguages, lucide_layout_grid_default as lucideLayoutGrid, lucide_link_default as lucideLink, lucide_list_default as lucideList, lucide_list_filter_default as lucideListFilter, lucide_list_restart_default as lucideListRestart, lucide_loader_circle_default as lucideLoaderCircle, lucide_mail_default as lucideMail, lucide_minus_default as lucideMinus, lucide_moon_default as lucideMoon, lucide_music_default as lucideMusic, lucide_package_default as lucidePackage, lucide_pen_line_default as lucidePenLine, lucide_pencil_default as lucidePencil, lucide_play_default as lucidePlay, lucide_plus_default as lucidePlus, lucide_printer_default as lucidePrinter, lucide_redo_2_default as lucideRedo2, lucide_refresh_cw_default as lucideRefreshCw, lucide_scissors_default as lucideScissors, lucide_search_default as lucideSearch, lucide_settings_default as lucideSettings, lucide_sliders_horizontal_default as lucideSlidersHorizontal, lucide_sparkles_default as lucideSparkles, lucide_star_default as lucideStar, lucide_sun_default as lucideSun, lucide_tag_default as lucideTag, lucide_tags_default as lucideTags, lucide_trash_2_default as lucideTrash2, lucide_triangle_alert_default as lucideTriangleAlert, lucide_undo_2_default as lucideUndo2, lucide_upload_default as lucideUpload, lucide_user_default as lucideUser, lucide_wrench_default as lucideWrench, lucide_x_default as lucideX, mdi_tag_search_outline_default as mdiTagSearchOutline, ooui_close_default as oouiClose, radix_icons_panel_left_minimized_default as radixIconsPanelLeftMinimized, radix_icons_reset_default as radixIconsReset, tabler_brand_typescript_default as tablerBrandTypescript, tabler_sort_ascending_letters_default as tablerSortAscendingLetters };
@@ -17,7 +17,8 @@ const LABELS = {
17
17
  nextImage: "Next image",
18
18
  zoomIn: "Zoom in",
19
19
  zoomOut: "Zoom out",
20
- resetZoom: "Reset zoom"
20
+ resetZoom: "Reset zoom",
21
+ progress: "Progress"
21
22
  };
22
23
  /** 显式覆盖优先(trim 后非空才生效);否则回退内置英文文案。 */
23
24
  function resolveBuiltinLabel(key, override) {
@@ -1 +1 @@
1
- {"version":3,"file":"builtin-labels.js","names":[],"sources":["../../../src/shared/locale/builtin-labels.ts"],"sourcesContent":["/**\n * 内置无障碍文案的唯一样表:图标控件的可访问名必须有值(无名称的图标按钮是\n * 默认的无障碍违规),内容文案不属于这里,始终由外部传入。\n *\n * fallback 固定英文,不跟随运行环境语言;需要其他语言时经覆盖通道改写——\n * 单标签组件用专用 attribute(`aria-close-label` 这类),多 key 成套组件用\n * `ariaLabels` 对象 property。分界规则见 ADR-0016。\n */\nexport type BuiltinLabelKey =\n | 'clear'\n | 'decrease'\n | 'increase'\n | 'close'\n | 'backToTop'\n | 'collapseSidebar'\n | 'expandSidebar'\n | 'resizeSidebar'\n | 'openNavigationMenu'\n | 'mainNavigation'\n | 'unread'\n | 'unreadCount'\n | 'noUnread'\n | 'previousImage'\n | 'nextImage'\n | 'zoomIn'\n | 'zoomOut'\n | 'resetZoom'\n\nconst LABELS: Record<BuiltinLabelKey, string> = {\n clear: 'Clear',\n decrease: 'Decrease',\n increase: 'Increase',\n close: 'Close',\n backToTop: 'Back to top',\n collapseSidebar: 'Collapse sidebar',\n expandSidebar: 'Expand sidebar',\n resizeSidebar: 'Resize sidebar',\n openNavigationMenu: 'Open navigation menu',\n mainNavigation: 'Main navigation',\n unread: 'Unread',\n unreadCount: '{count} unread messages',\n noUnread: 'No unread messages',\n previousImage: 'Previous image',\n nextImage: 'Next image',\n zoomIn: 'Zoom in',\n zoomOut: 'Zoom out',\n resetZoom: 'Reset zoom'\n}\n\n/** 显式覆盖优先(trim 后非空才生效);否则回退内置英文文案。 */\nexport function resolveBuiltinLabel(key: BuiltinLabelKey, override?: string | null): string {\n const custom = override?.trim()\n if (custom) return custom\n return LABELS[key]\n}\n\n/** 成组覆盖(`ariaLabels` 对象 property)里取单个 key;未提供的 key 回退内置英文。 */\nexport function resolveBuiltinLabelSet<K extends BuiltinLabelKey>(\n labels: Partial<Record<K, string>> | undefined,\n key: K\n): string {\n return resolveBuiltinLabel(key, labels?.[key])\n}\n\n/** 把 `{count}` 这类占位替换成实参;没有对应实参的占位原样保留。 */\nexport function formatBuiltinLabel(template: string, params: Record<string, string | number>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) => (name in params ? String(params[name]) : match))\n}\n"],"mappings":";AA4BA,MAAM,SAA0C;CAC9C,OAAO;CACP,UAAU;CACV,UAAU;CACV,OAAO;CACP,WAAW;CACX,iBAAiB;CACjB,eAAe;CACf,eAAe;CACf,oBAAoB;CACpB,gBAAgB;CAChB,QAAQ;CACR,aAAa;CACb,UAAU;CACV,eAAe;CACf,WAAW;CACX,QAAQ;CACR,SAAS;CACT,WAAW;AACb;;AAGA,SAAgB,oBAAoB,KAAsB,UAAkC;CAC1F,MAAM,SAAS,UAAU,KAAK;CAC9B,IAAI,QAAQ,OAAO;CACnB,OAAO,OAAO;AAChB;;AAGA,SAAgB,uBACd,QACA,KACQ;CACR,OAAO,oBAAoB,KAAK,SAAS,IAAI;AAC/C;;AAGA,SAAgB,mBAAmB,UAAkB,QAAiD;CACpG,OAAO,SAAS,QAAQ,eAAe,OAAO,SAAkB,QAAQ,SAAS,OAAO,OAAO,KAAK,IAAI,KAAM;AAChH"}
1
+ {"version":3,"file":"builtin-labels.js","names":[],"sources":["../../../src/shared/locale/builtin-labels.ts"],"sourcesContent":["/**\n * 内置无障碍文案的唯一样表:图标控件的可访问名必须有值(无名称的图标按钮是\n * 默认的无障碍违规),内容文案不属于这里,始终由外部传入。\n *\n * fallback 固定英文,不跟随运行环境语言;需要其他语言时经覆盖通道改写——\n * 单标签组件用专用 attribute(`aria-close-label` 这类),多 key 成套组件用\n * `ariaLabels` 对象 property。分界规则见 ADR-0016。\n */\nexport type BuiltinLabelKey =\n | 'clear'\n | 'decrease'\n | 'increase'\n | 'close'\n | 'backToTop'\n | 'collapseSidebar'\n | 'expandSidebar'\n | 'resizeSidebar'\n | 'openNavigationMenu'\n | 'mainNavigation'\n | 'unread'\n | 'unreadCount'\n | 'noUnread'\n | 'previousImage'\n | 'nextImage'\n | 'zoomIn'\n | 'zoomOut'\n | 'resetZoom'\n | 'progress'\n\nconst LABELS: Record<BuiltinLabelKey, string> = {\n clear: 'Clear',\n decrease: 'Decrease',\n increase: 'Increase',\n close: 'Close',\n backToTop: 'Back to top',\n collapseSidebar: 'Collapse sidebar',\n expandSidebar: 'Expand sidebar',\n resizeSidebar: 'Resize sidebar',\n openNavigationMenu: 'Open navigation menu',\n mainNavigation: 'Main navigation',\n unread: 'Unread',\n unreadCount: '{count} unread messages',\n noUnread: 'No unread messages',\n previousImage: 'Previous image',\n nextImage: 'Next image',\n zoomIn: 'Zoom in',\n zoomOut: 'Zoom out',\n resetZoom: 'Reset zoom',\n progress: 'Progress'\n}\n\n/** 显式覆盖优先(trim 后非空才生效);否则回退内置英文文案。 */\nexport function resolveBuiltinLabel(key: BuiltinLabelKey, override?: string | null): string {\n const custom = override?.trim()\n if (custom) return custom\n return LABELS[key]\n}\n\n/** 成组覆盖(`ariaLabels` 对象 property)里取单个 key;未提供的 key 回退内置英文。 */\nexport function resolveBuiltinLabelSet<K extends BuiltinLabelKey>(\n labels: Partial<Record<K, string>> | undefined,\n key: K\n): string {\n return resolveBuiltinLabel(key, labels?.[key])\n}\n\n/** 把 `{count}` 这类占位替换成实参;没有对应实参的占位原样保留。 */\nexport function formatBuiltinLabel(template: string, params: Record<string, string | number>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) => (name in params ? String(params[name]) : match))\n}\n"],"mappings":";AA6BA,MAAM,SAA0C;CAC9C,OAAO;CACP,UAAU;CACV,UAAU;CACV,OAAO;CACP,WAAW;CACX,iBAAiB;CACjB,eAAe;CACf,eAAe;CACf,oBAAoB;CACpB,gBAAgB;CAChB,QAAQ;CACR,aAAa;CACb,UAAU;CACV,eAAe;CACf,WAAW;CACX,QAAQ;CACR,SAAS;CACT,WAAW;CACX,UAAU;AACZ;;AAGA,SAAgB,oBAAoB,KAAsB,UAAkC;CAC1F,MAAM,SAAS,UAAU,KAAK;CAC9B,IAAI,QAAQ,OAAO;CACnB,OAAO,OAAO;AAChB;;AAGA,SAAgB,uBACd,QACA,KACQ;CACR,OAAO,oBAAoB,KAAK,SAAS,IAAI;AAC/C;;AAGA,SAAgB,mBAAmB,UAAkB,QAAiD;CACpG,OAAO,SAAS,QAAQ,eAAe,OAAO,SAAkB,QAAQ,SAAS,OAAO,OAAO,KAAK,IAAI,KAAM;AAChH"}
@@ -63,11 +63,11 @@ const defineAnchoredPanel = () => definePlugin((ctx) => {
63
63
  return handle;
64
64
  },
65
65
  open,
66
- async close(isStillOpen) {
66
+ async close(isStillOpen, isInstant = false) {
67
67
  handle?.deferArbitration();
68
68
  overlay?.close();
69
69
  const panel = getPanel();
70
- if (panel && !await hideOverlayPresence(panel)) return false;
70
+ if (panel && !await hideOverlayPresence(panel, { isInstant })) return false;
71
71
  if (isStillOpen()) {
72
72
  handle?.deferArbitration(false);
73
73
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"anchored-panel.js","names":[],"sources":["../../../src/shared/overlay/anchored-panel.ts"],"sourcesContent":["import { definePlugin } from '@greypan/js-kit'\n\nimport type { OpenOverlay, OpenOverlayHandle, OverlayArbitration } from './open-overlay'\nimport { defineOverlay, type OverlayApi, type OverlayOptions } from './overlay'\nimport type { OverlayPortal } from './portal'\nimport { hideOverlayPresence, showOverlayPresence } from './presence'\n\nexport interface AnchoredPanelOptions {\n getAnchor(): HTMLElement | null\n getLocalPanel(): HTMLElement | null\n getPositioning(): OverlayOptions\n isPortal(): boolean\n createPortal(): OverlayPortal\n /**\n * 承载「本 panel 是一次开启态 overlay」的实例:登记与 Escape 归属由它完成,本模块不\n * 自己维护逻辑父子关系。\n *\n * 必须是**调用方持有的那个实例**(而不是这里新建一个)——调用方同时要用它的帧\n * 事务入口,两个实例会让「我开着吗」重新分裂。\n */\n openOverlay: OpenOverlay\n /** 本 panel 与 Escape 仲裁的关系。tooltip 传 `none`;缺省 `escape`。 */\n arbitration?: OverlayArbitration\n}\n\n/**\n * 管理锚定 panel 的本地/Portal 容器、定位器和可中断 presence。\n * 内容迁移与交互语义由各组件保留,避免把不同组件的 public contract 混入此模块。\n */\nexport interface AnchoredPanelApi {\n getPanel(): HTMLElement | null\n /**\n * 当前在场会话的 handle;没有任何在场会话时为 `null`。\n * 查询(`contains` / `containsEvent` / `hasFocusWithin`)与 `setInert` 都走它,\n * 调用方因此不必持有 panel 引用,也不知道存在全局注册表。\n * 退场等待期间仍是同一个 handle(暂缓仲裁),动画播完或重新 `open()` 才换人。\n */\n getHandle(): OpenOverlayHandle | null\n open(isInstant?: boolean): void\n close(isStillOpen: () => boolean): Promise<boolean>\n updatePosition(): void\n reconfigure(isOpen: boolean): void\n dispose(): void\n}\n\nexport const defineAnchoredPanel = () =>\n definePlugin<AnchoredPanelApi, AnchoredPanelOptions>(ctx => {\n let overlay: OverlayApi | undefined\n let portal: OverlayPortal | undefined\n let handle: OpenOverlayHandle | null = null\n\n const getPanel = () => portal?.panel ?? ctx.getLocalPanel()\n\n const releaseHandle = () => {\n handle?.release()\n handle = null\n }\n\n const disposePortal = () => {\n if (!portal) return\n portal.restoreContent()\n portal.remove()\n portal = undefined\n overlay = undefined\n }\n\n const getOrCreatePanel = (): HTMLElement | null => {\n if (!ctx.isPortal()) return ctx.getLocalPanel()\n portal ??= ctx.createPortal()\n return portal.panel\n }\n\n const ensureOverlay = (anchor: HTMLElement, panel: HTMLElement) => {\n if (overlay) {\n overlay.updateAnchor(anchor)\n overlay.update(ctx.getPositioning())\n return\n }\n overlay = defineOverlay().make({ anchor, overlay: panel, ...ctx.getPositioning() })\n }\n\n const open = (isInstant = false) => {\n const anchor = ctx.getAnchor()\n if (!anchor) return\n const panel = getOrCreatePanel()\n if (!panel) return\n // portal panel 与宿主物理分离;本地 panel 也可能隔着 shadow 边界。\n // 以 anchor 祖先链寻找最近的已开启 overlay,建立统一逻辑父子关系。\n // claim ⟺ open:重复 open 视为新的一次开启,旧会话整体作废。\n releaseHandle()\n handle = ctx.openOverlay.claim(panel, { arbitration: ctx.arbitration, ancestryFrom: anchor })\n ensureOverlay(anchor, panel)\n overlay?.open()\n showOverlayPresence(panel, { isInstant })\n }\n\n const dispose = () => {\n overlay?.dispose()\n overlay = undefined\n releaseHandle()\n disposePortal()\n }\n\n return {\n getPanel() {\n return getPanel()\n },\n\n getHandle() {\n return handle\n },\n\n open,\n\n async close(isStillOpen) {\n /*\n * 第三态「可见但暂缓仲裁」:退场等待期间 panel 仍在场,登记不撤,但不再走关闭\n * 入口——它已经在关的路上了。撤销推迟到动画结束,或被 `open()` 以新会话取代。\n *\n * 若在这里立即 `releaseHandle()`,两条提前返回的路径都会把还看得见的 panel\n * 留在未登记状态:未登记即不参与「谁是最内层」的仲裁,直到下一次 `open()` 才\n * 恢复(issue #138)。\n *\n * 暂缓层只是兜底候选:仍在开启的外层永远优先。否则「内层关掉后立刻再按一次\n * Escape」会被退场动画吞掉,外层永远等不到自己那一次——issue #120 的契约。\n *\n * 退场被打断时 `showOverlayPresence` 已把 panel 带回场,`open()` 同时重新 claim\n * (与「重复 open 视为新的一次开启」同一条路径),本条 `close()` 随后的\n * `return false` 不碰那个新 handle。\n *\n * 走到 `isStillOpen()` 时退场已经播完:panel 已 `hidden`。此刻宿主仍认为开着,\n * 是 panel 状态与宿主状态不一致的那一格——把层交还仲裁而不是继续暂缓。继续暂缓的\n * 前提是「panel 可见」,而这里 panel 已经看不见了:一个隐藏的 panel 无限吞掉 Escape,\n * 用户再也没有按键路径把这个状态收敛掉(按一次 Escape 走宿主的关闭入口,宿主\n * 回写 open=false 后由随后的 close() 正常收尾)。登记仍然不撤,「宿主认为开着\n * 就不掉出仲裁」的 #138 语义不变。\n */\n handle?.deferArbitration()\n overlay?.close()\n const panel = getPanel()\n if (panel && !(await hideOverlayPresence(panel))) return false\n if (isStillOpen()) {\n handle?.deferArbitration(false)\n return false\n }\n releaseHandle()\n disposePortal()\n return true\n },\n\n updatePosition() {\n overlay?.update(ctx.getPositioning())\n },\n\n reconfigure(isOpen) {\n const shouldAnimate = getPanel()?.dataset.wuiPresence === 'entering'\n dispose()\n if (isOpen) open(!shouldAnimate)\n },\n\n dispose\n }\n })\n"],"mappings":";;;;AA6CA,MAAa,4BACX,cAAqD,QAAO;CAC1D,IAAI;CACJ,IAAI;CACJ,IAAI,SAAmC;CAEvC,MAAM,iBAAiB,QAAQ,SAAS,IAAI,cAAc;CAE1D,MAAM,sBAAsB;EAC1B,QAAQ,QAAQ;EAChB,SAAS;CACX;CAEA,MAAM,sBAAsB;EAC1B,IAAI,CAAC,QAAQ;EACb,OAAO,eAAe;EACtB,OAAO,OAAO;EACd,SAAS,KAAA;EACT,UAAU,KAAA;CACZ;CAEA,MAAM,yBAA6C;EACjD,IAAI,CAAC,IAAI,SAAS,GAAG,OAAO,IAAI,cAAc;EAC9C,WAAW,IAAI,aAAa;EAC5B,OAAO,OAAO;CAChB;CAEA,MAAM,iBAAiB,QAAqB,UAAuB;EACjE,IAAI,SAAS;GACX,QAAQ,aAAa,MAAM;GAC3B,QAAQ,OAAO,IAAI,eAAe,CAAC;GACnC;EACF;EACA,UAAU,cAAc,CAAC,CAAC,KAAK;GAAE;GAAQ,SAAS;GAAO,GAAG,IAAI,eAAe;EAAE,CAAC;CACpF;CAEA,MAAM,QAAQ,YAAY,UAAU;EAClC,MAAM,SAAS,IAAI,UAAU;EAC7B,IAAI,CAAC,QAAQ;EACb,MAAM,QAAQ,iBAAiB;EAC/B,IAAI,CAAC,OAAO;EAIZ,cAAc;EACd,SAAS,IAAI,YAAY,MAAM,OAAO;GAAE,aAAa,IAAI;GAAa,cAAc;EAAO,CAAC;EAC5F,cAAc,QAAQ,KAAK;EAC3B,SAAS,KAAK;EACd,oBAAoB,OAAO,EAAE,UAAU,CAAC;CAC1C;CAEA,MAAM,gBAAgB;EACpB,SAAS,QAAQ;EACjB,UAAU,KAAA;EACV,cAAc;EACd,cAAc;CAChB;CAEA,OAAO;EACL,WAAW;GACT,OAAO,SAAS;EAClB;EAEA,YAAY;GACV,OAAO;EACT;EAEA;EAEA,MAAM,MAAM,aAAa;GAuBvB,QAAQ,iBAAiB;GACzB,SAAS,MAAM;GACf,MAAM,QAAQ,SAAS;GACvB,IAAI,SAAS,CAAE,MAAM,oBAAoB,KAAK,GAAI,OAAO;GACzD,IAAI,YAAY,GAAG;IACjB,QAAQ,iBAAiB,KAAK;IAC9B,OAAO;GACT;GACA,cAAc;GACd,cAAc;GACd,OAAO;EACT;EAEA,iBAAiB;GACf,SAAS,OAAO,IAAI,eAAe,CAAC;EACtC;EAEA,YAAY,QAAQ;GAClB,MAAM,gBAAgB,SAAS,CAAC,EAAE,QAAQ,gBAAgB;GAC1D,QAAQ;GACR,IAAI,QAAQ,KAAK,CAAC,aAAa;EACjC;EAEA;CACF;AACF,CAAC"}
1
+ {"version":3,"file":"anchored-panel.js","names":[],"sources":["../../../src/shared/overlay/anchored-panel.ts"],"sourcesContent":["import { definePlugin } from '@greypan/js-kit'\n\nimport type { OpenOverlay, OpenOverlayHandle, OverlayArbitration } from './open-overlay'\nimport { defineOverlay, type OverlayApi, type OverlayOptions } from './overlay'\nimport type { OverlayPortal } from './portal'\nimport { hideOverlayPresence, showOverlayPresence } from './presence'\n\nexport interface AnchoredPanelOptions {\n getAnchor(): HTMLElement | null\n getLocalPanel(): HTMLElement | null\n getPositioning(): OverlayOptions\n isPortal(): boolean\n createPortal(): OverlayPortal\n /**\n * 承载「本 panel 是一次开启态 overlay」的实例:登记与 Escape 归属由它完成,本模块不\n * 自己维护逻辑父子关系。\n *\n * 必须是**调用方持有的那个实例**(而不是这里新建一个)——调用方同时要用它的帧\n * 事务入口,两个实例会让「我开着吗」重新分裂。\n */\n openOverlay: OpenOverlay\n /** 本 panel 与 Escape 仲裁的关系。tooltip 传 `none`;缺省 `escape`。 */\n arbitration?: OverlayArbitration\n}\n\n/**\n * 管理锚定 panel 的本地/Portal 容器、定位器和可中断 presence。\n * 内容迁移与交互语义由各组件保留,避免把不同组件的 public contract 混入此模块。\n */\nexport interface AnchoredPanelApi {\n getPanel(): HTMLElement | null\n /**\n * 当前在场会话的 handle;没有任何在场会话时为 `null`。\n * 查询(`contains` / `containsEvent` / `hasFocusWithin`)与 `setInert` 都走它,\n * 调用方因此不必持有 panel 引用,也不知道存在全局注册表。\n * 退场等待期间仍是同一个 handle(暂缓仲裁),动画播完或重新 `open()` 才换人。\n */\n getHandle(): OpenOverlayHandle | null\n open(isInstant?: boolean): void\n /**\n * 播放退场并收尾。`isInstant` 表示这次没有可退场的内容(例如候选被全部过滤掉),\n * panel 直接落隐藏态;不传则照常播退场过渡。\n */\n close(isStillOpen: () => boolean, isInstant?: boolean): Promise<boolean>\n updatePosition(): void\n reconfigure(isOpen: boolean): void\n dispose(): void\n}\n\nexport const defineAnchoredPanel = () =>\n definePlugin<AnchoredPanelApi, AnchoredPanelOptions>(ctx => {\n let overlay: OverlayApi | undefined\n let portal: OverlayPortal | undefined\n let handle: OpenOverlayHandle | null = null\n\n const getPanel = () => portal?.panel ?? ctx.getLocalPanel()\n\n const releaseHandle = () => {\n handle?.release()\n handle = null\n }\n\n const disposePortal = () => {\n if (!portal) return\n portal.restoreContent()\n portal.remove()\n portal = undefined\n overlay = undefined\n }\n\n const getOrCreatePanel = (): HTMLElement | null => {\n if (!ctx.isPortal()) return ctx.getLocalPanel()\n portal ??= ctx.createPortal()\n return portal.panel\n }\n\n const ensureOverlay = (anchor: HTMLElement, panel: HTMLElement) => {\n if (overlay) {\n overlay.updateAnchor(anchor)\n overlay.update(ctx.getPositioning())\n return\n }\n overlay = defineOverlay().make({ anchor, overlay: panel, ...ctx.getPositioning() })\n }\n\n const open = (isInstant = false) => {\n const anchor = ctx.getAnchor()\n if (!anchor) return\n const panel = getOrCreatePanel()\n if (!panel) return\n // portal panel 与宿主物理分离;本地 panel 也可能隔着 shadow 边界。\n // 以 anchor 祖先链寻找最近的已开启 overlay,建立统一逻辑父子关系。\n // claim ⟺ open:重复 open 视为新的一次开启,旧会话整体作废。\n releaseHandle()\n handle = ctx.openOverlay.claim(panel, { arbitration: ctx.arbitration, ancestryFrom: anchor })\n ensureOverlay(anchor, panel)\n overlay?.open()\n showOverlayPresence(panel, { isInstant })\n }\n\n const dispose = () => {\n overlay?.dispose()\n overlay = undefined\n releaseHandle()\n disposePortal()\n }\n\n return {\n getPanel() {\n return getPanel()\n },\n\n getHandle() {\n return handle\n },\n\n open,\n\n async close(isStillOpen, isInstant = false) {\n /*\n * 第三态「可见但暂缓仲裁」:退场等待期间 panel 仍在场,登记不撤,但不再走关闭\n * 入口——它已经在关的路上了。撤销推迟到动画结束,或被 `open()` 以新会话取代。\n *\n * 若在这里立即 `releaseHandle()`,两条提前返回的路径都会把还看得见的 panel\n * 留在未登记状态:未登记即不参与「谁是最内层」的仲裁,直到下一次 `open()` 才\n * 恢复(issue #138)。\n *\n * 暂缓层只是兜底候选:仍在开启的外层永远优先。否则「内层关掉后立刻再按一次\n * Escape」会被退场动画吞掉,外层永远等不到自己那一次——issue #120 的契约。\n *\n * 退场被打断时 `showOverlayPresence` 已把 panel 带回场,`open()` 同时重新 claim\n * (与「重复 open 视为新的一次开启」同一条路径),本条 `close()` 随后的\n * `return false` 不碰那个新 handle。\n *\n * 走到 `isStillOpen()` 时退场已经播完:panel 已 `hidden`。此刻宿主仍认为开着,\n * 是 panel 状态与宿主状态不一致的那一格——把层交还仲裁而不是继续暂缓。继续暂缓的\n * 前提是「panel 可见」,而这里 panel 已经看不见了:一个隐藏的 panel 无限吞掉 Escape,\n * 用户再也没有按键路径把这个状态收敛掉(按一次 Escape 走宿主的关闭入口,宿主\n * 回写 open=false 后由随后的 close() 正常收尾)。登记仍然不撤,「宿主认为开着\n * 就不掉出仲裁」的 #138 语义不变。\n */\n handle?.deferArbitration()\n overlay?.close()\n const panel = getPanel()\n if (panel && !(await hideOverlayPresence(panel, { isInstant }))) return false\n if (isStillOpen()) {\n handle?.deferArbitration(false)\n return false\n }\n releaseHandle()\n disposePortal()\n return true\n },\n\n updatePosition() {\n overlay?.update(ctx.getPositioning())\n },\n\n reconfigure(isOpen) {\n const shouldAnimate = getPanel()?.dataset.wuiPresence === 'entering'\n dispose()\n if (isOpen) open(!shouldAnimate)\n },\n\n dispose\n }\n })\n"],"mappings":";;;;AAiDA,MAAa,4BACX,cAAqD,QAAO;CAC1D,IAAI;CACJ,IAAI;CACJ,IAAI,SAAmC;CAEvC,MAAM,iBAAiB,QAAQ,SAAS,IAAI,cAAc;CAE1D,MAAM,sBAAsB;EAC1B,QAAQ,QAAQ;EAChB,SAAS;CACX;CAEA,MAAM,sBAAsB;EAC1B,IAAI,CAAC,QAAQ;EACb,OAAO,eAAe;EACtB,OAAO,OAAO;EACd,SAAS,KAAA;EACT,UAAU,KAAA;CACZ;CAEA,MAAM,yBAA6C;EACjD,IAAI,CAAC,IAAI,SAAS,GAAG,OAAO,IAAI,cAAc;EAC9C,WAAW,IAAI,aAAa;EAC5B,OAAO,OAAO;CAChB;CAEA,MAAM,iBAAiB,QAAqB,UAAuB;EACjE,IAAI,SAAS;GACX,QAAQ,aAAa,MAAM;GAC3B,QAAQ,OAAO,IAAI,eAAe,CAAC;GACnC;EACF;EACA,UAAU,cAAc,CAAC,CAAC,KAAK;GAAE;GAAQ,SAAS;GAAO,GAAG,IAAI,eAAe;EAAE,CAAC;CACpF;CAEA,MAAM,QAAQ,YAAY,UAAU;EAClC,MAAM,SAAS,IAAI,UAAU;EAC7B,IAAI,CAAC,QAAQ;EACb,MAAM,QAAQ,iBAAiB;EAC/B,IAAI,CAAC,OAAO;EAIZ,cAAc;EACd,SAAS,IAAI,YAAY,MAAM,OAAO;GAAE,aAAa,IAAI;GAAa,cAAc;EAAO,CAAC;EAC5F,cAAc,QAAQ,KAAK;EAC3B,SAAS,KAAK;EACd,oBAAoB,OAAO,EAAE,UAAU,CAAC;CAC1C;CAEA,MAAM,gBAAgB;EACpB,SAAS,QAAQ;EACjB,UAAU,KAAA;EACV,cAAc;EACd,cAAc;CAChB;CAEA,OAAO;EACL,WAAW;GACT,OAAO,SAAS;EAClB;EAEA,YAAY;GACV,OAAO;EACT;EAEA;EAEA,MAAM,MAAM,aAAa,YAAY,OAAO;GAuB1C,QAAQ,iBAAiB;GACzB,SAAS,MAAM;GACf,MAAM,QAAQ,SAAS;GACvB,IAAI,SAAS,CAAE,MAAM,oBAAoB,OAAO,EAAE,UAAU,CAAC,GAAI,OAAO;GACxE,IAAI,YAAY,GAAG;IACjB,QAAQ,iBAAiB,KAAK;IAC9B,OAAO;GACT;GACA,cAAc;GACd,cAAc;GACd,OAAO;EACT;EAEA,iBAAiB;GACf,SAAS,OAAO,IAAI,eAAe,CAAC;EACtC;EAEA,YAAY,QAAQ;GAClB,MAAM,gBAAgB,SAAS,CAAC,EAAE,QAAQ,gBAAgB;GAC1D,QAAQ;GACR,IAAI,QAAQ,KAAK,CAAC,aAAa;EACjC;EAEA;CACF;AACF,CAAC"}
@@ -22,10 +22,10 @@ function showOverlayPresence(panel, options = {}) {
22
22
  if (panel.dataset.wuiPresence === "entering") panel.dataset.wuiPresence = "open";
23
23
  });
24
24
  }
25
- function hideOverlayPresence(panel) {
25
+ function hideOverlayPresence(panel, options = {}) {
26
26
  pendingExits.get(panel)?.();
27
27
  panel.dataset.wuiPresence = "closing";
28
- if (getTransitionDuration(panel, 0) === 0) {
28
+ if (options.isInstant || getTransitionDuration(panel, 0) === 0) {
29
29
  panel.hidden = true;
30
30
  return Promise.resolve(true);
31
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"presence.js","names":[],"sources":["../../../src/shared/overlay/presence.ts"],"sourcesContent":["import { parseDuration } from '@/shared/theme/duration'\n\nconst DEFAULT_EXIT_DURATION = 160\nconst EXIT_FALLBACK_BUFFER = 80\n\nconst pendingExits = new WeakMap<HTMLElement, () => void>()\n\ninterface OverlayPresenceOptions {\n isInstant?: boolean\n}\n\n// 读取元素实际 CSS transition 的最长时长,供可覆盖主题 token 的 JS 生命周期使用。\nexport function getTransitionDuration(panel: HTMLElement, fallback = DEFAULT_EXIT_DURATION): number {\n const style = getComputedStyle(panel)\n const durations = style.transitionDuration.split(',').map(value => parseDuration(value) ?? 0)\n const delays = style.transitionDelay.split(',').map(value => parseDuration(value) ?? 0)\n const longest = durations.reduce(\n (max, duration, index) => Math.max(max, duration + (delays[index] ?? delays[0] ?? 0)),\n 0\n )\n\n return longest || fallback\n}\n\n// 以可中断的方式显示 overlay,避免快速切换时重启动画。\nexport function showOverlayPresence(panel: HTMLElement, options: OverlayPresenceOptions = {}) {\n pendingExits.get(panel)?.()\n panel.hidden = false\n if (options.isInstant) {\n panel.dataset.wuiPresence = 'open'\n return\n }\n panel.dataset.wuiPresence = 'entering'\n\n // 提交初始状态,让新挂载的 panel 拥有过渡起点。\n void panel.offsetWidth\n\n requestAnimationFrame(() => {\n if (panel.dataset.wuiPresence === 'entering') panel.dataset.wuiPresence = 'open'\n })\n}\n\n// 播放退出过渡;若在结束前重新显示则返回 false。\nexport function hideOverlayPresence(panel: HTMLElement): Promise<boolean> {\n pendingExits.get(panel)?.()\n panel.dataset.wuiPresence = 'closing'\n\n // jsdom 等没有计算 CSS transition 的环境无需伪造退场等待。\n if (getTransitionDuration(panel, 0) === 0) {\n panel.hidden = true\n return Promise.resolve(true)\n }\n\n return new Promise(resolve => {\n let settled = false\n const finish = (didClose: boolean) => {\n if (settled) return\n settled = true\n panel.removeEventListener('transitionend', onTransitionEnd)\n clearTimeout(timeout)\n pendingExits.delete(panel)\n if (didClose && panel.dataset.wuiPresence === 'closing') panel.hidden = true\n resolve(didClose)\n }\n\n const onTransitionEnd = (event: TransitionEvent) => {\n if (event.target === panel && (event.propertyName === 'opacity' || event.propertyName === 'transform'))\n finish(true)\n }\n\n pendingExits.set(panel, () => finish(false))\n panel.addEventListener('transitionend', onTransitionEnd)\n const timeout = setTimeout(() => finish(true), getTransitionDuration(panel) + EXIT_FALLBACK_BUFFER)\n })\n}\n"],"mappings":";;AAEA,MAAM,wBAAwB;AAC9B,MAAM,uBAAuB;AAE7B,MAAM,+BAAe,IAAI,QAAiC;AAO1D,SAAgB,sBAAsB,OAAoB,WAAW,uBAA+B;CAClG,MAAM,QAAQ,iBAAiB,KAAK;CACpC,MAAM,YAAY,MAAM,mBAAmB,MAAM,GAAG,CAAC,CAAC,KAAI,UAAS,cAAc,KAAK,KAAK,CAAC;CAC5F,MAAM,SAAS,MAAM,gBAAgB,MAAM,GAAG,CAAC,CAAC,KAAI,UAAS,cAAc,KAAK,KAAK,CAAC;CAMtF,OALgB,UAAU,QACvB,KAAK,UAAU,UAAU,KAAK,IAAI,KAAK,YAAY,OAAO,UAAU,OAAO,MAAM,EAAE,GACpF,CAGW,KAAK;AACpB;AAGA,SAAgB,oBAAoB,OAAoB,UAAkC,CAAC,GAAG;CAC5F,aAAa,IAAI,KAAK,CAAC,GAAG;CAC1B,MAAM,SAAS;CACf,IAAI,QAAQ,WAAW;EACrB,MAAM,QAAQ,cAAc;EAC5B;CACF;CACA,MAAM,QAAQ,cAAc;CAG5B,MAAW;CAEX,4BAA4B;EAC1B,IAAI,MAAM,QAAQ,gBAAgB,YAAY,MAAM,QAAQ,cAAc;CAC5E,CAAC;AACH;AAGA,SAAgB,oBAAoB,OAAsC;CACxE,aAAa,IAAI,KAAK,CAAC,GAAG;CAC1B,MAAM,QAAQ,cAAc;CAG5B,IAAI,sBAAsB,OAAO,CAAC,MAAM,GAAG;EACzC,MAAM,SAAS;EACf,OAAO,QAAQ,QAAQ,IAAI;CAC7B;CAEA,OAAO,IAAI,SAAQ,YAAW;EAC5B,IAAI,UAAU;EACd,MAAM,UAAU,aAAsB;GACpC,IAAI,SAAS;GACb,UAAU;GACV,MAAM,oBAAoB,iBAAiB,eAAe;GAC1D,aAAa,OAAO;GACpB,aAAa,OAAO,KAAK;GACzB,IAAI,YAAY,MAAM,QAAQ,gBAAgB,WAAW,MAAM,SAAS;GACxE,QAAQ,QAAQ;EAClB;EAEA,MAAM,mBAAmB,UAA2B;GAClD,IAAI,MAAM,WAAW,UAAU,MAAM,iBAAiB,aAAa,MAAM,iBAAiB,cACxF,OAAO,IAAI;EACf;EAEA,aAAa,IAAI,aAAa,OAAO,KAAK,CAAC;EAC3C,MAAM,iBAAiB,iBAAiB,eAAe;EACvD,MAAM,UAAU,iBAAiB,OAAO,IAAI,GAAG,sBAAsB,KAAK,IAAI,oBAAoB;CACpG,CAAC;AACH"}
1
+ {"version":3,"file":"presence.js","names":[],"sources":["../../../src/shared/overlay/presence.ts"],"sourcesContent":["import { parseDuration } from '@/shared/theme/duration'\n\nconst DEFAULT_EXIT_DURATION = 160\nconst EXIT_FALLBACK_BUFFER = 80\n\nconst pendingExits = new WeakMap<HTMLElement, () => void>()\n\ninterface OverlayPresenceOptions {\n isInstant?: boolean\n}\n\n// 读取元素实际 CSS transition 的最长时长,供可覆盖主题 token 的 JS 生命周期使用。\nexport function getTransitionDuration(panel: HTMLElement, fallback = DEFAULT_EXIT_DURATION): number {\n const style = getComputedStyle(panel)\n const durations = style.transitionDuration.split(',').map(value => parseDuration(value) ?? 0)\n const delays = style.transitionDelay.split(',').map(value => parseDuration(value) ?? 0)\n const longest = durations.reduce(\n (max, duration, index) => Math.max(max, duration + (delays[index] ?? delays[0] ?? 0)),\n 0\n )\n\n return longest || fallback\n}\n\n// 以可中断的方式显示 overlay,避免快速切换时重启动画。\nexport function showOverlayPresence(panel: HTMLElement, options: OverlayPresenceOptions = {}) {\n pendingExits.get(panel)?.()\n panel.hidden = false\n if (options.isInstant) {\n panel.dataset.wuiPresence = 'open'\n return\n }\n panel.dataset.wuiPresence = 'entering'\n\n // 提交初始状态,让新挂载的 panel 拥有过渡起点。\n void panel.offsetWidth\n\n requestAnimationFrame(() => {\n if (panel.dataset.wuiPresence === 'entering') panel.dataset.wuiPresence = 'open'\n })\n}\n\n// 播放退出过渡;若在结束前重新显示则返回 false。\n// `isInstant` 由调用方声明「这次没有可退场的内容」:直接落隐藏态,不播过渡。\nexport function hideOverlayPresence(panel: HTMLElement, options: OverlayPresenceOptions = {}): Promise<boolean> {\n pendingExits.get(panel)?.()\n panel.dataset.wuiPresence = 'closing'\n\n // 两条不播过渡的路:调用方要求立即隐藏,以及 jsdom 这类不计算 CSS transition 的环境。\n if (options.isInstant || getTransitionDuration(panel, 0) === 0) {\n panel.hidden = true\n return Promise.resolve(true)\n }\n\n return new Promise(resolve => {\n let settled = false\n const finish = (didClose: boolean) => {\n if (settled) return\n settled = true\n panel.removeEventListener('transitionend', onTransitionEnd)\n clearTimeout(timeout)\n pendingExits.delete(panel)\n if (didClose && panel.dataset.wuiPresence === 'closing') panel.hidden = true\n resolve(didClose)\n }\n\n const onTransitionEnd = (event: TransitionEvent) => {\n if (event.target === panel && (event.propertyName === 'opacity' || event.propertyName === 'transform'))\n finish(true)\n }\n\n pendingExits.set(panel, () => finish(false))\n panel.addEventListener('transitionend', onTransitionEnd)\n const timeout = setTimeout(() => finish(true), getTransitionDuration(panel) + EXIT_FALLBACK_BUFFER)\n })\n}\n"],"mappings":";;AAEA,MAAM,wBAAwB;AAC9B,MAAM,uBAAuB;AAE7B,MAAM,+BAAe,IAAI,QAAiC;AAO1D,SAAgB,sBAAsB,OAAoB,WAAW,uBAA+B;CAClG,MAAM,QAAQ,iBAAiB,KAAK;CACpC,MAAM,YAAY,MAAM,mBAAmB,MAAM,GAAG,CAAC,CAAC,KAAI,UAAS,cAAc,KAAK,KAAK,CAAC;CAC5F,MAAM,SAAS,MAAM,gBAAgB,MAAM,GAAG,CAAC,CAAC,KAAI,UAAS,cAAc,KAAK,KAAK,CAAC;CAMtF,OALgB,UAAU,QACvB,KAAK,UAAU,UAAU,KAAK,IAAI,KAAK,YAAY,OAAO,UAAU,OAAO,MAAM,EAAE,GACpF,CAGW,KAAK;AACpB;AAGA,SAAgB,oBAAoB,OAAoB,UAAkC,CAAC,GAAG;CAC5F,aAAa,IAAI,KAAK,CAAC,GAAG;CAC1B,MAAM,SAAS;CACf,IAAI,QAAQ,WAAW;EACrB,MAAM,QAAQ,cAAc;EAC5B;CACF;CACA,MAAM,QAAQ,cAAc;CAG5B,MAAW;CAEX,4BAA4B;EAC1B,IAAI,MAAM,QAAQ,gBAAgB,YAAY,MAAM,QAAQ,cAAc;CAC5E,CAAC;AACH;AAIA,SAAgB,oBAAoB,OAAoB,UAAkC,CAAC,GAAqB;CAC9G,aAAa,IAAI,KAAK,CAAC,GAAG;CAC1B,MAAM,QAAQ,cAAc;CAG5B,IAAI,QAAQ,aAAa,sBAAsB,OAAO,CAAC,MAAM,GAAG;EAC9D,MAAM,SAAS;EACf,OAAO,QAAQ,QAAQ,IAAI;CAC7B;CAEA,OAAO,IAAI,SAAQ,YAAW;EAC5B,IAAI,UAAU;EACd,MAAM,UAAU,aAAsB;GACpC,IAAI,SAAS;GACb,UAAU;GACV,MAAM,oBAAoB,iBAAiB,eAAe;GAC1D,aAAa,OAAO;GACpB,aAAa,OAAO,KAAK;GACzB,IAAI,YAAY,MAAM,QAAQ,gBAAgB,WAAW,MAAM,SAAS;GACxE,QAAQ,QAAQ;EAClB;EAEA,MAAM,mBAAmB,UAA2B;GAClD,IAAI,MAAM,WAAW,UAAU,MAAM,iBAAiB,aAAa,MAAM,iBAAiB,cACxF,OAAO,IAAI;EACf;EAEA,aAAa,IAAI,aAAa,OAAO,KAAK,CAAC;EAC3C,MAAM,iBAAiB,iBAAiB,eAAe;EACvD,MAAM,UAAU,iBAAiB,OAAO,IAAI,GAAG,sBAAsB,KAAK,IAAI,oBAAoB;CACpG,CAAC;AACH"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * tooltip / popover 共享的触发方式词表。
3
+ *
4
+ * `trigger` 是空格分隔的集合,不是单值枚举:「悬停和键盘聚焦都能开」是真实需求,
5
+ * 用单值表达同样的空间要拆成十几种字面量。这里只负责把取值规范化,
6
+ * 每种手势接哪些事件由组件自己决定。
7
+ */
8
+ export declare const OVERLAY_TRIGGER_MODES: readonly ["click", "hover", "focus", "manual"];
9
+ export type OverlayTriggerMode = (typeof OVERLAY_TRIGGER_MODES)[number];
10
+ //# sourceMappingURL=trigger-props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-props.d.ts","names":[],"sources":["../../../src/shared/overlay/trigger-props.ts"],"mappings":";;;;;;;qBAQa;YAED,6BAA6B"}
@@ -0,0 +1,42 @@
1
+ // src/shared/overlay/trigger-props.ts
2
+ /**
3
+ * tooltip / popover 共享的触发方式词表。
4
+ *
5
+ * `trigger` 是空格分隔的集合,不是单值枚举:「悬停和键盘聚焦都能开」是真实需求,
6
+ * 用单值表达同样的空间要拆成十几种字面量。这里只负责把取值规范化,
7
+ * 每种手势接哪些事件由组件自己决定。
8
+ */
9
+ const OVERLAY_TRIGGER_MODES = [
10
+ "click",
11
+ "hover",
12
+ "focus",
13
+ "manual"
14
+ ];
15
+ /**
16
+ * 规范化为空格分隔的规范串:未知 token 丢弃、重复去除、按声明顺序输出。
17
+ *
18
+ * 出现 `manual` 时整串只保留 `manual`:它的语义是「不接受任何自动开合」,
19
+ * 与并存的手势矛盾,取严的一侧。空集合回退到 `fallback`,所以 `trigger=""`
20
+ * 读作「没写」而不是「没有手势」——要没有手势写 `manual`。
21
+ */
22
+ function normalizeTriggerSet(value, fallback) {
23
+ const requested = new Set(readTokens(value));
24
+ const modes = requested.has("manual") ? ["manual"] : OVERLAY_TRIGGER_MODES.filter((mode) => requested.has(mode));
25
+ return (modes.length > 0 ? modes : fallback).join(" ");
26
+ }
27
+ /** 规范串里是否含某个 mode。 */
28
+ function hasTriggerMode(trigger, mode) {
29
+ return trigger.split(/\s+/u).includes(mode);
30
+ }
31
+ /**
32
+ * 数组走 property 通道(`:trigger="['hover', 'focus']"`),字符串走 attribute;
33
+ * 其余取值一律当作没写。
34
+ */
35
+ function readTokens(value) {
36
+ if (typeof value === "string") return value.split(/\s+/u).filter(Boolean);
37
+ if (Array.isArray(value)) return value.flatMap((item) => readTokens(item));
38
+ return [];
39
+ }
40
+ export { OVERLAY_TRIGGER_MODES, hasTriggerMode, normalizeTriggerSet };
41
+
42
+ //# sourceMappingURL=trigger-props.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-props.js","names":[],"sources":["../../../src/shared/overlay/trigger-props.ts"],"sourcesContent":["/**\n * tooltip / popover 共享的触发方式词表。\n *\n * `trigger` 是空格分隔的集合,不是单值枚举:「悬停和键盘聚焦都能开」是真实需求,\n * 用单值表达同样的空间要拆成十几种字面量。这里只负责把取值规范化,\n * 每种手势接哪些事件由组件自己决定。\n */\n\nexport const OVERLAY_TRIGGER_MODES = ['click', 'hover', 'focus', 'manual'] as const\n\nexport type OverlayTriggerMode = (typeof OVERLAY_TRIGGER_MODES)[number]\n\n/**\n * 规范化为空格分隔的规范串:未知 token 丢弃、重复去除、按声明顺序输出。\n *\n * 出现 `manual` 时整串只保留 `manual`:它的语义是「不接受任何自动开合」,\n * 与并存的手势矛盾,取严的一侧。空集合回退到 `fallback`,所以 `trigger=\"\"`\n * 读作「没写」而不是「没有手势」——要没有手势写 `manual`。\n */\nexport function normalizeTriggerSet(value: unknown, fallback: readonly OverlayTriggerMode[]): string {\n const requested = new Set(readTokens(value))\n const modes: readonly OverlayTriggerMode[] = requested.has('manual')\n ? ['manual']\n : OVERLAY_TRIGGER_MODES.filter(mode => requested.has(mode))\n return (modes.length > 0 ? modes : fallback).join(' ')\n}\n\n/** 规范串里是否含某个 mode。 */\nexport function hasTriggerMode(trigger: string, mode: OverlayTriggerMode): boolean {\n return trigger.split(/\\s+/u).includes(mode)\n}\n\n/**\n * 数组走 property 通道(`:trigger=\"['hover', 'focus']\"`),字符串走 attribute;\n * 其余取值一律当作没写。\n */\nfunction readTokens(value: unknown): string[] {\n if (typeof value === 'string') return value.split(/\\s+/u).filter(Boolean)\n if (Array.isArray(value)) return value.flatMap(item => readTokens(item))\n return []\n}\n"],"mappings":";;;;;;;;AAQA,MAAa,wBAAwB;CAAC;CAAS;CAAS;CAAS;AAAQ;;;;;;;;AAWzE,SAAgB,oBAAoB,OAAgB,UAAiD;CACnG,MAAM,YAAY,IAAI,IAAI,WAAW,KAAK,CAAC;CAC3C,MAAM,QAAuC,UAAU,IAAI,QAAQ,IAC/D,CAAC,QAAQ,IACT,sBAAsB,QAAO,SAAQ,UAAU,IAAI,IAAI,CAAC;CAC5D,QAAQ,MAAM,SAAS,IAAI,QAAQ,SAAA,CAAU,KAAK,GAAG;AACvD;;AAGA,SAAgB,eAAe,SAAiB,MAAmC;CACjF,OAAO,QAAQ,MAAM,MAAM,CAAC,CAAC,SAAS,IAAI;AAC5C;;;;;AAMA,SAAS,WAAW,OAA0B;CAC5C,IAAI,OAAO,UAAU,UAAU,OAAO,MAAM,MAAM,MAAM,CAAC,CAAC,OAAO,OAAO;CACxE,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,SAAQ,SAAQ,WAAW,IAAI,CAAC;CACvE,OAAO,CAAC;AACV"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greypan/web-ui",
3
- "version": "12.0.1",
3
+ "version": "12.2.0",
4
4
  "description": "Lit-based web components for React, Vue, and vanilla JS",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -48,12 +48,14 @@
48
48
  "@lit/context": "^1.1.6"
49
49
  },
50
50
  "devDependencies": {
51
- "@greypan/monorepo-kit": "0.0.1",
51
+ "@greypan/monorepo-kit": "0.0.2",
52
52
  "@greypan/tsconfig": "0.0.0",
53
53
  "@iconify-json/akar-icons": "^1.2.7",
54
54
  "@iconify-json/andrsrxn": "^1.2.2",
55
55
  "@iconify-json/bi": "^1.2.7",
56
+ "@iconify-json/ant-design": "^1.2.9",
56
57
  "@iconify-json/fluent": "^1.2.58",
58
+ "@iconify-json/ic": "^1.2.4",
57
59
  "@iconify-json/jam": "^1.2.3",
58
60
  "@iconify-json/lucide": "^1.2.126",
59
61
  "@iconify-json/mdi": "^1.2.3",