@greypan/web-ui 11.2.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.CN.md +79 -68
- package/README.md +81 -72
- package/dist/_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js +8 -0
- package/dist/assets/menu-portal.js +3 -4
- package/dist/assets/menu-portal.js.map +1 -1
- package/dist/assets/modal-surface.js +3 -4
- package/dist/assets/modal-surface.js.map +1 -1
- package/dist/assets/overlay-motion.js +3 -4
- package/dist/assets/overlay-motion.js.map +1 -1
- package/dist/assets/scrollbar.js +5 -0
- package/dist/assets/scrollbar.js.map +1 -0
- package/dist/assets/selection-control.js +3 -4
- package/dist/assets/selection-control.js.map +1 -1
- package/dist/assets/toast-containers.js +3 -4
- package/dist/assets/toast-containers.js.map +1 -1
- package/dist/classes/glass.js +3 -4
- package/dist/classes/glass.js.map +1 -1
- package/dist/classes/glow.js +3 -4
- package/dist/classes/glow.js.map +1 -1
- package/dist/components/autocomplete/index.d.ts +485 -483
- package/dist/components/autocomplete/index.d.ts.map +1 -0
- package/dist/components/autocomplete/index.js +475 -267
- package/dist/components/autocomplete/index.js.map +1 -1
- package/dist/components/autocomplete/style.js +3 -4
- package/dist/components/autocomplete/style.js.map +1 -1
- package/dist/components/avatar/index.d.ts +26 -24
- package/dist/components/avatar/index.d.ts.map +1 -0
- package/dist/components/avatar/index.js +72 -52
- package/dist/components/avatar/index.js.map +1 -1
- package/dist/components/avatar/style.js +3 -4
- package/dist/components/avatar/style.js.map +1 -1
- package/dist/components/back-top/index.d.ts +30 -27
- package/dist/components/back-top/index.d.ts.map +1 -0
- package/dist/components/back-top/index.js +96 -62
- package/dist/components/back-top/index.js.map +1 -1
- package/dist/components/back-top/style.js +3 -4
- package/dist/components/back-top/style.js.map +1 -1
- package/dist/components/badge/index.d.ts +32 -26
- package/dist/components/badge/index.d.ts.map +1 -0
- package/dist/components/badge/index.js +116 -74
- package/dist/components/badge/index.js.map +1 -1
- package/dist/components/badge/style.js +3 -4
- package/dist/components/badge/style.js.map +1 -1
- package/dist/components/button/index.d.ts +392 -390
- package/dist/components/button/index.d.ts.map +1 -0
- package/dist/components/button/index.js +108 -74
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/button/style.js +3 -4
- package/dist/components/button/style.js.map +1 -1
- package/dist/components/button-group/index.d.ts +14 -13
- package/dist/components/button-group/index.d.ts.map +1 -0
- package/dist/components/button-group/index.js +43 -33
- package/dist/components/button-group/index.js.map +1 -1
- package/dist/components/button-group/style.js +3 -4
- package/dist/components/button-group/style.js.map +1 -1
- package/dist/components/checkbox/index.d.ts +399 -397
- package/dist/components/checkbox/index.d.ts.map +1 -0
- package/dist/components/checkbox/index.js +103 -74
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox/style.js +3 -4
- package/dist/components/checkbox/style.js.map +1 -1
- package/dist/components/checkbox-group/index.d.ts +397 -396
- package/dist/components/checkbox-group/index.d.ts.map +1 -0
- package/dist/components/checkbox-group/index.js +92 -70
- package/dist/components/checkbox-group/index.js.map +1 -1
- package/dist/components/checkbox-group/style.js +3 -4
- package/dist/components/checkbox-group/style.js.map +1 -1
- package/dist/components/collapse/index.d.ts +72 -71
- package/dist/components/collapse/index.d.ts.map +1 -0
- package/dist/components/collapse/index.js +225 -130
- package/dist/components/collapse/index.js.map +1 -1
- package/dist/components/collapse/style.js +3 -4
- package/dist/components/collapse/style.js.map +1 -1
- package/dist/components/context-menu/index.d.ts +307 -310
- package/dist/components/context-menu/index.d.ts.map +1 -0
- package/dist/components/context-menu/index.js +685 -270
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/context-menu/scrim.js +3 -4
- package/dist/components/context-menu/scrim.js.map +1 -1
- package/dist/components/context-menu/style.js +3 -4
- package/dist/components/context-menu/style.js.map +1 -1
- package/dist/components/dialog/index.d.ts +87 -78
- package/dist/components/dialog/index.d.ts.map +1 -0
- package/dist/components/dialog/index.js +183 -88
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/dialog/style.js +3 -4
- package/dist/components/dialog/style.js.map +1 -1
- package/dist/components/drawer/index.d.ts +159 -150
- package/dist/components/drawer/index.d.ts.map +1 -0
- package/dist/components/drawer/index.js +503 -242
- package/dist/components/drawer/index.js.map +1 -1
- package/dist/components/drawer/style.js +3 -4
- package/dist/components/drawer/style.js.map +1 -1
- package/dist/components/dropdown/index.d.ts +125 -124
- package/dist/components/dropdown/index.d.ts.map +1 -0
- package/dist/components/dropdown/index.js +556 -328
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropdown/style.js +3 -4
- package/dist/components/dropdown/style.js.map +1 -1
- package/dist/components/dropdown-divider/index.d.ts +7 -6
- package/dist/components/dropdown-divider/index.d.ts.map +1 -0
- package/dist/components/dropdown-divider/index.js +10 -11
- package/dist/components/dropdown-divider/index.js.map +1 -1
- package/dist/components/dropdown-divider/style.js +3 -4
- package/dist/components/dropdown-divider/style.js.map +1 -1
- package/dist/components/dropdown-header/index.d.ts +7 -6
- package/dist/components/dropdown-header/index.d.ts.map +1 -0
- package/dist/components/dropdown-header/index.js +10 -11
- package/dist/components/dropdown-header/index.js.map +1 -1
- package/dist/components/dropdown-header/style.js +3 -4
- package/dist/components/dropdown-header/style.js.map +1 -1
- package/dist/components/dropdown-item/index.d.ts +13 -11
- package/dist/components/dropdown-item/index.d.ts.map +1 -0
- package/dist/components/dropdown-item/index.js +32 -25
- package/dist/components/dropdown-item/index.js.map +1 -1
- package/dist/components/dropdown-item/style.js +3 -4
- package/dist/components/dropdown-item/style.js.map +1 -1
- package/dist/components/editable-text/index.d.ts +506 -505
- package/dist/components/editable-text/index.d.ts.map +1 -0
- package/dist/components/editable-text/index.js +281 -127
- package/dist/components/editable-text/index.js.map +1 -1
- package/dist/components/editable-text/style.js +3 -4
- package/dist/components/editable-text/style.js.map +1 -1
- package/dist/components/empty/index.d.ts +17 -15
- package/dist/components/empty/index.d.ts.map +1 -0
- package/dist/components/empty/index.js +66 -37
- package/dist/components/empty/index.js.map +1 -1
- package/dist/components/empty/style.js +3 -4
- package/dist/components/empty/style.js.map +1 -1
- package/dist/components/icon/index.d.ts +12 -11
- package/dist/components/icon/index.d.ts.map +1 -0
- package/dist/components/icon/index.js +34 -27
- package/dist/components/icon/index.js.map +1 -1
- package/dist/components/icon/style.js +3 -4
- package/dist/components/icon/style.js.map +1 -1
- package/dist/components/image-preview/index.d.ts +58 -44
- package/dist/components/image-preview/index.d.ts.map +1 -0
- package/dist/components/image-preview/index.js +536 -265
- package/dist/components/image-preview/index.js.map +1 -1
- package/dist/components/image-preview/style.js +3 -4
- package/dist/components/image-preview/style.js.map +1 -1
- package/dist/components/index.d.ts +46 -43
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +41 -41
- package/dist/components/input/index.d.ts +418 -413
- package/dist/components/input/index.d.ts.map +1 -0
- package/dist/components/input/index.js +148 -84
- package/dist/components/input/index.js.map +1 -1
- package/dist/components/input/style.js +3 -4
- package/dist/components/input/style.js.map +1 -1
- package/dist/components/input-number/index.d.ts +453 -447
- package/dist/components/input-number/index.d.ts.map +1 -0
- package/dist/components/input-number/index.js +484 -292
- package/dist/components/input-number/index.js.map +1 -1
- package/dist/components/input-number/style.js +3 -4
- package/dist/components/input-number/style.js.map +1 -1
- package/dist/components/layout/index.d.ts +110 -87
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/layout/index.js +238 -144
- package/dist/components/layout/index.js.map +1 -1
- package/dist/components/layout/style.js +3 -4
- package/dist/components/layout/style.js.map +1 -1
- package/dist/components/middle-ellipsis/index.d.ts +93 -92
- package/dist/components/middle-ellipsis/index.d.ts.map +1 -0
- package/dist/components/middle-ellipsis/index.js +261 -107
- package/dist/components/middle-ellipsis/index.js.map +1 -1
- package/dist/components/middle-ellipsis/style.js +3 -4
- package/dist/components/middle-ellipsis/style.js.map +1 -1
- package/dist/components/middle-ellipsis/truncate.js +60 -30
- package/dist/components/middle-ellipsis/truncate.js.map +1 -1
- package/dist/components/option/index.d.ts +20 -18
- package/dist/components/option/index.d.ts.map +1 -0
- package/dist/components/option/index.js +53 -40
- package/dist/components/option/index.js.map +1 -1
- package/dist/components/option/style.js +3 -4
- package/dist/components/option/style.js.map +1 -1
- package/dist/components/popover/index.d.ts +69 -68
- package/dist/components/popover/index.d.ts.map +1 -0
- package/dist/components/popover/index.js +221 -104
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/popover/style.js +3 -4
- package/dist/components/popover/style.js.map +1 -1
- package/dist/components/radio/index.d.ts +396 -395
- package/dist/components/radio/index.d.ts.map +1 -0
- package/dist/components/radio/index.js +91 -62
- package/dist/components/radio/index.js.map +1 -1
- package/dist/components/radio/interaction.js +10 -11
- package/dist/components/radio/interaction.js.map +1 -1
- package/dist/components/radio/style.js +3 -4
- package/dist/components/radio/style.js.map +1 -1
- package/dist/components/radio-group/index.d.ts +417 -416
- package/dist/components/radio-group/index.d.ts.map +1 -0
- package/dist/components/radio-group/index.js +307 -207
- package/dist/components/radio-group/index.js.map +1 -1
- package/dist/components/radio-group/style.js +3 -4
- package/dist/components/radio-group/style.js.map +1 -1
- package/dist/components/segmented/index.d.ts +408 -402
- package/dist/components/segmented/index.d.ts.map +1 -0
- package/dist/components/segmented/index.js +267 -158
- package/dist/components/segmented/index.js.map +1 -1
- package/dist/components/segmented/style.js +3 -4
- package/dist/components/segmented/style.js.map +1 -1
- package/dist/components/segmented-trigger/index.d.ts +18 -17
- package/dist/components/segmented-trigger/index.d.ts.map +1 -0
- package/dist/components/segmented-trigger/index.js +45 -36
- package/dist/components/segmented-trigger/index.js.map +1 -1
- package/dist/components/segmented-trigger/style.js +3 -4
- package/dist/components/segmented-trigger/style.js.map +1 -1
- package/dist/components/select/index.d.ts +450 -448
- package/dist/components/select/index.d.ts.map +1 -0
- package/dist/components/select/index.js +342 -188
- package/dist/components/select/index.js.map +1 -1
- package/dist/components/select/style.js +3 -4
- package/dist/components/select/style.js.map +1 -1
- package/dist/components/slider/index.d.ts +428 -427
- package/dist/components/slider/index.d.ts.map +1 -0
- package/dist/components/slider/index.js +308 -216
- package/dist/components/slider/index.js.map +1 -1
- package/dist/components/slider/style.js +3 -4
- package/dist/components/slider/style.js.map +1 -1
- package/dist/components/spinner/index.d.ts +39 -38
- package/dist/components/spinner/index.d.ts.map +1 -0
- package/dist/components/spinner/index.js +118 -65
- package/dist/components/spinner/index.js.map +1 -1
- package/dist/components/spinner/style.js +3 -4
- package/dist/components/spinner/style.js.map +1 -1
- package/dist/components/svg-draw-lines/index.d.ts +40 -39
- package/dist/components/svg-draw-lines/index.d.ts.map +1 -0
- package/dist/components/svg-draw-lines/index.js +189 -106
- package/dist/components/svg-draw-lines/index.js.map +1 -1
- package/dist/components/svg-draw-lines/style.js +3 -4
- package/dist/components/svg-draw-lines/style.js.map +1 -1
- package/dist/components/switch/index.d.ts +411 -409
- package/dist/components/switch/index.d.ts.map +1 -0
- package/dist/components/switch/index.js +193 -106
- package/dist/components/switch/index.js.map +1 -1
- package/dist/components/switch/style.js +3 -4
- package/dist/components/switch/style.js.map +1 -1
- package/dist/components/textarea/index.d.ts +430 -425
- package/dist/components/textarea/index.d.ts.map +1 -0
- package/dist/components/textarea/index.js +187 -100
- package/dist/components/textarea/index.js.map +1 -1
- package/dist/components/textarea/style.js +3 -4
- package/dist/components/textarea/style.js.map +1 -1
- package/dist/components/theme/index.d.ts +45 -44
- package/dist/components/theme/index.d.ts.map +1 -0
- package/dist/components/theme/index.js +268 -161
- package/dist/components/theme/index.js.map +1 -1
- package/dist/components/theme/style.js +3 -4
- package/dist/components/theme/style.js.map +1 -1
- package/dist/components/toast/index.d.ts +4 -3
- package/dist/components/toast/index.js +3 -3
- package/dist/components/toast/manager.d.ts +9 -8
- package/dist/components/toast/manager.d.ts.map +1 -0
- package/dist/components/toast/manager.js +215 -119
- package/dist/components/toast/manager.js.map +1 -1
- package/dist/components/toast/style.js +3 -4
- package/dist/components/toast/style.js.map +1 -1
- package/dist/components/toast/toast.d.ts +75 -71
- package/dist/components/toast/toast.d.ts.map +1 -0
- package/dist/components/toast/toast.js +203 -96
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toast/types.d.ts +10 -9
- package/dist/components/toast/types.d.ts.map +1 -0
- package/dist/components/tooltip/index.d.ts +72 -62
- package/dist/components/tooltip/index.d.ts.map +1 -0
- package/dist/components/tooltip/index.js +251 -93
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/components/tooltip/style.js +3 -4
- package/dist/components/tooltip/style.js.map +1 -1
- package/dist/icons/generated/akar-icons-check.d.ts +5 -4
- package/dist/icons/generated/akar-icons-check.d.ts.map +1 -0
- package/dist/icons/generated/akar-icons-check.js +3 -4
- package/dist/icons/generated/akar-icons-check.js.map +1 -1
- package/dist/icons/generated/akar-icons-circle-check.d.ts +5 -4
- package/dist/icons/generated/akar-icons-circle-check.d.ts.map +1 -0
- package/dist/icons/generated/akar-icons-circle-check.js +3 -4
- package/dist/icons/generated/akar-icons-circle-check.js.map +1 -1
- package/dist/icons/generated/andrsrxn-inbox.d.ts +5 -4
- package/dist/icons/generated/andrsrxn-inbox.d.ts.map +1 -0
- package/dist/icons/generated/andrsrxn-inbox.js +3 -4
- package/dist/icons/generated/andrsrxn-inbox.js.map +1 -1
- package/dist/icons/generated/bi-check-lg.d.ts +5 -4
- package/dist/icons/generated/bi-check-lg.d.ts.map +1 -0
- package/dist/icons/generated/bi-check-lg.js +3 -4
- package/dist/icons/generated/bi-check-lg.js.map +1 -1
- package/dist/icons/generated/bi-check.d.ts +5 -4
- package/dist/icons/generated/bi-check.d.ts.map +1 -0
- package/dist/icons/generated/bi-check.js +3 -4
- package/dist/icons/generated/bi-check.js.map +1 -1
- package/dist/icons/generated/fluent-tag-search-24-regular.d.ts +5 -4
- package/dist/icons/generated/fluent-tag-search-24-regular.d.ts.map +1 -0
- package/dist/icons/generated/fluent-tag-search-24-regular.js +3 -4
- package/dist/icons/generated/fluent-tag-search-24-regular.js.map +1 -1
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.js.map +1 -1
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.js.map +1 -1
- package/dist/icons/generated/heroicons-check-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-check-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-check-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-check-16-solid.js.map +1 -1
- package/dist/icons/generated/heroicons-x-mark-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-x-mark-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-x-mark-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-x-mark-16-solid.js.map +1 -1
- package/dist/icons/generated/jam-close-circle-f.d.ts +7 -6
- package/dist/icons/generated/jam-close-circle-f.d.ts.map +1 -0
- package/dist/icons/generated/jam-close-circle-f.js +3 -4
- package/dist/icons/generated/jam-close-circle-f.js.map +1 -1
- package/dist/icons/generated/lucide-arrow-down-to-line.d.ts +5 -4
- package/dist/icons/generated/lucide-arrow-down-to-line.d.ts.map +1 -0
- package/dist/icons/generated/lucide-arrow-down-to-line.js +3 -4
- package/dist/icons/generated/lucide-arrow-down-to-line.js.map +1 -1
- package/dist/icons/generated/lucide-arrow-up-to-line.d.ts +5 -4
- package/dist/icons/generated/lucide-arrow-up-to-line.d.ts.map +1 -0
- package/dist/icons/generated/lucide-arrow-up-to-line.js +3 -4
- package/dist/icons/generated/lucide-arrow-up-to-line.js.map +1 -1
- package/dist/icons/generated/lucide-bell.d.ts +5 -4
- package/dist/icons/generated/lucide-bell.d.ts.map +1 -0
- package/dist/icons/generated/lucide-bell.js +3 -4
- package/dist/icons/generated/lucide-bell.js.map +1 -1
- package/dist/icons/generated/lucide-check.d.ts +5 -4
- package/dist/icons/generated/lucide-check.d.ts.map +1 -0
- package/dist/icons/generated/lucide-check.js +3 -4
- package/dist/icons/generated/lucide-check.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-down.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-down.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-down.js +3 -4
- package/dist/icons/generated/lucide-chevron-down.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-left.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-left.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-left.js +3 -4
- package/dist/icons/generated/lucide-chevron-left.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-right.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-right.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-right.js +3 -4
- package/dist/icons/generated/lucide-chevron-right.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-up.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-up.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-up.js +3 -4
- package/dist/icons/generated/lucide-chevron-up.js.map +1 -1
- package/dist/icons/generated/lucide-circle-alert.d.ts +5 -4
- package/dist/icons/generated/lucide-circle-alert.d.ts.map +1 -0
- package/dist/icons/generated/lucide-circle-alert.js +3 -4
- package/dist/icons/generated/lucide-circle-alert.js.map +1 -1
- package/dist/icons/generated/lucide-clapperboard.d.ts +5 -4
- package/dist/icons/generated/lucide-clapperboard.d.ts.map +1 -0
- package/dist/icons/generated/lucide-clapperboard.js +3 -4
- package/dist/icons/generated/lucide-clapperboard.js.map +1 -1
- package/dist/icons/generated/lucide-clipboard-paste.d.ts +5 -4
- package/dist/icons/generated/lucide-clipboard-paste.d.ts.map +1 -0
- package/dist/icons/generated/lucide-clipboard-paste.js +3 -4
- package/dist/icons/generated/lucide-clipboard-paste.js.map +1 -1
- package/dist/icons/generated/lucide-code.d.ts +5 -4
- package/dist/icons/generated/lucide-code.d.ts.map +1 -0
- package/dist/icons/generated/lucide-code.js +3 -4
- package/dist/icons/generated/lucide-code.js.map +1 -1
- package/dist/icons/generated/lucide-copy.d.ts +5 -4
- package/dist/icons/generated/lucide-copy.d.ts.map +1 -0
- package/dist/icons/generated/lucide-copy.js +3 -4
- package/dist/icons/generated/lucide-copy.js.map +1 -1
- package/dist/icons/generated/lucide-download.d.ts +5 -4
- package/dist/icons/generated/lucide-download.d.ts.map +1 -0
- package/dist/icons/generated/lucide-download.js +3 -4
- package/dist/icons/generated/lucide-download.js.map +1 -1
- package/dist/icons/generated/lucide-ellipsis-vertical.d.ts +5 -4
- package/dist/icons/generated/lucide-ellipsis-vertical.d.ts.map +1 -0
- package/dist/icons/generated/lucide-ellipsis-vertical.js +3 -4
- package/dist/icons/generated/lucide-ellipsis-vertical.js.map +1 -1
- package/dist/icons/generated/lucide-external-link.d.ts +5 -4
- package/dist/icons/generated/lucide-external-link.d.ts.map +1 -0
- package/dist/icons/generated/lucide-external-link.js +3 -4
- package/dist/icons/generated/lucide-external-link.js.map +1 -1
- package/dist/icons/generated/lucide-eye.d.ts +5 -4
- package/dist/icons/generated/lucide-eye.d.ts.map +1 -0
- package/dist/icons/generated/lucide-eye.js +3 -4
- package/dist/icons/generated/lucide-eye.js.map +1 -1
- package/dist/icons/generated/lucide-file-text.d.ts +5 -4
- package/dist/icons/generated/lucide-file-text.d.ts.map +1 -0
- package/dist/icons/generated/lucide-file-text.js +3 -4
- package/dist/icons/generated/lucide-file-text.js.map +1 -1
- package/dist/icons/generated/lucide-file.d.ts +5 -4
- package/dist/icons/generated/lucide-file.d.ts.map +1 -0
- package/dist/icons/generated/lucide-file.js +3 -4
- package/dist/icons/generated/lucide-file.js.map +1 -1
- package/dist/icons/generated/lucide-film.d.ts +5 -4
- package/dist/icons/generated/lucide-film.d.ts.map +1 -0
- package/dist/icons/generated/lucide-film.js +3 -4
- package/dist/icons/generated/lucide-film.js.map +1 -1
- package/dist/icons/generated/lucide-folder-open.d.ts +5 -4
- package/dist/icons/generated/lucide-folder-open.d.ts.map +1 -0
- package/dist/icons/generated/lucide-folder-open.js +3 -4
- package/dist/icons/generated/lucide-folder-open.js.map +1 -1
- package/dist/icons/generated/lucide-folder.d.ts +5 -4
- package/dist/icons/generated/lucide-folder.d.ts.map +1 -0
- package/dist/icons/generated/lucide-folder.js +3 -4
- package/dist/icons/generated/lucide-folder.js.map +1 -1
- package/dist/icons/generated/lucide-globe.d.ts +5 -4
- package/dist/icons/generated/lucide-globe.d.ts.map +1 -0
- package/dist/icons/generated/lucide-globe.js +3 -4
- package/dist/icons/generated/lucide-globe.js.map +1 -1
- package/dist/icons/generated/lucide-headphones.d.ts +5 -4
- package/dist/icons/generated/lucide-headphones.d.ts.map +1 -0
- package/dist/icons/generated/lucide-headphones.js +3 -4
- package/dist/icons/generated/lucide-headphones.js.map +1 -1
- package/dist/icons/generated/lucide-heart.d.ts +5 -4
- package/dist/icons/generated/lucide-heart.d.ts.map +1 -0
- package/dist/icons/generated/lucide-heart.js +3 -4
- package/dist/icons/generated/lucide-heart.js.map +1 -1
- package/dist/icons/generated/lucide-image.d.ts +5 -4
- package/dist/icons/generated/lucide-image.d.ts.map +1 -0
- package/dist/icons/generated/lucide-image.js +3 -4
- package/dist/icons/generated/lucide-image.js.map +1 -1
- package/dist/icons/generated/lucide-inbox.d.ts +5 -4
- package/dist/icons/generated/lucide-inbox.d.ts.map +1 -0
- package/dist/icons/generated/lucide-inbox.js +3 -4
- package/dist/icons/generated/lucide-inbox.js.map +1 -1
- package/dist/icons/generated/lucide-info.d.ts +5 -4
- package/dist/icons/generated/lucide-info.d.ts.map +1 -0
- package/dist/icons/generated/lucide-info.js +3 -4
- package/dist/icons/generated/lucide-info.js.map +1 -1
- package/dist/icons/generated/lucide-layout-grid.d.ts +5 -4
- package/dist/icons/generated/lucide-layout-grid.d.ts.map +1 -0
- package/dist/icons/generated/lucide-layout-grid.js +3 -4
- package/dist/icons/generated/lucide-layout-grid.js.map +1 -1
- package/dist/icons/generated/lucide-link.d.ts +5 -4
- package/dist/icons/generated/lucide-link.d.ts.map +1 -0
- package/dist/icons/generated/lucide-link.js +3 -4
- package/dist/icons/generated/lucide-link.js.map +1 -1
- package/dist/icons/generated/lucide-list-filter.d.ts +5 -4
- package/dist/icons/generated/lucide-list-filter.d.ts.map +1 -0
- package/dist/icons/generated/lucide-list-filter.js +3 -4
- package/dist/icons/generated/lucide-list-filter.js.map +1 -1
- package/dist/icons/generated/lucide-list-restart.d.ts +5 -4
- package/dist/icons/generated/lucide-list-restart.d.ts.map +1 -0
- package/dist/icons/generated/lucide-list-restart.js +3 -4
- package/dist/icons/generated/lucide-list-restart.js.map +1 -1
- package/dist/icons/generated/lucide-loader-circle.d.ts +5 -4
- package/dist/icons/generated/lucide-loader-circle.d.ts.map +1 -0
- package/dist/icons/generated/lucide-loader-circle.js +3 -4
- package/dist/icons/generated/lucide-loader-circle.js.map +1 -1
- package/dist/icons/generated/lucide-mail.d.ts +5 -4
- package/dist/icons/generated/lucide-mail.d.ts.map +1 -0
- package/dist/icons/generated/lucide-mail.js +3 -4
- package/dist/icons/generated/lucide-mail.js.map +1 -1
- package/dist/icons/generated/lucide-minus.d.ts +5 -4
- package/dist/icons/generated/lucide-minus.d.ts.map +1 -0
- package/dist/icons/generated/lucide-minus.js +3 -4
- package/dist/icons/generated/lucide-minus.js.map +1 -1
- package/dist/icons/generated/lucide-music.d.ts +5 -4
- package/dist/icons/generated/lucide-music.d.ts.map +1 -0
- package/dist/icons/generated/lucide-music.js +3 -4
- package/dist/icons/generated/lucide-music.js.map +1 -1
- package/dist/icons/generated/lucide-package.d.ts +5 -4
- package/dist/icons/generated/lucide-package.d.ts.map +1 -0
- package/dist/icons/generated/lucide-package.js +3 -4
- package/dist/icons/generated/lucide-package.js.map +1 -1
- package/dist/icons/generated/lucide-pen-line.d.ts +5 -4
- package/dist/icons/generated/lucide-pen-line.d.ts.map +1 -0
- package/dist/icons/generated/lucide-pen-line.js +3 -4
- package/dist/icons/generated/lucide-pen-line.js.map +1 -1
- package/dist/icons/generated/lucide-pencil.d.ts +5 -4
- package/dist/icons/generated/lucide-pencil.d.ts.map +1 -0
- package/dist/icons/generated/lucide-pencil.js +3 -4
- package/dist/icons/generated/lucide-pencil.js.map +1 -1
- package/dist/icons/generated/lucide-play.d.ts +5 -4
- package/dist/icons/generated/lucide-play.d.ts.map +1 -0
- package/dist/icons/generated/lucide-play.js +3 -4
- package/dist/icons/generated/lucide-play.js.map +1 -1
- package/dist/icons/generated/lucide-plus.d.ts +5 -4
- package/dist/icons/generated/lucide-plus.d.ts.map +1 -0
- package/dist/icons/generated/lucide-plus.js +3 -4
- package/dist/icons/generated/lucide-plus.js.map +1 -1
- package/dist/icons/generated/lucide-printer.d.ts +5 -4
- package/dist/icons/generated/lucide-printer.d.ts.map +1 -0
- package/dist/icons/generated/lucide-printer.js +3 -4
- package/dist/icons/generated/lucide-printer.js.map +1 -1
- package/dist/icons/generated/lucide-redo-2.d.ts +5 -4
- package/dist/icons/generated/lucide-redo-2.d.ts.map +1 -0
- package/dist/icons/generated/lucide-redo-2.js +3 -4
- package/dist/icons/generated/lucide-redo-2.js.map +1 -1
- package/dist/icons/generated/lucide-refresh-cw.d.ts +5 -4
- package/dist/icons/generated/lucide-refresh-cw.d.ts.map +1 -0
- package/dist/icons/generated/lucide-refresh-cw.js +3 -4
- package/dist/icons/generated/lucide-refresh-cw.js.map +1 -1
- package/dist/icons/generated/lucide-scissors.d.ts +5 -4
- package/dist/icons/generated/lucide-scissors.d.ts.map +1 -0
- package/dist/icons/generated/lucide-scissors.js +3 -4
- package/dist/icons/generated/lucide-scissors.js.map +1 -1
- package/dist/icons/generated/lucide-search.d.ts +5 -4
- package/dist/icons/generated/lucide-search.d.ts.map +1 -0
- package/dist/icons/generated/lucide-search.js +3 -4
- package/dist/icons/generated/lucide-search.js.map +1 -1
- package/dist/icons/generated/lucide-settings.d.ts +5 -4
- package/dist/icons/generated/lucide-settings.d.ts.map +1 -0
- package/dist/icons/generated/lucide-settings.js +3 -4
- package/dist/icons/generated/lucide-settings.js.map +1 -1
- package/dist/icons/generated/lucide-sliders-horizontal.d.ts +5 -4
- package/dist/icons/generated/lucide-sliders-horizontal.d.ts.map +1 -0
- package/dist/icons/generated/lucide-sliders-horizontal.js +3 -4
- package/dist/icons/generated/lucide-sliders-horizontal.js.map +1 -1
- package/dist/icons/generated/lucide-star.d.ts +5 -4
- package/dist/icons/generated/lucide-star.d.ts.map +1 -0
- package/dist/icons/generated/lucide-star.js +3 -4
- package/dist/icons/generated/lucide-star.js.map +1 -1
- package/dist/icons/generated/lucide-tag.d.ts +5 -4
- package/dist/icons/generated/lucide-tag.d.ts.map +1 -0
- package/dist/icons/generated/lucide-tag.js +3 -4
- package/dist/icons/generated/lucide-tag.js.map +1 -1
- package/dist/icons/generated/lucide-tags.d.ts +5 -4
- package/dist/icons/generated/lucide-tags.d.ts.map +1 -0
- package/dist/icons/generated/lucide-tags.js +3 -4
- package/dist/icons/generated/lucide-tags.js.map +1 -1
- package/dist/icons/generated/lucide-trash-2.d.ts +5 -4
- package/dist/icons/generated/lucide-trash-2.d.ts.map +1 -0
- package/dist/icons/generated/lucide-trash-2.js +3 -4
- package/dist/icons/generated/lucide-trash-2.js.map +1 -1
- package/dist/icons/generated/lucide-triangle-alert.d.ts +5 -4
- package/dist/icons/generated/lucide-triangle-alert.d.ts.map +1 -0
- package/dist/icons/generated/lucide-triangle-alert.js +3 -4
- package/dist/icons/generated/lucide-triangle-alert.js.map +1 -1
- package/dist/icons/generated/lucide-undo-2.d.ts +5 -4
- package/dist/icons/generated/lucide-undo-2.d.ts.map +1 -0
- package/dist/icons/generated/lucide-undo-2.js +3 -4
- package/dist/icons/generated/lucide-undo-2.js.map +1 -1
- package/dist/icons/generated/lucide-upload.d.ts +5 -4
- package/dist/icons/generated/lucide-upload.d.ts.map +1 -0
- package/dist/icons/generated/lucide-upload.js +3 -4
- package/dist/icons/generated/lucide-upload.js.map +1 -1
- package/dist/icons/generated/lucide-user.d.ts +5 -4
- package/dist/icons/generated/lucide-user.d.ts.map +1 -0
- package/dist/icons/generated/lucide-user.js +3 -4
- package/dist/icons/generated/lucide-user.js.map +1 -1
- package/dist/icons/generated/lucide-wrench.d.ts +5 -4
- package/dist/icons/generated/lucide-wrench.d.ts.map +1 -0
- package/dist/icons/generated/lucide-wrench.js +3 -4
- package/dist/icons/generated/lucide-wrench.js.map +1 -1
- package/dist/icons/generated/lucide-x.d.ts +5 -4
- package/dist/icons/generated/lucide-x.d.ts.map +1 -0
- package/dist/icons/generated/lucide-x.js +3 -4
- package/dist/icons/generated/lucide-x.js.map +1 -1
- package/dist/icons/generated/mdi-tag-search-outline.d.ts +5 -4
- package/dist/icons/generated/mdi-tag-search-outline.d.ts.map +1 -0
- package/dist/icons/generated/mdi-tag-search-outline.js +3 -4
- package/dist/icons/generated/mdi-tag-search-outline.js.map +1 -1
- package/dist/icons/generated/ooui-close.d.ts +5 -4
- package/dist/icons/generated/ooui-close.d.ts.map +1 -0
- package/dist/icons/generated/ooui-close.js +3 -4
- package/dist/icons/generated/ooui-close.js.map +1 -1
- package/dist/icons/generated/radix-icons-panel-left-minimized.d.ts +5 -4
- package/dist/icons/generated/radix-icons-panel-left-minimized.d.ts.map +1 -0
- package/dist/icons/generated/radix-icons-panel-left-minimized.js +3 -4
- package/dist/icons/generated/radix-icons-panel-left-minimized.js.map +1 -1
- package/dist/icons/generated/radix-icons-reset.d.ts +5 -4
- package/dist/icons/generated/radix-icons-reset.d.ts.map +1 -0
- package/dist/icons/generated/radix-icons-reset.js +3 -4
- package/dist/icons/generated/radix-icons-reset.js.map +1 -1
- package/dist/icons/generated/tabler-sort-ascending-letters.d.ts +5 -4
- package/dist/icons/generated/tabler-sort-ascending-letters.d.ts.map +1 -0
- package/dist/icons/generated/tabler-sort-ascending-letters.js +3 -4
- package/dist/icons/generated/tabler-sort-ascending-letters.js.map +1 -1
- package/dist/icons/index.d.ts +75 -74
- package/dist/icons/index.js +75 -75
- package/dist/shared/element-height/index.js +51 -25
- package/dist/shared/element-height/index.js.map +1 -1
- package/dist/shared/element-width/index.js +39 -24
- package/dist/shared/element-width/index.js.map +1 -1
- package/dist/shared/events/user-change.js +14 -8
- package/dist/shared/events/user-change.js.map +1 -1
- package/dist/shared/focus/pointer-focus.js +56 -30
- package/dist/shared/focus/pointer-focus.js.map +1 -1
- package/dist/shared/focus/tabbable.js +96 -0
- package/dist/shared/focus/tabbable.js.map +1 -0
- package/dist/shared/form-association/field-id.js +13 -6
- package/dist/shared/form-association/field-id.js.map +1 -1
- package/dist/shared/form-association/index.js +75 -42
- package/dist/shared/form-association/index.js.map +1 -1
- package/dist/shared/gesture/drag-gesture.js +239 -99
- package/dist/shared/gesture/drag-gesture.js.map +1 -1
- package/dist/shared/gesture/physics.js +49 -16
- package/dist/shared/gesture/physics.js.map +1 -1
- package/dist/shared/gesture/pinch-gesture.js +111 -60
- package/dist/shared/gesture/pinch-gesture.js.map +1 -1
- package/dist/shared/group-management/index.js +181 -84
- package/dist/shared/group-management/index.js.map +1 -1
- package/dist/shared/label-emptiness/index.js +45 -26
- package/dist/shared/label-emptiness/index.js.map +1 -1
- package/dist/shared/locale/builtin-labels.js +38 -0
- package/dist/shared/locale/builtin-labels.js.map +1 -0
- package/dist/shared/menu-behavior/index.js +113 -60
- package/dist/shared/menu-behavior/index.js.map +1 -1
- package/dist/shared/menu-portal/menu-portal.js +47 -26
- package/dist/shared/menu-portal/menu-portal.js.map +1 -1
- package/dist/shared/menu-portal/menu-tree.js +132 -75
- package/dist/shared/menu-portal/menu-tree.js.map +1 -1
- package/dist/shared/normalize/index.js +16 -7
- package/dist/shared/normalize/index.js.map +1 -1
- package/dist/shared/open-state/index.js +7 -8
- package/dist/shared/open-state/index.js.map +1 -1
- package/dist/shared/option-portal/combobox-shell.js +121 -56
- package/dist/shared/option-portal/combobox-shell.js.map +1 -1
- package/dist/shared/option-portal/index.js +65 -44
- package/dist/shared/option-portal/index.js.map +1 -1
- package/dist/shared/overlay/anchored-panel.js +75 -40
- package/dist/shared/overlay/anchored-panel.js.map +1 -1
- package/dist/shared/overlay/native-dialog-presence.js +116 -52
- package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
- package/dist/shared/overlay/nested-drawer-layers.js +76 -46
- package/dist/shared/overlay/nested-drawer-layers.js.map +1 -1
- package/dist/shared/overlay/open-overlay.js +240 -136
- package/dist/shared/overlay/open-overlay.js.map +1 -1
- package/dist/shared/overlay/overlay-root.js +33 -24
- package/dist/shared/overlay/overlay-root.js.map +1 -1
- package/dist/shared/overlay/overlay.js +109 -66
- package/dist/shared/overlay/overlay.js.map +1 -1
- package/dist/shared/overlay/placement-props.js +9 -4
- package/dist/shared/overlay/placement-props.js.map +1 -1
- package/dist/shared/overlay/portal.d.ts +2 -0
- package/dist/shared/overlay/portal.d.ts.map +1 -0
- package/dist/shared/overlay/portal.js +202 -117
- package/dist/shared/overlay/portal.js.map +1 -1
- package/dist/shared/overlay/positioning-generation.js +9 -10
- package/dist/shared/overlay/positioning-generation.js.map +1 -1
- package/dist/shared/overlay/presence.js +43 -21
- package/dist/shared/overlay/presence.js.map +1 -1
- package/dist/shared/overlay/theme-overlay-scope.js +22 -19
- package/dist/shared/overlay/theme-overlay-scope.js.map +1 -1
- package/dist/shared/scroll-lock/scroll-lock.js +49 -15
- package/dist/shared/scroll-lock/scroll-lock.js.map +1 -1
- package/dist/shared/theme/duration.js +13 -6
- package/dist/shared/theme/duration.js.map +1 -1
- package/dist/shared/theme/reduced-motion.js +14 -9
- package/dist/shared/theme/reduced-motion.js.map +1 -1
- package/dist/shared/theme/root-sync.js +85 -32
- package/dist/shared/theme/root-sync.js.map +1 -1
- package/dist/shared/visible-area/index.js +81 -37
- package/dist/shared/visible-area/index.js.map +1 -1
- package/dist/types/iconify.d.ts +1 -1
- package/dist/types/iconify.js +0 -0
- package/dist/types/react.d.ts +8 -10
- package/dist/types/react.d.ts.map +1 -0
- package/dist/types/react.js +0 -0
- package/dist/types/utils.d.ts +8 -13
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +0 -0
- package/dist/types/vue.d.ts +9 -13
- package/dist/types/vue.d.ts.map +1 -0
- package/dist/types/vue.js +0 -0
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +30 -4
- package/dist/vite/index.js.map +1 -1
- package/package.json +10 -23
- package/dist/_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js +0 -9
- package/dist/components/middle-ellipsis/truncate.d.ts +0 -62
- package/dist/components/radio/interaction.d.ts +0 -4
- package/dist/scrollbars/index.d.ts +0 -33
- package/dist/scrollbars/index.js +0 -18
- package/dist/scrollbars/index.js.map +0 -1
- package/dist/scrollbars/internal.js +0 -6
- package/dist/scrollbars/internal.js.map +0 -1
- package/dist/scrollbars/style.css +0 -10
|
@@ -1,386 +1,801 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { normalizeNumber
|
|
3
|
-
import { dispatchOpenChangeEvent
|
|
4
|
-
import { defineOverlayPositioningGeneration
|
|
5
|
-
import { hideOverlayPresence
|
|
6
|
-
import { defineOpenOverlay
|
|
7
|
-
import { findNearestTheme
|
|
8
|
-
import { defineScrollLockLease
|
|
9
|
-
import { UserChangeController
|
|
10
|
-
import { captureFrameworkAnchors
|
|
11
|
-
import { createClosingSubmenuStack
|
|
12
|
-
import { createMenuPortalOverlay
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import { LitElement
|
|
16
|
-
import { customElement
|
|
17
|
-
import { computePosition
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js";
|
|
2
|
+
import { normalizeNumber } from "../../shared/normalize/index.js";
|
|
3
|
+
import { dispatchOpenChangeEvent } from "../../shared/open-state/index.js";
|
|
4
|
+
import { defineOverlayPositioningGeneration } from "../../shared/overlay/positioning-generation.js";
|
|
5
|
+
import { hideOverlayPresence, showOverlayPresence } from "../../shared/overlay/presence.js";
|
|
6
|
+
import { defineOpenOverlay } from "../../shared/overlay/open-overlay.js";
|
|
7
|
+
import { findNearestTheme } from "../../shared/overlay/theme-overlay-scope.js";
|
|
8
|
+
import { defineScrollLockLease } from "../../shared/scroll-lock/scroll-lock.js";
|
|
9
|
+
import { UserChangeController } from "../../shared/events/user-change.js";
|
|
10
|
+
import { captureFrameworkAnchors, findFocusedMenuItem, focusMenuItem, getMenuChildren, getMenuItemFromEvent, hideNestedMenuChildren, moveMenuChildren, orderManagedMenuItems, reconcileManagedMenuItems, restoreFrameworkAnchors, returnManagedMenuItemsToSlot } from "../../shared/menu-portal/menu-tree.js";
|
|
11
|
+
import { createClosingSubmenuStack, createMenuHoverBinder, createMenuOutsideClickGuard, getEnabledMenuLevelItems, getFocusedMenuItemFromPanels, handleMenuKeyboard } from "../../shared/menu-behavior/index.js";
|
|
12
|
+
import { createMenuPortalOverlay } from "../../shared/menu-portal/menu-portal.js";
|
|
13
|
+
import scrim_default from "./scrim.js";
|
|
14
|
+
import style_default from "./style.js";
|
|
15
|
+
import { LitElement, html, unsafeCSS } from "lit";
|
|
16
|
+
import { customElement, property, state } from "lit/decorators.js";
|
|
17
|
+
import { computePosition, flip, shift } from "@floating-ui/dom";
|
|
18
|
+
// src/components/context-menu/index.ts
|
|
19
|
+
const MARKER_TEXT = "wui-context-menu-item";
|
|
20
|
+
/** 与 iOS / Android 原生长按一致的默认时长。 */
|
|
21
|
+
const DEFAULT_LONG_PRESS_DELAY = 500;
|
|
22
|
+
/** long-press-delay 的上界:超过 5s 的长按不再是「长按」,等同没有该属性。 */
|
|
23
|
+
const MAX_LONG_PRESS_DELAY = 5e3;
|
|
24
|
+
/** 按住期间的容差位移;超出即视为滚动/拖拽意图,取消长按。 */
|
|
25
|
+
const LONG_PRESS_MOVE_TOLERANCE = 10;
|
|
26
|
+
/**
|
|
27
|
+
* 长按开 menu 后吸收浏览器补发事件的窗口上限。
|
|
28
|
+
*
|
|
29
|
+
* 这不是时序保证:实测补发几乎紧跟抬手(touchend(1019ms) → click(1022ms),间隔 3ms),
|
|
30
|
+
* 1000ms 远大于实际需要,只是一个陈旧兜底上限。真正的边界是下一次 `pointerdown`
|
|
31
|
+
* (`_onPointerDown` 无条件清零,含鼠标)与 menu 关闭,两条硬边界都在窗口判定之外,
|
|
32
|
+
* 所以窗口只负责兜住「补发事件既没等到下一次按下、menu 也没关闭」这种不该发生的路径。
|
|
33
|
+
*
|
|
34
|
+
* **窗口的起点是手势结束而不是 menu 打开**(见 `_longPressGestureEndedAt`):补发事件由
|
|
35
|
+
* 引擎在 touchend 处理时生成,主线程被长任务占住时这一步能比 menu 打开晚 1s 以上
|
|
36
|
+
* (实测 click 比打开晚 1325ms)。以打开时刻为起点,这个上限会被那段延迟挤爆——
|
|
37
|
+
* 补发 click 落到窗口外,被当成用户真实点击把**同一次长按刚打开**的 menu 关掉。
|
|
38
|
+
* 以手势结束为起点,补发事件相对它只有几毫秒,窗口才真的覆盖「同一次手势的补发」。
|
|
39
|
+
*/
|
|
40
|
+
const LONG_PRESS_FOLLOW_UP_WINDOW_MS = 1e3;
|
|
41
|
+
/**
|
|
42
|
+
* menu 打开期间铺在整屏上的 scrim `<dialog>`。
|
|
43
|
+
*
|
|
44
|
+
* 用 `<dialog>` + `showModal()` 而不是 plain `div`:模态 dialog 进 top layer,
|
|
45
|
+
* 于是「z-index 谁高谁低」这道约束整体消失 —— panel 与 scrim 同在 top layer,
|
|
46
|
+
* 而 top layer 之下的任何 z-index 都碰不到它们。plain `div` 也能修好 light-dismiss
|
|
47
|
+
* 穿透,但那样 scrim 必须靠 z-index 压过 `--wui-layer-menu`(100),是另一套易碎的约定。
|
|
48
|
+
*/
|
|
49
|
+
const SCRIM_ATTR = "data-wui-menu-scrim";
|
|
50
|
+
/** 首项聚焦的最大尝试次数(含首次)。见 `_focusFirstItem`。 */
|
|
51
|
+
const FOCUS_FIRST_ITEM_ATTEMPTS = 5;
|
|
52
|
+
/** panel 与视口边缘的最小间距,与既有夹取算术同源。 */
|
|
53
|
+
const VIEWPORT_PADDING = 8;
|
|
54
|
+
let WebUiContextMenu = class WebUiContextMenu extends LitElement {
|
|
55
|
+
constructor(..._args) {
|
|
56
|
+
super(..._args);
|
|
57
|
+
this.disabled = false;
|
|
58
|
+
this.noScrollLock = false;
|
|
59
|
+
this.longPress = false;
|
|
60
|
+
this._longPressDelay = DEFAULT_LONG_PRESS_DELAY;
|
|
61
|
+
this._isOpen = false;
|
|
62
|
+
this._x = 0;
|
|
63
|
+
this._y = 0;
|
|
64
|
+
this._activeSubmenus = [];
|
|
65
|
+
this._activeSubmenuItems = [];
|
|
66
|
+
this._longPressOpenedAt = null;
|
|
67
|
+
this._longPressGestureEndedAt = null;
|
|
68
|
+
this._submenuPositionEpochs = /* @__PURE__ */ new WeakMap();
|
|
69
|
+
this._centerOnPressPoint = false;
|
|
70
|
+
this._closeSource = "default";
|
|
71
|
+
this._menuItemActivationEvent = null;
|
|
72
|
+
this._menuHandle = null;
|
|
73
|
+
this._submenuHandles = /* @__PURE__ */ new Map();
|
|
74
|
+
this._outsideClickGuard = createMenuOutsideClickGuard(this, (node) => this._menuHandle?.contains(node) ?? false);
|
|
75
|
+
this._closingSubmenus = createClosingSubmenuStack({
|
|
76
|
+
getPanel: (container) => container.panel,
|
|
77
|
+
restoreItems: (container, parentItem) => this._restoreSubmenuItems(container, parentItem),
|
|
78
|
+
dispose: (container) => {
|
|
79
|
+
this._releaseSubmenu(container.panel);
|
|
80
|
+
container.panel.remove();
|
|
26
81
|
}
|
|
27
|
-
})
|
|
82
|
+
});
|
|
83
|
+
this._hoverDelegate = {
|
|
28
84
|
getOpenDepth: () => this._activeSubmenus.length,
|
|
29
|
-
getLevelItems: (
|
|
30
|
-
getActiveItem: (
|
|
31
|
-
isSubmenuItem: (
|
|
32
|
-
openSubmenu: (
|
|
33
|
-
closeFrom: (
|
|
34
|
-
this._closeSubmenusFrom(
|
|
85
|
+
getLevelItems: (level) => this._getLevelItems(level),
|
|
86
|
+
getActiveItem: (level) => this._activeSubmenuItems[level],
|
|
87
|
+
isSubmenuItem: (item) => item.hasAttribute("submenu"),
|
|
88
|
+
openSubmenu: (item) => this._openSubmenu(item),
|
|
89
|
+
closeFrom: (level) => {
|
|
90
|
+
this._closeSubmenusFrom(level);
|
|
91
|
+
this._hoverBinder.bind();
|
|
35
92
|
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
93
|
+
};
|
|
94
|
+
this._hoverBinder = createMenuHoverBinder(this._hoverDelegate, "web-ui-dropdown-item");
|
|
95
|
+
this._keyboardDelegate = {
|
|
96
|
+
getFocusedItem: (event) => getFocusedMenuItemFromPanels(event, [this._menu?.content, ...this._activeSubmenus.map((submenu) => submenu.content)], "web-ui-dropdown-item"),
|
|
97
|
+
getLevelOf: (item) => {
|
|
98
|
+
const level = this._getItemLevel(item);
|
|
99
|
+
return level === -1 ? void 0 : level;
|
|
41
100
|
},
|
|
42
|
-
getEnabledItems: (
|
|
43
|
-
isSubmenuItem: (
|
|
44
|
-
openSubmenuInstant: (
|
|
45
|
-
closeToParent: (
|
|
46
|
-
|
|
47
|
-
|
|
101
|
+
getEnabledItems: (level) => getEnabledMenuLevelItems(this._getLevelContainer(level)?.content),
|
|
102
|
+
isSubmenuItem: (item) => item.hasAttribute("submenu"),
|
|
103
|
+
openSubmenuInstant: (item) => this._openSubmenu(item, true),
|
|
104
|
+
closeToParent: (level) => {
|
|
105
|
+
const parent = this._activeSubmenuItems[level - 1];
|
|
106
|
+
this._closeSubmenusFrom(level - 1);
|
|
107
|
+
this._hoverBinder.bind();
|
|
108
|
+
return parent;
|
|
48
109
|
},
|
|
49
110
|
closeDeepestOrAll: () => this._closeLastSubmenuOrMenu()
|
|
50
|
-
}
|
|
111
|
+
};
|
|
112
|
+
this._overlay = defineOpenOverlay().make({
|
|
51
113
|
requestClose: () => this._keyboardDelegate.closeDeepestOrAll(),
|
|
52
114
|
isConnected: () => this.isConnected
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
115
|
+
});
|
|
116
|
+
this._menuItemAnchors = /* @__PURE__ */ new Map();
|
|
117
|
+
this._scrollLock = defineScrollLockLease().make();
|
|
118
|
+
this._userOpenChange = new UserChangeController();
|
|
119
|
+
this._shouldOpenInstantly = true;
|
|
120
|
+
this._suppressInitialFocusVisible = true;
|
|
121
|
+
this._refreshScheduled = false;
|
|
122
|
+
this._menuPositionGeneration = defineOverlayPositioningGeneration().make();
|
|
123
|
+
this._contentObserver = new MutationObserver(() => {
|
|
124
|
+
if (this._isOpen) this._scheduleRefresh();
|
|
125
|
+
});
|
|
126
|
+
this._closeFromUser = (source = "default") => {
|
|
127
|
+
if (!this._isOpen) return;
|
|
128
|
+
this._userOpenChange.mark();
|
|
129
|
+
this._closeSource = source;
|
|
130
|
+
this.close();
|
|
131
|
+
};
|
|
132
|
+
this._onScrimClick = (e) => {
|
|
133
|
+
if (e.target !== this._scrim) return;
|
|
134
|
+
if (this._isLongPressFollowUp()) return;
|
|
135
|
+
this._closeFromUser();
|
|
136
|
+
};
|
|
137
|
+
this._onScrimCancel = (e) => {
|
|
60
138
|
e.preventDefault();
|
|
61
|
-
}
|
|
62
|
-
|
|
139
|
+
};
|
|
140
|
+
this._onPointerDown = (e) => {
|
|
141
|
+
this._clearLongPressFollowUp();
|
|
142
|
+
if (!this.longPress || this.disabled || e.pointerType !== "touch") return;
|
|
143
|
+
this._cancelLongPress();
|
|
144
|
+
this._longPressOrigin = {
|
|
63
145
|
x: e.clientX,
|
|
64
146
|
y: e.clientY
|
|
65
|
-
}
|
|
147
|
+
};
|
|
148
|
+
this._longPressTimer = setTimeout(() => {
|
|
66
149
|
this._longPressTimer = void 0;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
150
|
+
const origin = this._longPressOrigin;
|
|
151
|
+
if (!origin) return;
|
|
152
|
+
this._longPressOrigin = void 0;
|
|
153
|
+
if (this._isOpen) return;
|
|
154
|
+
this._longPressOpenedAt = performance.now();
|
|
155
|
+
if (this._openAt(origin.x, origin.y, false, true, true)) this._userOpenChange.mark();
|
|
156
|
+
}, this.longPressDelay);
|
|
157
|
+
};
|
|
158
|
+
this._onPointerMove = (e) => {
|
|
71
159
|
if (e.pointerType !== "touch") return;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
160
|
+
const origin = this._longPressOrigin;
|
|
161
|
+
if (!origin) return;
|
|
162
|
+
if (Math.hypot(e.clientX - origin.x, e.clientY - origin.y) > LONG_PRESS_MOVE_TOLERANCE) this._cancelLongPress();
|
|
163
|
+
};
|
|
164
|
+
this._onPointerUp = (e) => {
|
|
165
|
+
if (e.pointerType !== "touch") return;
|
|
166
|
+
if (this._longPressOpenedAt !== null && this._longPressGestureEndedAt === null) this._longPressGestureEndedAt = performance.now();
|
|
77
167
|
this._cancelLongPress();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
168
|
+
};
|
|
169
|
+
this._onPointerCancel = () => {
|
|
170
|
+
this._cancelLongPress();
|
|
171
|
+
};
|
|
172
|
+
this._onContextMenu = (e) => {
|
|
173
|
+
if (this.disabled) return;
|
|
174
|
+
if (this._isLongPressFollowUp()) {
|
|
175
|
+
e.preventDefault();
|
|
176
|
+
return;
|
|
85
177
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
178
|
+
e.preventDefault();
|
|
179
|
+
if (this._openAt(e.clientX, e.clientY, false, true)) this._userOpenChange.mark();
|
|
180
|
+
};
|
|
181
|
+
this._onContextMenuOutside = (e) => {
|
|
182
|
+
if (this._isOpen && !this._outsideClickGuard.isInside(e)) this._closeFromUser();
|
|
183
|
+
};
|
|
184
|
+
this._onKeydown = (e) => {
|
|
185
|
+
if (this.disabled) return;
|
|
186
|
+
if (e.key === "ContextMenu" || e.shiftKey && e.key === "F10") {
|
|
90
187
|
e.preventDefault();
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
this._openAt(
|
|
95
|
-
} else this._openAt(window.innerWidth / 2, window.innerHeight / 2,
|
|
188
|
+
const focused = document.activeElement;
|
|
189
|
+
if (focused && focused !== document.body) {
|
|
190
|
+
const rect = focused.getBoundingClientRect();
|
|
191
|
+
if (this._openAt(rect.left, rect.bottom, true, false)) this._userOpenChange.mark();
|
|
192
|
+
} else if (this._openAt(window.innerWidth / 2, window.innerHeight / 2, true, false)) this._userOpenChange.mark();
|
|
96
193
|
return;
|
|
97
194
|
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
this.
|
|
195
|
+
};
|
|
196
|
+
this._onMenuItemActivation = (e) => {
|
|
197
|
+
const item = getMenuItemFromEvent(e);
|
|
198
|
+
if (!item || item.hasAttribute("disabled") || item.hasAttribute("submenu")) return;
|
|
199
|
+
this._menuItemActivationEvent = e;
|
|
200
|
+
};
|
|
201
|
+
this._onMenuClick = (e) => {
|
|
202
|
+
const item = getMenuItemFromEvent(e);
|
|
203
|
+
if (!item || item.hasAttribute("disabled")) return;
|
|
204
|
+
if (item.hasAttribute("submenu")) {
|
|
205
|
+
this._openSubmenu(item);
|
|
206
|
+
return;
|
|
109
207
|
}
|
|
110
|
-
|
|
208
|
+
this._closeFromUser("menu-item");
|
|
209
|
+
};
|
|
210
|
+
this._onWheel = (e) => {
|
|
111
211
|
this._preventBackgroundScroll(e);
|
|
112
|
-
}
|
|
212
|
+
};
|
|
213
|
+
this._onTouchMove = (e) => {
|
|
113
214
|
this._preventBackgroundScroll(e);
|
|
114
|
-
}
|
|
115
|
-
|
|
215
|
+
};
|
|
216
|
+
this._onDocumentKeydown = (e) => {
|
|
217
|
+
if (!this._isOpen) return;
|
|
218
|
+
handleMenuKeyboard(this._keyboardDelegate, e);
|
|
116
219
|
};
|
|
117
220
|
}
|
|
118
221
|
static {
|
|
119
|
-
this.styles =
|
|
120
|
-
}
|
|
222
|
+
this.styles = unsafeCSS(style_default);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* 走包内既有的 `normalizeNumber` 通道(与 `dropdown.offset`、`popover.offset` 同形)。
|
|
226
|
+
* 不能只靠 `Math.max(0, …)` 挡负数:`Math.max(0, NaN) === NaN`,而属性写错
|
|
227
|
+
* (`long-press-delay="abc"`)时 Lit 的 Number converter 给的正是 NaN,
|
|
228
|
+
* `setTimeout(fn, NaN)` 会立刻触发,长按就在 pointerdown 同一帧开 menu、绕过全部时长语义。
|
|
229
|
+
*/
|
|
121
230
|
get longPressDelay() {
|
|
122
231
|
return this._longPressDelay;
|
|
123
232
|
}
|
|
124
|
-
set longPressDelay(
|
|
125
|
-
|
|
126
|
-
this._longPressDelay =
|
|
233
|
+
set longPressDelay(v) {
|
|
234
|
+
const old = this._longPressDelay;
|
|
235
|
+
this._longPressDelay = normalizeNumber(v, 0, MAX_LONG_PRESS_DELAY, DEFAULT_LONG_PRESS_DELAY);
|
|
236
|
+
this.requestUpdate("longPressDelay", old);
|
|
127
237
|
}
|
|
128
238
|
get isOpen() {
|
|
129
239
|
return this._isOpen;
|
|
130
240
|
}
|
|
131
241
|
connectedCallback() {
|
|
132
|
-
super.connectedCallback()
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
242
|
+
super.connectedCallback();
|
|
243
|
+
this._hideMenuItems();
|
|
244
|
+
this.addEventListener("contextmenu", this._onContextMenu);
|
|
245
|
+
this.addEventListener("keydown", this._onKeydown);
|
|
246
|
+
this.addEventListener("click", this._onMenuClick);
|
|
247
|
+
this.addEventListener("pointerdown", this._onPointerDown);
|
|
248
|
+
this.addEventListener("pointermove", this._onPointerMove);
|
|
249
|
+
this.addEventListener("pointerup", this._onPointerUp);
|
|
250
|
+
this.addEventListener("pointercancel", this._onPointerCancel);
|
|
251
|
+
document.addEventListener("contextmenu", this._onContextMenuOutside);
|
|
252
|
+
document.addEventListener("wheel", this._onWheel, {
|
|
253
|
+
capture: true,
|
|
254
|
+
passive: false
|
|
255
|
+
});
|
|
256
|
+
document.addEventListener("touchmove", this._onTouchMove, {
|
|
257
|
+
capture: true,
|
|
258
|
+
passive: false
|
|
259
|
+
});
|
|
260
|
+
document.addEventListener("keydown", this._onDocumentKeydown);
|
|
139
261
|
}
|
|
140
262
|
disconnectedCallback() {
|
|
141
|
-
super.disconnectedCallback()
|
|
142
|
-
|
|
143
|
-
|
|
263
|
+
super.disconnectedCallback();
|
|
264
|
+
this.removeEventListener("contextmenu", this._onContextMenu);
|
|
265
|
+
this.removeEventListener("keydown", this._onKeydown);
|
|
266
|
+
this.removeEventListener("click", this._onMenuClick);
|
|
267
|
+
this.removeEventListener("pointerdown", this._onPointerDown);
|
|
268
|
+
this.removeEventListener("pointermove", this._onPointerMove);
|
|
269
|
+
this.removeEventListener("pointerup", this._onPointerUp);
|
|
270
|
+
this.removeEventListener("pointercancel", this._onPointerCancel);
|
|
271
|
+
document.removeEventListener("contextmenu", this._onContextMenuOutside);
|
|
272
|
+
document.removeEventListener("wheel", this._onWheel, true);
|
|
273
|
+
document.removeEventListener("touchmove", this._onTouchMove, true);
|
|
274
|
+
document.removeEventListener("keydown", this._onDocumentKeydown);
|
|
275
|
+
this._contentObserver.disconnect();
|
|
276
|
+
this._menuPositionGeneration.invalidate();
|
|
277
|
+
this._outsideClickGuard.dispose();
|
|
278
|
+
this._hoverBinder.dispose();
|
|
279
|
+
this._scrollLock.release();
|
|
280
|
+
this._menuHandle?.release();
|
|
281
|
+
this._menuHandle = null;
|
|
282
|
+
this._returnItemsToSlot();
|
|
283
|
+
this._menu?.panel.remove();
|
|
284
|
+
this._menu = void 0;
|
|
285
|
+
this._closeSubmenusFrom(0, true);
|
|
286
|
+
this._closingSubmenus.restoreAll();
|
|
287
|
+
this._closeScrim();
|
|
288
|
+
this._isOpen = false;
|
|
289
|
+
this._cancelLongPress();
|
|
290
|
+
this._longPressOpenedAt = null;
|
|
291
|
+
this._longPressGestureEndedAt = null;
|
|
292
|
+
}
|
|
293
|
+
updated(changed) {
|
|
144
294
|
if (!this.isConnected) {
|
|
145
|
-
this._syncScrollLock(
|
|
295
|
+
this._syncScrollLock(false);
|
|
146
296
|
return;
|
|
147
297
|
}
|
|
148
|
-
if (
|
|
298
|
+
if (changed.has("_isOpen")) {
|
|
149
299
|
if (this._isOpen) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
300
|
+
this._syncScrollLock();
|
|
301
|
+
if (!this._menu) {
|
|
302
|
+
const scrim = this._openScrim();
|
|
303
|
+
this._menu = createMenuPortalOverlay("context-menu", this, scrim);
|
|
304
|
+
this._menu.panel.setAttribute("role", "menu");
|
|
305
|
+
this._menu.panel.setAttribute("aria-label", "Context menu");
|
|
306
|
+
this._menu.panel.addEventListener("click", this._onMenuClick);
|
|
307
|
+
this._menu.panel.addEventListener("click", this._onMenuItemActivation, true);
|
|
153
308
|
}
|
|
154
309
|
if (!this._menuHandle) {
|
|
155
310
|
this._menuHandle = this._overlay.claim(this._menu.panel);
|
|
156
|
-
for (
|
|
157
|
-
|
|
311
|
+
for (const submenu of this._activeSubmenus) {
|
|
312
|
+
this._submenuHandles.delete(submenu.panel);
|
|
313
|
+
this._submenuHandles.set(submenu.panel, this._menuHandle.adopt(submenu.panel));
|
|
314
|
+
}
|
|
315
|
+
for (const container of this._closingSubmenus.closing()) this._submenuHandles.set(container.panel, this._menuHandle.adopt(container.panel));
|
|
158
316
|
}
|
|
159
317
|
this._contentObserver.observe(this._menu.content, {
|
|
160
|
-
childList:
|
|
161
|
-
subtree:
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
318
|
+
childList: true,
|
|
319
|
+
subtree: true
|
|
320
|
+
});
|
|
321
|
+
requestAnimationFrame(() => {
|
|
322
|
+
if (!this._isOpen || !this._menu) return;
|
|
323
|
+
this._refreshMenu();
|
|
324
|
+
showOverlayPresence(this._menu.panel, { isInstant: this._shouldOpenInstantly });
|
|
325
|
+
this._shouldOpenInstantly = true;
|
|
326
|
+
requestAnimationFrame(() => {
|
|
327
|
+
if (!this._isOpen || !this._menu) return;
|
|
328
|
+
this._focusFirstItem();
|
|
329
|
+
});
|
|
166
330
|
});
|
|
167
|
-
} else
|
|
168
|
-
|
|
331
|
+
} else {
|
|
332
|
+
this._syncScrollLock(false);
|
|
333
|
+
this._longPressOpenedAt = null;
|
|
334
|
+
this._longPressGestureEndedAt = null;
|
|
335
|
+
this._menuHandle?.release();
|
|
336
|
+
this._menuHandle = null;
|
|
337
|
+
this._contentObserver.disconnect();
|
|
338
|
+
this._menuPositionGeneration.invalidate();
|
|
339
|
+
this._refreshScheduled = false;
|
|
340
|
+
this._closeMenuAfterPresence();
|
|
341
|
+
}
|
|
342
|
+
if (this._userOpenChange.consume()) this._dispatchChange(this._isOpen);
|
|
169
343
|
}
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
344
|
+
if (changed.has("noScrollLock")) this._syncScrollLock();
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* 在指定视口坐标打开 menu。
|
|
348
|
+
* @param x 水平坐标(px)。
|
|
349
|
+
* @param y 垂直坐标(px)。
|
|
350
|
+
* @returns 无返回值;命令式打开不派发 `open-change` 事件。
|
|
351
|
+
*/
|
|
352
|
+
openAt(x, y) {
|
|
353
|
+
this._openAt(x, y, true, true);
|
|
354
|
+
}
|
|
355
|
+
_openAt(x, y, isInstant, suppressFocusVisible, centerOnPressPoint = false) {
|
|
356
|
+
if (this.disabled) return false;
|
|
357
|
+
this._x = x;
|
|
358
|
+
this._y = y;
|
|
359
|
+
this._shouldOpenInstantly = isInstant;
|
|
360
|
+
this._suppressInitialFocusVisible = suppressFocusVisible;
|
|
361
|
+
this._centerOnPressPoint = centerOnPressPoint;
|
|
362
|
+
this._outsideClickGuard.arm();
|
|
363
|
+
if (this._isOpen) {
|
|
364
|
+
this._closeSubmenusFrom(0, true);
|
|
365
|
+
this._closingSubmenus.restoreAll();
|
|
366
|
+
this._menuPositionGeneration.invalidate();
|
|
367
|
+
this._scheduleRefresh();
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
this._isOpen = true;
|
|
371
|
+
this._menuItemActivationEvent = null;
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* 关闭 menu。
|
|
376
|
+
* @returns 无返回值;命令式关闭不派发 `open-change` 事件。
|
|
377
|
+
*/
|
|
178
378
|
close() {
|
|
179
|
-
|
|
180
|
-
|
|
379
|
+
if (!this._isOpen) return;
|
|
380
|
+
this._isOpen = false;
|
|
381
|
+
this._menuPositionGeneration.invalidate();
|
|
382
|
+
if (this._closeSource === "menu-item" || this._isDispatchingMenuItemActivation()) this._releaseScrimModality();
|
|
383
|
+
this._closeSource = "default";
|
|
384
|
+
this._menuItemActivationEvent = null;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* 「当前是否正处在一次可激活 menu item 的点击派发里」。
|
|
388
|
+
*
|
|
389
|
+
* 判据是 `eventPhase !== 0`(DOM 规范:派发开始前置 CAPTURING_PHASE,结束后由派发算法的
|
|
390
|
+
* terminating 步骤置回 NONE),即**事件自己知道它此刻有没有在派发中**。于是作用域精确等于
|
|
391
|
+
* 「这一次派发」,既不需要定时器也不需要猜微任务检查点的位置:
|
|
392
|
+
*
|
|
393
|
+
* - 消费方在条目自己的监听器里同步调 `close()` → 派发未结束 → 判定为真(要的就是这个)。
|
|
394
|
+
* - 消费方 `stopPropagation()` 让 menu 留着 → 派发照样结束 → 之后的 Escape / 点外面 / 程序式
|
|
395
|
+
* `close()` 一律判定为假,README 承诺的「那三条关闭不抢焦点」不会被这一次点击污染。
|
|
396
|
+
* - 消费方把 `close()` 推到下一个任务 → 判定为假,退回不提前出顶层(与没有这个标记时一致)。
|
|
397
|
+
*/
|
|
181
398
|
_isDispatchingMenuItemActivation() {
|
|
182
399
|
return this._menuItemActivationEvent !== null && this._menuItemActivationEvent.eventPhase !== 0;
|
|
183
400
|
}
|
|
184
401
|
_scheduleRefresh() {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
402
|
+
if (this._refreshScheduled || !this._isOpen) return;
|
|
403
|
+
this._refreshScheduled = true;
|
|
404
|
+
requestAnimationFrame(() => {
|
|
405
|
+
this._refreshScheduled = false;
|
|
406
|
+
if (!this._isOpen || !this._menu) return;
|
|
407
|
+
this._refreshMenu();
|
|
408
|
+
});
|
|
188
409
|
}
|
|
189
410
|
_refreshMenu() {
|
|
190
|
-
|
|
191
|
-
|
|
411
|
+
if (!this._menu) return;
|
|
412
|
+
this._setupMenuItems();
|
|
413
|
+
this._positionMenu();
|
|
414
|
+
this._hoverBinder.bind();
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* 定位:**触屏长按与鼠标右键共用这一条 Floating UI 路径**。
|
|
418
|
+
*
|
|
419
|
+
* 两条入口现在只差「触发点的 x/y 从哪来」,布局契约完全一致:
|
|
420
|
+
* `bottom-start` 表达「panel 上缘 == 触发点 y、向下展开」,水平以触发点 x 为基准。
|
|
421
|
+
* 落点交给 `flip` / `shift` 按**实际空间**决定,`placement` 只表达意图:把「贴视口底」硬编码
|
|
422
|
+
* 成算术,真机反馈证明那是错的(menu 跑到屏幕最底部,与手指按下的位置完全脱节)。
|
|
423
|
+
*
|
|
424
|
+
* 不按「是否触屏」分流:窄视口的鼠标右键同样期望 menu 贴着光标出现,按输入类型或视口
|
|
425
|
+
* 宽度分流会让同一块屏幕上的两种输入拿到两套布局。panel 恒为 open scrim `<dialog>` 的
|
|
426
|
+
* 直接子节点(`createMenuPortalOverlay` 第三参传入 scrim,`menu-portal.ts` 里
|
|
427
|
+
* `container = scrim ?? …`),所以「非 dialog 容器」的分支对 context-menu 不可达。
|
|
428
|
+
*
|
|
429
|
+
* 算出来的 left/top 是**视口坐标**。panel 是 `position: fixed`,而 scrim 刻意不带
|
|
430
|
+
* transform / filter / contain(见 style.css),因此不构成 fixed 的包含块 ——
|
|
431
|
+
* 坐标直接相对视口解析。这条等价关系由 style.css 的满屏声明保证,并由 R6 的
|
|
432
|
+
* 「scrim 无 transform/filter/contain」+ viewport-fit 的几何断言兜底。
|
|
433
|
+
*/
|
|
192
434
|
_positionMenu() {
|
|
193
|
-
|
|
194
|
-
if (!
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
435
|
+
const panel = this._menu?.panel;
|
|
436
|
+
if (!panel) return;
|
|
437
|
+
const safeAreaBottom = this._safeAreaBottom();
|
|
438
|
+
panel.style.visibility = "hidden";
|
|
439
|
+
panel.style.display = "";
|
|
440
|
+
const generation = this._menuPositionGeneration.next();
|
|
441
|
+
const boundaryPadding = {
|
|
442
|
+
top: VIEWPORT_PADDING,
|
|
443
|
+
bottom: VIEWPORT_PADDING + safeAreaBottom,
|
|
444
|
+
left: VIEWPORT_PADDING,
|
|
445
|
+
right: VIEWPORT_PADDING
|
|
446
|
+
};
|
|
447
|
+
const placements = this._centerOnPressPoint ? ["bottom", "top"] : ["bottom-start", "top-start"];
|
|
448
|
+
computePosition({ getBoundingClientRect: () => new DOMRect(this._x, this._y, 0, 0) }, panel, {
|
|
204
449
|
strategy: "fixed",
|
|
205
|
-
placement:
|
|
206
|
-
middleware: [
|
|
207
|
-
fallbackPlacements: [...
|
|
208
|
-
padding:
|
|
209
|
-
}),
|
|
210
|
-
padding:
|
|
211
|
-
crossAxis:
|
|
450
|
+
placement: placements[0],
|
|
451
|
+
middleware: [flip({
|
|
452
|
+
fallbackPlacements: [...placements],
|
|
453
|
+
padding: boundaryPadding
|
|
454
|
+
}), shift({
|
|
455
|
+
padding: boundaryPadding,
|
|
456
|
+
crossAxis: true
|
|
212
457
|
})]
|
|
213
|
-
}).then(({ x
|
|
214
|
-
if (!this._isOpen || this._menu?.panel !==
|
|
215
|
-
|
|
216
|
-
|
|
458
|
+
}).then(({ x, y, placement, middlewareData }) => {
|
|
459
|
+
if (!this._isOpen || this._menu?.panel !== panel || !this._menuPositionGeneration.isCurrent(generation)) return;
|
|
460
|
+
const shiftX = middlewareData.shift?.x ?? 0;
|
|
461
|
+
const horizontalOrigin = !placement.includes("-") ? shiftX === 0 ? "center" : shiftX < 0 ? "right" : "left" : shiftX < 0 ? "right" : "left";
|
|
462
|
+
this._applyMenuPosition(panel, x, y, horizontalOrigin, placement.startsWith("bottom") ? "top" : "bottom");
|
|
217
463
|
});
|
|
218
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* 视口下缘的安全区高度(px)。
|
|
467
|
+
*
|
|
468
|
+
* 它**仍然必需**,而且不只服务触屏:menu 默认从触发点向下长,触发点
|
|
469
|
+
* 落在屏幕下半部时 panel 下缘会进入 home indicator 区域。它折进 flip 与 shift 共用的
|
|
470
|
+
* 边界 padding(见 `_positionMenu`),不需要单独一条 `maxBottom` 算术。
|
|
471
|
+
*
|
|
472
|
+
* 读宿主的自定义属性而不是 `env()`:自定义属性读回的是**计算后**的解析值,
|
|
473
|
+
* 而 `env()` 在 JS 里没有对应的求值入口,只能间接经由声明它的属性取。
|
|
474
|
+
* 属性未解析时 `parseFloat` 得 NaN,落到 0 —— 与 `env(..., 0px)` 的缺省一致。
|
|
475
|
+
*/
|
|
219
476
|
_safeAreaBottom() {
|
|
220
|
-
|
|
221
|
-
return Number.isFinite(
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
477
|
+
const value = Number.parseFloat(getComputedStyle(this).getPropertyValue("--wui-context-menu-safe-area-bottom"));
|
|
478
|
+
return Number.isFinite(value) ? value : 0;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* 写下 panel 坐标与进场 transform 的原点。
|
|
482
|
+
*
|
|
483
|
+
* 两个 origin 必传且**不**再回退成坐标比较:flip 会改变垂直方向,回退表达式
|
|
484
|
+
* `y < this._y ? 'bottom' : 'top'` 在「panel 顶边与触发点重合」时两边都成立,等于随机取。
|
|
485
|
+
* 唯一调用方从 flip 后的 placement 与 shift 位移推出真实侧边,见 `_positionMenu`。
|
|
486
|
+
*/
|
|
487
|
+
_applyMenuPosition(panel, x, y, horizontalOrigin, verticalOrigin) {
|
|
488
|
+
panel.style.left = `${x}px`;
|
|
489
|
+
panel.style.top = `${y}px`;
|
|
490
|
+
panel.style.setProperty("--wui-internal-overlay-transform-origin", `${verticalOrigin} ${horizontalOrigin}`);
|
|
491
|
+
panel.style.visibility = "";
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* 把焦点带进 menu 的第一项。
|
|
495
|
+
*
|
|
496
|
+
* `attempt` 是重试计数:menu item 是刚被 `reconcileManagedMenuItems` 搬进来的自定义元素,
|
|
497
|
+
* 它们的 shadow(`.item-inner`)由各自的 Lit 更新**异步**渲染。`focusMenuItem()` 委托给
|
|
498
|
+
* 项的 `focusItem()`,那一刻 `.item-inner` 还不存在,于是**静默无操作** —— 不抛错、
|
|
499
|
+
* 也不留痕,只表现为「menu 开了但焦点没进去」。
|
|
500
|
+
*
|
|
501
|
+
* 所以这里不假设一次成功:调用后用 `findFocusedMenuItem` 复核,没落上就在下一帧再试,
|
|
502
|
+
* 最多 `FOCUS_FIRST_ITEM_ATTEMPTS` 次。上界是必要的 —— menu item 若始终渲染不出来
|
|
503
|
+
* (空 menu、内容被外部换掉),不能让重试链一直跑下去。
|
|
504
|
+
*/
|
|
505
|
+
_focusFirstItem(attempt = 0) {
|
|
506
|
+
const firstItem = (this._menu?.content.querySelectorAll("web-ui-dropdown-item:not([disabled])"))?.[0];
|
|
507
|
+
if (!firstItem) return;
|
|
508
|
+
focusMenuItem(firstItem, { suppressFocusVisible: this._suppressInitialFocusVisible });
|
|
509
|
+
if (attempt + 1 >= FOCUS_FIRST_ITEM_ATTEMPTS) return;
|
|
510
|
+
if (findFocusedMenuItem([this._menu?.panel])) return;
|
|
511
|
+
requestAnimationFrame(() => {
|
|
512
|
+
if (!this._isOpen || !this._menu) return;
|
|
513
|
+
this._focusFirstItem(attempt + 1);
|
|
514
|
+
});
|
|
231
515
|
}
|
|
232
516
|
_setupMenuItems() {
|
|
233
|
-
|
|
234
|
-
if (!
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
517
|
+
const menu = this._menu;
|
|
518
|
+
if (!menu) return;
|
|
519
|
+
const content = menu.content;
|
|
520
|
+
reconcileManagedMenuItems(this, content, this._menuItemAnchors, MARKER_TEXT);
|
|
521
|
+
this._hideMenuItems();
|
|
522
|
+
hideNestedMenuChildren(content, "context-menu-hidden");
|
|
523
|
+
const anchors = captureFrameworkAnchors(content, MARKER_TEXT);
|
|
524
|
+
orderManagedMenuItems(this, content, this._menuItemAnchors, MARKER_TEXT);
|
|
525
|
+
restoreFrameworkAnchors(content, anchors);
|
|
239
526
|
}
|
|
240
527
|
_returnItemsToSlot() {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
528
|
+
const menu = this._menu;
|
|
529
|
+
if (!menu) return;
|
|
530
|
+
this._closeSubmenusFrom(0, true);
|
|
531
|
+
this._closingSubmenus.restoreAll();
|
|
532
|
+
returnManagedMenuItemsToSlot(this, menu.content, this._menuItemAnchors);
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* 建 scrim 并让它进入模态态,返回容器供 panel 挂载。
|
|
536
|
+
*
|
|
537
|
+
* 每次开启都新建而不是复用:scrim 的生命周期必须与「这一次开启」严格同进同出。
|
|
538
|
+
* 复用一个 dialog 意味着上一轮的 `close()` 事件、`open` 属性与 UA 记下的焦点还原目标
|
|
539
|
+
* 会跨会话残留,而这些都不是本组件能重置的。
|
|
540
|
+
*/
|
|
244
541
|
_openScrim() {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
542
|
+
const scrim = document.createElement("dialog");
|
|
543
|
+
scrim.className = "wui-context-menu-scrim";
|
|
544
|
+
const scrimStyles = document.createElement("style");
|
|
545
|
+
scrimStyles.textContent = scrim_default;
|
|
546
|
+
scrim.append(scrimStyles);
|
|
547
|
+
scrim.setAttribute(SCRIM_ATTR, "");
|
|
548
|
+
scrim.addEventListener("click", this._onScrimClick);
|
|
549
|
+
scrim.addEventListener("cancel", this._onScrimCancel);
|
|
550
|
+
this._scrimParent().append(scrim);
|
|
551
|
+
scrim.showModal();
|
|
552
|
+
this._scrim = scrim;
|
|
553
|
+
return scrim;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* scrim 的挂载点:**与 panel 在没有 scrim 时会落到的容器同源** —— 最近主题的 theme-owned
|
|
557
|
+
* overlay root。scrim 就是那个容器的替身(panel 必须挂进 scrim,见 `updated()` 的顺序注释),
|
|
558
|
+
* 所以它得站在容器该站的位置上。
|
|
559
|
+
*
|
|
560
|
+
* 为什么不能在整棵 DOM 里随便挑位置:`--wui-color-*` 由 `<web-ui-theme>` 写在自己的 `:host`
|
|
561
|
+
* 上,只沿 DOM 树向下继承。scrim 若挂到 `document.body`,而 `<web-ui-theme>` 是 body 的**子节点**,
|
|
562
|
+
* 这条继承链就断了 —— panel 与 scrim 双双落回 `var(--wui-color-*, <浅色字面量>)` 的 fallback,
|
|
563
|
+
* 深色外观下 menu 是一块浅色玻璃(app 侧的 `dark:` 变体也够不到它)。挂进 theme overlay root
|
|
564
|
+
* 之后,panel 与 scrim 跟 dropdown / select 一样吃同一份 token。
|
|
565
|
+
*
|
|
566
|
+
* 无主题时挂在 `document.body`:那条路径本来就没有 token 作用域可继承,改用
|
|
567
|
+
* fallback overlay root 只会改变既有测试与消费者的观察面,不换来任何东西。
|
|
568
|
+
*/
|
|
250
569
|
_scrimParent() {
|
|
251
|
-
return
|
|
570
|
+
return findNearestTheme(this)?.getOverlayRoot() ?? document.body;
|
|
252
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* 关掉并摘除 scrim。幂等:关闭分支与 `disconnectedCallback` 都会调。
|
|
574
|
+
*
|
|
575
|
+
* `close()` 触发 UA 的焦点归还,**必须先于 panel `remove()`** —— 理由见 `_closeMenuAfterPresence`。
|
|
576
|
+
*/
|
|
253
577
|
_closeScrim() {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
578
|
+
const scrim = this._scrim;
|
|
579
|
+
if (!scrim) return;
|
|
580
|
+
this._scrim = void 0;
|
|
581
|
+
if (scrim.open) scrim.close();
|
|
582
|
+
scrim.remove();
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* 只让 scrim 出顶层,不摘除元素。panel 挂在 scrim 里,摘了就把退场动画一起摘掉。
|
|
586
|
+
*
|
|
587
|
+
* 提前出顶层是为了焦点(理由见 `close()`)。代价是这个尾巴上 scrim 已经在 top layer
|
|
588
|
+
* 之外:下层恢复可命中,且 panel 的层级退回普通流 —— 在「menu 开在 drawer/dialog 之上」
|
|
589
|
+
* 的场景里,退场动画会被下层的 top layer 盖住。
|
|
590
|
+
*
|
|
591
|
+
* 这条尾巴只有一次退场过渡的时长(默认 160ms),且只发生在 menu item 激活时。
|
|
592
|
+
* 摘除仍在 `_closeScrim()`,那时 panel 已经走完。
|
|
593
|
+
*/
|
|
257
594
|
_releaseScrimModality() {
|
|
258
|
-
|
|
259
|
-
|
|
595
|
+
const scrim = this._scrim;
|
|
596
|
+
if (scrim?.open) scrim.close();
|
|
260
597
|
}
|
|
261
598
|
async _closeMenuAfterPresence() {
|
|
262
|
-
|
|
263
|
-
|
|
599
|
+
const menu = this._menu;
|
|
600
|
+
if (menu && !await hideOverlayPresence(menu.panel)) return;
|
|
601
|
+
if (this._isOpen || !this.isConnected || this._menu !== menu) return;
|
|
602
|
+
this._closeScrim();
|
|
603
|
+
this._returnItemsToSlot();
|
|
604
|
+
menu?.panel.remove();
|
|
605
|
+
this._menu = void 0;
|
|
264
606
|
}
|
|
265
607
|
_hideMenuItems() {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
this.
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
608
|
+
getMenuChildren(this).forEach((child) => child.setAttribute("slot", "context-menu-hidden"));
|
|
609
|
+
hideNestedMenuChildren(this, "context-menu-hidden");
|
|
610
|
+
}
|
|
611
|
+
_openSubmenu(item, isInstant = false) {
|
|
612
|
+
if (!this._isOpen || !item.hasAttribute("submenu") || item.hasAttribute("disabled")) return;
|
|
613
|
+
const level = this._getItemLevel(item);
|
|
614
|
+
if (level === -1 || this._activeSubmenuItems[level] === item) return;
|
|
615
|
+
this._closeSubmenusFrom(level);
|
|
616
|
+
const closingSubmenu = this._closingSubmenus.take(item);
|
|
617
|
+
if (closingSubmenu) {
|
|
618
|
+
this._activeSubmenus[level] = closingSubmenu;
|
|
619
|
+
this._activeSubmenuItems[level] = item;
|
|
620
|
+
if (this._menuHandle) this._submenuHandles.set(closingSubmenu.panel, this._menuHandle.adopt(closingSubmenu.panel));
|
|
621
|
+
item.setAttribute("active", "");
|
|
622
|
+
this._positionSubmenu(item, closingSubmenu);
|
|
623
|
+
showOverlayPresence(closingSubmenu.panel, { isInstant });
|
|
624
|
+
this._hoverBinder.bind();
|
|
276
625
|
return;
|
|
277
626
|
}
|
|
278
|
-
if (
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
627
|
+
if (getMenuChildren(item).length === 0) return;
|
|
628
|
+
const submenu = createMenuPortalOverlay("context-submenu", this, this._scrim);
|
|
629
|
+
submenu.panel.dataset.level = String(level);
|
|
630
|
+
submenu.panel.setAttribute("role", "menu");
|
|
631
|
+
submenu.panel.setAttribute("aria-label", "submenu");
|
|
632
|
+
submenu.panel.style.visibility = "hidden";
|
|
633
|
+
submenu.panel.addEventListener("click", this._onMenuClick);
|
|
634
|
+
submenu.panel.addEventListener("click", this._onMenuItemActivation, true);
|
|
635
|
+
moveMenuChildren(item, submenu.content);
|
|
636
|
+
this._activeSubmenus[level] = submenu;
|
|
637
|
+
this._activeSubmenuItems[level] = item;
|
|
638
|
+
if (this._menuHandle) this._submenuHandles.set(submenu.panel, this._menuHandle.adopt(submenu.panel));
|
|
639
|
+
item.setAttribute("active", "");
|
|
640
|
+
this._positionSubmenu(item, submenu);
|
|
641
|
+
showOverlayPresence(submenu.panel, { isInstant });
|
|
642
|
+
this._hoverBinder.bind();
|
|
643
|
+
}
|
|
644
|
+
_closeSubmenusFrom(level, isInstant = false) {
|
|
645
|
+
for (let index = this._activeSubmenus.length - 1; index >= level; index--) {
|
|
646
|
+
const submenu = this._activeSubmenus[index];
|
|
647
|
+
const item = this._activeSubmenuItems[index];
|
|
648
|
+
item?.removeAttribute("active");
|
|
649
|
+
if (!item || isInstant) {
|
|
650
|
+
if (submenu) this._releaseSubmenu(submenu.panel);
|
|
651
|
+
this._restoreSubmenuItems(submenu, item);
|
|
652
|
+
submenu.panel.remove();
|
|
653
|
+
} else this._closingSubmenus.closeAsync(item, submenu);
|
|
286
654
|
}
|
|
287
|
-
this._activeSubmenus.length =
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
655
|
+
this._activeSubmenus.length = level;
|
|
656
|
+
this._activeSubmenuItems.length = level;
|
|
657
|
+
}
|
|
658
|
+
_restoreSubmenuItems(submenu, item) {
|
|
659
|
+
if (!item) return;
|
|
660
|
+
moveMenuChildren(submenu.content, item);
|
|
661
|
+
hideNestedMenuChildren(item, "context-menu-hidden");
|
|
662
|
+
}
|
|
663
|
+
_getItemLevel(item) {
|
|
664
|
+
if (this._menu?.panel.contains(item)) return 0;
|
|
665
|
+
const parentLevel = this._activeSubmenus.findIndex((submenu) => submenu.panel.contains(item));
|
|
666
|
+
return parentLevel === -1 ? -1 : parentLevel + 1;
|
|
667
|
+
}
|
|
668
|
+
_positionSubmenu(item, submenu) {
|
|
669
|
+
if (submenu.panel.parentElement instanceof HTMLDialogElement && submenu.panel.parentElement.open) {
|
|
670
|
+
const itemRect = item.getBoundingClientRect();
|
|
671
|
+
const padding = 8;
|
|
672
|
+
const canOpenRight = itemRect.right + submenu.panel.offsetWidth + padding <= window.innerWidth;
|
|
673
|
+
const epoch = (this._submenuPositionEpochs.get(submenu.panel) ?? 0) + 1;
|
|
674
|
+
this._submenuPositionEpochs.set(submenu.panel, epoch);
|
|
675
|
+
computePosition(item, submenu.panel, {
|
|
301
676
|
strategy: "fixed",
|
|
302
|
-
placement:
|
|
303
|
-
middleware: [
|
|
304
|
-
padding
|
|
305
|
-
crossAxis:
|
|
677
|
+
placement: canOpenRight ? "right-start" : "left-start",
|
|
678
|
+
middleware: [shift({
|
|
679
|
+
padding,
|
|
680
|
+
crossAxis: true
|
|
306
681
|
})]
|
|
307
|
-
}).then(({ x
|
|
308
|
-
if (!this._activeSubmenus.includes(
|
|
309
|
-
|
|
310
|
-
|
|
682
|
+
}).then(({ x, y, middlewareData }) => {
|
|
683
|
+
if (!this._activeSubmenus.includes(submenu) || epoch !== this._submenuPositionEpochs.get(submenu.panel)) return;
|
|
684
|
+
const shiftX = middlewareData.shift?.x ?? 0;
|
|
685
|
+
const shiftY = middlewareData.shift?.y ?? 0;
|
|
686
|
+
const horizontalOrigin = shiftX < 0 ? "right" : "left";
|
|
687
|
+
const verticalOrigin = shiftY < 0 ? "bottom" : "top";
|
|
688
|
+
submenu.panel.style.left = `${x}px`;
|
|
689
|
+
submenu.panel.style.top = `${y}px`;
|
|
690
|
+
submenu.panel.style.setProperty("--wui-internal-overlay-transform-origin", `${verticalOrigin} ${horizontalOrigin}`);
|
|
691
|
+
submenu.panel.style.visibility = "";
|
|
311
692
|
});
|
|
312
693
|
return;
|
|
313
694
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
695
|
+
const itemRect = item.getBoundingClientRect();
|
|
696
|
+
const padding = 8;
|
|
697
|
+
const submenuWidth = submenu.panel.offsetWidth;
|
|
698
|
+
const submenuHeight = submenu.panel.offsetHeight;
|
|
699
|
+
const canOpenRight = itemRect.right + submenuWidth + padding <= window.innerWidth;
|
|
700
|
+
const left = canOpenRight ? itemRect.right : Math.max(padding, itemRect.left - submenuWidth);
|
|
701
|
+
const top = Math.min(Math.max(padding, itemRect.top), window.innerHeight - submenuHeight - padding);
|
|
702
|
+
submenu.panel.style.left = `${left}px`;
|
|
703
|
+
submenu.panel.style.top = `${top}px`;
|
|
704
|
+
submenu.panel.style.setProperty("--wui-internal-overlay-transform-origin", canOpenRight ? "top left" : "top right");
|
|
705
|
+
submenu.panel.style.visibility = "";
|
|
706
|
+
}
|
|
707
|
+
_dispatchChange(open) {
|
|
708
|
+
dispatchOpenChangeEvent(this, open);
|
|
319
709
|
}
|
|
320
710
|
_cancelLongPress() {
|
|
321
|
-
|
|
711
|
+
if (this._longPressTimer !== void 0) {
|
|
712
|
+
clearTimeout(this._longPressTimer);
|
|
713
|
+
this._longPressTimer = void 0;
|
|
714
|
+
}
|
|
715
|
+
this._longPressOrigin = void 0;
|
|
322
716
|
}
|
|
717
|
+
/** 该事件是否是长按开 menu 之后、浏览器为同一次触摸补发的事件。 */
|
|
323
718
|
_isLongPressFollowUp() {
|
|
324
|
-
|
|
325
|
-
if (
|
|
326
|
-
|
|
327
|
-
|
|
719
|
+
const openedAt = this._longPressOpenedAt;
|
|
720
|
+
if (openedAt === null) return false;
|
|
721
|
+
const anchor = this._longPressGestureEndedAt ?? openedAt;
|
|
722
|
+
if (performance.now() - anchor > LONG_PRESS_FOLLOW_UP_WINDOW_MS) {
|
|
723
|
+
this._clearLongPressFollowUp();
|
|
724
|
+
return false;
|
|
725
|
+
}
|
|
726
|
+
return true;
|
|
328
727
|
}
|
|
728
|
+
/** 结束「同一次手势的补发事件」窗口。与 _longPressOpenedAt 的清零同源,两处都要清。 */
|
|
329
729
|
_clearLongPressFollowUp() {
|
|
330
|
-
this._longPressOpenedAt = null
|
|
730
|
+
this._longPressOpenedAt = null;
|
|
731
|
+
this._longPressGestureEndedAt = null;
|
|
331
732
|
}
|
|
332
|
-
_getLevelContainer(
|
|
333
|
-
return
|
|
733
|
+
_getLevelContainer(level) {
|
|
734
|
+
return level === 0 ? this._menu : this._activeSubmenus[level - 1];
|
|
334
735
|
}
|
|
335
|
-
_getLevelItems(
|
|
336
|
-
|
|
337
|
-
|
|
736
|
+
_getLevelItems(level) {
|
|
737
|
+
const container = this._getLevelContainer(level);
|
|
738
|
+
if (!container) return [];
|
|
739
|
+
return getMenuChildren(container.content);
|
|
338
740
|
}
|
|
339
741
|
_closeLastSubmenuOrMenu() {
|
|
340
742
|
if (this._activeSubmenus.length > 0) {
|
|
341
|
-
|
|
342
|
-
|
|
743
|
+
const level = this._activeSubmenus.length - 1;
|
|
744
|
+
const parent = this._activeSubmenuItems[level];
|
|
745
|
+
this._closeSubmenusFrom(level);
|
|
746
|
+
focusMenuItem(parent);
|
|
747
|
+
this._hoverBinder.bind();
|
|
343
748
|
} else this._closeFromUser();
|
|
344
749
|
}
|
|
345
750
|
_preventBackgroundScroll(e) {
|
|
346
|
-
!this._isOpen || this.noScrollLock || this._isMenuPanelEvent(e)
|
|
751
|
+
if (!this._isOpen || this.noScrollLock || this._isMenuPanelEvent(e)) return;
|
|
752
|
+
e.preventDefault();
|
|
347
753
|
}
|
|
348
|
-
_syncScrollLock(
|
|
349
|
-
this._scrollLock.sync(
|
|
754
|
+
_syncScrollLock(isOpen = this._isOpen) {
|
|
755
|
+
this._scrollLock.sync(isOpen && !this.noScrollLock);
|
|
350
756
|
}
|
|
351
|
-
|
|
352
|
-
|
|
757
|
+
/** 按 panel 撤销一层 submenu 的登记;handle 已随根层递归撤销时幂等无操作。 */
|
|
758
|
+
_releaseSubmenu(panel) {
|
|
759
|
+
this._submenuHandles.get(panel)?.release();
|
|
760
|
+
this._submenuHandles.delete(panel);
|
|
353
761
|
}
|
|
354
762
|
_isMenuPanelEvent(e) {
|
|
355
|
-
return this._menuHandle?.containsEvent(e) ??
|
|
763
|
+
return this._menuHandle?.containsEvent(e) ?? false;
|
|
356
764
|
}
|
|
357
765
|
render() {
|
|
358
|
-
return
|
|
766
|
+
return html`
|
|
359
767
|
<div class="context-menu-anchor">
|
|
360
768
|
<slot @slotchange=${this._onSlotChange}></slot>
|
|
361
769
|
</div>
|
|
362
770
|
`;
|
|
363
771
|
}
|
|
364
772
|
_onSlotChange() {
|
|
365
|
-
this._hideMenuItems()
|
|
773
|
+
this._hideMenuItems();
|
|
774
|
+
if (this._isOpen) this._scheduleRefresh();
|
|
366
775
|
}
|
|
367
776
|
};
|
|
368
|
-
|
|
777
|
+
__decorate([property({
|
|
369
778
|
type: Boolean,
|
|
370
|
-
reflect:
|
|
371
|
-
})],
|
|
779
|
+
reflect: true
|
|
780
|
+
})], WebUiContextMenu.prototype, "disabled", void 0);
|
|
781
|
+
__decorate([property({
|
|
372
782
|
type: Boolean,
|
|
373
|
-
reflect:
|
|
783
|
+
reflect: true,
|
|
374
784
|
attribute: "no-scroll-lock"
|
|
375
|
-
})],
|
|
785
|
+
})], WebUiContextMenu.prototype, "noScrollLock", void 0);
|
|
786
|
+
__decorate([property({
|
|
376
787
|
type: Boolean,
|
|
377
|
-
reflect:
|
|
788
|
+
reflect: true,
|
|
378
789
|
attribute: "long-press"
|
|
379
|
-
})],
|
|
790
|
+
})], WebUiContextMenu.prototype, "longPress", void 0);
|
|
791
|
+
__decorate([property({
|
|
380
792
|
type: Number,
|
|
381
793
|
attribute: "long-press-delay"
|
|
382
|
-
})],
|
|
383
|
-
|
|
384
|
-
|
|
794
|
+
})], WebUiContextMenu.prototype, "longPressDelay", null);
|
|
795
|
+
__decorate([state()], WebUiContextMenu.prototype, "_isOpen", void 0);
|
|
796
|
+
__decorate([state()], WebUiContextMenu.prototype, "_x", void 0);
|
|
797
|
+
__decorate([state()], WebUiContextMenu.prototype, "_y", void 0);
|
|
798
|
+
WebUiContextMenu = __decorate([customElement("web-ui-context-menu")], WebUiContextMenu);
|
|
799
|
+
export { WebUiContextMenu };
|
|
385
800
|
|
|
386
801
|
//# sourceMappingURL=index.js.map
|